diff --git a/Libraries/LibJS/AsmIntGen/src/codegen_aarch64.rs b/Libraries/LibJS/AsmIntGen/src/codegen_aarch64.rs index 9109886c26..58f4523151 100644 --- a/Libraries/LibJS/AsmIntGen/src/codegen_aarch64.rs +++ b/Libraries/LibJS/AsmIntGen/src/codegen_aarch64.rs @@ -386,6 +386,7 @@ fn generate_fallback_handler(out: &mut String, program: &Program, _pinned: &Pinn // Set up args: x0=vm (x20), w1=pc (ip - pb), x2=instruction (ip) w!(out, " mov x0, x20"); w!(out, " sub w1, w21, w26"); + emit_sync_pc_to_execution_context(out, program); w!(out, " mov x2, x21"); w!(out, " bl CSYM(asm_fallback_handler)"); // Check for exit (return < 0) @@ -430,6 +431,15 @@ fn emit_state_reload(out: &mut String, program: &Program) { emit_add_imm(out, "x27", "x28", sizeof_execctx); } +fn emit_sync_pc_to_execution_context(out: &mut String, program: &Program) { + let program_counter = program + .constants + .get("EXECUTION_CONTEXT_PROGRAM_COUNTER") + .copied() + .expect("EXECUTION_CONTEXT_PROGRAM_COUNTER constant required"); + emit_str32(out, "w1", "x28", program_counter); +} + /// Emit a dispatch sequence: recompute x21 from w25 + x26, then dispatch. /// Used only by dispatch_current (where DSL code has written to x25 directly). fn emit_dispatch(out: &mut String) { @@ -1347,6 +1357,7 @@ fn emit_instruction( if let Some(Operand::Register(func_name)) = insn.operands.first() { w!(out, " mov x0, x20"); // vm w!(out, " sub w1, w21, w26"); // pc = ip - pb + emit_sync_pc_to_execution_context(out, program); w!(out, " mov x2, x21"); // instruction w!(out, " bl CSYM({func_name})"); w!(out, " tbnz x0, #63, .Lexit"); diff --git a/Libraries/LibJS/AsmIntGen/src/codegen_x86_64.rs b/Libraries/LibJS/AsmIntGen/src/codegen_x86_64.rs index 9b665aa5e5..fe552dfa95 100644 --- a/Libraries/LibJS/AsmIntGen/src/codegen_x86_64.rs +++ b/Libraries/LibJS/AsmIntGen/src/codegen_x86_64.rs @@ -309,6 +309,7 @@ fn generate_fallback_handler(out: &mut String, program: &Program, abi: X86_64Abi // Returns >= 0: new pc to dispatch to. Returns < 0: exit. w!(out, ".p2align 4"); w!(out, "asm_handler_fallback:"); + emit_sync_pc_to_execution_context(out, program); emit_vm_pc_instruction_args(out, abi); w!(out, " call CSYM(asm_fallback_handler)"); // Check for exit (return < 0) @@ -388,6 +389,15 @@ fn emit_vm_pc_instruction_args(out: &mut String, abi: X86_64Abi) { } } +fn emit_sync_pc_to_execution_context(out: &mut String, program: &Program) { + let program_counter = program + .constants + .get("EXECUTION_CONTEXT_PROGRAM_COUNTER") + .copied() + .expect("EXECUTION_CONTEXT_PROGRAM_COUNTER constant required"); + w!(out, " mov DWORD PTR [rbx + {program_counter}], r13d"); +} + fn emit_dispatch(out: &mut String) { w!(out, " movzx eax, BYTE PTR [r14 + r13]"); w!(out, " jmp [r12 + rax * 8]"); @@ -765,6 +775,7 @@ fn emit_instruction( // context, since exception handling may have unwound inline frames. "call_slow_path" => { if let Some(Operand::Register(func_name)) = insn.operands.first() { + emit_sync_pc_to_execution_context(out, program); emit_vm_pc_instruction_args(out, abi); w!(out, " call CSYM({func_name})"); // Check for exit (return < 0) diff --git a/Libraries/LibJS/Bytecode/AsmInterpreter/AsmSlowPaths.cpp b/Libraries/LibJS/Bytecode/AsmInterpreter/AsmSlowPaths.cpp index b8ccb87105..0b14ad49a1 100644 --- a/Libraries/LibJS/Bytecode/AsmInterpreter/AsmSlowPaths.cpp +++ b/Libraries/LibJS/Bytecode/AsmInterpreter/AsmSlowPaths.cpp @@ -60,7 +60,6 @@ static i64 handle_asm_exception(VM& vm, u32 pc, Value exception) ({ \ auto& asm_try_vm = (vm); \ auto asm_try_pc = (pc); \ - asm_try_vm.running_execution_context().program_counter = asm_try_pc; \ auto&& asm_try_result = (expression); \ if (asm_try_result.is_error()) [[unlikely]] \ return handle_asm_exception(asm_try_vm, asm_try_pc, asm_try_result.release_error().value()); \ @@ -803,18 +802,18 @@ i64 asm_slow_path_decrement(VM* vm, u32 pc, Op::Decrement const* instruction) return static_cast(instruction->false_target().address()); \ } -DEFINE_JUMP_COMPARISON_SLOW_PATH(less_than, LessThan, less_than(VM::the(), lhs, rhs)) -DEFINE_JUMP_COMPARISON_SLOW_PATH(greater_than, GreaterThan, greater_than(VM::the(), lhs, rhs)) -DEFINE_JUMP_COMPARISON_SLOW_PATH(less_than_equals, LessThanEquals, less_than_equals(VM::the(), lhs, rhs)) -DEFINE_JUMP_COMPARISON_SLOW_PATH(greater_than_equals, GreaterThanEquals, greater_than_equals(VM::the(), lhs, rhs)) -DEFINE_JUMP_COMPARISON_SLOW_PATH(loosely_equals, LooselyEquals, is_loosely_equal(VM::the(), lhs, rhs)) +DEFINE_JUMP_COMPARISON_SLOW_PATH(less_than, LessThan, less_than(*vm, lhs, rhs)) +DEFINE_JUMP_COMPARISON_SLOW_PATH(greater_than, GreaterThan, greater_than(*vm, lhs, rhs)) +DEFINE_JUMP_COMPARISON_SLOW_PATH(less_than_equals, LessThanEquals, less_than_equals(*vm, lhs, rhs)) +DEFINE_JUMP_COMPARISON_SLOW_PATH(greater_than_equals, GreaterThanEquals, greater_than_equals(*vm, lhs, rhs)) +DEFINE_JUMP_COMPARISON_SLOW_PATH(loosely_equals, LooselyEquals, is_loosely_equal(*vm, lhs, rhs)) #undef DEFINE_JUMP_COMPARISON_SLOW_PATH i64 asm_slow_path_jump_loosely_inequals(VM* vm, u32 pc, Op::JumpLooselyInequals const* instruction) { auto lhs = vm->get(instruction->lhs()); auto rhs = vm->get(instruction->rhs()); - if (!ASM_TRY(*vm, pc, is_loosely_equal(VM::the(), lhs, rhs))) + if (!ASM_TRY(*vm, pc, is_loosely_equal(*vm, lhs, rhs))) return static_cast(instruction->true_target().address()); return static_cast(instruction->false_target().address()); } @@ -2963,8 +2962,6 @@ i64 asm_slow_path_resolve_this_binding(VM* vm, u32 pc, Op::ResolveThisBinding co // Direct handler for GetPrivateById: bypasses Reference indirection. i64 asm_slow_path_get_private_by_id(VM* vm, u32 pc, Op::GetPrivateById const* instruction) { - vm->running_execution_context().program_counter = pc; - auto base_value = vm->get(instruction->base()); auto& current_vm = *vm; @@ -2989,8 +2986,6 @@ i64 asm_slow_path_get_private_by_id(VM* vm, u32 pc, Op::GetPrivateById const* in // Direct handler for PutPrivateById: bypasses Reference indirection. i64 asm_slow_path_put_private_by_id(VM* vm, u32 pc, Op::PutPrivateById const* instruction) { - vm->running_execution_context().program_counter = pc; - auto base_value = vm->get(instruction->base()); auto& current_vm = *vm; auto value = vm->get(instruction->src());