From 24481781b4a20b40189a9f810ab5487bc8723d0b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 18 Nov 2016 14:50:21 +0100 Subject: [PATCH] - added missing unsigned casts to the VM. - make the pointer to string cast a bit more useful by using the actual object's type rather than 'Object' which can be a great asset when debugging. - fixed a few bad asserts. --- src/scripting/codegeneration/codegen.cpp | 6 +++--- src/scripting/vm/vm.h | 3 +++ src/scripting/vm/vmdisasm.cpp | 3 +++ src/scripting/vm/vmexec.h | 14 +++++++++++++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index e57303c0a..c8cf6b740 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -871,7 +871,7 @@ ExpEmit FxIntCast::Emit(VMFunctionBuilder *build) assert(basex->ValueType->GetRegType() == REGT_FLOAT); from.Free(build); ExpEmit to(build, REGT_INT); - build->Emit(OP_CAST, to.RegNum, from.RegNum, CAST_F2I); + build->Emit(OP_CAST, to.RegNum, from.RegNum, ValueType == TypeUInt32? CAST_F2U : CAST_F2I); return to; } @@ -962,7 +962,7 @@ ExpEmit FxFloatCast::Emit(VMFunctionBuilder *build) assert(basex->ValueType->GetRegType() == REGT_INT); from.Free(build); ExpEmit to(build, REGT_FLOAT); - build->Emit(OP_CAST, to.RegNum, from.RegNum, CAST_I2F); + build->Emit(OP_CAST, to.RegNum, from.RegNum, basex->ValueType == TypeUInt32? CAST_U2F : CAST_I2F); return to; } @@ -3554,7 +3554,7 @@ ExpEmit FxShift::Emit(VMFunctionBuilder *build) assert(!op2.Konst); instr = InstrMap[index][1]; } - assert(instr > 0); + assert(instr != 0); ExpEmit to(build, REGT_INT); build->Emit(instr, to.RegNum, op1.RegNum, rop); return to; diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index c9f75f214..4e833cf0b 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -111,7 +111,10 @@ enum { CAST_I2F, CAST_I2S, + CAST_U2F, + CAST_U2S, CAST_F2I, + CAST_F2U, CAST_F2S, CAST_P2S, CAST_S2I, diff --git a/src/scripting/vm/vmdisasm.cpp b/src/scripting/vm/vmdisasm.cpp index 48b6d168b..d39723dea 100644 --- a/src/scripting/vm/vmdisasm.cpp +++ b/src/scripting/vm/vmdisasm.cpp @@ -381,15 +381,18 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction switch (code[i].c) { case CAST_I2F: + case CAST_U2F: mode = MODE_AF | MODE_BI | MODE_CUNUSED; break; case CAST_Co2S: case CAST_So2S: case CAST_N2S: case CAST_I2S: + case CAST_U2S: mode = MODE_AS | MODE_BI | MODE_CUNUSED; break; case CAST_F2I: + case CAST_F2U: mode = MODE_AI | MODE_BF | MODE_CUNUSED; break; case CAST_F2S: diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index 6cc0d40cd..673582bda 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -1658,15 +1658,27 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c ASSERTF(a); ASSERTD(b); reg.f[a] = reg.d[b]; break; + case CAST_U2F: + ASSERTF(a); ASSERTD(b); + reg.f[a] = unsigned(reg.d[b]); + break; case CAST_I2S: ASSERTS(a); ASSERTD(b); reg.s[a].Format("%d", reg.d[b]); break; + case CAST_U2S: + ASSERTS(a); ASSERTD(b); + reg.s[a].Format("%u", reg.d[b]); + break; case CAST_F2I: ASSERTD(a); ASSERTF(b); reg.d[a] = (int)reg.f[b]; break; + case CAST_F2U: + ASSERTD(a); ASSERTF(b); + reg.d[a] = (int)(unsigned)reg.f[b]; + break; case CAST_F2S: ASSERTS(a); ASSERTD(b); reg.s[a].Format("%.14g", reg.f[b]); @@ -1674,7 +1686,7 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c case CAST_P2S: ASSERTS(a); ASSERTA(b); - reg.s[a].Format("%s<%p>", reg.atag[b] == ATAG_OBJECT ? "Object" : "Pointer", reg.a[b]); + reg.s[a].Format("%s<%p>", reg.atag[b] == ATAG_OBJECT ? (reg.a[b] == nullptr? "Object" : ((DObject*)reg.a[b])->GetClass()->TypeName.GetChars() ) : "Pointer", reg.a[b]); break; case CAST_S2I: