- extended the register limit for 'param'.
The instruction one free instruction byte so it's now using that to extend its argument's register range to 65535. For param this is needed because it passes strings by reference and creating an implicit temporary copy for string constants does not work here.
This commit is contained in:
parent
eee0946bc5
commit
dd719f0f14
6 changed files with 134 additions and 113 deletions
|
|
@ -519,12 +519,12 @@ static int EmitParameter(VMFunctionBuilder *build, FxExpression *operand, const
|
|||
if (where.RegType == REGT_NIL)
|
||||
{
|
||||
pos.Message(MSG_ERROR, "Attempted to pass a non-value");
|
||||
build->Emit(OP_PARAM, 0, where.RegType, where.RegNum);
|
||||
build->Emit(OP_PARAM, where.RegType, where.RegNum);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
build->Emit(OP_PARAM, 0, EncodeRegType(where), where.RegNum);
|
||||
build->Emit(OP_PARAM, EncodeRegType(where), where.RegNum);
|
||||
if (tempstrings != nullptr && where.RegType == REGT_STRING && !where.Fixed && !where.Konst)
|
||||
{
|
||||
tempstrings->Push(where); // keep temp strings until after the function call.
|
||||
|
|
@ -5549,7 +5549,7 @@ ExpEmit FxRandom::Emit(VMFunctionBuilder *build)
|
|||
if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
|
||||
int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K);
|
||||
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
if (min != nullptr && max != nullptr)
|
||||
{
|
||||
EmitParameter(build, min, ScriptPosition);
|
||||
|
|
@ -5670,7 +5670,7 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
|
|||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
build->EmitParamInt(0);
|
||||
build->EmitParamInt(choices.Size() - 1);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), 3, 1);
|
||||
|
|
@ -5800,7 +5800,7 @@ ExpEmit FxFRandom::Emit(VMFunctionBuilder *build)
|
|||
if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
|
||||
int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K);
|
||||
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
if (min != nullptr && max != nullptr)
|
||||
{
|
||||
EmitParameter(build, min, ScriptPosition);
|
||||
|
|
@ -5895,7 +5895,7 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build)
|
|||
if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
|
||||
int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K);
|
||||
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
EmitParameter(build, mask, ScriptPosition);
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc), 2, 1);
|
||||
|
||||
|
|
@ -5978,7 +5978,7 @@ ExpEmit FxRandomSeed::Emit(VMFunctionBuilder *build)
|
|||
if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
|
||||
int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K);
|
||||
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
EmitParameter(build, seed, ScriptPosition);
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc), 2, 0);
|
||||
|
||||
|
|
@ -8644,7 +8644,7 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
|
|||
build->Emit(OP_PARAMI, abs(Special)); // pass special number
|
||||
|
||||
ExpEmit selfemit(Self->Emit(build));
|
||||
build->Emit(OP_PARAM, 0, selfemit.Konst ? REGT_POINTER | REGT_KONST : REGT_POINTER, selfemit.RegNum); // pass special number
|
||||
build->Emit(OP_PARAM, selfemit.Konst ? REGT_POINTER | REGT_KONST : REGT_POINTER, selfemit.RegNum); // pass special number
|
||||
for (; i < ArgList.Size(); ++i)
|
||||
{
|
||||
FxExpression *argex = ArgList[i];
|
||||
|
|
@ -8664,7 +8664,7 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
|
|||
else
|
||||
{
|
||||
ExpEmit arg(argex->Emit(build));
|
||||
build->Emit(OP_PARAM, 0, arg.RegType, arg.RegNum);
|
||||
build->Emit(OP_PARAM, arg.RegType, arg.RegNum);
|
||||
arg.Free(build);
|
||||
}
|
||||
}
|
||||
|
|
@ -9086,11 +9086,11 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
|||
if ((selfemit.Fixed && selfemit.Target) || selfemit.RegType == REGT_STRING)
|
||||
{
|
||||
// Address of a local variable.
|
||||
build->Emit(OP_PARAM, 0, selfemit.RegType | REGT_ADDROF, selfemit.RegNum);
|
||||
build->Emit(OP_PARAM, selfemit.RegType | REGT_ADDROF, selfemit.RegNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
build->Emit(OP_PARAM, 0, selfemit.RegType, selfemit.RegNum);
|
||||
build->Emit(OP_PARAM, selfemit.RegType, selfemit.RegNum);
|
||||
}
|
||||
count += 1;
|
||||
if (Function->Variants[0].Flags & VARF_Action)
|
||||
|
|
@ -9098,14 +9098,14 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
|||
static_assert(NAP == 3, "This code needs to be updated if NAP changes");
|
||||
if (build->NumImplicits == NAP && selfemit.RegNum == 0) // only pass this function's stateowner and stateinfo if the subfunction is run in self's context.
|
||||
{
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 1);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 2);
|
||||
build->Emit(OP_PARAM, REGT_POINTER, 1);
|
||||
build->Emit(OP_PARAM, REGT_POINTER, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// pass self as stateowner, otherwise all attempts of the subfunction to retrieve a state from a name would fail.
|
||||
build->Emit(OP_PARAM, 0, selfemit.RegType, selfemit.RegNum);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(nullptr));
|
||||
build->Emit(OP_PARAM, selfemit.RegType, selfemit.RegNum);
|
||||
build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(nullptr));
|
||||
}
|
||||
count += 2;
|
||||
}
|
||||
|
|
@ -10696,7 +10696,7 @@ ExpEmit FxReturnStatement::Emit(VMFunctionBuilder *build)
|
|||
assert(pstr->mDestructor != nullptr);
|
||||
ExpEmit reg(build, REGT_POINTER);
|
||||
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(build->ConstructedStructs[i]->StackOffset));
|
||||
build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum);
|
||||
build->Emit(OP_PARAM, reg.RegType, reg.RegNum);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor), 1, 0);
|
||||
reg.Free(build);
|
||||
}
|
||||
|
|
@ -10893,8 +10893,8 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)
|
|||
ExpEmit clsname = basex->Emit(build);
|
||||
assert(!clsname.Konst);
|
||||
ExpEmit dest(build, REGT_POINTER);
|
||||
build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast<PClass *>(desttype)));
|
||||
build->Emit(OP_PARAM, clsname.RegType, clsname.RegNum);
|
||||
build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast<PClass *>(desttype)));
|
||||
|
||||
// Call the BuiltinNameToClass function to convert from 'name' to class.
|
||||
VMFunction *callfunc;
|
||||
|
|
@ -11002,8 +11002,8 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
ExpEmit clsname = basex->Emit(build);
|
||||
|
||||
build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(desttype));
|
||||
build->Emit(OP_PARAM, clsname.RegType, clsname.RegNum);
|
||||
build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(desttype));
|
||||
|
||||
VMFunction *callfunc;
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinClassCast, BuiltinClassCast);
|
||||
|
|
@ -11388,7 +11388,7 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
ExpEmit reg(build, REGT_POINTER);
|
||||
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset));
|
||||
build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum);
|
||||
build->Emit(OP_PARAM, reg.RegType, reg.RegNum);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mConstructor), 1, 0);
|
||||
reg.Free(build);
|
||||
}
|
||||
|
|
@ -11414,7 +11414,7 @@ void FxLocalVariableDeclaration::Release(VMFunctionBuilder *build)
|
|||
{
|
||||
ExpEmit reg(build, REGT_POINTER);
|
||||
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset));
|
||||
build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum);
|
||||
build->Emit(OP_PARAM, reg.RegType, reg.RegNum);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor), 1, 0);
|
||||
reg.Free(build);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -593,39 +593,19 @@ size_t VMFunctionBuilder::Emit(int opcode, int opa, int opb, int opc)
|
|||
}
|
||||
if (opc > 255)
|
||||
{
|
||||
if (opcode == OP_PARAM && (opb & REGT_KONST) && opc <= 32767)
|
||||
if (opRemap[opcode].kReg != 4 || opc > 32767)
|
||||
{
|
||||
int regtype = opb & REGT_TYPE;
|
||||
opb = regtype;
|
||||
ExpEmit emit(this, regtype);
|
||||
Emit(opcodes[regtype], emit.RegNum, opc);
|
||||
opc = emit.RegNum;
|
||||
emit.Free(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opRemap[opcode].kReg != 4 || opc > 32767)
|
||||
{
|
||||
I_Error("Register limit exceeded");
|
||||
}
|
||||
int regtype = opRemap[opcode].kType;
|
||||
ExpEmit emit(this, regtype);
|
||||
Emit(opcodes[regtype], emit.RegNum, opc);
|
||||
opcode = opRemap[opcode].altOp;
|
||||
opc = emit.RegNum;
|
||||
emit.Free(this);
|
||||
I_Error("Register limit exceeded");
|
||||
}
|
||||
int regtype = opRemap[opcode].kType;
|
||||
ExpEmit emit(this, regtype);
|
||||
Emit(opcodes[regtype], emit.RegNum, opc);
|
||||
opcode = opRemap[opcode].altOp;
|
||||
opc = emit.RegNum;
|
||||
emit.Free(this);
|
||||
}
|
||||
|
||||
if (opcode == OP_PARAM)
|
||||
{
|
||||
int chg;
|
||||
if (opb & REGT_MULTIREG2) chg = 2;
|
||||
else if (opb®T_MULTIREG3) chg = 3;
|
||||
else chg = 1;
|
||||
ParamChange(chg);
|
||||
}
|
||||
else if (opcode == OP_CALL || opcode == OP_CALL_K || opcode == OP_TAIL || opcode == OP_TAIL_K)
|
||||
if (opcode == OP_CALL || opcode == OP_CALL_K || opcode == OP_TAIL || opcode == OP_TAIL_K)
|
||||
{
|
||||
ParamChange(-opb);
|
||||
}
|
||||
|
|
@ -641,6 +621,16 @@ size_t VMFunctionBuilder::Emit(int opcode, int opa, VM_SHALF opbc)
|
|||
{
|
||||
assert(opcode >= 0 && opcode < NUM_OPS);
|
||||
assert(opa >= 0 && opa <= 255);
|
||||
|
||||
if (opcode == OP_PARAM)
|
||||
{
|
||||
int chg;
|
||||
if (opa & REGT_MULTIREG2) chg = 2;
|
||||
else if (opa & REGT_MULTIREG3) chg = 3;
|
||||
else chg = 1;
|
||||
ParamChange(chg);
|
||||
}
|
||||
|
||||
//assert(opbc >= -32768 && opbc <= 32767); always true due to parameter's width
|
||||
VMOP op;
|
||||
op.op = opcode;
|
||||
|
|
@ -681,7 +671,7 @@ size_t VMFunctionBuilder::EmitParamInt(int value)
|
|||
}
|
||||
else
|
||||
{
|
||||
return Emit(OP_PARAM, 0, REGT_INT | REGT_KONST, GetConstantInt(value));
|
||||
return Emit(OP_PARAM, REGT_INT | REGT_KONST, GetConstantInt(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@
|
|||
#define I24 MODE_ABCJOINT
|
||||
#define I8 MODE_AIMMZ | MODE_BUNUSED | MODE_CUNUSED
|
||||
#define I8I16 MODE_AIMMZ | MODE_BCIMMZ
|
||||
#define __BCP MODE_AUNUSED | MODE_BCJOINT | MODE_BCPARAM
|
||||
#define __BCP MODE_PARAM24
|
||||
#define RPI8 MODE_AP | MODE_BIMMZ | MODE_CUNUSED
|
||||
#define KPI8 MODE_AKP | MODE_BIMMZ | MODE_CUNUSED
|
||||
#define RPI8I8 MODE_AP | MODE_BIMMZ | MODE_CIMMZ
|
||||
|
|
@ -292,7 +292,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
|||
a &= CMP_CHECK | CMP_APPROX;
|
||||
cmp = true;
|
||||
}
|
||||
if (code[i].op == OP_PARAM && code[i].b & REGT_ADDROF)
|
||||
if (code[i].op == OP_PARAM && code[i].a & REGT_ADDROF)
|
||||
{
|
||||
name = "parama";
|
||||
}
|
||||
|
|
@ -340,6 +340,20 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_PARAM:
|
||||
{
|
||||
col = print_reg(out, col, code[i].i24 & 0xffffff, MODE_PARAM24, 16, func);
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_RESULT:
|
||||
{
|
||||
// Default handling for this broke after changing OP_PARAM...
|
||||
col = print_reg(out, col, code[i].i16u, MODE_PARAM, 16, func);
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_RET:
|
||||
if (code[i].b != REGT_NIL)
|
||||
{
|
||||
|
|
@ -583,14 +597,31 @@ static int print_reg(FILE *out, int col, int arg, int mode, int immshift, const
|
|||
return col+printf_wrapper(out, "%d", arg);
|
||||
|
||||
case MODE_PARAM:
|
||||
{
|
||||
int regtype, regnum;
|
||||
case MODE_PARAM24:
|
||||
{
|
||||
int regtype, regnum;
|
||||
#ifdef __BIG_ENDIAN__
|
||||
if (mode == MODE_PARAM)
|
||||
{
|
||||
regtype = (arg >> 8) & 255;
|
||||
regnum = arg & 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
regtype = (arg >> 16) & 255;
|
||||
regnum = arg & 65535;
|
||||
}
|
||||
#else
|
||||
if (mode == MODE_PARAM)
|
||||
{
|
||||
regtype = arg & 255;
|
||||
regnum = (arg >> 8) & 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
regtype = arg & 255;
|
||||
regnum = (arg >> 8) & 65535;
|
||||
}
|
||||
#endif
|
||||
switch (regtype & (REGT_TYPE | REGT_KONST | REGT_MULTIREG))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -582,77 +582,77 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
|||
assert(f->NumParam < sfunc->MaxParam);
|
||||
{
|
||||
VMValue *param = ®.param[f->NumParam++];
|
||||
b = B;
|
||||
if (b == REGT_NIL)
|
||||
b = BC;
|
||||
if (a == REGT_NIL)
|
||||
{
|
||||
::new(param) VMValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(b)
|
||||
switch(a)
|
||||
{
|
||||
case REGT_INT:
|
||||
assert(C < f->NumRegD);
|
||||
::new(param) VMValue(reg.d[C]);
|
||||
assert(b < f->NumRegD);
|
||||
::new(param) VMValue(reg.d[b]);
|
||||
break;
|
||||
case REGT_INT | REGT_ADDROF:
|
||||
assert(C < f->NumRegD);
|
||||
::new(param) VMValue(®.d[C]);
|
||||
assert(b < f->NumRegD);
|
||||
::new(param) VMValue(®.d[b]);
|
||||
break;
|
||||
case REGT_INT | REGT_KONST:
|
||||
assert(C < sfunc->NumKonstD);
|
||||
::new(param) VMValue(konstd[C]);
|
||||
assert(b < sfunc->NumKonstD);
|
||||
::new(param) VMValue(konstd[b]);
|
||||
break;
|
||||
case REGT_STRING:
|
||||
assert(C < f->NumRegS);
|
||||
::new(param) VMValue(®.s[C]);
|
||||
assert(b < f->NumRegS);
|
||||
::new(param) VMValue(®.s[b]);
|
||||
break;
|
||||
case REGT_STRING | REGT_ADDROF:
|
||||
assert(C < f->NumRegS);
|
||||
::new(param) VMValue((void*)®.s[C]); // Note that this may not use the FString* version of the constructor!
|
||||
assert(b < f->NumRegS);
|
||||
::new(param) VMValue((void*)®.s[b]); // Note that this may not use the FString* version of the constructor!
|
||||
break;
|
||||
case REGT_STRING | REGT_KONST:
|
||||
assert(C < sfunc->NumKonstS);
|
||||
::new(param) VMValue(&konsts[C]);
|
||||
assert(b < sfunc->NumKonstS);
|
||||
::new(param) VMValue(&konsts[b]);
|
||||
break;
|
||||
case REGT_POINTER:
|
||||
assert(C < f->NumRegA);
|
||||
::new(param) VMValue(reg.a[C]);
|
||||
assert(b < f->NumRegA);
|
||||
::new(param) VMValue(reg.a[b]);
|
||||
break;
|
||||
case REGT_POINTER | REGT_ADDROF:
|
||||
assert(C < f->NumRegA);
|
||||
::new(param) VMValue(®.a[C]);
|
||||
assert(b < f->NumRegA);
|
||||
::new(param) VMValue(®.a[b]);
|
||||
break;
|
||||
case REGT_POINTER | REGT_KONST:
|
||||
assert(C < sfunc->NumKonstA);
|
||||
::new(param) VMValue(konsta[C].v);
|
||||
assert(b < sfunc->NumKonstA);
|
||||
::new(param) VMValue(konsta[b].v);
|
||||
break;
|
||||
case REGT_FLOAT:
|
||||
assert(C < f->NumRegF);
|
||||
::new(param) VMValue(reg.f[C]);
|
||||
assert(b < f->NumRegF);
|
||||
::new(param) VMValue(reg.f[b]);
|
||||
break;
|
||||
case REGT_FLOAT | REGT_MULTIREG2:
|
||||
assert(C < f->NumRegF - 1);
|
||||
assert(b < f->NumRegF - 1);
|
||||
assert(f->NumParam < sfunc->MaxParam);
|
||||
::new(param) VMValue(reg.f[C]);
|
||||
::new(param + 1) VMValue(reg.f[C + 1]);
|
||||
::new(param) VMValue(reg.f[b]);
|
||||
::new(param + 1) VMValue(reg.f[b + 1]);
|
||||
f->NumParam++;
|
||||
break;
|
||||
case REGT_FLOAT | REGT_MULTIREG3:
|
||||
assert(C < f->NumRegF - 2);
|
||||
assert(b < f->NumRegF - 2);
|
||||
assert(f->NumParam < sfunc->MaxParam - 1);
|
||||
::new(param) VMValue(reg.f[C]);
|
||||
::new(param + 1) VMValue(reg.f[C + 1]);
|
||||
::new(param + 2) VMValue(reg.f[C + 2]);
|
||||
::new(param) VMValue(reg.f[b]);
|
||||
::new(param + 1) VMValue(reg.f[b + 1]);
|
||||
::new(param + 2) VMValue(reg.f[b + 2]);
|
||||
f->NumParam += 2;
|
||||
break;
|
||||
case REGT_FLOAT | REGT_ADDROF:
|
||||
assert(C < f->NumRegF);
|
||||
::new(param) VMValue(®.f[C]);
|
||||
assert(b < f->NumRegF);
|
||||
::new(param) VMValue(®.f[b]);
|
||||
break;
|
||||
case REGT_FLOAT | REGT_KONST:
|
||||
assert(C < sfunc->NumKonstF);
|
||||
::new(param) VMValue(konstf[C]);
|
||||
assert(b < sfunc->NumKonstF);
|
||||
::new(param) VMValue(konstf[b]);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ enum EVMOpMode
|
|||
MODE_CMP,
|
||||
|
||||
MODE_PARAM,
|
||||
MODE_PARAM24,
|
||||
MODE_THROW,
|
||||
MODE_CATCH,
|
||||
MODE_CAST,
|
||||
|
|
@ -208,7 +209,8 @@ enum EVMOpMode
|
|||
MODE_CIMMS = MODE_IMMS << MODE_CSHIFT,
|
||||
MODE_CIMMZ = MODE_IMMZ << MODE_CSHIFT,
|
||||
|
||||
MODE_BCJOINT = (MODE_JOINT << MODE_BSHIFT) | (MODE_JOINT << MODE_CSHIFT),
|
||||
MODE_ABCJOINT = (MODE_JOINT << MODE_ASHIFT) | (MODE_JOINT << MODE_BSHIFT) | (MODE_JOINT << MODE_CSHIFT),
|
||||
MODE_BCJOINT = (MODE_JOINT << MODE_BSHIFT) | (MODE_JOINT << MODE_CSHIFT),
|
||||
MODE_BCKI = MODE_KI << MODE_BCSHIFT,
|
||||
MODE_BCKF = MODE_KF << MODE_BCSHIFT,
|
||||
MODE_BCKS = MODE_KS << MODE_BCSHIFT,
|
||||
|
|
@ -219,8 +221,6 @@ enum EVMOpMode
|
|||
MODE_BCTHROW = MODE_THROW << MODE_BCSHIFT,
|
||||
MODE_BCCATCH = MODE_CATCH << MODE_BCSHIFT,
|
||||
MODE_BCCAST = MODE_CAST << MODE_BCSHIFT,
|
||||
|
||||
MODE_ABCJOINT = (MODE_JOINT << MODE_ASHIFT) | MODE_BCJOINT,
|
||||
};
|
||||
|
||||
struct VMOpInfo
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue