示例#1
0
TCA emitEndCatchHelper(CodeBlock& cb, UniqueStubs& us) {
  Asm a { cb };
  alignJmpTarget(cb);
  Label debuggerReturn;
  Label resumeCppUnwind;

  auto const start = a.frontier();
  a.    cmpq (0, rvmtl()[unwinderDebuggerReturnSPOff()]);
  a.    jne8 (debuggerReturn);

  // Normal endCatch situation: call back to tc_unwind_resume, which returns
  // the catch trace (or null) in rax and the new vmfp in rdx.
  a.    movq (rvmfp(), rarg(0));
  a.    call (TCA(tc_unwind_resume));
  a.    movq (rdx, rvmfp());
  a.    testq(rax, rax);
  a.    jz8  (resumeCppUnwind);
  a.    jmp  (rax);  // rdx is still live if we're going to code from llvm

asm_label(a, resumeCppUnwind);
  static_assert(sizeof(tl_regState) == 1,
                "The following store must match the size of tl_regState");
  auto vptr = emitTLSAddr(a, tl_regState, rax);
  Vasm::prefix(a, vptr).
        storeb(static_cast<int32_t>(VMRegState::CLEAN), vptr.mr());
  a.    loadq(rvmtl()[unwinderExnOff()], rarg(0));
  emitCall(a, TCA(_Unwind_Resume), arg_regs(1));
  us.endCatchHelperPast = a.frontier();
  a.    ud2();

asm_label(a, debuggerReturn);
  a.    loadq (rvmtl()[unwinderDebuggerReturnSPOff()], rvmsp());
  a.    storeq(0, rvmtl()[unwinderDebuggerReturnSPOff()]);
  svcreq::emit_persistent(a.code(), folly::none, REQ_POST_DEBUGGER_RET);

  return start;
}
示例#2
0
void emitTransCounterInc(Asm& a) {
  emitTransCounterInc(Vauto(a.code()).main());
}
示例#3
0
void emitCall(Asm& a, CppCall call, RegSet args) {
  emitCall(Vauto(a.code()).main(), call, args);
}