Ignore:
Timestamp:
Apr 4, 2017, 3:23:37 PM (8 years ago)
Author:
[email protected]
Message:

WebAssembly: JSWebAssemblyCallee should not be a JSCell
https://bugs.webkit.org/show_bug.cgi?id=170135

Reviewed by Michael Saboff.

Source/JavaScriptCore:

This patch is perhaps the last big change to the design of fundamental
Wasm API to allow for PIC. It changes JSWebAssemblyCallee into a thing
called Wasm::Callee. It serves the same purpose as before, except
Wasm::Callee is not a JSCell. I had to refactor the various parts of the
runtime that will see CallFrame's with Wasm::Callee's in the callee slot.
Thankfully, the parts of the runtime that Wasm touches are limited. The
main refactoring is changing the exception handling code, such as taking
a stack trace, to be friendly to seeing a non JSCell callee.

The callee() function on ExecState now returns a class I added in this
patch called CalleeBits. CalleeBits will tell you if the callee is a
JSCell or a Wasm::Callee. We tag Wasm::Callee's with a 1 in their lower
bit so we can easily tell what is and isn't a Wasm::Callee.

The stub that calls out from Wasm to JS still puts a JSCell callee
into the call frame, even though the callee logically represents a
Wasm frame. The reason for this is that we use the call IC infrastructure
to make a call out to JS code, and the code that writes the IC expects
a JSCell as the callee. This is knowingly part of our design. When we
do structured cloning of Wasm Modules, we'll need to regenerate these
JS call stubs.

  • API/JSContextRef.cpp:

(BacktraceFunctor::operator()):

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • debugger/Debugger.cpp:

(JSC::Debugger::pauseIfNeeded):
(JSC::Debugger::currentDebuggerCallFrame):

  • debugger/DebuggerCallFrame.cpp:

(JSC::DebuggerCallFrame::create):
(JSC::DebuggerCallFrame::DebuggerCallFrame):
(JSC::DebuggerCallFrame::currentPosition):
(JSC::DebuggerCallFrame::positionForCallFrame):

  • debugger/DebuggerCallFrame.h:
  • interpreter/CallFrame.cpp:

(JSC::CallFrame::vmEntryGlobalObject):
(JSC::CallFrame::wasmAwareLexicalGlobalObject):
(JSC::CallFrame::isAnyWasmCallee):
(JSC::CallFrame::callerSourceOrigin):

  • interpreter/CallFrame.h:

(JSC::ExecState::calleeAsValue):
(JSC::ExecState::jsCallee):
(JSC::ExecState::callee):
(JSC::ExecState::unsafeCallee):
(JSC::ExecState::scope):
(JSC::ExecState::iterate):

  • interpreter/CalleeBits.h: Added.

(JSC::CalleeBits::CalleeBits):
(JSC::CalleeBits::operator=):
(JSC::CalleeBits::boxWasm):
(JSC::CalleeBits::isWasm):
(JSC::CalleeBits::isCell):
(JSC::CalleeBits::asCell):
(JSC::CalleeBits::asWasmCallee):
(JSC::CalleeBits::rawPtr):

  • interpreter/Interpreter.cpp:

(JSC::GetStackTraceFunctor::operator()):
(JSC::Interpreter::getStackTrace):
(JSC::notifyDebuggerOfUnwinding):
(JSC::UnwindFunctor::UnwindFunctor):
(JSC::UnwindFunctor::operator()):
(JSC::UnwindFunctor::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::Interpreter::unwind):
(JSC::Interpreter::notifyDebuggerOfExceptionToBeThrown):

  • interpreter/Interpreter.h:
  • interpreter/Register.h:

(JSC::Register::pointer):

  • interpreter/ShadowChicken.cpp:

(JSC::ShadowChicken::update):

  • interpreter/ShadowChickenInlines.h:

(JSC::ShadowChicken::iterate):

  • interpreter/StackVisitor.cpp:

(JSC::StackVisitor::StackVisitor):
(JSC::StackVisitor::readFrame):
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::readInlinedFrame):
(JSC::StackVisitor::Frame::calleeSaveRegisters):
(JSC::StackVisitor::Frame::functionName):
(JSC::StackVisitor::Frame::dump):

  • interpreter/StackVisitor.h:

(JSC::StackVisitor::Frame::callee):
(JSC::StackVisitor::visit):

  • jit/Repatch.cpp:

(JSC::linkFor):
(JSC::linkPolymorphicCall):

  • jsc.cpp:

(callWasmFunction):
(functionTestWasmModuleFunctions):

  • runtime/ArrayPrototype.cpp:
  • runtime/Error.cpp:

(JSC::addErrorInfoAndGetBytecodeOffset):

  • runtime/ErrorInstance.cpp:

(JSC::ErrorInstance::finishCreation):

  • runtime/JSCell.cpp:

(JSC::JSCell::isAnyWasmCallee): Deleted.

  • runtime/JSCell.h:
  • runtime/JSCellInlines.h:

(JSC::ExecState::vm):

  • runtime/JSFunction.cpp:

(JSC::RetrieveArgumentsFunctor::operator()):
(JSC::RetrieveCallerFunctionFunctor::operator()):

  • runtime/JSGlobalObject.cpp:
  • runtime/SamplingProfiler.cpp:

(JSC::FrameWalker::recordJSFrame):
(JSC::SamplingProfiler::processUnverifiedStackTraces):

  • runtime/SamplingProfiler.h:

(JSC::SamplingProfiler::UnprocessedStackFrame::UnprocessedStackFrame):

  • runtime/StackFrame.cpp:

(JSC::StackFrame::sourceURL):
(JSC::StackFrame::functionName):

  • runtime/StackFrame.h:

(JSC::StackFrame::wasm):

  • runtime/VM.cpp:

(JSC::VM::VM):
(JSC::VM::throwException):

  • runtime/VM.h:
  • wasm/JSWebAssembly.h:
  • wasm/WasmB3IRGenerator.cpp:
  • wasm/WasmBinding.cpp:

(JSC::Wasm::wasmToWasm):

  • wasm/WasmCallee.cpp: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyCallee.cpp.

(JSC::Wasm::Callee::Callee):
(JSC::JSWebAssemblyCallee::JSWebAssemblyCallee): Deleted.
(JSC::JSWebAssemblyCallee::finishCreation): Deleted.
(JSC::JSWebAssemblyCallee::destroy): Deleted.

  • wasm/WasmCallee.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyCallee.h.

(JSC::Wasm::Callee::create):
(JSC::JSWebAssemblyCallee::create): Deleted.
(JSC::JSWebAssemblyCallee::createStructure): Deleted.
(JSC::JSWebAssemblyCallee::entrypoint): Deleted.
(JSC::JSWebAssemblyCallee::calleeSaveRegisters): Deleted.

  • wasm/WasmContext.h:
  • wasm/WasmPlan.cpp:
  • wasm/WasmPlan.h:
  • wasm/WasmPlanInlines.h:

(JSC::Wasm::Plan::initializeCallees):

  • wasm/WasmThunks.cpp:

(JSC::Wasm::throwExceptionFromWasmThunkGenerator):

  • wasm/js/JSWebAssemblyCallee.cpp: Removed.
  • wasm/js/JSWebAssemblyCallee.h: Removed.
  • wasm/js/JSWebAssemblyCodeBlock.cpp:

(JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
(JSC::JSWebAssemblyCodeBlock::initialize):
(JSC::JSWebAssemblyCodeBlock::visitChildren):

  • wasm/js/JSWebAssemblyCodeBlock.h:

(JSC::JSWebAssemblyCodeBlock::create):
(JSC::JSWebAssemblyCodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::JSWebAssemblyCodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
(JSC::JSWebAssemblyCodeBlock::wasmToJsCallStubForImport):
(JSC::JSWebAssemblyCodeBlock::offsetOfImportWasmToJSStub):
(JSC::JSWebAssemblyCodeBlock::setJSEntrypointCallee):
(JSC::JSWebAssemblyCodeBlock::setWasmEntrypointCallee):
(JSC::JSWebAssemblyCodeBlock::offsetOfImportStubs):
(JSC::JSWebAssemblyCodeBlock::allocationSize):
(JSC::JSWebAssemblyCodeBlock::importWasmToJSStub):
(JSC::JSWebAssemblyCodeBlock::callees): Deleted.
(JSC::JSWebAssemblyCodeBlock::offsetOfCallees): Deleted.

  • wasm/js/JSWebAssemblyInstance.h:

(JSC::JSWebAssemblyInstance::webAssemblyToJSCallee):

  • wasm/js/JSWebAssemblyModule.cpp:
  • wasm/js/WebAssemblyFunction.cpp:

(JSC::callWebAssemblyFunction):
(JSC::WebAssemblyFunction::create):
(JSC::WebAssemblyFunction::WebAssemblyFunction):
(JSC::WebAssemblyFunction::visitChildren):
(JSC::WebAssemblyFunction::finishCreation):

  • wasm/js/WebAssemblyFunction.h:

(JSC::WebAssemblyFunction::wasmEntrypoint):
(JSC::WebAssemblyFunction::jsEntrypoint):
(JSC::WebAssemblyFunction::offsetOfWasmEntrypoint):
(JSC::WebAssemblyFunction::offsetOfWasmEntryPointCode): Deleted.

  • wasm/js/WebAssemblyModuleConstructor.cpp:
  • wasm/js/WebAssemblyModuleRecord.cpp:

(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):

Source/WebCore:

  • bindings/js/JSDOMWindowBase.cpp:

(WebCore::callerDOMWindow):

Location:
trunk/Source/JavaScriptCore/interpreter
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp

    r212483 r214905  
    3232#include "JSCInlines.h"
    3333#include "VMEntryScope.h"
     34#include "WasmContext.h"
    3435#include <wtf/StringPrintStream.h>
    3536
     
    186187JSGlobalObject* CallFrame::vmEntryGlobalObject()
    187188{
    188     if (callee()->isObject()) {
     189    RELEASE_ASSERT(callee().isCell());
     190    if (callee().asCell()->isObject()) {
    189191        if (this == lexicalGlobalObject()->globalExec())
    190192            return lexicalGlobalObject();
     
    198200}
    199201
     202JSGlobalObject* CallFrame::vmEntryGlobalObject(VM& vm)
     203{
     204    if (callee().isCell() && callee().asCell()->isObject()) {
     205        if (this == lexicalGlobalObject()->globalExec())
     206            return lexicalGlobalObject();
     207    }
     208
     209    // For any ExecState that's not a globalExec, the
     210    // dynamic global object must be set since code is running
     211    ASSERT(vm.entryScope);
     212    return vm.entryScope->globalObject();
     213}
     214
     215JSGlobalObject* CallFrame::wasmAwareLexicalGlobalObject(VM& vm)
     216{
     217#if ENABLE(WEBASSEMBLY)
     218    if (!callee().isWasm())
     219        return lexicalGlobalObject();
     220    return Wasm::loadContext(vm)->globalObject();
     221#else
     222    UNUSED_PARAM(vm);
     223    return lexicalGlobalObject();
     224#endif
     225}
     226
     227bool CallFrame::isAnyWasmCallee()
     228{
     229    CalleeBits callee = this->callee();
     230    if (callee.isWasm())
     231        return true;
     232
     233    ASSERT(callee.isCell());
     234    if (!!callee.rawPtr() && isWebAssemblyToJSCallee(callee.asCell()))
     235        return true;
     236
     237    return false;
     238}
     239
    200240CallFrame* CallFrame::callerFrame(VMEntryFrame*& currVMEntryFrame)
    201241{
     
    220260SourceOrigin CallFrame::callerSourceOrigin()
    221261{
     262    RELEASE_ASSERT(callee().isCell());
     263    VM* vm = &this->vm();
    222264    SourceOrigin sourceOrigin;
    223265    bool haveSkippedFirstFrame = false;
    224     StackVisitor::visit(this, [&](StackVisitor& visitor) {
     266    StackVisitor::visit(this, vm, [&](StackVisitor& visitor) {
    225267        if (!std::exchange(haveSkippedFirstFrame, true))
    226268            return StackVisitor::Status::Continue;
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r212692 r214905  
    2424
    2525#include "AbstractPC.h"
     26#include "CalleeBits.h"
    2627#include "MacroAssemblerCodeRef.h"
    2728#include "Register.h"
     
    8788        static const int headerSizeInRegisters = CallFrameSlot::argumentCount + 1;
    8889
    89         JSValue calleeAsValue() const { return this[CallFrameSlot::callee].jsValue(); }
    90         JSObject* jsCallee() const { return this[CallFrameSlot::callee].object(); }
    91         JSCell* callee() const { return this[CallFrameSlot::callee].unboxedCell(); }
    92         SUPPRESS_ASAN JSValue unsafeCallee() const { return this[CallFrameSlot::callee].asanUnsafeJSValue(); }
     90        JSValue calleeAsValue() const
     91        {
     92            ASSERT(!callee().isWasm());
     93            return this[CallFrameSlot::callee].jsValue();
     94        }
     95        JSObject* jsCallee() const
     96        {
     97            ASSERT(!callee().isWasm());
     98            return this[CallFrameSlot::callee].object();
     99        }
     100        CalleeBits callee() const { return CalleeBits(this[CallFrameSlot::callee].pointer()); }
     101        SUPPRESS_ASAN CalleeBits unsafeCallee() const { return CalleeBits(this[CallFrameSlot::callee].pointer()); }
    93102        CodeBlock* codeBlock() const { return this[CallFrameSlot::codeBlock].Register::codeBlock(); }
    94103        CodeBlock** addressOfCodeBlock() const { return bitwise_cast<CodeBlock**>(this + CallFrameSlot::codeBlock); }
     
    99108            return this[scopeRegisterOffset].Register::scope();
    100109        }
    101 
    102110        // Global object in which execution began.
     111        // This variant is not safe to call from a Wasm frame.
    103112        JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject();
     113        // This variant is safe to call from a Wasm frame.
     114        JSGlobalObject* vmEntryGlobalObject(VM&);
     115
     116        JSGlobalObject* wasmAwareLexicalGlobalObject(VM&);
     117
     118        bool isAnyWasmCallee();
    104119
    105120        // Global object in which the currently executing code was defined.
     
    258273        // FIXME: This method is improper. We rely on the fact that we can call it with a null
    259274        // receiver. We should always be using StackVisitor directly.
     275        // It's only valid to call this from a non-wasm top frame.
    260276        template <typename Functor> void iterate(const Functor& functor)
    261277        {
    262             StackVisitor::visit<Functor>(this, functor);
     278            VM* vm;
     279            void* rawThis = this;
     280            if (!!rawThis) {
     281                RELEASE_ASSERT(callee().isCell());
     282                vm = &this->vm();
     283            } else
     284                vm = nullptr;
     285            StackVisitor::visit<Functor>(this, vm, functor);
    263286        }
    264287
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r214645 r214905  
    473473
    474474        if (m_remainingCapacityForFrameCapture) {
    475             if (!visitor->isWasmFrame()
    476                 && !!visitor->codeBlock()
    477                 && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) {
     475            if (visitor->isWasmFrame())
     476                m_results.append(StackFrame::wasm());
     477            else if (!!visitor->codeBlock() && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) {
    478478                m_results.append(
    479                     StackFrame(m_vm, visitor->callee(), visitor->codeBlock(), visitor->bytecodeOffset()));
     479                    StackFrame(m_vm, visitor->callee().asCell(), visitor->codeBlock(), visitor->bytecodeOffset()));
    480480            } else {
    481481                m_results.append(
    482                     StackFrame(m_vm,  visitor->callee()));
     482                    StackFrame(m_vm, visitor->callee().asCell()));
    483483            }
    484484   
     
    504504
    505505    size_t framesCount = 0;
    506     callFrame->iterate([&] (StackVisitor&) -> StackVisitor::Status {
     506    StackVisitor::visit(callFrame, &vm, [&] (StackVisitor&) -> StackVisitor::Status {
    507507        framesCount++;
    508508        return StackVisitor::Continue;
     
    515515
    516516    GetStackTraceFunctor functor(vm, results, framesToSkip, framesCount);
    517     callFrame->iterate(functor);
     517    StackVisitor::visit(callFrame, &vm, functor);
    518518    ASSERT(results.size() == results.capacity());
    519519}
     
    576576};
    577577
    578 ALWAYS_INLINE static void notifyDebuggerOfUnwinding(CallFrame* callFrame)
    579 {
    580     VM& vm = callFrame->vm();
     578ALWAYS_INLINE static void notifyDebuggerOfUnwinding(VM& vm, CallFrame* callFrame)
     579{
    581580    auto catchScope = DECLARE_CATCH_SCOPE(vm);
    582     if (Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger()) {
     581    if (Debugger* debugger = callFrame->vmEntryGlobalObject(vm)->debugger()) {
    583582        SuspendExceptionScope scope(&vm);
    584         if (jsDynamicCast<JSFunction*>(vm, callFrame->jsCallee()))
     583        if (callFrame->isAnyWasmCallee()
     584            || (callFrame->callee().isCell() && callFrame->callee().asCell()->inherits(vm, JSFunction::info())))
    585585            debugger->unwindEvent(callFrame);
    586586        else
     
    592592class UnwindFunctor {
    593593public:
    594     UnwindFunctor(CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)
    595         : m_callFrame(callFrame)
     594    UnwindFunctor(VM& vm, CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)
     595        : m_vm(vm)
     596        , m_callFrame(callFrame)
    596597        , m_isTermination(isTermination)
    597598        , m_codeBlock(codeBlock)
     
    615616        }
    616617
    617         notifyDebuggerOfUnwinding(m_callFrame);
     618        notifyDebuggerOfUnwinding(m_vm, m_callFrame);
    618619
    619620        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(visitor);
     
    635636            return;
    636637
    637         VM& vm = m_callFrame->vm();
    638638        RegisterAtOffsetList* allCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
    639639        RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
     
    641641
    642642        unsigned registerCount = currentCalleeSaves->size();
    643         VMEntryRecord* record = vmEntryRecord(vm.topVMEntryFrame);
     643        VMEntryRecord* record = vmEntryRecord(m_vm.topVMEntryFrame);
    644644        for (unsigned i = 0; i < registerCount; i++) {
    645645            RegisterAtOffset currentEntry = currentCalleeSaves->at(i);
     
    655655    }
    656656
     657    VM& m_vm;
    657658    CallFrame*& m_callFrame;
    658659    bool m_isTermination;
     
    687688    // Calculate an exception handler vPC, unwinding call frames as necessary.
    688689    HandlerInfo* handler = nullptr;
    689     UnwindFunctor functor(callFrame, isTerminatedExecutionException(vm, exception), codeBlock, handler);
    690     callFrame->iterate(functor);
     690    UnwindFunctor functor(vm, callFrame, isTerminatedExecutionException(vm, exception), codeBlock, handler);
     691    StackVisitor::visit(callFrame, &vm, functor);
    691692    if (!handler)
    692693        return nullptr;
     
    695696}
    696697
    697 void Interpreter::notifyDebuggerOfExceptionToBeThrown(CallFrame* callFrame, Exception* exception)
    698 {
    699     VM& vm = callFrame->vm();
    700     Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
     698void Interpreter::notifyDebuggerOfExceptionToBeThrown(VM& vm, CallFrame* callFrame, Exception* exception)
     699{
     700    Debugger* debugger = callFrame->vmEntryGlobalObject(vm)->debugger();
    701701    if (debugger && debugger->needsExceptionCallbacks() && !exception->didNotifyInspectorOfThrow()) {
    702702        // This code assumes that if the debugger is enabled then there is no inlining.
     
    711711        else {
    712712            GetCatchHandlerFunctor functor;
    713             callFrame->iterate(functor);
     713            StackVisitor::visit(callFrame, &vm, functor);
    714714            HandlerInfo* handler = functor.handler();
    715715            ASSERT(!handler || handler->isCatchHandler());
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r212692 r214905  
    139139       
    140140        NEVER_INLINE HandlerInfo* unwind(VM&, CallFrame*&, Exception*, UnwindStart);
    141         void notifyDebuggerOfExceptionToBeThrown(CallFrame*, Exception*);
     141        void notifyDebuggerOfExceptionToBeThrown(VM&, CallFrame*, Exception*);
    142142        NEVER_INLINE void debug(CallFrame*, DebugHookType);
    143143        static JSString* stackTraceAsString(VM&, const Vector<StackFrame>&);
  • trunk/Source/JavaScriptCore/interpreter/Register.h

    r206525 r214905  
    7777        int32_t& tag();
    7878
     79        void* pointer() const;
     80
    7981        static Register withInt(int32_t i)
    8082        {
     
    196198    }
    197199
     200    ALWAYS_INLINE void* Register::pointer() const
     201    {
     202#if USE(JSVALUE64)
     203        return u.encodedValue.ptr;
     204#else
     205        return bitwise_cast<void*>(payload());
     206#endif
     207    }
     208
    198209    ALWAYS_INLINE int32_t Register::payload() const
    199210    {
  • trunk/Source/JavaScriptCore/interpreter/ShadowChicken.cpp

    r211247 r214905  
    153153        Vector<Frame> stackRightNow;
    154154        StackVisitor::visit(
    155             exec, [&] (StackVisitor& visitor) -> StackVisitor::Status {
     155            exec, &vm, [&] (StackVisitor& visitor) -> StackVisitor::Status {
    156156                if (visitor->isInlinedFrame())
    157157                    return StackVisitor::Continue;
     
    165165                // FIXME: Make shadow chicken work with Wasm.
    166166                // https://bugs.webkit.org/show_bug.cgi?id=165441
    167                 stackRightNow.append(Frame(jsCast<JSObject*>(visitor->callee()), visitor->callFrame(), isTailDeleted));
     167                stackRightNow.append(Frame(jsCast<JSObject*>(visitor->callee().asCell()), visitor->callFrame(), isTailDeleted));
    168168                return StackVisitor::Continue;
    169169            });
     
    274274    Vector<Frame> toPush;
    275275    StackVisitor::visit(
    276         exec, [&] (StackVisitor& visitor) -> StackVisitor::Status {
     276        exec, &vm, [&] (StackVisitor& visitor) -> StackVisitor::Status {
    277277            if (visitor->isInlinedFrame()) {
    278278                // FIXME: Handle inlining.
     
    307307                    RELEASE_ASSERT(scope->inherits(vm, JSScope::info()));
    308308            }
    309             toPush.append(Frame(jsCast<JSObject*>(visitor->callee()), callFrame, isTailDeleted, callFrame->thisValue(), scope, codeBlock, callFrame->callSiteIndex()));
     309            toPush.append(Frame(jsCast<JSObject*>(visitor->callee().asCell()), callFrame, isTailDeleted, callFrame->thisValue(), scope, codeBlock, callFrame->callSiteIndex()));
    310310
    311311            if (indexInLog < logCursorIndex
  • trunk/Source/JavaScriptCore/interpreter/ShadowChickenInlines.h

    r199076 r214905  
    3434void ShadowChicken::iterate(VM& vm, ExecState* exec, const Functor& functor)
    3535{
    36     DeferGC deferGC(exec->vm().heap);
     36    DeferGC deferGC(vm.heap);
    3737
    3838    update(vm, exec);
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp

    r211247 r214905  
    3232#include "Interpreter.h"
    3333#include "JSCInlines.h"
    34 #include "JSWebAssemblyCallee.h"
     34#include "WasmCallee.h"
    3535#include <wtf/text/StringBuilder.h>
    3636
    3737namespace JSC {
    3838
    39 StackVisitor::StackVisitor(CallFrame* startFrame)
     39StackVisitor::StackVisitor(CallFrame* startFrame, VM* vm)
    4040{
    4141    m_frame.m_index = 0;
     
    4343    CallFrame* topFrame;
    4444    if (startFrame) {
    45         m_frame.m_VMEntryFrame = startFrame->vm().topVMEntryFrame;
    46         topFrame = startFrame->vm().topCallFrame;
     45        ASSERT(vm);
     46        m_frame.m_VMEntryFrame = vm->topVMEntryFrame;
     47        topFrame = vm->topCallFrame;
    4748       
    4849        if (topFrame && static_cast<void*>(m_frame.m_VMEntryFrame) == static_cast<void*>(topFrame)) {
     
    104105    }
    105106
    106     if (callFrame->callee()->isAnyWasmCallee(callFrame->vm())) {
     107    if (callFrame->isAnyWasmCallee()) {
    107108        readNonInlinedFrame(callFrame);
    108109        return;
     
    156157    m_frame.m_isWasmFrame = false;
    157158
    158     JSCell* callee = callFrame->callee();
     159    CalleeBits callee = callFrame->callee();
    159160    m_frame.m_callee = callee;
    160161
    161     if (callee->isAnyWasmCallee(*callee->vm())) {
     162    if (callFrame->isAnyWasmCallee()) {
    162163        m_frame.m_isWasmFrame = true;
    163164        m_frame.m_codeBlock = nullptr;
     
    205206        JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame);
    206207        m_frame.m_callee = callee;
    207         ASSERT(m_frame.callee());
     208        ASSERT(!!m_frame.callee().rawPtr());
    208209
    209210        // The callerFrame just needs to be non-null to indicate that we
     
    255256#if ENABLE(WEBASSEMBLY)
    256257    if (isWasmFrame()) {
    257         if (JSCell* callee = this->callee()) {
    258             if (JSWebAssemblyCallee* wasmCallee = jsDynamicCast<JSWebAssemblyCallee*>(*callee->vm(), callee))
    259                 return wasmCallee->calleeSaveRegisters();
    260             // Other wasm callees (e.g, stubs) don't use callee save registers, so nothing needs
    261             // to be restored for them.
     258        if (callee().isCell()) {
     259            RELEASE_ASSERT(isWebAssemblyToJSCallee(callee().asCell()));
     260            return nullptr;
    262261        }
    263 
    264         return nullptr;
     262        Wasm::Callee* wasmCallee = callee().asWasmCallee();
     263        return wasmCallee->calleeSaveRegisters();
    265264    }
    266265#endif // ENABLE(WEBASSEMBLY)
     
    277276{
    278277    String traceLine;
    279     JSCell* callee = this->callee();
    280278
    281279    switch (codeType()) {
     
    289287        traceLine = ASCIILiteral("module code");
    290288        break;
    291     case CodeType::Native:
     289    case CodeType::Native: {
     290        JSCell* callee = this->callee().asCell();
    292291        if (callee)
    293292            traceLine = getCalculatedDisplayName(callFrame()->vm(), jsCast<JSObject*>(callee)).impl();
    294293        break;
    295     case CodeType::Function:
    296         traceLine = getCalculatedDisplayName(callFrame()->vm(), jsCast<JSObject*>(callee)).impl();
     294    }
     295    case CodeType::Function:
     296        traceLine = getCalculatedDisplayName(callFrame()->vm(), jsCast<JSObject*>(this->callee().asCell())).impl();
    297297        break;
    298298    case CodeType::Global:
     
    456456#endif
    457457
    458         out.print(indent, "callee: ", RawPointer(callee()), "\n");
     458        out.print(indent, "callee: ", RawPointer(callee().rawPtr()), "\n");
    459459        out.print(indent, "returnPC: ", RawPointer(returnPC), "\n");
    460460        out.print(indent, "callerFrame: ", RawPointer(callerFrame), "\n");
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.h

    r209722 r214905  
    2626#pragma once
    2727
     28#include "CalleeBits.h"
    2829#include "VMEntryRecord.h"
    2930#include <functional>
     
    6364        bool callerIsVMEntryFrame() const { return m_callerIsVMEntryFrame; }
    6465        CallFrame* callerFrame() const { return m_callerFrame; }
    65         JSCell* callee() const { return m_callee; }
     66        CalleeBits callee() const { return m_callee; }
    6667        CodeBlock* codeBlock() const { return m_codeBlock; }
    6768        unsigned bytecodeOffset() const { return m_bytecodeOffset; }
     
    111112        VMEntryFrame* m_CallerVMEntryFrame;
    112113        CallFrame* m_callerFrame;
    113         JSCell* m_callee;
     114        CalleeBits m_callee;
    114115        CodeBlock* m_codeBlock;
    115116        size_t m_index;
     
    131132
    132133    template <typename Functor>
    133     static void visit(CallFrame* startFrame, const Functor& functor)
     134    static void visit(CallFrame* startFrame, VM* vm, const Functor& functor)
    134135    {
    135         StackVisitor visitor(startFrame);
     136        StackVisitor visitor(startFrame, vm);
    136137        while (visitor->callFrame()) {
    137138            Status status = functor(visitor);
     
    147148
    148149private:
    149     JS_EXPORT_PRIVATE StackVisitor(CallFrame* startFrame);
     150    JS_EXPORT_PRIVATE StackVisitor(CallFrame* startFrame, VM*);
    150151
    151152    JS_EXPORT_PRIVATE void gotoNextFrame();
Note: See TracChangeset for help on using the changeset viewer.