#include "platform_macro.h" #if defined(TARGET_ARCH_ARM) #include "dobby_internal.h" #include "core/modules/assembler/assembler-arm.h" #include "TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.h" using namespace zz; using namespace zz::arm; static void *closure_bridge = NULL; void *get_closure_bridge() { // if already initialized, just return. if (closure_bridge) return closure_bridge; // check if enable the inline-assembly closure_bridge_template #if ENABLE_CLOSURE_BRIDGE_TEMPLATE extern void closure_bridge_tempate(); closure_bridge = closure_bridge_template; // otherwise, use the Assembler build the closure_bridge #else #define _ turbo_assembler_. TurboAssembler turbo_assembler_(0); _ sub(sp, sp, Operand(14 * 4)); _ str(lr, MemOperand(sp, 13 * 4)); _ str(r12, MemOperand(sp, 12 * 4)); _ str(r11, MemOperand(sp, 11 * 4)); _ str(r10, MemOperand(sp, 10 * 4)); _ str(r9, MemOperand(sp, 9 * 4)); _ str(r8, MemOperand(sp, 8 * 4)); _ str(r7, MemOperand(sp, 7 * 4)); _ str(r6, MemOperand(sp, 6 * 4)); _ str(r5, MemOperand(sp, 5 * 4)); _ str(r4, MemOperand(sp, 4 * 4)); _ str(r3, MemOperand(sp, 3 * 4)); _ str(r2, MemOperand(sp, 2 * 4)); _ str(r1, MemOperand(sp, 1 * 4)); _ str(r0, MemOperand(sp, 0 * 4)); // store sp _ add(r0, sp, Operand(14 * 4)); _ sub(sp, sp, Operand(8)); _ str(r0, MemOperand(sp, 4)); // stack align _ sub(sp, sp, Operand(8)); _ mov(r0, Operand(sp)); _ mov(r1, Operand(r12)); _ CallFunction(ExternalReference((void *)intercept_routing_common_bridge_handler)); // stack align _ add(sp, sp, Operand(8)); // restore sp placeholder stack _ add(sp, sp, Operand(8)); _ ldr(r0, MemOperand(sp, 4, PostIndex)); _ ldr(r1, MemOperand(sp, 4, PostIndex)); _ ldr(r2, MemOperand(sp, 4, PostIndex)); _ ldr(r3, MemOperand(sp, 4, PostIndex)); _ ldr(r4, MemOperand(sp, 4, PostIndex)); _ ldr(r5, MemOperand(sp, 4, PostIndex)); _ ldr(r6, MemOperand(sp, 4, PostIndex)); _ ldr(r7, MemOperand(sp, 4, PostIndex)); _ ldr(r8, MemOperand(sp, 4, PostIndex)); _ ldr(r9, MemOperand(sp, 4, PostIndex)); _ ldr(r10, MemOperand(sp, 4, PostIndex)); _ ldr(r11, MemOperand(sp, 4, PostIndex)); _ ldr(r12, MemOperand(sp, 4, PostIndex)); _ ldr(lr, MemOperand(sp, 4, PostIndex)); // auto switch A32 & T32 with `least significant bit`, refer `docs/A32_T32_states_switch.md` _ mov(pc, Operand(r12)); AssemblyCodeChunk *code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); closure_bridge = (void *)code->raw_instruction_start(); DLOG(0, "[closure bridge] Build the closure bridge at %p", closure_bridge); #endif return (void *)closure_bridge; } #endif