Add common function calling support
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user