diff --git a/src/mono/browser/runtime/jiterpreter-opcodes.ts b/src/mono/browser/runtime/jiterpreter-opcodes.ts index 1680016d2a670..de98528709353 100644 --- a/src/mono/browser/runtime/jiterpreter-opcodes.ts +++ b/src/mono/browser/runtime/jiterpreter-opcodes.ts @@ -36,7 +36,6 @@ export const enum MintOpArgType { MintOpFloat, MintOpDouble, MintOpBranch, - MintOpShortBranch, MintOpSwitch, MintOpMethodToken, MintOpFieldToken, diff --git a/src/mono/browser/runtime/jiterpreter-trace-generator.ts b/src/mono/browser/runtime/jiterpreter-trace-generator.ts index dab0be4b2abed..2a4471b20899a 100644 --- a/src/mono/browser/runtime/jiterpreter-trace-generator.ts +++ b/src/mono/browser/runtime/jiterpreter-trace-generator.ts @@ -2752,6 +2752,21 @@ function append_call_handler_store_ret_ip ( builder.callHandlerReturnAddresses.push(retIp); } +function getBranchImmediate ( + ip: MintOpcodePtr, opcode: MintOpcode +): number | undefined { + const opArgType = cwraps.mono_jiterp_get_opcode_info(opcode, OpcodeInfoType.OpArgType), + payloadOffset = cwraps.mono_jiterp_get_opcode_info(opcode, OpcodeInfoType.Sregs), + payloadAddress = ip + 2 + (payloadOffset * 2); + + switch (opArgType) { + case MintOpArgType.MintOpShortAndBranch: + return getI16(payloadAddress); + default: + return undefined; + } +} + function getBranchDisplacement ( ip: MintOpcodePtr, opcode: MintOpcode ): number | undefined { @@ -2785,8 +2800,10 @@ function emit_branch ( (opcode <= MintOpcode.MINT_BLT_UN_I8_IMM_SP); const displacement = getBranchDisplacement(ip, opcode); - if (typeof (displacement) !== "number") + if (typeof (displacement) !== "number") { + // mono_log_info(`Failed to decode branch displacement for ${getOpcodeName(opcode)}`); return false; + } // If the branch is taken we bail out to allow the interpreter to do it. // So for brtrue, we want to do 'cond == 0' to produce a bailout only @@ -2874,9 +2891,6 @@ function emit_branch ( if (relopbranchTable[opcode] === undefined) throw new Error(`Unsupported relop branch opcode: ${getOpcodeName(opcode)}`); - if (cwraps.mono_jiterp_get_opcode_info(opcode, OpcodeInfoType.Length) !== 4) - throw new Error(`Unsupported long branch opcode: ${getOpcodeName(opcode)}`); - break; } } @@ -2920,8 +2934,10 @@ function emit_relop_branch ( frame: NativePointer, opcode: MintOpcode ): boolean { const relopBranchInfo = relopbranchTable[opcode]; - if (!relopBranchInfo) + if (!relopBranchInfo) { + // mono_log_info(`No info for relop branch ${getOpcodeName(opcode)}`); return false; + } const relop = Array.isArray(relopBranchInfo) ? relopBranchInfo[0] @@ -2930,8 +2946,10 @@ function emit_relop_branch ( const relopInfo = binopTable[relop]; const intrinsicFpBinop = intrinsicFpBinops[relop]; - if (!relopInfo && !intrinsicFpBinop) + if (!relopInfo && !intrinsicFpBinop) { + // mono_log_info(`No info for relop ${getOpcodeName(opcode)} -> ${getOpcodeName(relop)}`); return false; + } const operandLoadOp = relopInfo ? relopInfo[1] @@ -2948,11 +2966,13 @@ function emit_relop_branch ( // Compare with immediate if (Array.isArray(relopBranchInfo) && relopBranchInfo[1]) { + const immediate = getBranchImmediate(ip, opcode); + mono_assert(immediate !== undefined, `Failed to decode immediate for branch opcode ${getOpcodeName(opcode)}`); // For i8 immediates we need to generate an i64.const even though // the immediate is 16 bits, so we store the relevant opcode // in the relop branch info table builder.appendU8(relopBranchInfo[1]); - builder.appendLeb(getArgI16(ip, 2)); + builder.appendLeb(immediate); } else append_ldloc(builder, getArgU16(ip, 2), operandLoadOp);