1
0

Add common function calling support

This commit is contained in:
otya128
2016-12-23 20:36:18 +09:00
parent 53e7138bd7
commit aa3c8af549
3 changed files with 33 additions and 3 deletions

View File

@@ -31,6 +31,11 @@ struct VMVariable
} }
class VMSlot class VMSlot
{ {
int index;
this(int index)
{
this.index = index;
}
bool isUsed; bool isUsed;
DataTable globalDataTable; DataTable globalDataTable;
//2MBらしい //2MBらしい
@@ -64,7 +69,7 @@ class VM
this.backTraceStack = new Trace[16384]; this.backTraceStack = new Trace[16384];
for(int i = 0; i < slots.length; i++) for(int i = 0; i < slots.length; i++)
{ {
slots[i] = new VMSlot(); slots[i] = new VMSlot(i);
} }
} }
int currentSlotNumber() int currentSlotNumber()
@@ -102,6 +107,7 @@ class VM
{ {
if (f.isCommon) if (f.isCommon)
{ {
f.isDead = true;
commonFunctions.remove(f.name); commonFunctions.remove(f.name);
} }
} }
@@ -123,6 +129,7 @@ class VM
if (f.name in commonFunctions) if (f.name in commonFunctions)
throw new DuplicateFunction(slot, dinfo.getLocationByAddress(f.address)); throw new DuplicateFunction(slot, dinfo.getLocationByAddress(f.address));
commonFunctions[f.name] = f; commonFunctions[f.name] = f;
f.slot = s;
} }
} }
s.globalDataTable = gdt; s.globalDataTable = gdt;
@@ -209,8 +216,9 @@ class VM
void pushpc() void pushpc()
{ {
Value value; Value value;
value.type = ValueType.InternalAddress; value.type = ValueType.InternalSlotAddress;
value.integerValue = pc; value.internalAddress.address = pc;
value.internalAddress.slot = cast(byte)currentSlotNumber;
push(value); push(value);
} }
void push(ref Value value) void push(ref Value value)
@@ -1374,6 +1382,8 @@ class CallFunctionCode : Code
void resolve(VM vm) void resolve(VM vm)
{ {
func = vm.currentSlot.functions.get(name, null); func = vm.currentSlot.functions.get(name, null);
if (!func)
func = vm.commonFunctions.get(name, null);
if (!func) if (!func)
throw new SyntaxError(name); throw new SyntaxError(name);
} }
@@ -1384,6 +1394,10 @@ class CallFunctionCode : Code
//楽だし実行時に解決させる //楽だし実行時に解決させる
resolve(vm); resolve(vm);
} }
if (func.isDead)
{
resolve(vm);
}
if(func.argCount != this.argCount) if(func.argCount != this.argCount)
{ {
throw new IllegalFunctionCall(name.to!string); throw new IllegalFunctionCall(name.to!string);
@@ -1392,6 +1406,10 @@ class CallFunctionCode : Code
{ {
throw new IllegalFunctionCall(name.to!string); throw new IllegalFunctionCall(name.to!string);
} }
if (func.isCommon)
{
vm.setCurrentSlot(func.slot.index);
}
vm.pushBackTrace(name); vm.pushBackTrace(name);
//TODO:args //TODO:args
auto bp = vm.stacki; auto bp = vm.stacki;
@@ -1477,6 +1495,10 @@ class CallFunctionS : Code
vm.stack[bp + v.index] = Value(v.type); vm.stack[bp + v.index] = Value(v.type);
} }
} }
if (func.isCommon)
{
vm.setCurrentSlot(func.slot.index);
}
} }
override void execute(VM vm) override void execute(VM vm)
{ {
@@ -1489,6 +1511,10 @@ class CallFunctionS : Code
auto name = vname.castDString.toUpper; auto name = vname.castDString.toUpper;
Function func = vm.currentSlot.functions.get(name, null); Function func = vm.currentSlot.functions.get(name, null);
if (!func) if (!func)
{
func = vm.commonFunctions.get(name, null);
}
if(!func)
{ {
auto bfuncs = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(name, null); auto bfuncs = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(name, null);
if (!bfuncs) if (!bfuncs)

View File

@@ -104,6 +104,8 @@ class Function
bool returnExpr; bool returnExpr;
int outArgCount; int outArgCount;
bool isCommon; bool isCommon;
VMSlot slot;/*common function*/
bool isDead;/*common function*/
/** /**
0:bp 0:bp
1:pc 1:pc

View File

@@ -213,6 +213,8 @@ struct Value
case ValueType.StringArray: case ValueType.StringArray:
return format("doublearray[%s]", length); return format("doublearray[%s]", length);
case ValueType.InternalAddress: case ValueType.InternalAddress:
return format("internal address address=0x%x", integerValue);
case ValueType.InternalSlotAddress:
return format("internal address slot=%d, address=0x%x", internalAddress.slot, internalAddress.address); return format("internal address slot=%d, address=0x%x", internalAddress.slot, internalAddress.address);
default: default:
return type.to!string; return type.to!string;