diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index f33cd2129..3d7f18e36 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -696,8 +696,11 @@ static void CreatePlaySoundFunc(FunctionCallEmitter &emitters, int value1, int v // misc1 = state, misc2 = probability static void CreateRandomJumpFunc(FunctionCallEmitter &emitters, int value1, int value2) { // A_Jump + auto symlabel = StateLabels.AddPointer(FindState(value1)); + emitters.AddParameterIntConst(value2); // maxchance - emitters.AddParameterPointerConst(FindState(value1)); // jumpto + emitters.AddParameterIntConst(symlabel); // jumpto + emitters.AddReturn(REGT_POINTER); } // misc1 = Boom linedef type, misc2 = sector tag @@ -754,6 +757,8 @@ void SetDehParams(FState *state, int codepointer) int value2 = state->GetMisc2(); if (!(value1|value2)) return; + bool returnsState = codepointer == 6; + // Fakey fake script position thingamajig. Because NULL cannot be used instead. // Even if the lump was parsed by an FScanner, there would hardly be a way to // identify which line is troublesome. @@ -772,6 +777,7 @@ void SetDehParams(FState *state, int codepointer) else { int numargs = sym->GetImplicitArgs(); + auto funcsym = CreateAnonymousFunction(RUNTIME_CLASS(AActor)->VMType, returnsState? (PType*)TypeState : TypeVoid, numargs==3? SUF_ACTOR|SUF_WEAPON : SUF_ACTOR); VMFunctionBuilder buildit(numargs); // Allocate registers used to pass parameters in. // self, stateowner, state (all are pointers) @@ -784,10 +790,15 @@ void SetDehParams(FState *state, int codepointer) } // Emit code for action parameters. MBFCodePointerFactories[codepointer](emitters, value1, value2); - emitters.EmitCall(&buildit); - buildit.Emit(OP_RET, RET_FINAL, REGT_NIL, 0); + auto where = emitters.EmitCall(&buildit); + if (!returnsState) buildit.Emit(OP_RET, RET_FINAL, REGT_NIL, 0); + else buildit.Emit(OP_RET, RET_FINAL, EncodeRegType(where), where.RegNum); + where.Free(&buildit); + // Attach it to the state. VMScriptFunction *sfunc = new VMScriptFunction; + funcsym->Variants[0].Implementation = sfunc; + sfunc->Proto = funcsym->Variants[0].Proto; sfunc->RegTypes = regts; // These functions are built after running the script compiler so they don't get this info. buildit.MakeFunction(sfunc); sfunc->NumArgs = numargs; diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index 287a49908..928f645a8 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -208,7 +208,7 @@ void SetImplicitArgs(TArray *args, TArray *argflags, TArray rets(1); + TArray rets; TArray args; TArray argflags; TArray argnames; @@ -220,7 +220,7 @@ PFunction *CreateAnonymousFunction(PContainerType *containingclass, PType *retur // (just give them VARF_Play, whatever) fflags |= VARF_Play; - rets[0] = returntype != nullptr? returntype : TypeError; // Use TypeError as placeholder if we do not know the return type yet. + if (returntype) rets.Push(returntype); SetImplicitArgs(&args, &argflags, &argnames, containingclass, fflags, flags); PFunction *sym = Create(containingclass, NAME_None); // anonymous functions do not have names.