From 6f1bf257e980fbe8bad16c50579cb76b19fdd2c2 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 14 Feb 2010 19:59:21 +0000 Subject: [PATCH] - State code now properly calls action functions and has a RET instruction. As expected, running with the checked VM can be quite slow, since it has asserts everywhere. Some other fixes were needed before the code actually worked: - A_CallSpecial needs to have its arguments cast to ints. - Some functions that set pnum/paramnum directly did not decrement it by 1. This also applies to A_Jump, though it just uses the value of paramnum instead of changing it. - Renamed pnum in the PARAM macros to paramnum, since pnum is already used in a few other places for something different, so this makes searching for it easier. This has not been tested especially thoroughly, but a first glance seems to indicate success. SVN r2163 (scripting) --- src/thingdef/thingdef.cpp | 73 +++++++++++++++--------- src/thingdef/thingdef.h | 7 ++- src/thingdef/thingdef_codeptr.cpp | 11 ++-- src/thingdef/thingdef_expression.cpp | 12 ++-- src/thingdef/thingdef_states.cpp | 8 +-- src/zscript/vm.h | 85 +++++++++++++++------------- src/zscript/vmdisasm.cpp | 2 +- src/zscript/vmexec.h | 35 +++++------- wadsrc/static/actors/actor.txt | 1 - 9 files changed, 128 insertions(+), 106 deletions(-) diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index 4e526665d9..b22e558d36 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -286,42 +286,59 @@ static void FinishThingdef() for (i = 0; i < StateTempCalls.Size(); ++i) { FStateTempCall *tcall = StateTempCalls[i]; - FCompileContext ctx(tcall->ActorInfo->Class, true); - for (j = 0; j < tcall->Parameters.Size(); ++j) + VMFunction *func; + + assert(tcall->Function != NULL); + if (tcall->Parameters.Size() == 0) { - tcall->Parameters[j]->Resolve(ctx); + func = tcall->Function; } - VMFunctionBuilder buildit; - // Allocate registers used to pass parameters in. - // self, stateowner, state, statecalldata (all are pointers) - buildit.Registers[REGT_POINTER].Get(4); - // Emit code for action parameters. - for (j = 0; j < tcall->Parameters.Size(); ++j) + else { - FxExpression *p = /*new FxParameter*/(tcall->Parameters[j]); - p->Emit(&buildit); - delete p; + FCompileContext ctx(tcall->ActorInfo->Class, true); + for (j = 0; j < tcall->Parameters.Size(); ++j) + { + tcall->Parameters[j]->Resolve(ctx); + } + VMFunctionBuilder buildit; + // Allocate registers used to pass parameters in. + // self, stateowner, state, statecalldata (all are pointers) + buildit.Registers[REGT_POINTER].Get(4); + // Emit code to pass the standard action function parameters. + buildit.Emit(OP_PARAM, 0, REGT_POINTER, 0); + buildit.Emit(OP_PARAM, 0, REGT_POINTER, 1); + buildit.Emit(OP_PARAM, 0, REGT_POINTER, 2); + buildit.Emit(OP_PARAM, 0, REGT_POINTER, 3); + // Emit code for action parameters. + for (j = 0; j < tcall->Parameters.Size(); ++j) + { + FxExpression *p = /*new FxParameter*/(tcall->Parameters[j]); + p->Emit(&buildit); + delete p; + } + buildit.Emit(OP_CALL_K, buildit.GetConstantAddress(tcall->Function, ATAG_OBJECT), NAP + j, 0); + buildit.Emit(OP_RET, 0, REGT_NIL, 0); + VMScriptFunction *sfunc = buildit.MakeFunction(); + sfunc->NumArgs = NAP; + func = sfunc; +#if 1 + const char *marks = "======================================================="; + char label[64]; + int labellen = mysnprintf(label, countof(label), "Function %s.States[%d] (*%d)", + tcall->ActorInfo->Class->TypeName.GetChars(), + tcall->FirstState, tcall->NumStates); + fprintf(dump, "\n%.*s %s %.*s", MAX(3, 38 - labellen / 2), marks, label, MAX(3, 38 - labellen / 2), marks); + fprintf(dump, "\nInteger regs: %-3d Float regs: %-3d Address regs: %-3d String regs: %-3d\nStack size: %d\n", + sfunc->NumRegD, sfunc->NumRegF, sfunc->NumRegA, sfunc->NumRegS, sfunc->MaxParam); + VMDumpConstants(dump, sfunc); + fprintf(dump, "\nDisassembly @ %p:\n", sfunc->Code); + VMDisasm(dump, sfunc->Code, sfunc->CodeSize, sfunc); +#endif } - buildit.Emit(OP_CALL_K, buildit.GetConstantAddress(NULL, ATAG_OBJECT), j, 0); - VMScriptFunction *func = buildit.MakeFunction(); - func->NumArgs = tcall->Parameters.Size(); for (int k = 0; k < tcall->NumStates; ++k) { tcall->ActorInfo->OwnedStates[tcall->FirstState + k].SetAction(func); } -#if 1 - const char *marks = "======================================================="; - char label[64]; - int labellen = mysnprintf(label, countof(label), "Function %s.States[%d] (*%d)", - tcall->ActorInfo->Class->TypeName.GetChars(), - tcall->FirstState, tcall->NumStates); - fprintf(dump, "\n%.*s %s %.*s", MAX(3, 38 - labellen / 2), marks, label, MAX(3, 38 - labellen / 2), marks); - fprintf(dump, "\nInteger regs: %-3d Float regs: %-3d Address regs: %-3d String regs: %-3d\nStack size: %d\n", - func->NumRegD, func->NumRegF, func->NumRegA, func->NumRegS, func->MaxParam); - VMDumpConstants(dump, func); - fprintf(dump, "\nDisassembly:\n"); - VMDisasm(dump, func->Code, func->CodeSize, func); -#endif } fclose(dump); diff --git a/src/thingdef/thingdef.h b/src/thingdef/thingdef.h index 60ff50620f..4829cc306b 100644 --- a/src/thingdef/thingdef.h +++ b/src/thingdef/thingdef.h @@ -111,10 +111,13 @@ public: struct FStateTempCall { + FStateTempCall() : ActorInfo(NULL), Function(NULL), FirstState(0), NumStates(0) {} + FActorInfo *ActorInfo; + VMFunction *Function; + TArray Parameters; int FirstState; int NumStates; - TArray Parameters; }; extern TDeletingArray StateTempCalls; @@ -386,7 +389,7 @@ struct StateCallData //#define PUSH_PARAMINFO self, stateowner, CallingState, ParameterIndex, statecall #define CALL_ACTION(name,self) { /*AF_##name(self, self, NULL, 0, NULL)*/ \ - VMValue params[5] = { self, self, NULL, VMValue(NULL, ATAG_STATE) }; \ + VMValue params[5] = { self, self, VMValue(NULL, ATAG_STATE), VMValue(NULL, ATAG_GENERIC) }; \ stack->Call(name##_VMPtr, params, countof(params), NULL, 0, NULL); \ } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 9da7ff3b51..c12f41a527 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -452,11 +452,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Jump) PARAM_ACTION_PROLOGUE; PARAM_INT_OPT(maxchance) { maxchance = 256; } - int count = numparam - pnum; + paramnum++; // Increment paramnum to point at the first jump target + int count = numparam - paramnum; if (count > 0 && (maxchance >= 256 || pr_cajump() < maxchance)) { int jumpnum = (count == 1 ? 0 : (pr_cajump() % count)); - PARAM_STATE_AT(pnum + jumpnum, jumpto); + PARAM_STATE_AT(paramnum + jumpnum, jumpto); ACTION_JUMP(jumpto); } ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains! @@ -529,7 +530,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfCloser) //========================================================================== void DoJumpIfInventory(AActor *owner, AActor *self, StateCallData *statecall, FState *callingstate, VMValue *param, int numparam) { - int pnum = NAP; + int paramnum = NAP-1; PARAM_CLASS (itemtype, AInventory); PARAM_INT (itemamount); PARAM_STATE (label); @@ -1314,7 +1315,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) static void DoGiveInventory(AActor *receiver, StateCallData *statecall, VM_ARGS) { - int pnum = NAP; + int paramnum = NAP-1; PARAM_CLASS (mi, AInventory); PARAM_INT_OPT (amount) { amount = 1; } @@ -1381,7 +1382,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GiveToTarget) void DoTakeInventory(AActor *receiver, StateCallData *statecall, VM_ARGS) { - int pnum = NAP; + int paramnum = NAP-1; PARAM_CLASS (itemtype, AInventory); PARAM_INT_OPT (amount) { amount = 0; } diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 7b32a132f1..5167bba6a5 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -3735,7 +3735,7 @@ int DecoNameToClass(VMFrameStack *stack, VMValue *param, int numparam, VMReturn Printf("class '%s' is not compatible with '%s'", clsname.GetChars(), desttype->TypeName.GetChars()); cls = NULL; } - ret->SetPointer(const_cast(cls)); + ret->SetPointer(const_cast(cls), ATAG_OBJECT); return 1; } @@ -3923,15 +3923,15 @@ int DecoFindMultiNameState(VMFrameStack *stack, VMValue *param, int numparam, VM { assert(numparam > 1); assert(numret == 1); - assert(param[0].Type == REGT_POINTER); assert(ret->RegType == REGT_POINTER); FName *names = (FName *)alloca((numparam - 1) * sizeof(FName)); for (int i = 1; i < numparam; ++i) { - names[i - 1] = ENamedName(param[i].i); + PARAM_NAME_AT(i, zaname); + names[i - 1] = zaname; } - AActor *self = reinterpret_cast(param[0].a); + PARAM_OBJECT_AT(0, self, AActor); FState *state = self->GetClass()->ActorInfo->FindState(numparam - 1, names); if (state == NULL) { @@ -3944,14 +3944,14 @@ int DecoFindMultiNameState(VMFrameStack *stack, VMValue *param, int numparam, VM } Printf("' not found in %s\n", self->GetClass()->TypeName.GetChars()); } - ret->SetPointer(state); + ret->SetPointer(state, ATAG_STATE); return 1; } ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build) { ExpEmit dest(build, REGT_POINTER); - build->Emit(OP_PARAM, 0, REGT_POINTER, 0); // pass self + build->Emit(OP_PARAM, 0, REGT_POINTER, 1); // pass stateowner for (unsigned i = 0; i < names.Size(); ++i) { EmitConstantInt(build, names[i]); diff --git a/src/thingdef/thingdef_states.cpp b/src/thingdef/thingdef_states.cpp index a27bd48d31..208581b516 100644 --- a/src/thingdef/thingdef_states.cpp +++ b/src/thingdef/thingdef_states.cpp @@ -81,7 +81,7 @@ bool DoActionSpecials(FScanner &sc, FState & state, Baggage &bag, FStateTempCall { for (i = 0; i < 5;) { - tcall->Parameters.Push(new FxParameter(ParseExpression(sc, bag.Info->Class))); + tcall->Parameters.Push(new FxParameter(new FxIntCast(ParseExpression(sc, bag.Info->Class)))); i++; if (!sc.CheckToken (',')) break; } @@ -98,8 +98,7 @@ bool DoActionSpecials(FScanner &sc, FState & state, Baggage &bag, FStateTempCall sc.ScriptError ("Too many arguments to %s", specname.GetChars()); } - //FIXME - //state.SetAction(FindGlobalActionFunction("A_CallSpecial"), false); + tcall->Function = FindGlobalActionFunction("A_CallSpecial")->Function; return true; } return false; @@ -262,6 +261,7 @@ do_stop: if (sym != NULL && sym->SymbolType == SYM_ActionFunction) { PSymbolActionFunction *afd = static_cast(sym); + tcall->Function = afd->Function; if (!afd->Arguments.IsEmpty()) { const char *params = afd->Arguments.GetChars(); @@ -374,7 +374,7 @@ endofstate: sc.ScriptError ("Invalid frame character string '%s'", statestring.GetChars()); count = -count; } - if (tcall->Parameters.Size() != 0) + if (tcall->Function != NULL) { tcall->ActorInfo = actor; tcall->FirstState = bag.statedef.GetStateCount() - count; diff --git a/src/zscript/vm.h b/src/zscript/vm.h index 21a67188e4..72e2141d58 100644 --- a/src/zscript/vm.h +++ b/src/zscript/vm.h @@ -251,54 +251,63 @@ extern const VMOpInfo OpInfo[NUM_OPS]; struct VMReturn { void *Location; - VM_SHALF RegNum; // Used to find ObjFlag index for pointers; set negative if the caller is native code and doesn't care + VM_SHALF TagOfs; // for pointers: Offset from Location to ATag; set to 0 if the caller is native code and doesn't care VM_UBYTE RegType; // Same as VMParam RegType, except REGT_KONST is invalid; only used by asserts void SetInt(int val) { + assert(RegType == REGT_INT); *(int *)Location = val; } void SetFloat(double val) { + assert(RegType == REGT_FLOAT); *(double *)Location = val; } void SetVector(const double val[3]) - { + { + //assert(RegType == REGT_FLOAT); ((double *)Location)[0] = val[0]; ((double *)Location)[1] = val[1]; ((double *)Location)[2] = val[2]; } void SetString(const FString &val) { + assert(RegType == REGT_STRING); *(FString *)Location = val; } - void SetPointer(void *val) + void SetPointer(void *val, int tag) { + assert(RegType == REGT_POINTER); *(void **)Location = val; + if (TagOfs != 0) + { + *((VM_ATAG *)Location + TagOfs) = tag; + } } void IntAt(int *loc) { Location = loc; - RegNum = -1; + TagOfs = 0; RegType = REGT_INT; } void FloatAt(double *loc) { Location = loc; - RegNum = -1; + TagOfs = 0; RegType = REGT_FLOAT; } void StringAt(FString *loc) { Location = loc; - RegNum = -1; + TagOfs = 0; RegType = REGT_STRING; } void PointerAt(void **loc) { Location = loc; - RegNum = -1; + TagOfs = 0; RegType = REGT_POINTER; } }; @@ -863,8 +872,8 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_STRING_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_STRING); FString x = param[p].s(); #define PARAM_STATE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].a == NULL)); FState *x = (FState *)param[p].a; #define PARAM_POINTER_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)param[p].a; -#define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); type *x = (type *)param[p].a; -#define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); PClass *x = (PClass *)param[p].a; assert(x->IsDescendantOf(RUNTIME_CLASS(base))); +#define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); type *x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); +#define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); PClass *x = (PClass *)param[p].a; assert(x != NULL && x->IsDescendantOf(RUNTIME_CLASS(base))); // For optional paramaters. These have dangling elses for you to fill in the default assignment. e.g.: // PARAM_INT_OPT(0,myint) { myint = 55; } @@ -881,38 +890,38 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_STRING_OPT_AT(p,x) FString x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_STRING); x = param[p].s(); } else #define PARAM_STATE_OPT_AT(p,x) FState *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].a == NULL)); x = (FState *)param[p].a; } else #define PARAM_POINTER_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER); x = (type *)param[p].a; } else -#define PARAM_OBJECT_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (type *)param[p].a; } else -#define PARAM_CLASS_OPT_AT(p,x,base) PClass *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (PClass *)param[p].a; assert(x->IsKindOf(RUNTIME_CLASS(base))); } else +#define PARAM_OBJECT_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); } else +#define PARAM_CLASS_OPT_AT(p,x,base) PClass *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (PClass *)param[p].a; assert(x != NULL && x->IsDescendantOf(RUNTIME_CLASS(base))); } else // The above, but with an automatically increasing position index. -#define PARAM_PROLOGUE int pnum = -1; +#define PARAM_PROLOGUE int paramnum = -1; -#define PARAM_INT(x) ++pnum; PARAM_INT_AT(pnum,x) -#define PARAM_BOOL(x) ++pnum; PARAM_BOOL_AT(pnum,x) -#define PARAM_NAME(x) ++pnum; PARAM_NAME_AT(pnum,x) -#define PARAM_SOUND(x) ++pnum; PARAM_SOUND_AT(pnum,x) -#define PARAM_COLOR(x) ++pnum; PARAM_COLOR_AT(pnum,x) -#define PARAM_FLOAT(x) ++pnum; PARAM_FLOAT_AT(pnum,x) -#define PARAM_FIXED(x) ++pnum; PARAM_FIXED_AT(pnum,x) -#define PARAM_ANGLE(x) ++pnum; PARAM_ANGLE_AT(pnum,x) -#define PARAM_STRING(x) ++pnum; PARAM_STRING_AT(pnum,x) -#define PARAM_STATE(x) ++pnum; PARAM_STATE_AT(pnum,x) -#define PARAM_POINTER(x,type) ++pnum; PARAM_POINTER_AT(pnum,x,type) -#define PARAM_OBJECT(x,type) ++pnum; PARAM_OBJECT_AT(pnum,x,type) -#define PARAM_CLASS(x,base) ++pnum; PARAM_CLASS_AT(pnum,x,base) +#define PARAM_INT(x) ++paramnum; PARAM_INT_AT(paramnum,x) +#define PARAM_BOOL(x) ++paramnum; PARAM_BOOL_AT(paramnum,x) +#define PARAM_NAME(x) ++paramnum; PARAM_NAME_AT(paramnum,x) +#define PARAM_SOUND(x) ++paramnum; PARAM_SOUND_AT(paramnum,x) +#define PARAM_COLOR(x) ++paramnum; PARAM_COLOR_AT(paramnum,x) +#define PARAM_FLOAT(x) ++paramnum; PARAM_FLOAT_AT(paramnum,x) +#define PARAM_FIXED(x) ++paramnum; PARAM_FIXED_AT(paramnum,x) +#define PARAM_ANGLE(x) ++paramnum; PARAM_ANGLE_AT(paramnum,x) +#define PARAM_STRING(x) ++paramnum; PARAM_STRING_AT(paramnum,x) +#define PARAM_STATE(x) ++paramnum; PARAM_STATE_AT(paramnum,x) +#define PARAM_POINTER(x,type) ++paramnum; PARAM_POINTER_AT(paramnum,x,type) +#define PARAM_OBJECT(x,type) ++paramnum; PARAM_OBJECT_AT(paramnum,x,type) +#define PARAM_CLASS(x,base) ++paramnum; PARAM_CLASS_AT(paramnum,x,base) -#define PARAM_INT_OPT(x) ++pnum; PARAM_INT_OPT_AT(pnum,x) -#define PARAM_BOOL_OPT(x) ++pnum; PARAM_BOOL_OPT_AT(pnum,x) -#define PARAM_NAME_OPT(x) ++pnum; PARAM_NAME_OPT_AT(pnum,x) -#define PARAM_SOUND_OPT(x) ++pnum; PARAM_SOUND_OPT_AT(pnum,x) -#define PARAM_COLOR_OPT(x) ++pnum; PARAM_COLOR_OPT_AT(pnum,x) -#define PARAM_FLOAT_OPT(x) ++pnum; PARAM_FLOAT_OPT_AT(pnum,x) -#define PARAM_FIXED_OPT(x) ++pnum; PARAM_FIXED_OPT_AT(pnum,x) -#define PARAM_ANGLE_OPT(x) ++pnum; PARAM_ANGLE_OPT_AT(pnum,x) -#define PARAM_STRING_OPT(x) ++pnum; PARAM_STRING_OPT_AT(pnum,x) -#define PARAM_STATE_OPT(x) ++pnum; PARAM_STATE_OPT_AT(pnum,x) -#define PARAM_POINTER_OPT(x,type) ++pnum; PARAM_POINTER_OPT_AT(pnum,x,type) -#define PARAM_OBJECT_OPT(x,type) ++pnum; PARAM_OBJECT_OPT_AT(pnum,x,type) -#define PARAM_CLASS_OPT(x,base) ++pnum; PARAM_CLASS_OPT_AT(pnum,x,base) +#define PARAM_INT_OPT(x) ++paramnum; PARAM_INT_OPT_AT(paramnum,x) +#define PARAM_BOOL_OPT(x) ++paramnum; PARAM_BOOL_OPT_AT(paramnum,x) +#define PARAM_NAME_OPT(x) ++paramnum; PARAM_NAME_OPT_AT(paramnum,x) +#define PARAM_SOUND_OPT(x) ++paramnum; PARAM_SOUND_OPT_AT(paramnum,x) +#define PARAM_COLOR_OPT(x) ++paramnum; PARAM_COLOR_OPT_AT(paramnum,x) +#define PARAM_FLOAT_OPT(x) ++paramnum; PARAM_FLOAT_OPT_AT(paramnum,x) +#define PARAM_FIXED_OPT(x) ++paramnum; PARAM_FIXED_OPT_AT(paramnum,x) +#define PARAM_ANGLE_OPT(x) ++paramnum; PARAM_ANGLE_OPT_AT(paramnum,x) +#define PARAM_STRING_OPT(x) ++paramnum; PARAM_STRING_OPT_AT(paramnum,x) +#define PARAM_STATE_OPT(x) ++paramnum; PARAM_STATE_OPT_AT(paramnum,x) +#define PARAM_POINTER_OPT(x,type) ++paramnum; PARAM_POINTER_OPT_AT(paramnum,x,type) +#define PARAM_OBJECT_OPT(x,type) ++paramnum; PARAM_OBJECT_OPT_AT(paramnum,x,type) +#define PARAM_CLASS_OPT(x,base) ++paramnum; PARAM_CLASS_OPT_AT(paramnum,x,base) #endif diff --git a/src/zscript/vmdisasm.cpp b/src/zscript/vmdisasm.cpp index 9175cc096a..5e7d4e0cc0 100644 --- a/src/zscript/vmdisasm.cpp +++ b/src/zscript/vmdisasm.cpp @@ -155,7 +155,7 @@ void VMDumpConstants(FILE *out, const VMScriptFunction *func) { for (j = 0, k = i; j < 4 && k < func->NumKonstA; j++, k += kk) { - mysnprintf(tmp, countof(tmp), "%3d. %p", k, func->KonstA[k]); + mysnprintf(tmp, countof(tmp), "%3d. %p:%d", k, func->KonstA[k], func->KonstATags()[k]); printf_wrapper(out, "%-20s", tmp); } printf_wrapper(out, "\n"); diff --git a/src/zscript/vmexec.h b/src/zscript/vmexec.h index 07809909b6..e9847946f5 100644 --- a/src/zscript/vmexec.h +++ b/src/zscript/vmexec.h @@ -1384,7 +1384,7 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c static void FillReturns(const VMRegisters ®, VMFrame *frame, VMReturn *returns, const VMOP *retval, int numret) { - int i, type, num; + int i, type, regnum; VMReturn *ret; assert(REGT_INT == 0 && REGT_FLOAT == 1 && REGT_STRING == 2 && REGT_POINTER == 3); @@ -1392,33 +1392,35 @@ static void FillReturns(const VMRegisters ®, VMFrame *frame, VMReturn *return for (i = 0, ret = returns; i < numret; ++i, ++ret, ++retval) { assert(retval->op == OP_RESULT); // opcode + ret->TagOfs = 0; ret->RegType = type = retval->b; - ret->RegNum = num = retval->c; + regnum = retval->c; assert(!(type & REGT_KONST)); type &= REGT_TYPE; if (type < REGT_STRING) { if (type == REGT_INT) { - assert(num < frame->NumRegD); - ret->Location = ®.d[num]; + assert(regnum < frame->NumRegD); + ret->Location = ®.d[regnum]; } else // type == REGT_FLOAT { - assert(num < frame->NumRegF); - ret->Location = ®.f[num]; + assert(regnum < frame->NumRegF); + ret->Location = ®.f[regnum]; } } else if (type == REGT_STRING) { - assert(num < frame->NumRegS); - ret->Location = ®.s[num]; + assert(regnum < frame->NumRegS); + ret->Location = ®.s[regnum]; } else { assert(type == REGT_POINTER); - assert(num < frame->NumRegA); - ret->Location = ®.a[num]; + assert(regnum < frame->NumRegA); + ret->Location = ®.a[regnum]; + ret->TagOfs = (VM_SHALF)(&frame->GetRegATag()[regnum] - (VM_ATAG *)ret->Location); } } } @@ -1434,7 +1436,6 @@ static void FillReturns(const VMRegisters ®, VMFrame *frame, VMReturn *return static void SetReturn(const VMRegisters ®, VMFrame *frame, VMReturn *ret, VM_UBYTE regtype, int regnum) { const void *src; - VM_ATAG atag; VMScriptFunction *func = static_cast(frame->Func); assert(func != NULL && !func->Native); @@ -1498,20 +1499,12 @@ static void SetReturn(const VMRegisters ®, VMFrame *frame, VMReturn *ret, VM_ if (regtype & REGT_KONST) { assert(regnum < func->NumKonstA); - ret->SetPointer(func->KonstA[regnum].v); - atag = func->KonstATags()[regnum]; + ret->SetPointer(func->KonstA[regnum].v, func->KonstATags()[regnum]); } else { assert(regnum < frame->NumRegA); - ret->SetPointer(reg.a[regnum]); - atag = reg.atag[regnum]; - } - if (ret->RegNum >= 0) - { - VMFrame *parent = frame->ParentFrame; - assert(parent != NULL); - parent->GetRegATag()[ret->RegNum] = atag; + ret->SetPointer(reg.a[regnum], reg.atag[regnum]); } break; } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 0bb53fa0aa..568ecf262a 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -26,7 +26,6 @@ ACTOR Actor native //: Thinker native fixed_t alpha; native angle_t angle; native int args[5]; - native int uservar[10]; native fixed_t ceilingz; native fixed_t floorz; native int health;