- moved all handling for the simple calls into EmitterArray to have it in one place only.

The main case of FxVmFunctionCall is not done yet, though.
This commit is contained in:
Christoph Oelckers 2018-11-18 08:29:41 +01:00
parent 629d329f22
commit cbedcff559
4 changed files with 58 additions and 58 deletions

View file

@ -783,8 +783,8 @@ void SetDehParams(FState *state, int codepointer)
}
// Emit code for action parameters.
MBFCodePointerFactories[codepointer](emitters, value1, value2);
int count = emitters.EmitParameters(&buildit);
buildit.Emit(OP_CALL_K, buildit.GetConstantAddress(sym->Variants[0].Implementation), count, 0);
emitters.AddTarget(sym->Variants[0].Implementation);
emitters.EmitCall(&buildit);
buildit.Emit(OP_RET, RET_FINAL, REGT_NIL, 0);
// Attach it to the state.
VMScriptFunction *sfunc = new VMScriptFunction;

View file

@ -5499,12 +5499,9 @@ ExpEmit FxRandom::Emit(VMFunctionBuilder *build)
emitters.AddParameterPointerConst(rng);
emitters.AddParameter(build, min);
emitters.AddParameter(build, max);
int count = emitters.EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), count, 1);
ExpEmit out(build, REGT_INT);
build->Emit(OP_RESULT, 0, REGT_INT, out.RegNum);
return out;
emitters.AddTarget(callfunc);
emitters.AddReturn(REGT_INT);
return emitters.EmitCall(build);
}
//==========================================================================
@ -5608,10 +5605,10 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
emitters.AddParameterPointerConst(rng);
emitters.AddParameterIntConst(0);
emitters.AddParameterIntConst(choices.Size() - 1);
int count = emitters.EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), count, 1);
emitters.AddTarget(callfunc);
emitters.AddReturn(REGT_INT);
auto resultreg = emitters.EmitCall(build);
ExpEmit resultreg(build, REGT_INT);
build->Emit(OP_RESULT, 0, REGT_INT, resultreg.RegNum);
build->Emit(OP_IJMP, resultreg.RegNum, choices.Size());
@ -5729,12 +5726,9 @@ ExpEmit FxFRandom::Emit(VMFunctionBuilder *build)
emitters.AddParameterPointerConst(rng);
emitters.AddParameter(build, min);
emitters.AddParameter(build, max);
int count = emitters.EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), count, 1);
ExpEmit out(build, REGT_FLOAT);
build->Emit(OP_RESULT, 0, REGT_FLOAT, out.RegNum);
return out;
emitters.AddTarget(callfunc);
emitters.AddReturn(REGT_FLOAT);
return emitters.EmitCall(build);
}
//==========================================================================
@ -5810,12 +5804,9 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build)
emitters.AddParameterPointerConst(rng);
emitters.AddParameter(build, mask);
int count = emitters.EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), count, 1);
ExpEmit out(build, REGT_INT);
build->Emit(OP_RESULT, 0, REGT_INT, out.RegNum);
return out;
emitters.AddTarget(callfunc);
emitters.AddReturn(REGT_INT);
return emitters.EmitCall(build);
}
//==========================================================================
@ -5885,11 +5876,8 @@ ExpEmit FxRandomSeed::Emit(VMFunctionBuilder *build)
emitters.AddParameterPointerConst(rng);
emitters.AddParameter(build, seed);
int count = emitters.EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), count, 0);
ExpEmit call;
return call;
emitters.AddTarget(callfunc);
return emitters.EmitCall(build);
}
//==========================================================================
@ -8554,9 +8542,7 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
EmitterArray emitters;
emitters.AddParameterIntConst(abs(Special)); // pass special number
ExpEmit selfemit(Self->Emit(build));
emitters.AddParameterPointer(selfemit.RegNum, selfemit.Konst);
emitters.AddParameter(build, Self);
for (; i < ArgList.Size(); ++i)
{
@ -8590,13 +8576,9 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
ArgList.DeleteAndClear();
ArgList.ShrinkToFit();
int count = emitters.EmitParameters(build);
selfemit.Free(build);
ExpEmit dest(build, REGT_INT);
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), count, 1);
build->Emit(OP_RESULT, 0, REGT_INT, dest.RegNum);
return dest;
emitters.AddTarget(callfunc);
emitters.AddReturn(REGT_INT);
return emitters.EmitCall(build);
}
//==========================================================================
@ -10641,8 +10623,8 @@ ExpEmit FxReturnStatement::Emit(VMFunctionBuilder *build)
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(build->ConstructedStructs[i]->StackOffset));
EmitterArray emitters;
emitters.AddParameter(reg, false);
int count = emitters.EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor), count, 0);
emitters.AddTarget(pstr->mDestructor);
emitters.EmitCall(build);
}
// If we return nothing, use a regular RET opcode.
@ -10834,11 +10816,8 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)
{
return ExpEmit(build->GetConstantAddress(nullptr), REGT_POINTER, true);
}
ExpEmit clsname = basex->Emit(build);
assert(!clsname.Konst);
ExpEmit dest(build, REGT_POINTER);
EmitterArray emitters;
emitters.AddParameter(clsname, false);
emitters.AddParameter(build, basex);
emitters.AddParameterPointerConst(const_cast<PClass *>(desttype));
// Call the BuiltinNameToClass function to convert from 'name' to class.
@ -10849,10 +10828,9 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
callfunc = ((PSymbolVMFunction *)sym)->Function;
int count = emitters.EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), count, 1);
build->Emit(OP_RESULT, 0, REGT_POINTER, dest.RegNum);
return dest;
emitters.AddTarget(callfunc);
emitters.AddReturn(REGT_POINTER);
return emitters.EmitCall(build);
}
//==========================================================================
@ -10958,11 +10936,9 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build)
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
callfunc = ((PSymbolVMFunction *)sym)->Function;
ExpEmit dest(build, REGT_POINTER);
int count = emitters.EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), count, 1);
build->Emit(OP_RESULT, 0, REGT_POINTER, dest.RegNum);
return dest;
emitters.AddTarget(callfunc);
emitters.AddReturn(REGT_POINTER);
return emitters.EmitCall(build);
}
//==========================================================================
@ -11337,8 +11313,8 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset));
EmitterArray emitters;
emitters.AddParameter(reg, false);
int count = emitters.EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mConstructor), count, 0);
emitters.AddTarget(pstr->mConstructor);
emitters.EmitCall(build);
}
if (pstr->mDestructor != nullptr) build->ConstructedStructs.Push(this);
}
@ -11364,8 +11340,8 @@ void FxLocalVariableDeclaration::Release(VMFunctionBuilder *build)
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset));
EmitterArray emitters;
emitters.AddParameter(reg, false);
int count = emitters.EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor), count, 0);
emitters.AddTarget(pstr->mDestructor);
emitters.EmitCall(build);
}
build->ConstructedStructs.Delete(build->ConstructedStructs.Find(this));
}

View file

@ -1038,3 +1038,16 @@ int EmitterArray::EmitParameters(VMFunctionBuilder *build)
assert(paramcount == numparams);
return paramcount;
}
ExpEmit EmitterArray::EmitCall(VMFunctionBuilder *build)
{
int count = EmitParameters(build);
build->Emit(OP_CALL_K, build->GetConstantAddress(target), count, returns.Size());
if (returns.Size() == 0) return ExpEmit();
ExpEmit out(build, returns[0]);
build->Emit(OP_RESULT, 0, returns[0], out.RegNum);
return out;
}

View file

@ -167,7 +167,9 @@ class EmitterArray
{
// std::function and TArray are not compatible so this has to use std::vector instead.
std::vector<std::function<int(VMFunctionBuilder *)>> emitters;
unsigned numparams = 0;
TArray<int> returns;
unsigned numparams = 0; // This counts the number of pushed elements, which can differ from the number of emitters with vectors.
VMFunction *target = nullptr;
public:
void AddParameter(VMFunctionBuilder *build, FxExpression *operand);
@ -178,6 +180,15 @@ public:
void AddParameterIntConst(int konst);
void AddParameterStringConst(const FString &konst);
int EmitParameters(VMFunctionBuilder *build);
ExpEmit EmitCall(VMFunctionBuilder *build);
void AddReturn(int regtype)
{
returns.Push(regtype);
}
void AddTarget(VMFunction *func)
{
target = func;
}
unsigned Count() const
{
return numparams;