Beispiel #1
0
static MacroAssemblerCodeRef linkForGenerator(VM* vm, FunctionPtr lazyLink, FunctionPtr notJSFunction, const char* name)
{
    JSInterfaceJIT jit;

    JSInterfaceJIT::JumpList slowCase;

#if USE(JSVALUE64)
    slowCase.append(jit.emitJumpIfNotJSCell(JSInterfaceJIT::regT0));
    slowCase.append(jit.emitJumpIfNotType(JSInterfaceJIT::regT0, JSInterfaceJIT::regT1, JSFunctionType));
#else // USE(JSVALUE64)
    slowCase.append(jit.branch32(JSInterfaceJIT::NotEqual, JSInterfaceJIT::regT1, JSInterfaceJIT::TrustedImm32(JSValue::CellTag)));
    slowCase.append(jit.emitJumpIfNotType(JSInterfaceJIT::regT0, JSInterfaceJIT::regT1, JSFunctionType));
#endif // USE(JSVALUE64)

    // Finish canonical initialization before JS function call.
    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSFunction::offsetOfScopeChain()), JSInterfaceJIT::regT1);
    jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);

    // Also initialize ReturnPC for use by lazy linking and exceptions.
    jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT3);
    jit.emitPutToCallFrameHeader(JSInterfaceJIT::regT3, JSStack::ReturnPC);

    jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
    jit.restoreArgumentReference();
    JSInterfaceJIT::Call callLazyLink = jit.call();
    jit.restoreReturnAddressBeforeReturn(JSInterfaceJIT::regT3);
    jit.jump(JSInterfaceJIT::regT0);

    slowCase.link(&jit);
    JSInterfaceJIT::Call callNotJSFunction = generateSlowCaseFor(vm, jit);

    LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
    patchBuffer.link(callLazyLink, lazyLink);
    patchBuffer.link(callNotJSFunction, notJSFunction);

    return FINALIZE_CODE(patchBuffer, ("link %s trampoline", name));
}
Beispiel #2
0
static MacroAssemblerCodeRef virtualForGenerator(VM* vm, FunctionPtr compile, FunctionPtr notJSFunction, const char* name, CodeSpecializationKind kind)
{
    JSInterfaceJIT jit;

    JSInterfaceJIT::JumpList slowCase;

#if USE(JSVALUE64)
    slowCase.append(jit.emitJumpIfNotJSCell(JSInterfaceJIT::regT0));
#else // USE(JSVALUE64)
    slowCase.append(jit.branch32(JSInterfaceJIT::NotEqual, JSInterfaceJIT::regT1, JSInterfaceJIT::TrustedImm32(JSValue::CellTag)));
#endif // USE(JSVALUE64)
    slowCase.append(jit.emitJumpIfNotType(JSInterfaceJIT::regT0, JSInterfaceJIT::regT1, JSFunctionType));

    // Finish canonical initialization before JS function call.
    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSFunction::offsetOfScopeChain()), JSInterfaceJIT::regT1);
    jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);

    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSFunction::offsetOfExecutable()), JSInterfaceJIT::regT2);
    JSInterfaceJIT::Jump hasCodeBlock1 = jit.branch32(JSInterfaceJIT::GreaterThanOrEqual, JSInterfaceJIT::Address(JSInterfaceJIT::regT2, FunctionExecutable::offsetOfNumParametersFor(kind)), JSInterfaceJIT::TrustedImm32(0));
    jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT3);
    jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
    jit.restoreArgumentReference();
    JSInterfaceJIT::Call callCompile = jit.call();
    jit.restoreReturnAddressBeforeReturn(JSInterfaceJIT::regT3);
    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSFunction::offsetOfExecutable()), JSInterfaceJIT::regT2);

    hasCodeBlock1.link(&jit);
    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT2, FunctionExecutable::offsetOfJITCodeWithArityCheckFor(kind)), JSInterfaceJIT::regT0);
#if !ASSERT_DISABLED
    JSInterfaceJIT::Jump ok = jit.branchTestPtr(JSInterfaceJIT::NonZero, JSInterfaceJIT::regT0);
    jit.breakpoint();
    ok.link(&jit);
#endif
    jit.jump(JSInterfaceJIT::regT0);

    slowCase.link(&jit);
    JSInterfaceJIT::Call callNotJSFunction = generateSlowCaseFor(vm, jit);

    LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
    patchBuffer.link(callCompile, compile);
    patchBuffer.link(callNotJSFunction, notJSFunction);

    return FINALIZE_CODE(patchBuffer, ("virtual %s trampoline", name));
}