diff --git a/src/engine/Runtime.v3 b/src/engine/Runtime.v3 index 623fa2526..c37e92193 100644 --- a/src/engine/Runtime.v3 +++ b/src/engine/Runtime.v3 @@ -378,15 +378,7 @@ component Runtime { def cast(instance: Instance, nullable: bool, ht_val: int, val: Value) -> bool { match (val) { Ref(obj) => return if(obj == null, nullable, castObject(instance, ht_val, obj)); - I31(val) => { - match (ht_val) { - BpHeapTypeCode.EXTERN.val, - BpHeapTypeCode.ANY.val, - BpHeapTypeCode.EQ.val, - BpHeapTypeCode.I31.val => return true; - _ => return false; - } - } + I31(val) => return castI31(instance, ht_val); _ => return false; } } @@ -399,7 +391,7 @@ component Runtime { _ => return false; } } - // caller do nullable + // Caller must handle nullability. def castObject(instance: Instance, ht_val: int, obj: Object) -> bool { match (ht_val) { BpHeapTypeCode.FUNC.val => return Function.?(obj); diff --git a/src/engine/v3/V3Interpreter.v3 b/src/engine/v3/V3Interpreter.v3 index dcbb4c9b1..95c72b94f 100644 --- a/src/engine/v3/V3Interpreter.v3 +++ b/src/engine/v3/V3Interpreter.v3 @@ -892,7 +892,7 @@ class V3Interpreter extends WasmStack { REF_TEST_NULL => { var nullable = (opcode == Opcode.REF_TEST_NULL); var ht_val = codeptr.read_sleb32(); - var result = doRuntimeCast(frame.func.instance, nullable, ht_val, pop()); + var result = Runtime.cast(frame.func.instance, nullable, ht_val, pop()); pushz(result); } REF_CAST, @@ -900,14 +900,14 @@ class V3Interpreter extends WasmStack { var nullable = (opcode == Opcode.REF_CAST_NULL); var ht_val = codeptr.read_sleb32(); var val = pop(); - var result = doRuntimeCast(frame.func.instance, nullable, ht_val, val); + var result = Runtime.cast(frame.func.instance, nullable, ht_val, val); if (!result) trap(TrapReason.FAILED_CAST); else push(val); } BR_ON_CAST => { var imm = codeptr.read_BrOnCastImm(); var val = pop(); - var result = doRuntimeCast(frame.func.instance, imm.null2(), imm.ht2, val); + var result = Runtime.cast(frame.func.instance, imm.null2(), imm.ht2, val); push(val); if (result) codeptr.at(doGoto(pc)); else doFallthru(); @@ -915,7 +915,7 @@ class V3Interpreter extends WasmStack { BR_ON_CAST_FAIL => { var imm = codeptr.read_BrOnCastImm(); var val = pop(); - var result = doRuntimeCast(frame.func.instance, imm.null2(), imm.ht2, val); + var result = Runtime.cast(frame.func.instance, imm.null2(), imm.ht2, val); push(val); if (!result) codeptr.at(doGoto(pc)); else doFallthru(); @@ -2050,13 +2050,6 @@ class V3Interpreter extends WasmStack { last_fp = f.fp; } } - private def doRuntimeCast(instance: Instance, nullable: bool, ht_val: int, val: Value) -> bool { - match (val) { - Ref(obj) => return if(obj == null, nullable, Runtime.castObject(instance, ht_val, obj)); - I31 => return Runtime.castI31(instance, ht_val); - _ => return false; - } - } } class V3Frame { diff --git a/src/engine/x86-64/X86_64Runtime.v3 b/src/engine/x86-64/X86_64Runtime.v3 index 607bc5254..965034801 100644 --- a/src/engine/x86-64/X86_64Runtime.v3 +++ b/src/engine/x86-64/X86_64Runtime.v3 @@ -213,10 +213,11 @@ component X86_64Runtime { curStack.pushRspPointer(Pointer.NULL); return null; } - def runtime_doCast(stack: X86_64Stack, instance: Instance, nullable: byte, ht_val: int) -> bool { + def runtime_doCast(stack: X86_64Stack, instance: Instance, nullable: byte, ht_val: int) -> bool { // XXX: inline into caller var isI31 = stack.topObjectIsI31(); - if (isI31) return Runtime.castI31(instance, ht_val); - else { + if (isI31) { + return Runtime.castI31(instance, ht_val); + } else { var obj = stack.peekObject(); return if(obj == null, (nullable & 2) != 0, Runtime.castObject(instance, ht_val, obj)); } diff --git a/src/monitors/ControlInstrumenter.v3 b/src/monitors/ControlInstrumenter.v3 index 129834388..c2c857a7e 100644 --- a/src/monitors/ControlInstrumenter.v3 +++ b/src/monitors/ControlInstrumenter.v3 @@ -136,12 +136,7 @@ private class CiBrOnCastProbe(nullable: bool, ht_val: int, success_taken: bool) def fire(loc: DynamicLoc) -> ProbeAction { var accessor = loc.frame.getFrameAccessor(); var instance = accessor.func().instance; - var result: bool; - match (accessor.getOperand(0)) { - Ref(obj) => result = if(obj == null, nullable, Runtime.castObject(instance, ht_val, obj)); - I31 => result = Runtime.castI31(instance, ht_val); - _ => result = false; - } + var result = Runtime.cast(instance, nullable, ht_val, accessor.getOperand(0)); taken[if(result == success_taken, 0, 1)]++; return ProbeAction.Continue; } diff --git a/src/monitors/LoopTraceMonitor.v3 b/src/monitors/LoopTraceMonitor.v3 index 43eaaf49e..39f2c1159 100644 --- a/src/monitors/LoopTraceMonitor.v3 +++ b/src/monitors/LoopTraceMonitor.v3 @@ -239,12 +239,7 @@ private class TraceBrOnCastProbe(trace: TraceBuffer, nullable: bool, ht_val: int // XXX: introduce a utility for taken/not taken branches var accessor = loc.frame.getFrameAccessor(); var instance = accessor.func().instance; - var result: bool; - match (accessor.getOperand(0)) { - Ref(obj) => result = if(obj == null, nullable, Runtime.castObject(instance, ht_val, obj)); - I31 => result = Runtime.castI31(instance, ht_val); - _ => result = false; - } + var result = Runtime.cast(instance, nullable, ht_val, accessor.getOperand(0)); if (result == success_taken) trace.pushNotTaken(); else trace.pushTaken(); return ProbeAction.Continue;