WebAssembly: no VM / JS version of everything but Instance
authorjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Oct 2017 18:33:14 +0000 (18:33 +0000)
committerjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Oct 2017 18:33:14 +0000 (18:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177473

Reviewed by Filip Pizlo.

JSTests:

- Exceeding max on memory growth now returns a range error as per
spec. This is a (very minor) breaking change: it used to throw OOM
error. Update the corresponding test.

* wasm/js-api/memory-grow.js:
(assertEq):
* wasm/js-api/table.js:
(assert.throws):

Source/JavaScriptCore:

This change entails cleaning up and splitting a bunch of code which we had
intertwined between C++ classes which represent JS objects, and pure C++
implementation objects. This specific change goes most of the way towards
allowing JSC's WebAssembly to work without VM / JS, up to but excluding
JSWebAssemblyInstance (there's Wasm::Instance, but it's not *the* thing
yet). Because of this we still have a few FIXME identifying places that need to
change. A follow-up change will go the rest of the way.

I went about this change in the simplest way possible: grep the
JavaScriptCore/wasm directory for "JS[^C_]" as well as "VM" and exclude the /js/
sub-directory (which contains the JS implementation of WebAssembly).

None of this change removes the need for a JIT entitlement to be able to use
WebAssembly. We don't have an interpreter, the process therefore still needs to
be allowed to JIT to use these pure-C++ APIs.

Interesting things to note:

  - Remove VM from Plan and associated places. It can just live as a capture in
    the callback lambda if it's needed.
  - Wasm::Memory shouldn't require a VM. It was only used to ask the GC to
    collect. We now instead pass two lambdas at construction time for this
    purpose: one to notify of memory pressure, and the other to ask for
    syncrhonous memory reclamation. This allows whoever creates the memory to
    dictate how to react to both these cases, and for a JS embedding that's to
    call the GC (async or sync, respectively).
  - Move grow logic from JSWebAssemblyMemory to Wasm::Memory::grow. Use Expected
    there, with an enum class for failure types.
  - Exceeding max on memory growth now returns a range error as per spec. This
    is a (very minor) breaking change: it used to throw OOM error. Update the
    corresponding test.
  - When generating the grow_memory opcode, no need to get the VM. Instead,
    reach directly for Wasm::Memory and grow it.
  - JSWebAssemblyMemory::grow can now always throw on failure, because it's only
    ever called from JS (not from grow_memory as before).
  - Wasm::Memory now takes a callback for successful growth. This allows JS
    wrappers to register themselves when growth succeeds without Wasm::Memory
    knowning anything about JS. It'll also allow creating a list of callbacks
    for when we add thread support (we'll want to notify many wrappers, all
    under a lock).
  - Wasm::Memory is now back to being the source of truth about address / size,
    used directly by generated code instead of JSWebAssemblyMemory.
  - Move wasmToJS from the general WasmBinding header to its own header under
    wasm/js. It's only used by wasm/js/JSWebAssemblyCodeBlock.cpp, and uses VM,
    and therefore isn't general WebAssembly.
  - Make Wasm::Context an actual type (just a struct holding a
    JSWebAssemlyInstance for now) instead of an alias for that. Notably this
    doesn't add anything to the Context and doesn't change what actually gets
    passed around in JIT code (fast TLS or registers) because these changes
    potentially impact performance. The entire purpose of this change is to
    allow passing Wasm::Context around without having to know about VM. Since VM
    contains a Wasm::Context the JS embedding is effectively the same, but with
    this setup a non-JS embedding is much better off.
  - Move JSWebAssembly into the JS folder.
  - OMGPlan: use Wasm::CodeBlock directly instead of JSWebAssemblyCodeBlock.
  - wasm->JS stubs are now on Wasm::CodeBlock's tail as raw pointers, instead of
    being on JSWebAssemblyCodeBlock, and are now called wasm->Embedder
    stubs. The owned reference is still on JSWebAssemblyCodeBlock, and is still
    called wasm->JS stub. This move means that the embedder must, after creating
    a Wasm::CodeBlock, somehow create the stubs to call back into the
    embedder. This isn't adding any indirection to the generated code because
    the B3 IR generator now reaches for Wasm::CodeBlock instead of
    JSWebAssemblyCodeBlock.
  - Move more CodeBlock things. Compilation completion is now marked by its own
    atomic<bool> flag instead of a nullptr plan: that required using a lock, and
    was causing a deadlock in stack-trace.js because before my changes
    JSWebAssemblyCodeBlock did its own completion checking separately from
    Wasm::CodeBlock, without getting the lock. Now that everything points to
    Wasm::CodeBlock and there's no cached completion marker, the lock was being
    acquired in a sanity-check assertion.
  - Embedder -> Wasm wrappers are now generated through a function that's passed
    in at compilation time, instead of being hard-coded as a JS -> Wasm wrapper.
  - WasmMemory doens't need to know about fault handling thunks. Only the IR
    generator should know, and should make sure that the exception throwing
    thunk is generated if any memory is present (note: with signal handling not
    all of them generate an exception check).
  - Make exception throwing pluggable: instead of having a hard-coded
    JS-specific lambda we now have a regular C++ function being called from JIT
    code when a WebAssembly exception is thrown. This allows any embedder to get
    called as they wish. For now a process can only have a single of these
    functions (i.e. only one embedder per process) because the trap handler is a
    singleton. That can be fixed in in #177475.
  - Create WasmEmbedder.h where all embedder plugging will live.
  - Split up JSWebAssemblyTable into Wasm::Table which is
    refcounted. JSWebAssemblyTable now only contains the JS functions in the
    table, and Wasm::Table is what's used by the JIT code to lookup where to
    call and do the instance check (for context switch). Note that this creates
    an extra allocation for all the instances in Wasm::Table, and in exchange
    removes an indirection in JIT code because the instance used to be obtained
    off of the JS function. Also note that it's the embedder than keeps the
    instances alive, not Wasm::Table (which holds a dumb pointer to the
    instance), because doing otherwise would cause reference cycles.
  - Add WasmInstance. It doesn't do much for now, owns globals.
  - JSWebAssembly instance now doesn't just contain the imported functions as
    JSObjects, it also has the corresponding import's instance and wasm
    entrypoint. This triples the space allocated per instance's imported
    function, but there shouldn't be that many imports. This has two upsides: it
    creates smaller and faster code, and makes is easier to disassociate
    embedder-specific things from embedder-neutral things. The small / faster
    win is in two places: B3 IR generator only needs offsetOfImportFunction for
    the call opcode (when the called index is an import) to know whether the
    import is wasm->wasm or wasm->embedder (this isn't known at compile-time
    because it's dependent on the import object), this is now done by seeing if
    that import function has an associated target instance (only wasm->wasm
    does); the other place is wasmBinding which uses offsetOfImportFunction to
    figure out the wasm->wasm target instance, and then gets
    WebAssemblyFunction::offsetOfWasmEntrypointLoadLocation to do a tail
    call. The disassociation comes because the target instance can be
    Wasm::Instance once we change what the Context is, and
    WasmEntrypointLoadLocation is already embedder-independent. As a next step I
    can move this tail allocation from JSWebAssemblyInstance to Wasm::Instance,
    and leave importFunction in as an opaque pointer which is embedder-specific,
    and in JS will remain WriteBarrier<JSObject>.
  - Rename VMEntryFrame to EntryFrame, and in many places pass a pointer to it
    around instead of VM. This is a first step in allowing entry frames which
    aren't stored on VM, but which are instead stored in an embedder-specific
    location. That change won't really affect JS except through code churn, but
    will allow WebAssembly to use some machinery in a generic manner without
    having a VM.

* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
* debugger/Debugger.cpp:
(JSC::Debugger::stepOutOfFunction):
(JSC::Debugger::returnEvent):
(JSC::Debugger::unwindEvent):
(JSC::Debugger::didExecuteProgram):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::compileOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::wasmAwareLexicalGlobalObject):
(JSC::CallFrame::callerFrame):
(JSC::CallFrame::unsafeCallerFrame):
* interpreter/CallFrame.h:
(JSC::ExecState::callerFrame const):
(JSC::ExecState::callerFrameOrEntryFrame const):
(JSC::ExecState::unsafeCallerFrameOrEntryFrame const):
* interpreter/FrameTracers.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::operator() const):
(JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const):
(JSC::Interpreter::unwind):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::StackVisitor):
(JSC::StackVisitor::gotoNextFrame):
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::Frame::dump const):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::callerIsEntryFrame const):
* interpreter/VMEntryRecord.h:
(JSC::VMEntryRecord::prevTopEntryFrame):
(JSC::VMEntryRecord::unsafePrevTopEntryFrame):
(JSC::EntryFrame::vmEntryRecordOffset):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::loadWasmContextInstance):
(JSC::AssemblyHelpers::storeWasmContextInstance):
(JSC::AssemblyHelpers::loadWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::storeWasmContextInstanceNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
* jit/JIT.cpp:
(JSC::JIT::emitEnterOptimizationCheck):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::nativeForGenerator):
* jsc.cpp:
(functionDumpCallFrame):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntThunks.cpp:
(JSC::vmEntryRecord):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/Options.h:
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::FrameWalker):
(JSC::FrameWalker::advanceToParentFrame):
(JSC::SamplingProfiler::processUnverifiedStackTraces):
* runtime/ThrowScope.cpp:
(JSC::ThrowScope::~ThrowScope):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::VM::topEntryFrameOffset):
* runtime/VMTraps.cpp:
(JSC::isSaneFrame):
(JSC::VMTraps::tryInstallTrapBreakpoints):
(JSC::VMTraps::invalidateCodeBlocksOnStack):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::restoreWasmContextInstance):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addGrowMemory):
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
(JSC::Wasm::B3IRGenerator::addCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::parseAndCompile):
* wasm/WasmB3IRGenerator.h:
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
* wasm/WasmBBQPlan.h:
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmBinding.h:
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::create):
(JSC::Wasm::CodeBlock::CodeBlock):
(JSC::Wasm::CodeBlock::compileAsync):
(JSC::Wasm::CodeBlock::setCompilationFinished):
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::offsetOfImportStubs):
(JSC::Wasm::CodeBlock::allocationSize):
(JSC::Wasm::CodeBlock::importWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::offsetOfImportWasmToEmbedderStub):
(JSC::Wasm::CodeBlock::wasmToJSCallStubForImport):
(JSC::Wasm::CodeBlock::compilationFinished):
(JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
* wasm/WasmContext.cpp:
(JSC::Wasm::Context::useFastTLS):
(JSC::Wasm::Context::load const):
(JSC::Wasm::Context::store):
* wasm/WasmContext.h:
* wasm/WasmEmbedder.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
* wasm/WasmFaultSignalHandler.cpp:
* wasm/WasmFaultSignalHandler.h:
* wasm/WasmFormat.h:
* wasm/WasmInstance.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::~Instance):
(JSC::Wasm::Instance::extraMemoryAllocated const):
* wasm/WasmInstance.h: Added.
(JSC::Wasm::Instance::create):
(JSC::Wasm::Instance::finalizeCreation):
(JSC::Wasm::Instance::module):
(JSC::Wasm::Instance::codeBlock):
(JSC::Wasm::Instance::memory):
(JSC::Wasm::Instance::table):
(JSC::Wasm::Instance::loadI32Global const):
(JSC::Wasm::Instance::loadI64Global const):
(JSC::Wasm::Instance::loadF32Global const):
(JSC::Wasm::Instance::loadF64Global const):
(JSC::Wasm::Instance::setGlobal):
(JSC::Wasm::Instance::offsetOfCachedStackLimit):
(JSC::Wasm::Instance::cachedStackLimit const):
(JSC::Wasm::Instance::setCachedStackLimit):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::Memory):
(JSC::Wasm::Memory::create):
(JSC::Wasm::Memory::~Memory):
(JSC::Wasm::Memory::grow):
* wasm/WasmMemory.h:
(JSC::Wasm::Memory::offsetOfMemory):
(JSC::Wasm::Memory::offsetOfSize):
* wasm/WasmMemoryInformation.cpp:
(JSC::Wasm::PinnedRegisterInfo::get):
(JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
* wasm/WasmMemoryInformation.h:
(JSC::Wasm::PinnedRegisterInfo::toSave const):
* wasm/WasmMemoryMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
(JSC::Wasm::makeString):
* wasm/WasmMemoryMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
* wasm/WasmModule.cpp:
(JSC::Wasm::makeValidationCallback):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
(JSC::Wasm::Module::getOrCreateCodeBlock):
(JSC::Wasm::Module::compileSync):
(JSC::Wasm::Module::compileAsync):
* wasm/WasmModule.h:
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parseTableHelper):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::OMGPlan):
(JSC::Wasm::OMGPlan::runForIndex):
* wasm/WasmOMGPlan.h:
* wasm/WasmPageCount.h:
(JSC::Wasm::PageCount::isValid const):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::runCompletionTasks):
(JSC::Wasm::Plan::addCompletionTask):
(JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast):
* wasm/WasmPlan.h:
(JSC::Wasm::Plan::dontFinalize):
* wasm/WasmSignature.cpp:
* wasm/WasmSignature.h:
* wasm/WasmTable.cpp: Added.
(JSC::Wasm::Table::create):
(JSC::Wasm::Table::~Table):
(JSC::Wasm::Table::Table):
(JSC::Wasm::Table::grow):
(JSC::Wasm::Table::clearFunction):
(JSC::Wasm::Table::setFunction):
* wasm/WasmTable.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h.
(JSC::Wasm::Table::maximum const):
(JSC::Wasm::Table::size const):
(JSC::Wasm::Table::offsetOfSize):
(JSC::Wasm::Table::offsetOfFunctions):
(JSC::Wasm::Table::offsetOfInstances):
(JSC::Wasm::Table::isValidSize):
* wasm/WasmThunks.cpp:
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::triggerOMGTierUpThunkGenerator):
(JSC::Wasm::Thunks::setThrowWasmException):
(JSC::Wasm::Thunks::throwWasmException):
* wasm/WasmThunks.h:
* wasm/WasmWorklist.cpp:
(JSC::Wasm::Worklist::stopAllPlansForContext):
* wasm/WasmWorklist.h:
* wasm/js/JSToWasm.cpp: Added.
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/JSToWasm.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/JSWebAssembly.cpp: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.cpp.
* wasm/js/JSWebAssembly.h: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.h.
* wasm/js/JSWebAssemblyCodeBlock.cpp:
(JSC::JSWebAssemblyCodeBlock::create):
(JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
* wasm/js/JSWebAssemblyCodeBlock.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
(JSC::JSWebAssemblyInstance::finishCreation):
(JSC::JSWebAssemblyInstance::visitChildren):
(JSC::JSWebAssemblyInstance::finalizeCreation):
(JSC::JSWebAssemblyInstance::create):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::instance):
(JSC::JSWebAssemblyInstance::context const):
(JSC::JSWebAssemblyInstance::table):
(JSC::JSWebAssemblyInstance::webAssemblyToJSCallee):
(JSC::JSWebAssemblyInstance::setMemory):
(JSC::JSWebAssemblyInstance::offsetOfTail):
(JSC::JSWebAssemblyInstance::importFunctionInfo):
(JSC::JSWebAssemblyInstance::offsetOfTargetInstance):
(JSC::JSWebAssemblyInstance::offsetOfWasmEntrypoint):
(JSC::JSWebAssemblyInstance::offsetOfImportFunction):
(JSC::JSWebAssemblyInstance::importFunction):
(JSC::JSWebAssemblyInstance::internalMemory):
(JSC::JSWebAssemblyInstance::wasmCodeBlock const):
(JSC::JSWebAssemblyInstance::offsetOfWasmTable):
(JSC::JSWebAssemblyInstance::offsetOfCallee):
(JSC::JSWebAssemblyInstance::offsetOfGlobals):
(JSC::JSWebAssemblyInstance::offsetOfWasmCodeBlock):
(JSC::JSWebAssemblyInstance::offsetOfWasmMemory):
(JSC::JSWebAssemblyInstance::cachedStackLimit const):
(JSC::JSWebAssemblyInstance::setCachedStackLimit):
(JSC::JSWebAssemblyInstance::wasmMemory):
(JSC::JSWebAssemblyInstance::wasmModule):
(JSC::JSWebAssemblyInstance::allocationSize):
(JSC::JSWebAssemblyInstance::module const):
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::create):
(JSC::JSWebAssemblyMemory::adopt):
(JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
(JSC::JSWebAssemblyMemory::grow):
(JSC::JSWebAssemblyMemory::growSuccessCallback):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::moduleInformation const):
(JSC::JSWebAssemblyModule::exportSymbolTable const):
(JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace const):
(JSC::JSWebAssemblyModule::callee const):
(JSC::JSWebAssemblyModule::codeBlock):
(JSC::JSWebAssemblyModule::module):
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::create):
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::visitChildren):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::getFunction):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/JSWebAssemblyTable.h:
(JSC::JSWebAssemblyTable::isValidSize):
(JSC::JSWebAssemblyTable::maximum const):
(JSC::JSWebAssemblyTable::size const):
(JSC::JSWebAssemblyTable::table):
* wasm/js/WasmToJS.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.cpp.
(JSC::Wasm::materializeImportJSCell):
(JSC::Wasm::wasmToJS):
(JSC::Wasm::wasmToJSException):
* wasm/js/WasmToJS.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::webAssemblyMemoryProtoFuncGrow):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::constructJSWebAssemblyModule):
(JSC::WebAssemblyModuleConstructor::createModule):
* wasm/js/WebAssemblyModuleConstructor.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyCompileFunc):
(JSC::instantiate):
(JSC::compileAndInstantiate):
(JSC::webAssemblyValidateFunc):
* wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::constructJSWebAssemblyTable):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::create):

Source/WebCore:

* ForwardingHeaders/wasm/WasmModule.h: Added. This used to be
included in JSWebAssemblyModule.h.
* bindings/js/SerializedScriptValue.cpp: Update postMessage code
according to C++ API changes.

Source/WTF:

* wtf/StdLibExtras.h:
(WTF::default_construct_at): this makes code in WasmTable much
more readable, and is generally useful for generic code

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222791 268f45cc-cd09-0410-ab3c-d52691b4dbfc

115 files changed:
JSTests/ChangeLog
JSTests/wasm/js-api/memory-grow.js
JSTests/wasm/js-api/table.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Sources.txt
Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
Source/JavaScriptCore/debugger/Debugger.cpp
Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
Source/JavaScriptCore/dfg/DFGOSREntry.cpp
Source/JavaScriptCore/dfg/DFGOSRExit.cpp
Source/JavaScriptCore/dfg/DFGThunks.cpp
Source/JavaScriptCore/ftl/FTLCompile.cpp
Source/JavaScriptCore/ftl/FTLLink.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
Source/JavaScriptCore/interpreter/CallFrame.cpp
Source/JavaScriptCore/interpreter/CallFrame.h
Source/JavaScriptCore/interpreter/FrameTracers.h
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/interpreter/StackVisitor.cpp
Source/JavaScriptCore/interpreter/StackVisitor.h
Source/JavaScriptCore/interpreter/VMEntryRecord.h
Source/JavaScriptCore/jit/AssemblyHelpers.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.h
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JITExceptions.cpp
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/jit/ThunkGenerators.cpp
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/llint/LLIntThunks.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/runtime/Options.cpp
Source/JavaScriptCore/runtime/Options.h
Source/JavaScriptCore/runtime/SamplingProfiler.cpp
Source/JavaScriptCore/runtime/ThrowScope.cpp
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/JavaScriptCore/runtime/VMTraps.cpp
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
Source/JavaScriptCore/wasm/WasmB3IRGenerator.h
Source/JavaScriptCore/wasm/WasmBBQPlan.cpp
Source/JavaScriptCore/wasm/WasmBBQPlan.h
Source/JavaScriptCore/wasm/WasmBBQPlanInlines.h
Source/JavaScriptCore/wasm/WasmBinding.cpp
Source/JavaScriptCore/wasm/WasmBinding.h
Source/JavaScriptCore/wasm/WasmCodeBlock.cpp
Source/JavaScriptCore/wasm/WasmCodeBlock.h
Source/JavaScriptCore/wasm/WasmContext.cpp
Source/JavaScriptCore/wasm/WasmContext.h
Source/JavaScriptCore/wasm/WasmEmbedder.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp
Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h
Source/JavaScriptCore/wasm/WasmFormat.h
Source/JavaScriptCore/wasm/WasmInstance.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmInstance.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmMemory.cpp
Source/JavaScriptCore/wasm/WasmMemory.h
Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp
Source/JavaScriptCore/wasm/WasmMemoryInformation.h
Source/JavaScriptCore/wasm/WasmMemoryMode.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmMemoryMode.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmModule.cpp
Source/JavaScriptCore/wasm/WasmModule.h
Source/JavaScriptCore/wasm/WasmModuleParser.cpp
Source/JavaScriptCore/wasm/WasmNameSection.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmOMGPlan.cpp
Source/JavaScriptCore/wasm/WasmOMGPlan.h
Source/JavaScriptCore/wasm/WasmPageCount.h
Source/JavaScriptCore/wasm/WasmPlan.cpp
Source/JavaScriptCore/wasm/WasmPlan.h
Source/JavaScriptCore/wasm/WasmSignature.cpp
Source/JavaScriptCore/wasm/WasmSignature.h
Source/JavaScriptCore/wasm/WasmTable.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmTable.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmThunks.cpp
Source/JavaScriptCore/wasm/WasmThunks.h
Source/JavaScriptCore/wasm/WasmWorklist.cpp
Source/JavaScriptCore/wasm/WasmWorklist.h
Source/JavaScriptCore/wasm/js/JSToWasm.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/js/JSToWasm.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp [moved from Source/JavaScriptCore/wasm/JSWebAssembly.cpp with 100% similarity]
Source/JavaScriptCore/wasm/js/JSWebAssembly.h [moved from Source/JavaScriptCore/wasm/JSWebAssembly.h with 62% similarity]
Source/JavaScriptCore/wasm/js/JSWebAssemblyCodeBlock.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyCodeBlock.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h
Source/JavaScriptCore/wasm/js/WasmToJS.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/js/WasmToJS.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.h
Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyTableConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp
Source/WTF/ChangeLog
Source/WTF/wtf/StdLibExtras.h
Source/WebCore/ChangeLog
Source/WebCore/ForwardingHeaders/wasm/WasmModule.h [new file with mode: 0644]
Source/WebCore/bindings/js/SerializedScriptValue.cpp

index f6c1935..add1388 100644 (file)
@@ -1,3 +1,19 @@
+2017-10-03  JF Bastien  <jfbastien@apple.com>
+
+        WebAssembly: no VM / JS version of everything but Instance
+        https://bugs.webkit.org/show_bug.cgi?id=177473
+
+        Reviewed by Filip Pizlo.
+
+        - Exceeding max on memory growth now returns a range error as per
+        spec. This is a (very minor) breaking change: it used to throw OOM
+        error. Update the corresponding test.
+
+        * wasm/js-api/memory-grow.js:
+        (assertEq):
+        * wasm/js-api/table.js:
+        (assert.throws):
+
 2017-10-03  Ryan Haddad  <ryanhaddad@apple.com>
 
         Skip JSC test stress/regress-159779-2.js on debug.
index c28001e..0f8fc96 100644 (file)
@@ -45,7 +45,7 @@ for (let buffer of buffers) {
     assertEq(buffer.byteLength, 2*64*1024);
 
     // This shouldn't neuter the buffer since it fails.
-    assertThrows(() => memory.grow(1000), Error, "Out of memory"); 
+    assertThrows(() => memory.grow(1000), RangeError, "WebAssembly.Memory.grow would exceed the memory's declared maximum size");
     assertEq(buffer.byteLength, 2*64*1024);
     assertEq(memory.buffer, buffer);
 }
index 72d495b..413284d 100644 (file)
@@ -166,8 +166,8 @@ function assertBadTableImport(tableDescription, message) {
          "WebAssembly.Module doesn't parse at byte 29 / 32: resizable limits has a initial page count of 4294967295 which is greater than its maximum 4294967294 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
          "WebAssembly.Module doesn't parse at byte 37 / 43: resizable limits has a initial page count of 4294967295 which is greater than its maximum 4294967294 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
         [{initial: 2**31, element: "anyfunc"},
-         "WebAssembly.Module doesn't parse at byte 24 / 27: Table's initial page count of 2147483648 is invalid (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 32 / 38: Table's initial page count of 2147483648 is invalid (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
+         "WebAssembly.Module doesn't parse at byte 24 / 27: Table's initial page count of 2147483648 is too big, maximum 10000000 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 32 / 38: Table's initial page count of 2147483648 is too big, maximum 10000000 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
     ];
 
     for (const d of badDescriptions) {
index 6c169bc..549bca8 100644 (file)
@@ -1,3 +1,461 @@
+2017-10-03  JF Bastien  <jfbastien@apple.com>
+
+        WebAssembly: no VM / JS version of everything but Instance
+        https://bugs.webkit.org/show_bug.cgi?id=177473
+
+        Reviewed by Filip Pizlo.
+
+        This change entails cleaning up and splitting a bunch of code which we had
+        intertwined between C++ classes which represent JS objects, and pure C++
+        implementation objects. This specific change goes most of the way towards
+        allowing JSC's WebAssembly to work without VM / JS, up to but excluding
+        JSWebAssemblyInstance (there's Wasm::Instance, but it's not *the* thing
+        yet). Because of this we still have a few FIXME identifying places that need to
+        change. A follow-up change will go the rest of the way.
+
+        I went about this change in the simplest way possible: grep the
+        JavaScriptCore/wasm directory for "JS[^C_]" as well as "VM" and exclude the /js/
+        sub-directory (which contains the JS implementation of WebAssembly).
+
+        None of this change removes the need for a JIT entitlement to be able to use
+        WebAssembly. We don't have an interpreter, the process therefore still needs to
+        be allowed to JIT to use these pure-C++ APIs.
+
+        Interesting things to note:
+
+          - Remove VM from Plan and associated places. It can just live as a capture in
+            the callback lambda if it's needed.
+          - Wasm::Memory shouldn't require a VM. It was only used to ask the GC to
+            collect. We now instead pass two lambdas at construction time for this
+            purpose: one to notify of memory pressure, and the other to ask for
+            syncrhonous memory reclamation. This allows whoever creates the memory to
+            dictate how to react to both these cases, and for a JS embedding that's to
+            call the GC (async or sync, respectively).
+          - Move grow logic from JSWebAssemblyMemory to Wasm::Memory::grow. Use Expected
+            there, with an enum class for failure types.
+          - Exceeding max on memory growth now returns a range error as per spec. This
+            is a (very minor) breaking change: it used to throw OOM error. Update the
+            corresponding test.
+          - When generating the grow_memory opcode, no need to get the VM. Instead,
+            reach directly for Wasm::Memory and grow it.
+          - JSWebAssemblyMemory::grow can now always throw on failure, because it's only
+            ever called from JS (not from grow_memory as before).
+          - Wasm::Memory now takes a callback for successful growth. This allows JS
+            wrappers to register themselves when growth succeeds without Wasm::Memory
+            knowning anything about JS. It'll also allow creating a list of callbacks
+            for when we add thread support (we'll want to notify many wrappers, all
+            under a lock).
+          - Wasm::Memory is now back to being the source of truth about address / size,
+            used directly by generated code instead of JSWebAssemblyMemory.
+          - Move wasmToJS from the general WasmBinding header to its own header under
+            wasm/js. It's only used by wasm/js/JSWebAssemblyCodeBlock.cpp, and uses VM,
+            and therefore isn't general WebAssembly.
+          - Make Wasm::Context an actual type (just a struct holding a
+            JSWebAssemlyInstance for now) instead of an alias for that. Notably this
+            doesn't add anything to the Context and doesn't change what actually gets
+            passed around in JIT code (fast TLS or registers) because these changes
+            potentially impact performance. The entire purpose of this change is to
+            allow passing Wasm::Context around without having to know about VM. Since VM
+            contains a Wasm::Context the JS embedding is effectively the same, but with
+            this setup a non-JS embedding is much better off.
+          - Move JSWebAssembly into the JS folder.
+          - OMGPlan: use Wasm::CodeBlock directly instead of JSWebAssemblyCodeBlock.
+          - wasm->JS stubs are now on Wasm::CodeBlock's tail as raw pointers, instead of
+            being on JSWebAssemblyCodeBlock, and are now called wasm->Embedder
+            stubs. The owned reference is still on JSWebAssemblyCodeBlock, and is still
+            called wasm->JS stub. This move means that the embedder must, after creating
+            a Wasm::CodeBlock, somehow create the stubs to call back into the
+            embedder. This isn't adding any indirection to the generated code because
+            the B3 IR generator now reaches for Wasm::CodeBlock instead of
+            JSWebAssemblyCodeBlock.
+          - Move more CodeBlock things. Compilation completion is now marked by its own
+            atomic<bool> flag instead of a nullptr plan: that required using a lock, and
+            was causing a deadlock in stack-trace.js because before my changes
+            JSWebAssemblyCodeBlock did its own completion checking separately from
+            Wasm::CodeBlock, without getting the lock. Now that everything points to
+            Wasm::CodeBlock and there's no cached completion marker, the lock was being
+            acquired in a sanity-check assertion.
+          - Embedder -> Wasm wrappers are now generated through a function that's passed
+            in at compilation time, instead of being hard-coded as a JS -> Wasm wrapper.
+          - WasmMemory doens't need to know about fault handling thunks. Only the IR
+            generator should know, and should make sure that the exception throwing
+            thunk is generated if any memory is present (note: with signal handling not
+            all of them generate an exception check).
+          - Make exception throwing pluggable: instead of having a hard-coded
+            JS-specific lambda we now have a regular C++ function being called from JIT
+            code when a WebAssembly exception is thrown. This allows any embedder to get
+            called as they wish. For now a process can only have a single of these
+            functions (i.e. only one embedder per process) because the trap handler is a
+            singleton. That can be fixed in in #177475.
+          - Create WasmEmbedder.h where all embedder plugging will live.
+          - Split up JSWebAssemblyTable into Wasm::Table which is
+            refcounted. JSWebAssemblyTable now only contains the JS functions in the
+            table, and Wasm::Table is what's used by the JIT code to lookup where to
+            call and do the instance check (for context switch). Note that this creates
+            an extra allocation for all the instances in Wasm::Table, and in exchange
+            removes an indirection in JIT code because the instance used to be obtained
+            off of the JS function. Also note that it's the embedder than keeps the
+            instances alive, not Wasm::Table (which holds a dumb pointer to the
+            instance), because doing otherwise would cause reference cycles.
+          - Add WasmInstance. It doesn't do much for now, owns globals.
+          - JSWebAssembly instance now doesn't just contain the imported functions as
+            JSObjects, it also has the corresponding import's instance and wasm
+            entrypoint. This triples the space allocated per instance's imported
+            function, but there shouldn't be that many imports. This has two upsides: it
+            creates smaller and faster code, and makes is easier to disassociate
+            embedder-specific things from embedder-neutral things. The small / faster
+            win is in two places: B3 IR generator only needs offsetOfImportFunction for
+            the call opcode (when the called index is an import) to know whether the
+            import is wasm->wasm or wasm->embedder (this isn't known at compile-time
+            because it's dependent on the import object), this is now done by seeing if
+            that import function has an associated target instance (only wasm->wasm
+            does); the other place is wasmBinding which uses offsetOfImportFunction to
+            figure out the wasm->wasm target instance, and then gets
+            WebAssemblyFunction::offsetOfWasmEntrypointLoadLocation to do a tail
+            call. The disassociation comes because the target instance can be
+            Wasm::Instance once we change what the Context is, and
+            WasmEntrypointLoadLocation is already embedder-independent. As a next step I
+            can move this tail allocation from JSWebAssemblyInstance to Wasm::Instance,
+            and leave importFunction in as an opaque pointer which is embedder-specific,
+            and in JS will remain WriteBarrier<JSObject>.
+          - Rename VMEntryFrame to EntryFrame, and in many places pass a pointer to it
+            around instead of VM. This is a first step in allowing entry frames which
+            aren't stored on VM, but which are instead stored in an embedder-specific
+            location. That change won't really affect JS except through code churn, but
+            will allow WebAssembly to use some machinery in a generic manner without
+            having a VM.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * bytecode/PolymorphicAccess.cpp:
+        (JSC::AccessGenerationState::emitExplicitExceptionHandler):
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::stepOutOfFunction):
+        (JSC::Debugger::returnEvent):
+        (JSC::Debugger::unwindEvent):
+        (JSC::Debugger::didExecuteProgram):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileExceptionHandlers):
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::prepareOSREntry):
+        * dfg/DFGOSRExit.cpp:
+        (JSC::DFG::OSRExit::compileOSRExit):
+        (JSC::DFG::OSRExit::compileExit):
+        * dfg/DFGThunks.cpp:
+        (JSC::DFG::osrEntryThunkGenerator):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::compile):
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::lower):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * interpreter/CallFrame.cpp:
+        (JSC::CallFrame::wasmAwareLexicalGlobalObject):
+        (JSC::CallFrame::callerFrame):
+        (JSC::CallFrame::unsafeCallerFrame):
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::callerFrame const):
+        (JSC::ExecState::callerFrameOrEntryFrame const):
+        (JSC::ExecState::unsafeCallerFrameOrEntryFrame const):
+        * interpreter/FrameTracers.h:
+        (JSC::NativeCallFrameTracer::NativeCallFrameTracer):
+        (JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
+        (JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
+        * interpreter/Interpreter.cpp:
+        (JSC::UnwindFunctor::operator() const):
+        (JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const):
+        (JSC::Interpreter::unwind):
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::StackVisitor):
+        (JSC::StackVisitor::gotoNextFrame):
+        (JSC::StackVisitor::readNonInlinedFrame):
+        (JSC::StackVisitor::Frame::dump const):
+        * interpreter/StackVisitor.h:
+        (JSC::StackVisitor::Frame::callerIsEntryFrame const):
+        * interpreter/VMEntryRecord.h:
+        (JSC::VMEntryRecord::prevTopEntryFrame):
+        (JSC::VMEntryRecord::unsafePrevTopEntryFrame):
+        (JSC::EntryFrame::vmEntryRecordOffset):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::loadWasmContextInstance):
+        (JSC::AssemblyHelpers::storeWasmContextInstance):
+        (JSC::AssemblyHelpers::loadWasmContextInstanceNeedsMacroScratchRegister):
+        (JSC::AssemblyHelpers::storeWasmContextInstanceNeedsMacroScratchRegister):
+        (JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
+        * jit/JIT.cpp:
+        (JSC::JIT::emitEnterOptimizationCheck):
+        (JSC::JIT::privateCompileExceptionHandlers):
+        * jit/JITExceptions.cpp:
+        (JSC::genericUnwind):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_throw):
+        (JSC::JIT::emit_op_catch):
+        (JSC::JIT::emitSlow_op_loop_hint):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_throw):
+        (JSC::JIT::emit_op_catch):
+        * jit/JITOperations.cpp:
+        * jit/ThunkGenerators.cpp:
+        (JSC::throwExceptionFromCallSlowPathGenerator):
+        (JSC::nativeForGenerator):
+        * jsc.cpp:
+        (functionDumpCallFrame):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntThunks.cpp:
+        (JSC::vmEntryRecord):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+        * runtime/Options.h:
+        * runtime/SamplingProfiler.cpp:
+        (JSC::FrameWalker::FrameWalker):
+        (JSC::FrameWalker::advanceToParentFrame):
+        (JSC::SamplingProfiler::processUnverifiedStackTraces):
+        * runtime/ThrowScope.cpp:
+        (JSC::ThrowScope::~ThrowScope):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::~VM):
+        * runtime/VM.h:
+        (JSC::VM::topEntryFrameOffset):
+        * runtime/VMTraps.cpp:
+        (JSC::isSaneFrame):
+        (JSC::VMTraps::tryInstallTrapBreakpoints):
+        (JSC::VMTraps::invalidateCodeBlocksOnStack):
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::B3IRGenerator::restoreWasmContextInstance):
+        (JSC::Wasm::B3IRGenerator::B3IRGenerator):
+        (JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
+        (JSC::Wasm::B3IRGenerator::addGrowMemory):
+        (JSC::Wasm::B3IRGenerator::addCurrentMemory):
+        (JSC::Wasm::B3IRGenerator::addCall):
+        (JSC::Wasm::B3IRGenerator::addCallIndirect):
+        (JSC::Wasm::parseAndCompile):
+        * wasm/WasmB3IRGenerator.h:
+        * wasm/WasmBBQPlan.cpp:
+        (JSC::Wasm::BBQPlan::BBQPlan):
+        (JSC::Wasm::BBQPlan::compileFunctions):
+        (JSC::Wasm::BBQPlan::complete):
+        * wasm/WasmBBQPlan.h:
+        * wasm/WasmBBQPlanInlines.h:
+        (JSC::Wasm::BBQPlan::initializeCallees):
+        * wasm/WasmBinding.cpp:
+        (JSC::Wasm::wasmToWasm):
+        * wasm/WasmBinding.h:
+        * wasm/WasmCodeBlock.cpp:
+        (JSC::Wasm::CodeBlock::create):
+        (JSC::Wasm::CodeBlock::CodeBlock):
+        (JSC::Wasm::CodeBlock::compileAsync):
+        (JSC::Wasm::CodeBlock::setCompilationFinished):
+        * wasm/WasmCodeBlock.h:
+        (JSC::Wasm::CodeBlock::offsetOfImportStubs):
+        (JSC::Wasm::CodeBlock::allocationSize):
+        (JSC::Wasm::CodeBlock::importWasmToEmbedderStub):
+        (JSC::Wasm::CodeBlock::offsetOfImportWasmToEmbedderStub):
+        (JSC::Wasm::CodeBlock::wasmToJSCallStubForImport):
+        (JSC::Wasm::CodeBlock::compilationFinished):
+        (JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
+        (JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
+        * wasm/WasmContext.cpp:
+        (JSC::Wasm::Context::useFastTLS):
+        (JSC::Wasm::Context::load const):
+        (JSC::Wasm::Context::store):
+        * wasm/WasmContext.h:
+        * wasm/WasmEmbedder.h: Copied from Source/JavaScriptCore/wasm/WasmContext.h.
+        * wasm/WasmFaultSignalHandler.cpp:
+        * wasm/WasmFaultSignalHandler.h:
+        * wasm/WasmFormat.h:
+        * wasm/WasmInstance.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
+        (JSC::Wasm::Instance::Instance):
+        (JSC::Wasm::Instance::~Instance):
+        (JSC::Wasm::Instance::extraMemoryAllocated const):
+        * wasm/WasmInstance.h: Added.
+        (JSC::Wasm::Instance::create):
+        (JSC::Wasm::Instance::finalizeCreation):
+        (JSC::Wasm::Instance::module):
+        (JSC::Wasm::Instance::codeBlock):
+        (JSC::Wasm::Instance::memory):
+        (JSC::Wasm::Instance::table):
+        (JSC::Wasm::Instance::loadI32Global const):
+        (JSC::Wasm::Instance::loadI64Global const):
+        (JSC::Wasm::Instance::loadF32Global const):
+        (JSC::Wasm::Instance::loadF64Global const):
+        (JSC::Wasm::Instance::setGlobal):
+        (JSC::Wasm::Instance::offsetOfCachedStackLimit):
+        (JSC::Wasm::Instance::cachedStackLimit const):
+        (JSC::Wasm::Instance::setCachedStackLimit):
+        * wasm/WasmMemory.cpp:
+        (JSC::Wasm::Memory::Memory):
+        (JSC::Wasm::Memory::create):
+        (JSC::Wasm::Memory::~Memory):
+        (JSC::Wasm::Memory::grow):
+        * wasm/WasmMemory.h:
+        (JSC::Wasm::Memory::offsetOfMemory):
+        (JSC::Wasm::Memory::offsetOfSize):
+        * wasm/WasmMemoryInformation.cpp:
+        (JSC::Wasm::PinnedRegisterInfo::get):
+        (JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
+        * wasm/WasmMemoryInformation.h:
+        (JSC::Wasm::PinnedRegisterInfo::toSave const):
+        * wasm/WasmMemoryMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
+        (JSC::Wasm::makeString):
+        * wasm/WasmMemoryMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
+        * wasm/WasmModule.cpp:
+        (JSC::Wasm::makeValidationCallback):
+        (JSC::Wasm::Module::validateSync):
+        (JSC::Wasm::Module::validateAsync):
+        (JSC::Wasm::Module::getOrCreateCodeBlock):
+        (JSC::Wasm::Module::compileSync):
+        (JSC::Wasm::Module::compileAsync):
+        * wasm/WasmModule.h:
+        * wasm/WasmModuleParser.cpp:
+        (JSC::Wasm::ModuleParser::parseTableHelper):
+        * wasm/WasmOMGPlan.cpp:
+        (JSC::Wasm::OMGPlan::OMGPlan):
+        (JSC::Wasm::OMGPlan::runForIndex):
+        * wasm/WasmOMGPlan.h:
+        * wasm/WasmPageCount.h:
+        (JSC::Wasm::PageCount::isValid const):
+        * wasm/WasmPlan.cpp:
+        (JSC::Wasm::Plan::Plan):
+        (JSC::Wasm::Plan::runCompletionTasks):
+        (JSC::Wasm::Plan::addCompletionTask):
+        (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast):
+        * wasm/WasmPlan.h:
+        (JSC::Wasm::Plan::dontFinalize):
+        * wasm/WasmSignature.cpp:
+        * wasm/WasmSignature.h:
+        * wasm/WasmTable.cpp: Added.
+        (JSC::Wasm::Table::create):
+        (JSC::Wasm::Table::~Table):
+        (JSC::Wasm::Table::Table):
+        (JSC::Wasm::Table::grow):
+        (JSC::Wasm::Table::clearFunction):
+        (JSC::Wasm::Table::setFunction):
+        * wasm/WasmTable.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h.
+        (JSC::Wasm::Table::maximum const):
+        (JSC::Wasm::Table::size const):
+        (JSC::Wasm::Table::offsetOfSize):
+        (JSC::Wasm::Table::offsetOfFunctions):
+        (JSC::Wasm::Table::offsetOfInstances):
+        (JSC::Wasm::Table::isValidSize):
+        * wasm/WasmThunks.cpp:
+        (JSC::Wasm::throwExceptionFromWasmThunkGenerator):
+        (JSC::Wasm::triggerOMGTierUpThunkGenerator):
+        (JSC::Wasm::Thunks::setThrowWasmException):
+        (JSC::Wasm::Thunks::throwWasmException):
+        * wasm/WasmThunks.h:
+        * wasm/WasmWorklist.cpp:
+        (JSC::Wasm::Worklist::stopAllPlansForContext):
+        * wasm/WasmWorklist.h:
+        * wasm/js/JSToWasm.cpp: Added.
+        (JSC::Wasm::createJSToWasmWrapper):
+        * wasm/js/JSToWasm.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
+        * wasm/js/JSWebAssembly.cpp: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.cpp.
+        * wasm/js/JSWebAssembly.h: Renamed from Source/JavaScriptCore/wasm/JSWebAssembly.h.
+        * wasm/js/JSWebAssemblyCodeBlock.cpp:
+        (JSC::JSWebAssemblyCodeBlock::create):
+        (JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
+        * wasm/js/JSWebAssemblyCodeBlock.h:
+        * wasm/js/JSWebAssemblyInstance.cpp:
+        (JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
+        (JSC::JSWebAssemblyInstance::finishCreation):
+        (JSC::JSWebAssemblyInstance::visitChildren):
+        (JSC::JSWebAssemblyInstance::finalizeCreation):
+        (JSC::JSWebAssemblyInstance::create):
+        * wasm/js/JSWebAssemblyInstance.h:
+        (JSC::JSWebAssemblyInstance::instance):
+        (JSC::JSWebAssemblyInstance::context const):
+        (JSC::JSWebAssemblyInstance::table):
+        (JSC::JSWebAssemblyInstance::webAssemblyToJSCallee):
+        (JSC::JSWebAssemblyInstance::setMemory):
+        (JSC::JSWebAssemblyInstance::offsetOfTail):
+        (JSC::JSWebAssemblyInstance::importFunctionInfo):
+        (JSC::JSWebAssemblyInstance::offsetOfTargetInstance):
+        (JSC::JSWebAssemblyInstance::offsetOfWasmEntrypoint):
+        (JSC::JSWebAssemblyInstance::offsetOfImportFunction):
+        (JSC::JSWebAssemblyInstance::importFunction):
+        (JSC::JSWebAssemblyInstance::internalMemory):
+        (JSC::JSWebAssemblyInstance::wasmCodeBlock const):
+        (JSC::JSWebAssemblyInstance::offsetOfWasmTable):
+        (JSC::JSWebAssemblyInstance::offsetOfCallee):
+        (JSC::JSWebAssemblyInstance::offsetOfGlobals):
+        (JSC::JSWebAssemblyInstance::offsetOfWasmCodeBlock):
+        (JSC::JSWebAssemblyInstance::offsetOfWasmMemory):
+        (JSC::JSWebAssemblyInstance::cachedStackLimit const):
+        (JSC::JSWebAssemblyInstance::setCachedStackLimit):
+        (JSC::JSWebAssemblyInstance::wasmMemory):
+        (JSC::JSWebAssemblyInstance::wasmModule):
+        (JSC::JSWebAssemblyInstance::allocationSize):
+        (JSC::JSWebAssemblyInstance::module const):
+        * wasm/js/JSWebAssemblyMemory.cpp:
+        (JSC::JSWebAssemblyMemory::create):
+        (JSC::JSWebAssemblyMemory::adopt):
+        (JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
+        (JSC::JSWebAssemblyMemory::grow):
+        (JSC::JSWebAssemblyMemory::growSuccessCallback):
+        * wasm/js/JSWebAssemblyMemory.h:
+        * wasm/js/JSWebAssemblyModule.cpp:
+        (JSC::JSWebAssemblyModule::moduleInformation const):
+        (JSC::JSWebAssemblyModule::exportSymbolTable const):
+        (JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace const):
+        (JSC::JSWebAssemblyModule::callee const):
+        (JSC::JSWebAssemblyModule::codeBlock):
+        (JSC::JSWebAssemblyModule::module):
+        * wasm/js/JSWebAssemblyModule.h:
+        * wasm/js/JSWebAssemblyTable.cpp:
+        (JSC::JSWebAssemblyTable::create):
+        (JSC::JSWebAssemblyTable::JSWebAssemblyTable):
+        (JSC::JSWebAssemblyTable::visitChildren):
+        (JSC::JSWebAssemblyTable::grow):
+        (JSC::JSWebAssemblyTable::getFunction):
+        (JSC::JSWebAssemblyTable::clearFunction):
+        (JSC::JSWebAssemblyTable::setFunction):
+        * wasm/js/JSWebAssemblyTable.h:
+        (JSC::JSWebAssemblyTable::isValidSize):
+        (JSC::JSWebAssemblyTable::maximum const):
+        (JSC::JSWebAssemblyTable::size const):
+        (JSC::JSWebAssemblyTable::table):
+        * wasm/js/WasmToJS.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.cpp.
+        (JSC::Wasm::materializeImportJSCell):
+        (JSC::Wasm::wasmToJS):
+        (JSC::Wasm::wasmToJSException):
+        * wasm/js/WasmToJS.h: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
+        * wasm/js/WebAssemblyFunction.cpp:
+        (JSC::callWebAssemblyFunction):
+        * wasm/js/WebAssemblyInstanceConstructor.cpp:
+        (JSC::constructJSWebAssemblyInstance):
+        * wasm/js/WebAssemblyMemoryConstructor.cpp:
+        (JSC::constructJSWebAssemblyMemory):
+        * wasm/js/WebAssemblyMemoryPrototype.cpp:
+        (JSC::webAssemblyMemoryProtoFuncGrow):
+        * wasm/js/WebAssemblyModuleConstructor.cpp:
+        (JSC::constructJSWebAssemblyModule):
+        (JSC::WebAssemblyModuleConstructor::createModule):
+        * wasm/js/WebAssemblyModuleConstructor.h:
+        * wasm/js/WebAssemblyModuleRecord.cpp:
+        (JSC::WebAssemblyModuleRecord::link):
+        (JSC::WebAssemblyModuleRecord::evaluate):
+        * wasm/js/WebAssemblyPrototype.cpp:
+        (JSC::webAssemblyCompileFunc):
+        (JSC::instantiate):
+        (JSC::compileAndInstantiate):
+        (JSC::webAssemblyValidateFunc):
+        * wasm/js/WebAssemblyTableConstructor.cpp:
+        (JSC::constructJSWebAssemblyTable):
+        * wasm/js/WebAssemblyWrapperFunction.cpp:
+        (JSC::WebAssemblyWrapperFunction::create):
+
 2017-10-02  Keith Miller  <keith_miller@apple.com>
 
         VMTraps shouldn't crash if it sees an exception it doesn't understand.
index feb7401..b9052da 100644 (file)
                79C4B15E1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79CFC6F01C33B10000C768EA /* LLIntPCRanges.h in Headers */ = {isa = PBXBuildFile; fileRef = 79CFC6EF1C33B10000C768EA /* LLIntPCRanges.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79D5CD5B1C1106A900CECA07 /* SamplingProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 79D5CD591C1106A900CECA07 /* SamplingProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               79DAE27A1E03C82200B526AA /* WasmExceptionType.h in Headers */ = {isa = PBXBuildFile; fileRef = 79DAE2791E03C82200B526AA /* WasmExceptionType.h */; };
+               79DAE27A1E03C82200B526AA /* WasmExceptionType.h in Headers */ = {isa = PBXBuildFile; fileRef = 79DAE2791E03C82200B526AA /* WasmExceptionType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79DFCBDB1D88C59600527D03 /* HasOwnPropertyCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 79DFCBDA1D88C59600527D03 /* HasOwnPropertyCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79EE0C001B4AFB85000385C9 /* VariableEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79EFD4841EBC045C00F3DFEA /* JSWebAssemblyCodeBlockSubspace.h in Headers */ = {isa = PBXBuildFile; fileRef = 79EFD4821EBC045C00F3DFEA /* JSWebAssemblyCodeBlockSubspace.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD2FCC201DB59CB200B3E736 /* WebAssemblyTableConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCC141DB59C5900B3E736 /* WebAssemblyTableConstructor.lut.h */; };
                AD2FCC211DB59CB200B3E736 /* WebAssemblyTablePrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCC151DB59C5900B3E736 /* WebAssemblyTablePrototype.lut.h */; };
                AD2FCC2D1DB838FD00B3E736 /* WebAssemblyPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCC271DB838C400B3E736 /* WebAssemblyPrototype.h */; };
-               AD2FCC311DB83D4900B3E736 /* JSWebAssembly.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCC2F1DB839F700B3E736 /* JSWebAssembly.h */; };
                AD412B341E7B2E9E008AF157 /* WasmContext.h in Headers */ = {isa = PBXBuildFile; fileRef = AD412B321E7B2E8A008AF157 /* WasmContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD4252511E5D0E14009D2A97 /* FullCodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4252501E5D0DEB009D2A97 /* FullCodeOrigin.h */; };
                AD4937C41DDBE6140077C807 /* AbstractModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4937C21DDBE60A0077C807 /* AbstractModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD4937D41DDD27DE0077C807 /* WebAssemblyFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4937CA1DDD27340077C807 /* WebAssemblyFunction.h */; };
                AD4B1DFA1DF244E20071AE32 /* WasmBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4B1DF81DF244D70071AE32 /* WasmBinding.h */; };
                AD5B416F1EBAFB77008EFA43 /* WasmName.h in Headers */ = {isa = PBXBuildFile; fileRef = AD5B416E1EBAFB65008EFA43 /* WasmName.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               AD5C36DD1F688B65000BCAAF /* WasmEmbedder.h in Headers */ = {isa = PBXBuildFile; fileRef = AD5C36DC1F688B5F000BCAAF /* WasmEmbedder.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               AD5C36E21F699EC0000BCAAF /* WasmInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = AD5C36DF1F699EB6000BCAAF /* WasmInstance.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               AD5C36E61F69EC91000BCAAF /* WasmTable.h in Headers */ = {isa = PBXBuildFile; fileRef = AD5C36E41F69EC8B000BCAAF /* WasmTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               AD5C36EA1F75AD6A000BCAAF /* JSToWasm.h in Headers */ = {isa = PBXBuildFile; fileRef = AD8DD6CF1F67089F0004EB52 /* JSToWasm.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               AD5C36EB1F75AD73000BCAAF /* JSWebAssembly.h in Headers */ = {isa = PBXBuildFile; fileRef = ADD09AF31F62482E001313C2 /* JSWebAssembly.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               AD5C36EC1F75AD7C000BCAAF /* WasmToJS.h in Headers */ = {isa = PBXBuildFile; fileRef = ADD09AEE1F5F623F001313C2 /* WasmToJS.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               AD5C36EF1F7A263A000BCAAF /* WasmMemoryMode.h in Headers */ = {isa = PBXBuildFile; fileRef = AD5C36EE1F7A2629000BCAAF /* WasmMemoryMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = AD7438BF1E04579200FD0C2A /* WasmSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD8FF3981EB5BDB20087FF82 /* WasmIndexOrName.h in Headers */ = {isa = PBXBuildFile; fileRef = AD8FF3951EB5BD850087FF82 /* WasmIndexOrName.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD2FCC151DB59C5900B3E736 /* WebAssemblyTablePrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAssemblyTablePrototype.lut.h; sourceTree = "<group>"; };
                AD2FCC261DB838C400B3E736 /* WebAssemblyPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyPrototype.cpp; path = js/WebAssemblyPrototype.cpp; sourceTree = "<group>"; };
                AD2FCC271DB838C400B3E736 /* WebAssemblyPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyPrototype.h; path = js/WebAssemblyPrototype.h; sourceTree = "<group>"; };
-               AD2FCC2E1DB839F700B3E736 /* JSWebAssembly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebAssembly.cpp; sourceTree = "<group>"; };
-               AD2FCC2F1DB839F700B3E736 /* JSWebAssembly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebAssembly.h; sourceTree = "<group>"; };
                AD2FCC321DC4045300B3E736 /* WasmFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmFormat.cpp; sourceTree = "<group>"; };
+               AD3F1E471F4BA78600669912 /* WABase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WABase.h; sourceTree = "<group>"; };
+               AD3F1E4A1F4DE68C00669912 /* WAInstance.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WAInstance.h; sourceTree = "<group>"; };
+               AD3F1E4B1F4DE68C00669912 /* WATable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WATable.h; sourceTree = "<group>"; };
+               AD3F1E4C1F4DE68C00669912 /* WAMemory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WAMemory.h; sourceTree = "<group>"; };
+               AD3F1E521F4F4AE500669912 /* WAMemory.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WAMemory.cpp; sourceTree = "<group>"; };
+               AD3F1E531F4F4AE500669912 /* WAModule.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WAModule.cpp; sourceTree = "<group>"; };
+               AD3F1E541F4F4AE500669912 /* WAInstance.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WAInstance.cpp; sourceTree = "<group>"; };
+               AD3F1E551F4F4AE500669912 /* WATable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WATable.cpp; sourceTree = "<group>"; };
+               AD3F1E641F50E57F00669912 /* WAException.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WAException.h; sourceTree = "<group>"; };
+               AD3F1E651F50E57F00669912 /* WAException.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WAException.cpp; sourceTree = "<group>"; };
+               AD3F1E681F547CB600669912 /* WAMemoryDescriptor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WAMemoryDescriptor.cpp; sourceTree = "<group>"; };
+               AD3F1E691F547CB600669912 /* WAMemoryDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WAMemoryDescriptor.h; sourceTree = "<group>"; };
+               AD3F1E6A1F547CB600669912 /* WAImportObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WAImportObject.h; sourceTree = "<group>"; };
+               AD3F1E6B1F547CB800669912 /* WATableDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WATableDescriptor.h; sourceTree = "<group>"; };
+               AD3F1E6C1F547CB800669912 /* WAImportObject.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WAImportObject.cpp; sourceTree = "<group>"; };
+               AD3F1E6D1F547CB800669912 /* WATableDescriptor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WATableDescriptor.cpp; sourceTree = "<group>"; };
+               AD3F1E701F54C3AA00669912 /* WAFunction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WAFunction.h; sourceTree = "<group>"; };
+               AD3F1E711F54C3AA00669912 /* WAFunction.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WAFunction.cpp; sourceTree = "<group>"; };
                AD412B311E7B2E8A008AF157 /* WasmContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmContext.cpp; sourceTree = "<group>"; };
                AD412B321E7B2E8A008AF157 /* WasmContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmContext.h; sourceTree = "<group>"; };
                AD412B351E7B57C0008AF157 /* AllowMacroScratchRegisterUsageIf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllowMacroScratchRegisterUsageIf.h; sourceTree = "<group>"; };
                AD4B1DF71DF244D70071AE32 /* WasmBinding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmBinding.cpp; sourceTree = "<group>"; };
                AD4B1DF81DF244D70071AE32 /* WasmBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmBinding.h; sourceTree = "<group>"; };
                AD5B416E1EBAFB65008EFA43 /* WasmName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmName.h; sourceTree = "<group>"; };
+               AD5C36DC1F688B5F000BCAAF /* WasmEmbedder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmEmbedder.h; sourceTree = "<group>"; };
+               AD5C36DE1F699EB6000BCAAF /* WasmInstance.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmInstance.cpp; sourceTree = "<group>"; };
+               AD5C36DF1F699EB6000BCAAF /* WasmInstance.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmInstance.h; sourceTree = "<group>"; };
+               AD5C36E31F69EC8B000BCAAF /* WasmTable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmTable.cpp; sourceTree = "<group>"; };
+               AD5C36E41F69EC8B000BCAAF /* WasmTable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmTable.h; sourceTree = "<group>"; };
+               AD5C36EE1F7A2629000BCAAF /* WasmMemoryMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmMemoryMode.h; sourceTree = "<group>"; };
+               AD5C36F01F7A26BF000BCAAF /* WasmMemoryMode.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmMemoryMode.cpp; sourceTree = "<group>"; };
                AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmSignature.cpp; sourceTree = "<group>"; };
                AD7438BF1E04579200FD0C2A /* WasmSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSignature.h; sourceTree = "<group>"; };
                AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = "<group>"; };
+               AD8DD6CF1F67089F0004EB52 /* JSToWasm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JSToWasm.h; path = js/JSToWasm.h; sourceTree = "<group>"; };
+               AD8DD6D01F6708A30004EB52 /* JSToWasm.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = JSToWasm.cpp; path = js/JSToWasm.cpp; sourceTree = "<group>"; };
                AD8FF3951EB5BD850087FF82 /* WasmIndexOrName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmIndexOrName.h; sourceTree = "<group>"; };
                AD8FF3961EB5BD850087FF82 /* WasmIndexOrName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmIndexOrName.cpp; sourceTree = "<group>"; };
                AD9E852E1E8A0C6E008DE39E /* JSWebAssemblyCodeBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSWebAssemblyCodeBlock.h; path = js/JSWebAssemblyCodeBlock.h; sourceTree = "<group>"; };
                ADB6F67C1E15D7500082F384 /* WasmPageCount.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmPageCount.cpp; sourceTree = "<group>"; };
                ADBC54D21DF8EA00005BF738 /* WebAssemblyToJSCallee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyToJSCallee.cpp; path = js/WebAssemblyToJSCallee.cpp; sourceTree = "<group>"; };
                ADBC54D31DF8EA00005BF738 /* WebAssemblyToJSCallee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyToJSCallee.h; path = js/WebAssemblyToJSCallee.h; sourceTree = "<group>"; };
+               ADD09AEE1F5F623F001313C2 /* WasmToJS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WasmToJS.h; path = js/WasmToJS.h; sourceTree = "<group>"; };
+               ADD09AEF1F5F623F001313C2 /* WasmToJS.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = WasmToJS.cpp; path = js/WasmToJS.cpp; sourceTree = "<group>"; };
+               ADD09AF21F624829001313C2 /* JSWebAssembly.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = JSWebAssembly.cpp; path = js/JSWebAssembly.cpp; sourceTree = "<group>"; };
+               ADD09AF31F62482E001313C2 /* JSWebAssembly.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JSWebAssembly.h; path = js/JSWebAssembly.h; sourceTree = "<group>"; };
                ADD8FA431EB3077100DF542F /* WasmNameSectionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmNameSectionParser.h; sourceTree = "<group>"; };
                ADD8FA441EB3077100DF542F /* WasmNameSectionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmNameSectionParser.cpp; sourceTree = "<group>"; };
                ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueRootSet.h; sourceTree = "<group>"; };
                ADE802961E08F1C90058DE78 /* WebAssemblyLinkErrorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyLinkErrorPrototype.cpp; path = js/WebAssemblyLinkErrorPrototype.cpp; sourceTree = "<group>"; };
                ADE802971E08F1C90058DE78 /* WebAssemblyLinkErrorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyLinkErrorPrototype.h; path = js/WebAssemblyLinkErrorPrototype.h; sourceTree = "<group>"; };
                ADE8029D1E08F2260058DE78 /* WebAssemblyLinkErrorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyLinkErrorConstructor.cpp; path = js/WebAssemblyLinkErrorConstructor.cpp; sourceTree = "<group>"; };
+               ADFC30F71F47A7B8006451D3 /* WebAssembly.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebAssembly.h; sourceTree = "<group>"; };
+               ADFC30F91F47A8C0006451D3 /* WAModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WAModule.h; sourceTree = "<group>"; };
                B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedInstructionStream.h; sourceTree = "<group>"; };
                B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedInstructionStream.cpp; sourceTree = "<group>"; };
                BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ToolExecutable.xcconfig; sourceTree = "<group>"; };
                                86F3EEB616855A5B0077B92A /* ObjcRuntimeExtras.h */,
                                E124A8F60E555775003091F1 /* OpaqueJSString.cpp */,
                                E124A8F50E555775003091F1 /* OpaqueJSString.h */,
+                               AD3F1E471F4BA78600669912 /* WABase.h */,
+                               AD3F1E651F50E57F00669912 /* WAException.cpp */,
+                               AD3F1E641F50E57F00669912 /* WAException.h */,
+                               AD3F1E711F54C3AA00669912 /* WAFunction.cpp */,
+                               AD3F1E701F54C3AA00669912 /* WAFunction.h */,
+                               AD3F1E6C1F547CB800669912 /* WAImportObject.cpp */,
+                               AD3F1E6A1F547CB600669912 /* WAImportObject.h */,
+                               AD3F1E541F4F4AE500669912 /* WAInstance.cpp */,
+                               AD3F1E4A1F4DE68C00669912 /* WAInstance.h */,
+                               AD3F1E521F4F4AE500669912 /* WAMemory.cpp */,
+                               AD3F1E4C1F4DE68C00669912 /* WAMemory.h */,
+                               AD3F1E681F547CB600669912 /* WAMemoryDescriptor.cpp */,
+                               AD3F1E691F547CB600669912 /* WAMemoryDescriptor.h */,
+                               AD3F1E531F4F4AE500669912 /* WAModule.cpp */,
+                               ADFC30F91F47A8C0006451D3 /* WAModule.h */,
+                               AD3F1E551F4F4AE500669912 /* WATable.cpp */,
+                               AD3F1E4B1F4DE68C00669912 /* WATable.h */,
+                               AD3F1E6D1F547CB800669912 /* WATableDescriptor.cpp */,
+                               AD3F1E6B1F547CB800669912 /* WATableDescriptor.h */,
+                               ADFC30F71F47A7B8006451D3 /* WebAssembly.h */,
                                5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */,
                        );
                        path = API;
                        isa = PBXGroup;
                        children = (
                                AD2FCB8A1DB5840000B3E736 /* js */,
-                               AD2FCC2E1DB839F700B3E736 /* JSWebAssembly.cpp */,
-                               AD2FCC2F1DB839F700B3E736 /* JSWebAssembly.h */,
                                53F40E8E1D5902820099A1B6 /* WasmB3IRGenerator.cpp */,
                                53F40E921D5A4AB30099A1B6 /* WasmB3IRGenerator.h */,
                                53CA73071EA533D80076049D /* WasmBBQPlan.cpp */,
                                526AC4B51E977C5D003500E1 /* WasmCodeBlock.h */,
                                AD412B311E7B2E8A008AF157 /* WasmContext.cpp */,
                                AD412B321E7B2E8A008AF157 /* WasmContext.h */,
+                               AD5C36DC1F688B5F000BCAAF /* WasmEmbedder.h */,
                                79DAE2791E03C82200B526AA /* WasmExceptionType.h */,
                                5381B9361E60E9660090F794 /* WasmFaultSignalHandler.cpp */,
                                5381B9381E60E97D0090F794 /* WasmFaultSignalHandler.h */,
                                53F40E8A1D5901BB0099A1B6 /* WasmFunctionParser.h */,
                                AD8FF3961EB5BD850087FF82 /* WasmIndexOrName.cpp */,
                                AD8FF3951EB5BD850087FF82 /* WasmIndexOrName.h */,
+                               AD5C36DE1F699EB6000BCAAF /* WasmInstance.cpp */,
+                               AD5C36DF1F699EB6000BCAAF /* WasmInstance.h */,
                                AD00659D1ECAC7FE000CA926 /* WasmLimits.h */,
                                53E9E0A91EAE83DE00FEE251 /* WasmMachineThreads.cpp */,
                                53E9E0AA1EAE83DE00FEE251 /* WasmMachineThreads.h */,
                                535557131D9D9EA5006D583B /* WasmMemory.h */,
                                79B759711DFA4C600052174C /* WasmMemoryInformation.cpp */,
                                79B759721DFA4C600052174C /* WasmMemoryInformation.h */,
+                               AD5C36F01F7A26BF000BCAAF /* WasmMemoryMode.cpp */,
+                               AD5C36EE1F7A2629000BCAAF /* WasmMemoryMode.h */,
                                790081361E95A8EC0052D7CD /* WasmModule.cpp */,
                                790081371E95A8EC0052D7CD /* WasmModule.h */,
                                53E777E11E92E265007CBEC4 /* WasmModuleInformation.cpp */,
                                53F40E841D58F9770099A1B6 /* WasmSections.h */,
                                AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */,
                                AD7438BF1E04579200FD0C2A /* WasmSignature.h */,
+                               AD5C36E31F69EC8B000BCAAF /* WasmTable.cpp */,
+                               AD5C36E41F69EC8B000BCAAF /* WasmTable.h */,
                                5250D2CF1E8DA05A0029A932 /* WasmThunks.cpp */,
                                5250D2D01E8DA05A0029A932 /* WasmThunks.h */,
                                53E9E0AE1EAEC45700FEE251 /* WasmTierUpCount.h */,
                AD2FCB8A1DB5840000B3E736 /* js */ = {
                        isa = PBXGroup;
                        children = (
+                               AD8DD6D01F6708A30004EB52 /* JSToWasm.cpp */,
+                               AD8DD6CF1F67089F0004EB52 /* JSToWasm.h */,
+                               ADD09AF21F624829001313C2 /* JSWebAssembly.cpp */,
+                               ADD09AF31F62482E001313C2 /* JSWebAssembly.h */,
                                5383AA2F1E65E8A100A532FC /* JSWebAssemblyCodeBlock.cpp */,
                                AD9E852E1E8A0C6E008DE39E /* JSWebAssemblyCodeBlock.h */,
                                79EFD4811EBC045C00F3DFEA /* JSWebAssemblyCodeBlockSubspace.cpp */,
                                AD2FCBAD1DB58DA400B3E736 /* JSWebAssemblyRuntimeError.h */,
                                AD2FCBAE1DB58DA400B3E736 /* JSWebAssemblyTable.cpp */,
                                AD2FCBAF1DB58DA400B3E736 /* JSWebAssemblyTable.h */,
+                               ADD09AEF1F5F623F001313C2 /* WasmToJS.cpp */,
+                               ADD09AEE1F5F623F001313C2 /* WasmToJS.h */,
                                AD2FCBB01DB58DA400B3E736 /* WebAssemblyCompileErrorConstructor.cpp */,
                                AD2FCBB11DB58DA400B3E736 /* WebAssemblyCompileErrorConstructor.h */,
                                AD2FCBB21DB58DA400B3E736 /* WebAssemblyCompileErrorPrototype.cpp */,
                                0FEC85BB1BE1462F0080FF74 /* B3InsertionSetInlines.h in Headers */,
                                0FDF67D21D9C6D27001B9825 /* B3Kind.h in Headers */,
                                436E54531C468E7400B5AF73 /* B3LegalizeMemoryOffsets.h in Headers */,
+                               AD5C36EC1F75AD7C000BCAAF /* WasmToJS.h in Headers */,
                                0F338E1E1BF286EA0013C88F /* B3LowerMacros.h in Headers */,
                                4319DA041C1BE40D001D260B /* B3LowerMacrosAfterOptimizations.h in Headers */,
                                0FEC851E1BDACDAC0080FF74 /* B3LowerToAir.h in Headers */,
                                E328DAEB1D38D005001A2529 /* BytecodeRewriter.h in Headers */,
                                6514F21918B3E1670098FF8B /* Bytecodes.h in Headers */,
                                0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */,
+                               AD5C36EB1F75AD73000BCAAF /* JSWebAssembly.h in Headers */,
                                0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */,
                                65B8392E1BACAD360044E824 /* CachedRecovery.h in Headers */,
                                0FEC3C601F379F5300F59B6C /* CagedBarrierPtr.h in Headers */,
                                0FA581BC150E953000B9A2D9 /* DFGNodeType.h in Headers */,
                                DCEE220D1CEBAF75000C2396 /* DFGNullAbstractState.h in Headers */,
                                0F2B9CE719D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h in Headers */,
+                               AD5C36DD1F688B65000BCAAF /* WasmEmbedder.h in Headers */,
                                0F2B9CE919D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h in Headers */,
                                86EC9DD01328DF82002B2AD7 /* DFGOperations.h in Headers */,
                                0F7C39FF1C90C55B00480151 /* DFGOpInfo.h in Headers */,
                                0F3AC754188E5EC80032029F /* ExitingJITType.h in Headers */,
                                0FB105861675481200F8AB6E /* ExitKind.h in Headers */,
                                0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
+                               AD5C36EA1F75AD6A000BCAAF /* JSToWasm.h in Headers */,
                                0FEC3C571F33A45300F59B6C /* FastMallocAlignedMemoryAllocator.h in Headers */,
                                A7A8AF3817ADB5F3005AB174 /* Float32Array.h in Headers */,
+                               AD5C36E21F699EC0000BCAAF /* WasmInstance.h in Headers */,
                                A7A8AF3917ADB5F3005AB174 /* Float64Array.h in Headers */,
                                0F24E54317EA9F5900ABB217 /* FPRInfo.h in Headers */,
                                E34EDBF71DB5FFC900DC87A5 /* FrameTracers.h in Headers */,
                                A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
                                0F0B286B1EB8E6CF000EB5D2 /* JSWeakPrivate.h in Headers */,
                                709FB8681AE335C60039D069 /* JSWeakSet.h in Headers */,
-                               AD2FCC311DB83D4900B3E736 /* JSWebAssembly.h in Headers */,
                                AD9E852F1E8A0C7C008DE39E /* JSWebAssemblyCodeBlock.h in Headers */,
                                79EFD4841EBC045C00F3DFEA /* JSWebAssemblyCodeBlockSubspace.h in Headers */,
                                AD2FCBE31DB58DAD00B3E736 /* JSWebAssemblyCompileError.h in Headers */,
                                BCD202D60E170708002C7E82 /* RegExpConstructor.lut.h in Headers */,
                                0F7C39FB1C8F629300480151 /* RegExpInlines.h in Headers */,
                                A1712B4111C7B235007A5315 /* RegExpKey.h in Headers */,
+                               AD5C36E61F69EC91000BCAAF /* WasmTable.h in Headers */,
                                BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */,
                                0F7C39FD1C8F659500480151 /* RegExpObjectInlines.h in Headers */,
                                BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */,
                                0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */,
                                0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
                                0F1FB3931E177A7200A9BE50 /* VisitingTimeout.h in Headers */,
+                               AD5C36EF1F7A263A000BCAAF /* WasmMemoryMode.h in Headers */,
                                0F952AA11DF7860900E06FBD /* VisitRaceKey.h in Headers */,
                                BC18C4200E16F5CD00B34460 /* VM.h in Headers */,
                                658D3A5619638268003C45D6 /* VMEntryRecord.h in Headers */,
index 41455db..b4a4b46 100644 (file)
@@ -935,7 +935,6 @@ tools/JSDollarVMPrototype.cpp
 tools/SigillCrashAnalyzer.cpp
 tools/VMInspector.cpp
 
-wasm/JSWebAssembly.cpp
 wasm/WasmB3IRGenerator.cpp
 wasm/WasmBBQPlan.cpp
 wasm/WasmBinding.cpp
@@ -943,12 +942,16 @@ wasm/WasmCallee.cpp
 wasm/WasmCallingConvention.cpp
 wasm/WasmCodeBlock.cpp
 wasm/WasmContext.cpp
+wasm/WasmEmbedder.h
 wasm/WasmFaultSignalHandler.cpp
 wasm/WasmFormat.cpp
 wasm/WasmIndexOrName.cpp
+wasm/WasmInstance.cpp
+wasm/WasmInstance.h
 wasm/WasmMachineThreads.cpp
 wasm/WasmMemory.cpp
 wasm/WasmMemoryInformation.cpp
+wasm/WasmMemoryMode.cpp
 wasm/WasmModule.cpp
 wasm/WasmModuleInformation.cpp
 wasm/WasmModuleParser.cpp
@@ -958,10 +961,15 @@ wasm/WasmOpcodeOrigin.cpp
 wasm/WasmPageCount.cpp
 wasm/WasmPlan.cpp
 wasm/WasmSignature.cpp
+wasm/WasmTable.cpp
+wasm/WasmTable.h
 wasm/WasmThunks.cpp
 wasm/WasmValidate.cpp
 wasm/WasmWorklist.cpp
 
+wasm/js/JSToWasm.cpp
+wasm/js/JSToWasm.h
+wasm/js/JSWebAssembly.cpp
 wasm/js/JSWebAssemblyCodeBlock.cpp
 wasm/js/JSWebAssemblyCodeBlockSubspace.cpp
 wasm/js/JSWebAssemblyCompileError.cpp
@@ -971,6 +979,8 @@ wasm/js/JSWebAssemblyMemory.cpp
 wasm/js/JSWebAssemblyModule.cpp
 wasm/js/JSWebAssemblyRuntimeError.cpp
 wasm/js/JSWebAssemblyTable.cpp
+wasm/js/WasmToJS.cpp
+wasm/js/WasmToJS.h
 wasm/js/WebAssemblyCompileErrorConstructor.cpp
 wasm/js/WebAssemblyCompileErrorPrototype.cpp
 wasm/js/WebAssemblyFunction.cpp
index 42280c5..f8a3977 100644 (file)
@@ -179,7 +179,7 @@ CallSiteIndex AccessGenerationState::originalCallSiteIndex() const { return stub
 void AccessGenerationState::emitExplicitExceptionHandler()
 {
     restoreScratch();
-    jit->copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(m_vm);
+    jit->copyCalleeSavesToEntryFrameCalleeSavesBuffer(m_vm.topEntryFrame);
     if (needsToRestoreRegistersIfException()) {
         // To the JIT that produces the original exception handling
         // call site, they will expect the OSR exit to be arrived
index 348c68c..7716e89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2008, 2013, 2014, 2016 Apple Inc. All rights reserved.
+ *  Copyright (C) 2008-2017 Apple Inc. All rights reserved.
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
  *
@@ -652,8 +652,8 @@ void Debugger::stepOutOfFunction()
     if (!m_isPaused)
         return;
 
-    VMEntryFrame* topVMEntryFrame = m_vm.topVMEntryFrame;
-    m_pauseOnCallFrame = m_currentCallFrame ? m_currentCallFrame->callerFrame(topVMEntryFrame) : nullptr;
+    EntryFrame* topEntryFrame = m_vm.topEntryFrame;
+    m_pauseOnCallFrame = m_currentCallFrame ? m_currentCallFrame->callerFrame(topEntryFrame) : nullptr;
     m_pauseOnStepOut = true;
     setSteppingMode(SteppingModeEnabled);
     notifyDoneProcessingDebuggerEvents();
@@ -831,8 +831,8 @@ void Debugger::returnEvent(CallFrame* callFrame)
     if (!m_currentCallFrame)
         return;
 
-    VMEntryFrame* topVMEntryFrame = m_vm.topVMEntryFrame;
-    CallFrame* callerFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
+    EntryFrame* topEntryFrame = m_vm.topEntryFrame;
+    CallFrame* callerFrame = m_currentCallFrame->callerFrame(topEntryFrame);
 
     // Returning from a call, there was at least one expression on the statement we are returning to.
     m_pastFirstExpressionInStatement = true;
@@ -856,8 +856,8 @@ void Debugger::unwindEvent(CallFrame* callFrame)
     if (!m_currentCallFrame)
         return;
 
-    VMEntryFrame* topVMEntryFrame = m_vm.topVMEntryFrame;
-    CallFrame* callerFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
+    EntryFrame* topEntryFrame = m_vm.topEntryFrame;
+    CallFrame* callerFrame = m_currentCallFrame->callerFrame(topEntryFrame);
 
     // Treat stepping over an exception location like a step-out.
     if (m_currentCallFrame == m_pauseOnCallFrame)
@@ -886,8 +886,8 @@ void Debugger::didExecuteProgram(CallFrame* callFrame)
     if (!m_currentCallFrame)
         return;
 
-    VMEntryFrame* topVMEntryFrame = m_vm.topVMEntryFrame;
-    CallFrame* callerFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
+    EntryFrame* topEntryFrame = m_vm.topEntryFrame;
+    CallFrame* callerFrame = m_currentCallFrame->callerFrame(topEntryFrame);
 
     // Returning from a program, could be eval(), there was at least one expression on the statement we are returning to.
     m_pastFirstExpressionInStatement = true;
index d19ddb7..5fa48f1 100644 (file)
@@ -140,7 +140,7 @@ void JITCompiler::compileExceptionHandlers()
     if (!m_exceptionChecksWithCallFrameRollback.empty()) {
         m_exceptionChecksWithCallFrameRollback.link(this);
 
-        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm());
+        copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm()->topEntryFrame);
 
         // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
         move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
@@ -160,7 +160,7 @@ void JITCompiler::compileExceptionHandlers()
     if (!m_exceptionChecks.empty()) {
         m_exceptionChecks.link(this);
 
-        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm());
+        copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm()->topEntryFrame);
 
         // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
         move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
index 583bf98..021eaab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -317,7 +317,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
     RegisterSet dontSaveRegisters = RegisterSet(RegisterSet::stackRegisters(), RegisterSet::allFPRs());
 
     unsigned registerCount = registerSaveLocations->size();
-    VMEntryRecord* record = vmEntryRecord(vm->topVMEntryFrame);
+    VMEntryRecord* record = vmEntryRecord(vm->topEntryFrame);
     for (unsigned i = 0; i < registerCount; i++) {
         RegisterAtOffset currentEntry = registerSaveLocations->at(i);
         if (dontSaveRegisters.get(currentEntry.reg()))
index 343308c..ab7ac56 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -185,7 +185,7 @@ void JIT_OPERATION OSRExit::compileOSRExit(ExecState* exec)
         if (exit.m_kind == GenericUnwind) {
             // We are acting as a defacto op_catch because we arrive here from genericUnwind().
             // So, we must restore our call frame and stack pointer.
-            jit.restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(*vm);
+            jit.restoreCalleeSavesFromEntryFrameCalleeSavesBuffer(vm->topEntryFrame);
             jit.loadPtr(vm->addressOfCallFrameForCatch(), GPRInfo::callFrameRegister);
         }
         jit.addPtr(
@@ -537,7 +537,7 @@ void OSRExit::compileExit(CCallHelpers& jit, VM& vm, const OSRExit& exit, const
     jit.emitMaterializeTagCheckRegisters();
 
     if (exit.isExceptionHandler())
-        jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm);
+        jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm.topEntryFrame);
 
     // Do all data format conversions and store the results into the stack.
 
index b7327f3..d0c4f45 100644 (file)
@@ -135,7 +135,7 @@ MacroAssemblerCodeRef osrEntryThunkGenerator(VM* vm)
     jit.abortWithReason(DFGUnreasonableOSREntryJumpDestination);
 
     ok.link(&jit);
-    jit.restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(*vm);
+    jit.restoreCalleeSavesFromEntryFrameCalleeSavesBuffer(vm->topEntryFrame);
     jit.emitMaterializeTagCheckRegisters();
 
     jit.jump(GPRInfo::regT1);
index ff2ce56..ff24676 100644 (file)
@@ -131,7 +131,7 @@ void compile(State& state, Safepoint::Result& safepointResult)
 
     // Emit the exception handler.
     *state.exceptionHandler = jit.label();
-    jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm);
+    jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm.topEntryFrame);
     jit.move(MacroAssembler::TrustedImmPtr(&vm), GPRInfo::argumentGPR0);
     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
     CCallHelpers::Call call = jit.call();
index 7c0181d..2a1eb76 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -143,7 +143,7 @@ void link(State& state)
             CCallHelpers::Call callArityCheck = jit.call();
 
             auto noException = jit.branch32(CCallHelpers::GreaterThanOrEqual, GPRInfo::returnValueGPR, CCallHelpers::TrustedImm32(0));
-            jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm);
+            jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm.topEntryFrame);
             jit.move(CCallHelpers::TrustedImmPtr(&vm), GPRInfo::argumentGPR0);
             jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
             CCallHelpers::Call callLookupExceptionHandlerFromCallerFrame = jit.call();
index c7934e3..a99b5c4 100644 (file)
@@ -264,7 +264,7 @@ public:
                     jit.store32(
                         MacroAssembler::TrustedImm32(callSiteIndex.bits()),
                         CCallHelpers::tagFor(VirtualRegister(CallFrameSlot::argumentCount)));
-                    jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm);
+                    jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm->topEntryFrame);
 
                     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
                     jit.move(CCallHelpers::TrustedImmPtr(jit.codeBlock()), GPRInfo::argumentGPR1);
index 8e081d7..1c7e687 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -186,7 +186,7 @@ static void compileStub(
     // The first thing we need to do is restablish our frame in the case of an exception.
     if (exit.isGenericUnwindHandler()) {
         RELEASE_ASSERT(vm->callFrameForCatch); // The first time we hit this exit, like at all other times, this field should be non-null.
-        jit.restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(*vm);
+        jit.restoreCalleeSavesFromEntryFrameCalleeSavesBuffer(vm->topEntryFrame);
         jit.loadPtr(vm->addressOfCallFrameForCatch(), MacroAssembler::framePointerRegister);
         jit.addPtr(CCallHelpers::TrustedImm32(codeBlock->stackPointerOffset() * sizeof(Register)),
             MacroAssembler::framePointerRegister, CCallHelpers::stackPointerRegister);
@@ -412,8 +412,8 @@ static void compileStub(
     RegisterAtOffsetList* vmCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
     RegisterSet vmCalleeSavesToSkip = RegisterSet::stackRegisters();
     if (exit.isExceptionHandler()) {
-        jit.loadPtr(&vm->topVMEntryFrame, GPRInfo::regT1);
-        jit.addPtr(CCallHelpers::TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), GPRInfo::regT1);
+        jit.loadPtr(&vm->topEntryFrame, GPRInfo::regT1);
+        jit.addPtr(CCallHelpers::TrustedImm32(EntryFrame::calleeSaveRegistersBufferOffset()), GPRInfo::regT1);
     }
 
     for (Reg reg = Reg::first(); reg <= Reg::last(); reg = reg.next()) {
index 9fa29d0..be61a4f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2013-2014, 2016 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
 #include "InlineCallFrame.h"
 #include "Interpreter.h"
 #include "JSCInlines.h"
+#include "JSWebAssemblyInstance.h"
 #include "VMEntryScope.h"
 #include "WasmContext.h"
 #include <wtf/StringPrintStream.h>
@@ -217,7 +218,7 @@ JSGlobalObject* CallFrame::wasmAwareLexicalGlobalObject(VM& vm)
 #if ENABLE(WEBASSEMBLY)
     if (!callee().isWasm())
         return lexicalGlobalObject();
-    return Wasm::loadContext(vm)->globalObject();
+    return vm.wasmContext.load()->globalObject();
 #else
     UNUSED_PARAM(vm);
     return lexicalGlobalObject();
@@ -237,24 +238,24 @@ bool CallFrame::isAnyWasmCallee()
     return false;
 }
 
-CallFrame* CallFrame::callerFrame(VMEntryFrame*& currVMEntryFrame)
+CallFrame* CallFrame::callerFrame(EntryFrame*& currEntryFrame)
 {
-    if (callerFrameOrVMEntryFrame() == currVMEntryFrame) {
-        VMEntryRecord* currVMEntryRecord = vmEntryRecord(currVMEntryFrame);
-        currVMEntryFrame = currVMEntryRecord->prevTopVMEntryFrame();
+    if (callerFrameOrEntryFrame() == currEntryFrame) {
+        VMEntryRecord* currVMEntryRecord = vmEntryRecord(currEntryFrame);
+        currEntryFrame = currVMEntryRecord->prevTopEntryFrame();
         return currVMEntryRecord->prevTopCallFrame();
     }
-    return static_cast<CallFrame*>(callerFrameOrVMEntryFrame());
+    return static_cast<CallFrame*>(callerFrameOrEntryFrame());
 }
 
-SUPPRESS_ASAN CallFrame* CallFrame::unsafeCallerFrame(VMEntryFrame*& currVMEntryFrame)
+SUPPRESS_ASAN CallFrame* CallFrame::unsafeCallerFrame(EntryFrame*& currEntryFrame)
 {
-    if (unsafeCallerFrameOrVMEntryFrame() == currVMEntryFrame) {
-        VMEntryRecord* currVMEntryRecord = vmEntryRecord(currVMEntryFrame);
-        currVMEntryFrame = currVMEntryRecord->unsafePrevTopVMEntryFrame();
+    if (unsafeCallerFrameOrEntryFrame() == currEntryFrame) {
+        VMEntryRecord* currVMEntryRecord = vmEntryRecord(currEntryFrame);
+        currEntryFrame = currVMEntryRecord->unsafePrevTopEntryFrame();
         return currVMEntryRecord->unsafePrevTopCallFrame();
     }
-    return static_cast<CallFrame*>(unsafeCallerFrameOrVMEntryFrame());
+    return static_cast<CallFrame*>(unsafeCallerFrameOrEntryFrame());
 }
 
 SourceOrigin CallFrame::callerSourceOrigin()
index 62309a0..6d5d723 100644 (file)
@@ -141,12 +141,12 @@ namespace JSC  {
 
         CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
 
-        CallFrame* callerFrame() const { return static_cast<CallFrame*>(callerFrameOrVMEntryFrame()); }
-        void* callerFrameOrVMEntryFrame() const { return callerFrameAndPC().callerFrame; }
-        SUPPRESS_ASAN void* unsafeCallerFrameOrVMEntryFrame() const { return unsafeCallerFrameAndPC().callerFrame; }
+        CallFrame* callerFrame() const { return static_cast<CallFrame*>(callerFrameOrEntryFrame()); }
+        void* callerFrameOrEntryFrame() const { return callerFrameAndPC().callerFrame; }
+        SUPPRESS_ASAN void* unsafeCallerFrameOrEntryFrame() const { return unsafeCallerFrameAndPC().callerFrame; }
 
-        CallFrame* unsafeCallerFrame(VMEntryFrame*&);
-        JS_EXPORT_PRIVATE CallFrame* callerFrame(VMEntryFrame*&);
+        CallFrame* unsafeCallerFrame(EntryFrame*&);
+        JS_EXPORT_PRIVATE CallFrame* callerFrame(EntryFrame*&);
 
         JS_EXPORT_PRIVATE SourceOrigin callerSourceOrigin();
 
index c5b6b83..76acd64 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
 
 namespace JSC {
 
-struct VMEntryFrame;
+struct EntryFrame;
 
 class SuspendExceptionScope {
 public:
@@ -74,33 +74,33 @@ public:
     {
         ASSERT(vm);
         ASSERT(callFrame);
-        ASSERT(reinterpret_cast<void*>(callFrame) < reinterpret_cast<void*>(vm->topVMEntryFrame));
+        ASSERT(reinterpret_cast<void*>(callFrame) < reinterpret_cast<void*>(vm->topEntryFrame));
         vm->topCallFrame = callFrame;
     }
 };
 
 class NativeCallFrameTracerWithRestore {
 public:
-    ALWAYS_INLINE NativeCallFrameTracerWithRestore(VM* vm, VMEntryFrame* vmEntryFrame, CallFrame* callFrame)
+    ALWAYS_INLINE NativeCallFrameTracerWithRestore(VM* vm, EntryFrame* EntryFrame, CallFrame* callFrame)
         : m_vm(vm)
     {
         ASSERT(vm);
         ASSERT(callFrame);
-        m_savedTopVMEntryFrame = vm->topVMEntryFrame;
+        m_savedTopEntryFrame = vm->topEntryFrame;
         m_savedTopCallFrame = vm->topCallFrame;
-        vm->topVMEntryFrame = vmEntryFrame;
+        vm->topEntryFrame = EntryFrame;
         vm->topCallFrame = callFrame;
     }
 
     ALWAYS_INLINE ~NativeCallFrameTracerWithRestore()
     {
-        m_vm->topVMEntryFrame = m_savedTopVMEntryFrame;
+        m_vm->topEntryFrame = m_savedTopEntryFrame;
         m_vm->topCallFrame = m_savedTopCallFrame;
     }
 
 private:
     VM* m_vm;
-    VMEntryFrame* m_savedTopVMEntryFrame;
+    EntryFrame* m_savedTopEntryFrame;
     CallFrame* m_savedTopCallFrame;
 };
 
index 3d011ad..745a38a 100644 (file)
@@ -653,9 +653,9 @@ public:
 
         notifyDebuggerOfUnwinding(m_vm, m_callFrame);
 
-        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(visitor);
+        copyCalleeSavesToEntryFrameCalleeSavesBuffer(visitor);
 
-        bool shouldStopUnwinding = visitor->callerIsVMEntryFrame();
+        bool shouldStopUnwinding = visitor->callerIsEntryFrame();
         if (shouldStopUnwinding)
             return StackVisitor::Done;
 
@@ -663,7 +663,7 @@ public:
     }
 
 private:
-    void copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(StackVisitor& visitor) const
+    void copyCalleeSavesToEntryFrameCalleeSavesBuffer(StackVisitor& visitor) const
     {
 #if ENABLE(JIT) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
         RegisterAtOffsetList* currentCalleeSaves = visitor->calleeSaveRegisters();
@@ -676,7 +676,7 @@ private:
         intptr_t* frame = reinterpret_cast<intptr_t*>(m_callFrame->registers());
 
         unsigned registerCount = currentCalleeSaves->size();
-        VMEntryRecord* record = vmEntryRecord(m_vm.topVMEntryFrame);
+        VMEntryRecord* record = vmEntryRecord(m_vm.topEntryFrame);
         for (unsigned i = 0; i < registerCount; i++) {
             RegisterAtOffset currentEntry = currentCalleeSaves->at(i);
             if (dontCopyRegisters.get(currentEntry.reg()))
@@ -702,7 +702,7 @@ NEVER_INLINE HandlerInfo* Interpreter::unwind(VM& vm, CallFrame*& callFrame, Exc
     auto scope = DECLARE_CATCH_SCOPE(vm);
 
     if (unwindStart == UnwindFromCallerFrame) {
-        if (callFrame->callerFrameOrVMEntryFrame() == vm.topVMEntryFrame)
+        if (callFrame->callerFrameOrEntryFrame() == vm.topEntryFrame)
             return nullptr;
 
         callFrame = callFrame->callerFrame();
index 85d147a..d082b63 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -44,18 +44,18 @@ StackVisitor::StackVisitor(CallFrame* startFrame, VM* vm)
     CallFrame* topFrame;
     if (startFrame) {
         ASSERT(vm);
-        m_frame.m_VMEntryFrame = vm->topVMEntryFrame;
+        m_frame.m_entryFrame = vm->topEntryFrame;
         topFrame = vm->topCallFrame;
         
-        if (topFrame && static_cast<void*>(m_frame.m_VMEntryFrame) == static_cast<void*>(topFrame)) {
-            topFrame = vmEntryRecord(m_frame.m_VMEntryFrame)->m_prevTopCallFrame;
-            m_frame.m_VMEntryFrame = vmEntryRecord(m_frame.m_VMEntryFrame)->m_prevTopVMEntryFrame;
+        if (topFrame && static_cast<void*>(m_frame.m_entryFrame) == static_cast<void*>(topFrame)) {
+            topFrame = vmEntryRecord(m_frame.m_entryFrame)->m_prevTopCallFrame;
+            m_frame.m_entryFrame = vmEntryRecord(m_frame.m_entryFrame)->m_prevTopEntryFrame;
         }
     } else {
-        m_frame.m_VMEntryFrame = 0;
+        m_frame.m_entryFrame = 0;
         topFrame = 0;
     }
-    m_frame.m_callerIsVMEntryFrame = false;
+    m_frame.m_callerIsEntryFrame = false;
     readFrame(topFrame);
 
     // Find the frame the caller wants to start unwinding from.
@@ -75,14 +75,14 @@ void StackVisitor::gotoNextFrame()
                 readInlinedFrame(m_frame.callFrame(), &inlineCallFrame->directCaller);
                 inlineCallFrame = m_frame.inlineCallFrame();
             }
-            m_frame.m_VMEntryFrame = m_frame.m_CallerVMEntryFrame;
+            m_frame.m_entryFrame = m_frame.m_callerEntryFrame;
             readFrame(m_frame.callerFrame());
         } else
             readInlinedFrame(m_frame.callFrame(), callerCodeOrigin);
         return;
     }
 #endif // ENABLE(DFG_JIT)
-    m_frame.m_VMEntryFrame = m_frame.m_CallerVMEntryFrame;
+    m_frame.m_entryFrame = m_frame.m_callerEntryFrame;
     readFrame(m_frame.callerFrame());
 }
 
@@ -152,9 +152,9 @@ void StackVisitor::readNonInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOri
 {
     m_frame.m_callFrame = callFrame;
     m_frame.m_argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
-    m_frame.m_CallerVMEntryFrame = m_frame.m_VMEntryFrame;
-    m_frame.m_callerFrame = callFrame->callerFrame(m_frame.m_CallerVMEntryFrame);
-    m_frame.m_callerIsVMEntryFrame = m_frame.m_CallerVMEntryFrame != m_frame.m_VMEntryFrame;
+    m_frame.m_callerEntryFrame = m_frame.m_entryFrame;
+    m_frame.m_callerFrame = callFrame->callerFrame(m_frame.m_callerEntryFrame);
+    m_frame.m_callerIsEntryFrame = m_frame.m_callerEntryFrame != m_frame.m_entryFrame;
     m_frame.m_isWasmFrame = false;
 
     CalleeBits callee = callFrame->callee();
@@ -500,7 +500,7 @@ void StackVisitor::Frame::dump(PrintStream& out, Indenter indent, std::function<
 
             indent--;
         }
-        out.print(indent, "vmEntryFrame: ", RawPointer(vmEntryFrame()), "\n");
+        out.print(indent, "EntryFrame: ", RawPointer(m_entryFrame), "\n");
         indent--;
     }
     out.print(indent, "}\n");
index 8ad0940..e2a1368 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -62,7 +62,7 @@ public:
 
         size_t index() const { return m_index; }
         size_t argumentCountIncludingThis() const { return m_argumentCountIncludingThis; }
-        bool callerIsVMEntryFrame() const { return m_callerIsVMEntryFrame; }
+        bool callerIsEntryFrame() const { return m_callerIsEntryFrame; }
         CallFrame* callerFrame() const { return m_callerFrame; }
         CalleeBits callee() const { return m_callee; }
         CodeBlock* codeBlock() const { return m_codeBlock; }
@@ -97,7 +97,6 @@ public:
         RegisterAtOffsetList* calleeSaveRegisters();
 
         ClonedArguments* createArguments();
-        VMEntryFrame* vmEntryFrame() const { return m_VMEntryFrame; }
         CallFrame* callFrame() const { return m_callFrame; }
         
         void dump(PrintStream&, Indenter = Indenter()) const;
@@ -114,8 +113,8 @@ public:
         InlineCallFrame* m_inlineCallFrame;
 #endif
         CallFrame* m_callFrame;
-        VMEntryFrame* m_VMEntryFrame;
-        VMEntryFrame* m_CallerVMEntryFrame;
+        EntryFrame* m_entryFrame;
+        EntryFrame* m_callerEntryFrame;
         CallFrame* m_callerFrame;
         CalleeBits m_callee;
         CodeBlock* m_codeBlock;
@@ -123,7 +122,7 @@ public:
         size_t m_argumentCountIncludingThis;
         unsigned m_bytecodeOffset;
         Wasm::IndexOrName m_wasmFunctionIndexOrName;
-        bool m_callerIsVMEntryFrame : 1;
+        bool m_callerIsEntryFrame : 1;
         bool m_isWasmFrame : 1;
 
         friend class StackVisitor;
index f36c2be..0103a78 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,7 +29,7 @@
 
 namespace JSC {
 
-struct VMEntryFrame;
+struct EntryFrame;
 class ExecState;
 class VM;
 
@@ -40,7 +40,7 @@ struct VMEntryRecord {
      */
     VM* m_vm;
     ExecState* m_prevTopCallFrame;
-    VMEntryFrame* m_prevTopVMEntryFrame;
+    EntryFrame* m_prevTopEntryFrame;
 
 #if ENABLE(JIT) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
     intptr_t calleeSaveRegistersBuffer[NUMBER_OF_CALLEE_SAVES_REGISTERS];
@@ -49,20 +49,20 @@ struct VMEntryRecord {
     ExecState* prevTopCallFrame() { return m_prevTopCallFrame; }
     SUPPRESS_ASAN ExecState* unsafePrevTopCallFrame() { return m_prevTopCallFrame; }
 
-    VMEntryFrame* prevTopVMEntryFrame() { return m_prevTopVMEntryFrame; }
-    SUPPRESS_ASAN VMEntryFrame* unsafePrevTopVMEntryFrame() { return m_prevTopVMEntryFrame; }
+    EntryFrame* prevTopEntryFrame() { return m_prevTopEntryFrame; }
+    SUPPRESS_ASAN EntryFrame* unsafePrevTopEntryFrame() { return m_prevTopEntryFrame; }
 };
 
-extern "C" VMEntryRecord* vmEntryRecord(VMEntryFrame*);
+extern "C" VMEntryRecord* vmEntryRecord(EntryFrame*);
 
-struct VMEntryFrame {
+struct EntryFrame {
 #if ENABLE(JIT) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
     static ptrdiff_t vmEntryRecordOffset()
     {
-        VMEntryFrame* fakeVMEntryFrame = reinterpret_cast<VMEntryFrame*>(0x1000);
-        VMEntryRecord* record = vmEntryRecord(fakeVMEntryFrame);
+        EntryFrame* fakeEntryFrame = reinterpret_cast<EntryFrame*>(0x1000);
+        VMEntryRecord* record = vmEntryRecord(fakeEntryFrame);
         return static_cast<ptrdiff_t>(
-            reinterpret_cast<char*>(record) - reinterpret_cast<char*>(fakeVMEntryFrame));
+            reinterpret_cast<char*>(record) - reinterpret_cast<char*>(fakeEntryFrame));
     }
 
     static ptrdiff_t calleeSaveRegistersBufferOffset()
index 8d31f7a..a4a4c0f 100644 (file)
@@ -582,7 +582,7 @@ void AssemblyHelpers::emitRandomThunk(VM& vm, GPRReg scratch0, GPRReg scratch1,
 }
 #endif
 
-void AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(VM& vm)
+void AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer(EntryFrame*& topEntryFrame)
 {
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
     RegisterAtOffsetList* allCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
@@ -605,8 +605,8 @@ void AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(VM& vm
     }
     ASSERT(scratch != InvalidGPRReg);
 
-    loadPtr(&vm.topVMEntryFrame, scratch);
-    addPtr(TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), scratch);
+    loadPtr(&topEntryFrame, scratch);
+    addPtr(TrustedImm32(EntryFrame::calleeSaveRegistersBufferOffset()), scratch);
 
     // Restore all callee saves except for the scratch.
     for (unsigned i = 0; i < registerCount; i++) {
@@ -627,7 +627,7 @@ void AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(VM& vm
     ASSERT(scratch == entry.reg().gpr());
     loadPtr(Address(scratch, entry.offset()), scratch);
 #else
-    UNUSED_PARAM(vm);
+    UNUSED_PARAM(topEntryFrame);
 #endif
 }
 
@@ -778,41 +778,41 @@ void AssemblyHelpers::emitConvertValueToBoolean(VM& vm, JSValueRegs value, GPRRe
 }
 
 #if ENABLE(WEBASSEMBLY)
-void AssemblyHelpers::loadWasmContext(GPRReg dst)
+void AssemblyHelpers::loadWasmContextInstance(GPRReg dst)
 {
 #if ENABLE(FAST_TLS_JIT)
-    if (Wasm::useFastTLSForContext()) {
+    if (Wasm::Context::useFastTLS()) {
         loadFromTLSPtr(fastTLSOffsetForKey(WTF_WASM_CONTEXT_KEY), dst);
         return;
     }
 #endif
-    move(Wasm::PinnedRegisterInfo::get().wasmContextPointer, dst);
+    move(Wasm::PinnedRegisterInfo::get().wasmContextInstancePointer, dst);
 }
 
-void AssemblyHelpers::storeWasmContext(GPRReg src)
+void AssemblyHelpers::storeWasmContextInstance(GPRReg src)
 {
 #if ENABLE(FAST_TLS_JIT)
-    if (Wasm::useFastTLSForContext()) {
+    if (Wasm::Context::useFastTLS()) {
         storeToTLSPtr(src, fastTLSOffsetForKey(WTF_WASM_CONTEXT_KEY));
         return;
     }
 #endif
-    move(src, Wasm::PinnedRegisterInfo::get().wasmContextPointer);
+    move(src, Wasm::PinnedRegisterInfo::get().wasmContextInstancePointer);
 }
 
-bool AssemblyHelpers::loadWasmContextNeedsMacroScratchRegister()
+bool AssemblyHelpers::loadWasmContextInstanceNeedsMacroScratchRegister()
 {
 #if ENABLE(FAST_TLS_JIT)
-    if (Wasm::useFastTLSForContext())
+    if (Wasm::Context::useFastTLS())
         return loadFromTLSPtrNeedsMacroScratchRegister();
 #endif
     return false;
 }
 
-bool AssemblyHelpers::storeWasmContextNeedsMacroScratchRegister()
+bool AssemblyHelpers::storeWasmContextInstanceNeedsMacroScratchRegister()
 {
 #if ENABLE(FAST_TLS_JIT)
-    if (Wasm::useFastTLSForContext())
+    if (Wasm::Context::useFastTLS())
         return storeToTLSPtrNeedsMacroScratchRegister();
 #endif
     return false;
@@ -875,10 +875,10 @@ void AssemblyHelpers::debugCall(VM& vm, V_DebugOperation_EPP function, void* arg
     }
 }
 
-void AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBufferImpl(GPRReg calleeSavesBuffer)
+void AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl(GPRReg calleeSavesBuffer)
 {
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
-    addPtr(TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), calleeSavesBuffer);
+    addPtr(TrustedImm32(EntryFrame::calleeSaveRegistersBufferOffset()), calleeSavesBuffer);
 
     RegisterAtOffsetList* allCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
     RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
index a68c369..ce0abdd 100644 (file)
@@ -360,28 +360,28 @@ public:
     void copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(GPRReg vmGPR)
     {
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
-        loadPtr(Address(vmGPR, VM::topVMEntryFrameOffset()), vmGPR);
-        copyCalleeSavesToVMEntryFrameCalleeSavesBufferImpl(vmGPR);
+        loadPtr(Address(vmGPR, VM::topEntryFrameOffset()), vmGPR);
+        copyCalleeSavesToEntryFrameCalleeSavesBufferImpl(vmGPR);
 #else
         UNUSED_PARAM(vmGPR);
 #endif
     }
 
-    void copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(VM& vm, const TempRegisterSet& usedRegisters = { RegisterSet::stubUnavailableRegisters() })
+    void copyCalleeSavesToEntryFrameCalleeSavesBuffer(EntryFrame*& topEntryFrame, const TempRegisterSet& usedRegisters = { RegisterSet::stubUnavailableRegisters() })
     {
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
         GPRReg temp1 = usedRegisters.getFreeGPR(0);
-        loadPtr(&vm.topVMEntryFrame, temp1);
-        copyCalleeSavesToVMEntryFrameCalleeSavesBufferImpl(temp1);
+        loadPtr(&topEntryFrame, temp1);
+        copyCalleeSavesToEntryFrameCalleeSavesBufferImpl(temp1);
 #else
-        UNUSED_PARAM(vm);
+        UNUSED_PARAM(topEntryFrame);
         UNUSED_PARAM(usedRegisters);
 #endif
     }
 
-    void restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(VM&);
+    void restoreCalleeSavesFromEntryFrameCalleeSavesBuffer(EntryFrame*&);
 
-    void copyCalleeSavesFromFrameOrRegisterToVMEntryFrameCalleeSavesBuffer(VM& vm, const TempRegisterSet& usedRegisters = { RegisterSet::stubUnavailableRegisters() })
+    void copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer(EntryFrame*& topEntryFrame, const TempRegisterSet& usedRegisters = { RegisterSet::stubUnavailableRegisters() })
     {
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
         GPRReg temp1 = usedRegisters.getFreeGPR(0);
@@ -392,8 +392,8 @@ public:
         ASSERT(codeBlock());
 
         // Copy saved calleeSaves on stack or unsaved calleeSaves in register to vm calleeSave buffer
-        loadPtr(&vm.topVMEntryFrame, temp1);
-        addPtr(TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), temp1);
+        loadPtr(&topEntryFrame, temp1);
+        addPtr(TrustedImm32(EntryFrame::calleeSaveRegistersBufferOffset()), temp1);
 
         RegisterAtOffsetList* allCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
         RegisterAtOffsetList* currentCalleeSaves = codeBlock()->calleeSaveRegisters();
@@ -401,12 +401,12 @@ public:
         unsigned registerCount = allCalleeSaves->size();
 
         for (unsigned i = 0; i < registerCount; i++) {
-            RegisterAtOffset vmEntry = allCalleeSaves->at(i);
-            if (dontCopyRegisters.get(vmEntry.reg()))
+            RegisterAtOffset entry = allCalleeSaves->at(i);
+            if (dontCopyRegisters.get(entry.reg()))
                 continue;
-            RegisterAtOffset* currentFrameEntry = currentCalleeSaves->find(vmEntry.reg());
+            RegisterAtOffset* currentFrameEntry = currentCalleeSaves->find(entry.reg());
 
-            if (vmEntry.reg().isGPR()) {
+            if (entry.reg().isGPR()) {
                 GPRReg regToStore;
                 if (currentFrameEntry) {
                     // Load calleeSave from stack into temp register
@@ -414,9 +414,9 @@ public:
                     loadPtr(Address(framePointerRegister, currentFrameEntry->offset()), regToStore);
                 } else
                     // Just store callee save directly
-                    regToStore = vmEntry.reg().gpr();
+                    regToStore = entry.reg().gpr();
 
-                storePtr(regToStore, Address(temp1, vmEntry.offset()));
+                storePtr(regToStore, Address(temp1, entry.offset()));
             } else {
                 FPRReg fpRegToStore;
                 if (currentFrameEntry) {
@@ -425,13 +425,13 @@ public:
                     loadDouble(Address(framePointerRegister, currentFrameEntry->offset()), fpRegToStore);
                 } else
                     // Just store callee save directly
-                    fpRegToStore = vmEntry.reg().fpr();
+                    fpRegToStore = entry.reg().fpr();
 
-                storeDouble(fpRegToStore, Address(temp1, vmEntry.offset()));
+                storeDouble(fpRegToStore, Address(temp1, entry.offset()));
             }
         }
 #else
-        UNUSED_PARAM(vm);
+        UNUSED_PARAM(topEntryFrame);
         UNUSED_PARAM(usedRegisters);
 #endif
     }
@@ -1644,14 +1644,14 @@ public:
 #endif
 
 #if ENABLE(WEBASSEMBLY)
-    void loadWasmContext(GPRReg dst);
-    void storeWasmContext(GPRReg src);
-    static bool loadWasmContextNeedsMacroScratchRegister();
-    static bool storeWasmContextNeedsMacroScratchRegister();
+    void loadWasmContextInstance(GPRReg dst);
+    void storeWasmContextInstance(GPRReg src);
+    static bool loadWasmContextInstanceNeedsMacroScratchRegister();
+    static bool storeWasmContextInstanceNeedsMacroScratchRegister();
 #endif
 
 protected:
-    void copyCalleeSavesToVMEntryFrameCalleeSavesBufferImpl(GPRReg calleeSavesBuffer);
+    void copyCalleeSavesToEntryFrameCalleeSavesBufferImpl(GPRReg calleeSavesBuffer);
 
     CodeBlock* m_codeBlock;
     CodeBlock* m_baselineCodeBlock;
index 5ecf3a6..c812f8c 100644 (file)
@@ -111,7 +111,7 @@ void JIT::emitEnterOptimizationCheck()
     skipOptimize.append(branchAdd32(Signed, TrustedImm32(Options::executionCounterIncrementForEntry()), AbsoluteAddress(m_codeBlock->addressOfJITExecuteCounter())));
     ASSERT(!m_bytecodeOffset);
 
-    copyCalleeSavesFromFrameOrRegisterToVMEntryFrameCalleeSavesBuffer(*vm());
+    copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer(vm()->topEntryFrame);
 
     callOperation(operationOptimize, m_bytecodeOffset);
     skipOptimize.append(branchTestPtr(Zero, returnValueGPR));
@@ -885,7 +885,7 @@ void JIT::privateCompileExceptionHandlers()
     if (!m_exceptionChecksWithCallFrameRollback.empty()) {
         m_exceptionChecksWithCallFrameRollback.link(this);
 
-        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm());
+        copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm()->topEntryFrame);
 
         // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
 
@@ -905,7 +905,7 @@ void JIT::privateCompileExceptionHandlers()
         m_exceptionHandler = label();
         m_exceptionChecks.link(this);
 
-        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm());
+        copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm()->topEntryFrame);
 
         // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
         move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
index ca2db8c..f2018ca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,8 +56,8 @@ void genericUnwind(VM* vm, ExecState* callFrame, UnwindStart unwindStart)
     
     ExecState* shadowChickenTopFrame = callFrame;
     if (unwindStart == UnwindFromCallerFrame) {
-        VMEntryFrame* topVMEntryFrame = vm->topVMEntryFrame;
-        shadowChickenTopFrame = callFrame->callerFrame(topVMEntryFrame);
+        EntryFrame* topEntryFrame = vm->topEntryFrame;
+        shadowChickenTopFrame = callFrame->callerFrame(topEntryFrame);
     }
     vm->shadowChicken().log(*vm, shadowChickenTopFrame, ShadowChicken::Packet::throwPacket());
     
@@ -84,7 +84,7 @@ void genericUnwind(VM* vm, ExecState* callFrame, UnwindStart unwindStart)
     } else
         catchRoutine = LLInt::getCodePtr(handleUncaughtException);
     
-    ASSERT(bitwise_cast<uintptr_t>(callFrame) < bitwise_cast<uintptr_t>(vm->topVMEntryFrame));
+    ASSERT(bitwise_cast<uintptr_t>(callFrame) < bitwise_cast<uintptr_t>(vm->topEntryFrame));
 
     vm->callFrameForCatch = callFrame;
     vm->targetMachinePCForThrow = catchRoutine;
index 9b4166a..8b4be65 100644 (file)
@@ -455,7 +455,7 @@ void JIT::emit_op_neq(Instruction* currentInstruction)
 void JIT::emit_op_throw(Instruction* currentInstruction)
 {
     ASSERT(regT0 == returnValueGPR);
-    copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm());
+    copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm()->topEntryFrame);
     emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
     callOperationNoExceptionCheck(operationThrow, regT0);
     jumpToExceptionHandler(*vm());
@@ -534,7 +534,7 @@ void JIT::emit_op_to_string(Instruction* currentInstruction)
 
 void JIT::emit_op_catch(Instruction* currentInstruction)
 {
-    restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(*vm());
+    restoreCalleeSavesFromEntryFrameCalleeSavesBuffer(vm()->topEntryFrame);
 
     move(TrustedImmPtr(m_vm), regT3);
     load64(Address(regT3, VM::callFrameForCatchOffset()), callFrameRegister);
@@ -952,7 +952,7 @@ void JIT::emitSlow_op_loop_hint(Instruction*, Vector<SlowCaseEntry>::iterator& i
     if (canBeOptimized()) {
         linkSlowCase(iter);
 
-        copyCalleeSavesFromFrameOrRegisterToVMEntryFrameCalleeSavesBuffer(*vm());
+        copyCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer(vm()->topEntryFrame);
 
         callOperation(operationOptimize, m_bytecodeOffset);
         Jump noOptimizedEntry = branchTestPtr(Zero, returnValueGPR);
index a1228d3..0ad7828 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, 2012-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
  * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -765,7 +765,7 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
 void JIT::emit_op_throw(Instruction* currentInstruction)
 {
     ASSERT(regT0 == returnValueGPR);
-    copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm());
+    copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm()->topEntryFrame);
     emitLoad(currentInstruction[1].u.operand, regT1, regT0);
     callOperationNoExceptionCheck(operationThrow, regT1, regT0);
     jumpToExceptionHandler(*vm());
@@ -826,7 +826,7 @@ void JIT::emitSlow_op_to_string(Instruction* currentInstruction, Vector<SlowCase
 
 void JIT::emit_op_catch(Instruction* currentInstruction)
 {
-    restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(*vm());
+    restoreCalleeSavesFromEntryFrameCalleeSavesBuffer(vm()->topEntryFrame);
 
     move(TrustedImmPtr(m_vm), regT3);
     // operationThrow returns the callFrame for the handler.
index 48cb6ed..0655004 100644 (file)
@@ -103,14 +103,14 @@ void JIT_OPERATION operationThrowStackOverflowError(ExecState* exec, CodeBlock*
     VM* vm = codeBlock->vm();
     auto scope = DECLARE_THROW_SCOPE(*vm);
 
-    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
-    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
+    EntryFrame* entryFrame = vm->topEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(entryFrame);
     if (!callerFrame) {
         callerFrame = exec;
-        vmEntryFrame = vm->topVMEntryFrame;
+        entryFrame = vm->topEntryFrame;
     }
 
-    NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
+    NativeCallFrameTracerWithRestore tracer(vm, entryFrame, callerFrame);
     throwStackOverflowError(callerFrame, scope);
 }
 
@@ -120,10 +120,10 @@ void JIT_OPERATION operationThrowDivideError(ExecState* exec)
     VM* vm = &exec->vm();
     auto scope = DECLARE_THROW_SCOPE(*vm);
 
-    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
-    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
+    EntryFrame* entryFrame = vm->topEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(entryFrame);
 
-    NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
+    NativeCallFrameTracerWithRestore tracer(vm, entryFrame, callerFrame);
     ErrorHandlingScope errorScope(*vm);
     throwException(callerFrame, scope, createError(callerFrame, ASCIILiteral("Division by zero or division overflow.")));
 }
@@ -133,10 +133,10 @@ void JIT_OPERATION operationThrowOutOfBoundsAccessError(ExecState* exec)
     VM* vm = &exec->vm();
     auto scope = DECLARE_THROW_SCOPE(*vm);
 
-    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
-    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
+    EntryFrame* entryFrame = vm->topEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(entryFrame);
 
-    NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
+    NativeCallFrameTracerWithRestore tracer(vm, entryFrame, callerFrame);
     ErrorHandlingScope errorScope(*vm);
     throwException(callerFrame, scope, createError(callerFrame, ASCIILiteral("Out-of-bounds access.")));
 }
@@ -149,9 +149,9 @@ int32_t JIT_OPERATION operationCallArityCheck(ExecState* exec)
 
     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, *vm, CodeForCall);
     if (missingArgCount < 0) {
-        VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
-        CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
-        NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
+        EntryFrame* entryFrame = vm->topEntryFrame;
+        CallFrame* callerFrame = exec->callerFrame(entryFrame);
+        NativeCallFrameTracerWithRestore tracer(vm, entryFrame, callerFrame);
         throwStackOverflowError(callerFrame, scope);
     }
 
@@ -165,9 +165,9 @@ int32_t JIT_OPERATION operationConstructArityCheck(ExecState* exec)
 
     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, *vm, CodeForConstruct);
     if (missingArgCount < 0) {
-        VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
-        CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
-        NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
+        EntryFrame* entryFrame = vm->topEntryFrame;
+        CallFrame* callerFrame = exec->callerFrame(entryFrame);
+        NativeCallFrameTracerWithRestore tracer(vm, entryFrame, callerFrame);
         throwStackOverflowError(callerFrame, scope);
     }
 
index 92e42b1..903a05c 100644 (file)
@@ -66,7 +66,7 @@ MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(VM* vm)
     // even though we won't use it.
     jit.preserveReturnAddressAfterCall(GPRInfo::nonPreservedNonReturnGPR);
 
-    jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm);
+    jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm->topEntryFrame);
 
     jit.setupArguments(CCallHelpers::TrustedImmPtr(vm), GPRInfo::callFrameRegister);
     jit.move(CCallHelpers::TrustedImmPtr(bitwise_cast<void*>(lookupExceptionHandler)), GPRInfo::nonArgGPR0);
@@ -362,7 +362,7 @@ static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind k
     // Handle an exception
     exceptionHandler.link(&jit);
 
-    jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm);
+    jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm->topEntryFrame);
     jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
 
 #if CPU(X86) && USE(JSVALUE32_64)
index c064664..5277583 100644 (file)
@@ -1957,8 +1957,8 @@ EncodedJSValue JSC_HOST_CALL functionPrintStdErr(ExecState* exec) { return print
 EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec)
 {
     VM& vm = exec->vm();
-    VMEntryFrame* topVMEntryFrame = vm.topVMEntryFrame;
-    ExecState* callerFrame = exec->callerFrame(topVMEntryFrame);
+    EntryFrame* topEntryFrame = vm.topEntryFrame;
+    ExecState* callerFrame = exec->callerFrame(topEntryFrame);
     if (callerFrame)
         vm.interpreter->dumpCallFrame(callerFrame);
     return JSValue::encode(jsUndefined());
index f2d49a6..2315c82 100644 (file)
@@ -481,13 +481,13 @@ LLINT_SLOW_PATH_DECL(stack_check)
     VM& vm = exec->vm();
     auto throwScope = DECLARE_THROW_SCOPE(vm);
 
-    VMEntryFrame* vmEntryFrame = vm.topVMEntryFrame;
-    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
+    EntryFrame* topEntryFrame = vm.topEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(topEntryFrame);
     if (!callerFrame) {
         callerFrame = exec;
-        vmEntryFrame = vm.topVMEntryFrame;
+        topEntryFrame = vm.topEntryFrame;
     }
-    NativeCallFrameTracerWithRestore tracer(&vm, vmEntryFrame, callerFrame);
+    NativeCallFrameTracerWithRestore tracer(&vm, topEntryFrame, callerFrame);
 
     LLINT_SET_PC_FOR_STUBS();
 
index 36f6486..52967e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -116,7 +116,7 @@ EncodedJSValue vmEntryToNative(void* executableAddress, VM* vm, ProtoCallFrame*
     return JSValue::encode(result);
 }
 
-extern "C" VMEntryRecord* vmEntryRecord(VMEntryFrame* entryFrame)
+extern "C" VMEntryRecord* vmEntryRecord(EntryFrame* entryFrame)
 {
     // The C Loop doesn't have any callee save registers, so the VMEntryRecord is allocated at the base of the frame.
     intptr_t stackAlignment = stackAlignmentBytes();
index 5dde664..7bf1ece 100644 (file)
@@ -659,7 +659,7 @@ end
 
 macro copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm, temp)
     if ARM64 or X86_64 or X86_64_WIN
-        loadp VM::topVMEntryFrame[vm], temp
+        loadp VM::topEntryFrame[vm], temp
         vmEntryRecord(temp, temp)
         leap VMEntryRecord::calleeSaveRegistersBuffer[temp], temp
         if ARM64
@@ -701,7 +701,7 @@ end
 
 macro restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(vm, temp)
     if ARM64 or X86_64 or X86_64_WIN
-        loadp VM::topVMEntryFrame[vm], temp
+        loadp VM::topEntryFrame[vm], temp
         vmEntryRecord(temp, temp)
         leap VMEntryRecord::calleeSaveRegistersBuffer[temp], temp
         if ARM64
@@ -1144,7 +1144,7 @@ if not C_LOOP
         storep address, VM::m_lastStackTop[vm]
         ret
     
-    # VMEntryRecord* vmEntryRecord(const VMEntryFrame* entryFrame)
+    # VMEntryRecord* vmEntryRecord(const EntryFrame* entryFrame)
     global _vmEntryRecord
     _vmEntryRecord:
         if X86 or X86_WIN
index 114a978..33090e3 100644 (file)
@@ -125,8 +125,8 @@ macro doVMEntry(makeCall)
     storep vm, VMEntryRecord::m_vm[sp]
     loadp VM::topCallFrame[vm], t4
     storep t4, VMEntryRecord::m_prevTopCallFrame[sp]
-    loadp VM::topVMEntryFrame[vm], t4
-    storep t4, VMEntryRecord::m_prevTopVMEntryFrame[sp]
+    loadp VM::topEntryFrame[vm], t4
+    storep t4, VMEntryRecord::m_prevTopEntryFrame[sp]
 
     # Align stack pointer
     if X86_WIN or MIPS
@@ -189,8 +189,8 @@ macro doVMEntry(makeCall)
     loadp VMEntryRecord::m_vm[sp], t5
     loadp VMEntryRecord::m_prevTopCallFrame[sp], t4
     storep t4, VM::topCallFrame[t5]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], t4
-    storep t4, VM::topVMEntryFrame[t5]
+    loadp VMEntryRecord::m_prevTopEntryFrame[sp], t4
+    storep t4, VM::topEntryFrame[t5]
 
     if ARMv7
         subp cfr, CalleeRegisterSaveSize, t5
@@ -241,7 +241,7 @@ macro doVMEntry(makeCall)
 
 .copyArgsDone:
     storep sp, VM::topCallFrame[vm]
-    storep cfr, VM::topVMEntryFrame[vm]
+    storep cfr, VM::topEntryFrame[vm]
 
     makeCall(entry, t3, t4)
 
@@ -255,8 +255,8 @@ macro doVMEntry(makeCall)
     loadp VMEntryRecord::m_vm[sp], t5
     loadp VMEntryRecord::m_prevTopCallFrame[sp], t4
     storep t4, VM::topCallFrame[t5]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], t4
-    storep t4, VM::topVMEntryFrame[t5]
+    loadp VMEntryRecord::m_prevTopEntryFrame[sp], t4
+    storep t4, VM::topEntryFrame[t5]
 
     if ARMv7
         subp cfr, CalleeRegisterSaveSize, t5
@@ -324,8 +324,8 @@ _handleUncaughtException:
     loadp VMEntryRecord::m_vm[sp], t3
     loadp VMEntryRecord::m_prevTopCallFrame[sp], t5
     storep t5, VM::topCallFrame[t3]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], t5
-    storep t5, VM::topVMEntryFrame[t3]
+    loadp VMEntryRecord::m_prevTopEntryFrame[sp], t5
+    storep t5, VM::topEntryFrame[t3]
 
     if ARMv7
         subp cfr, CalleeRegisterSaveSize, t3
index 5d62987..769f624 100644 (file)
@@ -129,8 +129,8 @@ macro doVMEntry(makeCall)
     storep vm, VMEntryRecord::m_vm[sp]
     loadp VM::topCallFrame[vm], t4
     storep t4, VMEntryRecord::m_prevTopCallFrame[sp]
-    loadp VM::topVMEntryFrame[vm], t4
-    storep t4, VMEntryRecord::m_prevTopVMEntryFrame[sp]
+    loadp VM::topEntryFrame[vm], t4
+    storep t4, VMEntryRecord::m_prevTopEntryFrame[sp]
 
     loadi ProtoCallFrame::paddedArgCount[protoCallFrame], t4
     addp CallFrameHeaderSlots, t4, t4
@@ -171,8 +171,8 @@ macro doVMEntry(makeCall)
     loadp VMEntryRecord::m_vm[t4], vm
     loadp VMEntryRecord::m_prevTopCallFrame[t4], extraTempReg
     storep extraTempReg, VM::topCallFrame[vm]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], extraTempReg
-    storep extraTempReg, VM::topVMEntryFrame[vm]
+    loadp VMEntryRecord::m_prevTopEntryFrame[t4], extraTempReg
+    storep extraTempReg, VM::topEntryFrame[vm]
 
     subp cfr, CalleeRegisterSaveSize, sp
 
@@ -220,7 +220,7 @@ macro doVMEntry(makeCall)
     else
         storep sp, VM::topCallFrame[vm]
     end
-    storep cfr, VM::topVMEntryFrame[vm]
+    storep cfr, VM::topEntryFrame[vm]
 
     checkStackPointerAlignment(extraTempReg, 0xbad0dc02)
 
@@ -236,8 +236,8 @@ macro doVMEntry(makeCall)
     loadp VMEntryRecord::m_vm[t4], vm
     loadp VMEntryRecord::m_prevTopCallFrame[t4], t2
     storep t2, VM::topCallFrame[vm]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], t2
-    storep t2, VM::topVMEntryFrame[vm]
+    loadp VMEntryRecord::m_prevTopEntryFrame[t4], t2
+    storep t2, VM::topEntryFrame[vm]
 
     subp cfr, CalleeRegisterSaveSize, sp
 
@@ -276,7 +276,6 @@ macro makeHostFunctionCall(entry, temp)
     end
 end
 
-
 _handleUncaughtException:
     loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
@@ -291,8 +290,8 @@ _handleUncaughtException:
     loadp VMEntryRecord::m_vm[t2], t3
     loadp VMEntryRecord::m_prevTopCallFrame[t2], extraTempReg
     storep extraTempReg, VM::topCallFrame[t3]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[t2], extraTempReg
-    storep extraTempReg, VM::topVMEntryFrame[t3]
+    loadp VMEntryRecord::m_prevTopEntryFrame[t2], extraTempReg
+    storep extraTempReg, VM::topEntryFrame[t3]
 
     subp cfr, CalleeRegisterSaveSize, sp
 
index a5a53c6..2a2bbdf 100644 (file)
@@ -406,7 +406,7 @@ static void recomputeDependentOptions()
         Options::useWebAssembly() = false;
 
     if (!Options::useWebAssembly())
-        Options::useWebAssemblyFastTLS() = false;
+        Options::useFastTLSForWasmContext() = false;
     
     if (Options::dumpDisassembly()
         || Options::dumpDFGDisassembly()
index 3cec552..8475c22 100644 (file)
@@ -467,8 +467,7 @@ typedef const char* optionString;
     v(unsigned, webAssemblyFastMemoryRedzonePages, 128, Normal, "WebAssembly fast memories use 4GiB virtual allocations, plus a redzone (counted as multiple of 64KiB WebAssembly pages) at the end to catch reg+imm accesses which exceed 32-bit, anything beyond the redzone is explicitly bounds-checked") \
     v(bool, crashIfWebAssemblyCantFastMemory, false, Normal, "If true, we will crash if we can't obtain fast memory for wasm.") \
     v(unsigned, maxNumWebAssemblyFastMemories, 4, Normal, nullptr) \
-    v(bool, useWebAssemblyFastTLS, true, Normal, "If true, we will try to use fast thread-local storage if available on the current platform.") \
-    v(bool, useFastTLSForWasmContext, true, Normal, "If true (and fast TLS is enabled), we will store context in fast TLS. If false, we will pin it to a register.") \
+    v(bool, useFastTLSForWasmContext, true, Normal, "If true, we will store context in fast TLS. If false, we will pin it to a register.") \
     v(bool, useCallICsForWebAssemblyToJSCalls, true, Normal, "If true, we will use CallLinkInfo to inline cache Wasm to JS calls.") \
     v(bool, useObjectRestSpread, true, Normal, "If true, we will enable Object Rest/Spread feature.") \
     v(bool, useArrayAllocationProfiling, true, Normal, "If true, we will use our normal array allocation profiling. If false, the allocation profile will always claim to be undecided.")
index a4be95b..3bcf6c3 100644 (file)
@@ -83,7 +83,7 @@ public:
     FrameWalker(VM& vm, ExecState* callFrame, const AbstractLocker& codeBlockSetLocker, const AbstractLocker& machineThreadsLocker)
         : m_vm(vm)
         , m_callFrame(callFrame)
-        , m_vmEntryFrame(vm.topVMEntryFrame)
+        , m_entryFrame(vm.topEntryFrame)
         , m_codeBlockSetLocker(codeBlockSetLocker)
         , m_machineThreadsLocker(machineThreadsLocker)
     {
@@ -130,7 +130,7 @@ protected:
     SUPPRESS_ASAN
     void advanceToParentFrame()
     {
-        m_callFrame = m_callFrame->unsafeCallerFrame(m_vmEntryFrame);
+        m_callFrame = m_callFrame->unsafeCallerFrame(m_entryFrame);
     }
 
     bool isAtTop() const
@@ -188,7 +188,7 @@ protected:
 
     VM& m_vm;
     ExecState* m_callFrame;
-    VMEntryFrame* m_vmEntryFrame;
+    EntryFrame* m_entryFrame;
     const AbstractLocker& m_codeBlockSetLocker;
     const AbstractLocker& m_machineThreadsLocker;
     bool m_bailingOut { false };
@@ -577,7 +577,7 @@ void SamplingProfiler::processUnverifiedStackTraces()
                 // We reuse LLInt CodeBlocks for the baseline JIT, so we need to check for both jit types.
                 // This might also be false for various reasons (known and unknown), even though
                 // it's super unlikely. One reason that this can be false is when we throw from a DFG frame,
-                // and we end up having to unwind past a VMEntryFrame, we will end up executing
+                // and we end up having to unwind past aEntryFrame, we will end up executing
                 // inside the LLInt's handleUncaughtException. So we just protect against this
                 // by ignoring it.
                 unsigned bytecodeIndex = 0;
index 06e9303..4c65d62 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -57,13 +57,13 @@ ThrowScope::~ThrowScope()
 
     bool willBeHandleByLLIntOrJIT = false;
     void* previousScope = m_previousScope;
-    void* topVMEntryFrame = m_vm.topVMEntryFrame;
+    void* topEntryFrame = m_vm.topEntryFrame;
 
-    // If the topVMEntryFrame was pushed on the stack after the previousScope was instantiated,
+    // If the topEntryFrame was pushed on the stack after the previousScope was instantiated,
     // then this throwScope will be returning to LLINT or JIT code that always do an exception
     // check. In that case, skip the simulated throw because the LLInt and JIT will be
     // checking for the exception their own way instead of calling ThrowScope::exception().
-    if (topVMEntryFrame && previousScope > topVMEntryFrame)
+    if (topEntryFrame && previousScope > topEntryFrame)
         willBeHandleByLLIntOrJIT = true;
     
     if (!willBeHandleByLLIntOrJIT)
index 181e3b7..3ee5182 100644 (file)
@@ -184,7 +184,7 @@ VM::VM(VMType vmType, HeapType heapType)
 #endif
     , vmType(vmType)
     , clientData(0)
-    , topVMEntryFrame(nullptr)
+    , topEntryFrame(nullptr)
     , topCallFrame(CallFrame::noCaller())
     , promiseDeferredTimer(std::make_unique<PromiseDeferredTimer>(*this))
     , m_atomicStringTable(vmType == Default ? Thread::current().atomicStringTable() : new AtomicStringTable)
@@ -368,7 +368,7 @@ VM::~VM()
     promiseDeferredTimer->stopRunningTasks();
 #if ENABLE(WEBASSEMBLY)
     if (Wasm::existingWorklistOrNull())
-        Wasm::ensureWorklist().stopAllPlansForVM(*this);
+        Wasm::ensureWorklist().stopAllPlansForContext(wasmContext);
 #endif
     if (UNLIKELY(m_watchdog))
         m_watchdog->willDestroyVM(this);
index 9558594..d20e394 100644 (file)
@@ -55,6 +55,7 @@
 #include "TemplateRegistryKeyTable.h"
 #include "VMEntryRecord.h"
 #include "VMTraps.h"
+#include "WasmContext.h"
 #include "Watchpoint.h"
 #include <wtf/BumpPointerAllocator.h>
 #include <wtf/CheckedArithmetic.h>
@@ -329,14 +330,15 @@ public:
 
     VMType vmType;
     ClientData* clientData;
-    VMEntryFrame* topVMEntryFrame;
+    EntryFrame* topEntryFrame;
     // NOTE: When throwing an exception while rolling back the call frame, this may be equal to
-    // topVMEntryFrame.
+    // topEntryFrame.
     // FIXME: This should be a void*, because it might not point to a CallFrame.
     // https://bugs.webkit.org/show_bug.cgi?id=160441
     ExecState* topCallFrame { nullptr };
-    // FIXME: Save this state elsewhere to allow PIC. https://bugs.webkit.org/show_bug.cgi?id=169773
-    JSWebAssemblyInstance* wasmContext { nullptr };
+#if ENABLE(WEBASSEMBLY)
+    Wasm::Context wasmContext;
+#endif
     Strong<Structure> structureStructure;
     Strong<Structure> structureRareDataStructure;
     Strong<Structure> terminatedExecutionErrorStructure;
@@ -501,9 +503,9 @@ public:
         return OBJECT_OFFSETOF(VM, targetMachinePCForThrow);
     }
 
-    static ptrdiff_t topVMEntryFrameOffset()
+    static ptrdiff_t topEntryFrameOffset()
     {
-        return OBJECT_OFFSETOF(VM, topVMEntryFrame);
+        return OBJECT_OFFSETOF(VM, topEntryFrame);
     }
 
     void restorePreviousException(Exception* exception) { setException(exception); }
index e236ed3..a20d094 100644 (file)
@@ -89,7 +89,7 @@ inline CallFrame* sanitizedTopCallFrame(CallFrame* topCallFrame)
     return topCallFrame;
 }
 
-static bool isSaneFrame(CallFrame* frame, CallFrame* calleeFrame, VMEntryFrame* entryFrame, StackBounds stackBounds)
+static bool isSaneFrame(CallFrame* frame, CallFrame* calleeFrame, EntryFrame* entryFrame, StackBounds stackBounds)
 {
     if (reinterpret_cast<void*>(frame) >= reinterpret_cast<void*>(entryFrame))
         return false;
@@ -121,18 +121,18 @@ void VMTraps::tryInstallTrapBreakpoints(SignalContext& context, StackBounds stac
     }
 
     CodeBlock* foundCodeBlock = nullptr;
-    VMEntryFrame* vmEntryFrame = vm.topVMEntryFrame;
+    EntryFrame* entryFrame = vm.topEntryFrame;
 
     // We don't have a callee to start with. So, use the end of the stack to keep the
     // isSaneFrame() checker below happy for the first iteration. It will still check
     // to ensure that the address is in the stackBounds.
     CallFrame* calleeFrame = reinterpret_cast<CallFrame*>(stackBounds.end());
 
-    if (!vmEntryFrame || !callFrame)
+    if (!entryFrame || !callFrame)
         return; // Not running JS code. Let the SignalSender try again later.
 
     do {
-        if (!isSaneFrame(callFrame, calleeFrame, vmEntryFrame, stackBounds))
+        if (!isSaneFrame(callFrame, calleeFrame, entryFrame, stackBounds))
             return; // Let the SignalSender try again later.
 
         CodeBlock* candidateCodeBlock = callFrame->codeBlock();
@@ -142,9 +142,9 @@ void VMTraps::tryInstallTrapBreakpoints(SignalContext& context, StackBounds stac
         }
 
         calleeFrame = callFrame;
-        callFrame = callFrame->callerFrame(vmEntryFrame);
+        callFrame = callFrame->callerFrame(entryFrame);
 
-    } while (callFrame && vmEntryFrame);
+    } while (callFrame && entryFrame);
 
     if (!foundCodeBlock) {
         // We may have just entered the frame and the codeBlock pointer is not
@@ -181,17 +181,17 @@ void VMTraps::invalidateCodeBlocksOnStack(Locker<Lock>&, ExecState* topCallFrame
 
     m_needToInvalidatedCodeBlocks = false;
 
-    VMEntryFrame* vmEntryFrame = vm().topVMEntryFrame;
+    EntryFrame* entryFrame = vm().topEntryFrame;
     CallFrame* callFrame = topCallFrame;
 
-    if (!vmEntryFrame)
+    if (!entryFrame)
         return; // Not running JS code. Nothing to invalidate.
 
     while (callFrame) {
         CodeBlock* codeBlock = callFrame->codeBlock();
         if (codeBlock && JITCode::isOptimizingJIT(codeBlock->jitType()))
             codeBlock->jettison(Profiler::JettisonDueToVMTraps);
-        callFrame = callFrame->callerFrame(vmEntryFrame);
+        callFrame = callFrame->callerFrame(entryFrame);
     }
 }
 
index ad7d621..af6cfe8 100644 (file)
@@ -49,8 +49,6 @@
 #include "B3WasmBoundsCheckValue.h"
 #include "JSCInlines.h"
 #include "JSWebAssemblyInstance.h"
-#include "JSWebAssemblyModule.h"
-#include "JSWebAssemblyRuntimeError.h"
 #include "ScratchRegisterAllocator.h"
 #include "VirtualRegister.h"
 #include "WasmCallingConvention.h"
@@ -178,7 +176,7 @@ public:
             return fail(__VA_ARGS__);             \
     } while (0)
 
-    B3IRGenerator(const ModuleInformation&, Procedure&, InternalFunction*, Vector<UnlinkedWasmToWasmCall>&, MemoryMode, CompilationMode, unsigned functionIndex, TierUpCount*);
+    B3IRGenerator(const ModuleInformation&, Procedure&, InternalFunction*, Vector<UnlinkedWasmToWasmCall>&, MemoryMode, CompilationMode, unsigned functionIndex, TierUpCount*, ThrowWasmException);
 
     PartialResult WARN_UNUSED_RETURN addArguments(const Signature&);
     PartialResult WARN_UNUSED_RETURN addLocal(Type, uint32_t);
@@ -247,7 +245,7 @@ private:
 
     int32_t WARN_UNUSED_RETURN fixupPointerPlusOffset(ExpressionType&, uint32_t);
 
-    void restoreWasmContext(Procedure&, BasicBlock*, Value*);
+    void restoreWasmContextInstance(Procedure&, BasicBlock*, Value*);
     void restoreWebAssemblyGlobalState(const MemoryInformation&, Value* instance, Procedure&, BasicBlock*);
 
     Origin origin();
@@ -267,7 +265,7 @@ private:
     InsertionSet m_constantInsertionValues;
     GPRReg m_memoryBaseGPR { InvalidGPRReg };
     GPRReg m_memorySizeGPR { InvalidGPRReg };
-    GPRReg m_wasmContextGPR { InvalidGPRReg };
+    GPRReg m_wasmContextInstanceGPR { InvalidGPRReg };
     bool m_makesCalls { false };
 
     Value* m_instanceValue { nullptr }; // Always use the accessor below to ensure the instance value is materialized when used.
@@ -291,37 +289,37 @@ int32_t B3IRGenerator::fixupPointerPlusOffset(ExpressionType& ptr, uint32_t offs
     return offset;
 }
 
-void B3IRGenerator::restoreWasmContext(Procedure& proc, BasicBlock* block, Value* arg)
+void B3IRGenerator::restoreWasmContextInstance(Procedure& proc, BasicBlock* block, Value* arg)
 {
-    if (useFastTLSForContext()) {
+    if (Context::useFastTLS()) {
         PatchpointValue* patchpoint = block->appendNew<PatchpointValue>(proc, B3::Void, Origin());
-        if (CCallHelpers::storeWasmContextNeedsMacroScratchRegister())
+        if (CCallHelpers::storeWasmContextInstanceNeedsMacroScratchRegister())
             patchpoint->clobber(RegisterSet::macroScratchRegisters());
         patchpoint->append(ConstrainedValue(arg, ValueRep::SomeRegister));
         patchpoint->setGenerator(
             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
-                AllowMacroScratchRegisterUsageIf allowScratch(jit, CCallHelpers::storeWasmContextNeedsMacroScratchRegister());
-                jit.storeWasmContext(params[0].gpr());
+                AllowMacroScratchRegisterUsageIf allowScratch(jit, CCallHelpers::storeWasmContextInstanceNeedsMacroScratchRegister());
+                jit.storeWasmContextInstance(params[0].gpr());
             });
         return;
     }
 
-    // FIXME: Because WasmToWasm call clobbers wasmContext register and does not restore it, we need to restore it in the caller side.
+    // FIXME: Because WasmToWasm call clobbers wasmContextInstance register and does not restore it, we need to restore it in the caller side.
     // This prevents us from using ArgumentReg to this (logically) immutable pinned register.
     PatchpointValue* patchpoint = block->appendNew<PatchpointValue>(proc, B3::Void, Origin());
     Effects effects = Effects::none();
     effects.writesPinned = true;
     effects.reads = B3::HeapRange::top();
     patchpoint->effects = effects;
-    patchpoint->clobberLate(RegisterSet(m_wasmContextGPR));
+    patchpoint->clobberLate(RegisterSet(m_wasmContextInstanceGPR));
     patchpoint->append(instanceValue(), ValueRep::SomeRegister);
-    GPRReg wasmContextGPR = m_wasmContextGPR;
+    GPRReg wasmContextInstanceGPR = m_wasmContextInstanceGPR;
     patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& param) {
-        jit.move(param[0].gpr(), wasmContextGPR);
+        jit.move(param[0].gpr(), wasmContextInstanceGPR);
     });
 }
 
-B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure, InternalFunction* compilation, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, MemoryMode mode, CompilationMode compilationMode, unsigned functionIndex, TierUpCount* tierUp)
+B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure, InternalFunction* compilation, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, MemoryMode mode, CompilationMode compilationMode, unsigned functionIndex, TierUpCount* tierUp, ThrowWasmException throwWasmException)
     : m_info(info)
     , m_mode(mode)
     , m_compilationMode(compilationMode)
@@ -339,9 +337,9 @@ B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure
     m_memoryBaseGPR = pinnedRegs.baseMemoryPointer;
     m_proc.pinRegister(m_memoryBaseGPR);
 
-    m_wasmContextGPR = pinnedRegs.wasmContextPointer;
-    if (!useFastTLSForContext())
-        m_proc.pinRegister(m_wasmContextGPR);
+    m_wasmContextInstanceGPR = pinnedRegs.wasmContextInstancePointer;
+    if (!Context::useFastTLS())
+        m_proc.pinRegister(m_wasmContextInstanceGPR);
 
     if (mode != MemoryMode::Signaling) {
         ASSERT(!pinnedRegs.sizeRegisters[0].sizeOffset);
@@ -350,6 +348,9 @@ B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure
             m_proc.pinRegister(regInfo.sizeRegister);
     }
 
+    if (throwWasmException)
+        Thunks::singleton().setThrowWasmException(throwWasmException);
+
     if (info.memory) {
         m_proc.setWasmBoundsCheckGenerator([=] (CCallHelpers& jit, GPRReg pinnedGPR) {
             AllowMacroScratchRegisterUsage allowScratch(jit);
@@ -363,6 +364,16 @@ B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure
             }
             this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess);
         });
+
+        switch (m_mode) {
+        case MemoryMode::BoundsChecking:
+            break;
+        case MemoryMode::Signaling:
+        // Most memory accesses in signaling mode don't do an explicit exception check because they can rely on fault handling to detect out-of-bounds accesses. FaultSignalHandler nonetheless needs the thunk to exist so that it can jump to that thunk.
+            if (UNLIKELY(!Thunks::singleton().stub(throwExceptionFromWasmThunkGenerator)))
+                CRASH();
+            break;
+        }
     }
 
     wasmCallingConvention().setupFrameInPrologue(&compilation->calleeMoveLocation, m_proc, Origin(), m_currentBlock);
@@ -373,12 +384,12 @@ B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure
         m_instanceValue = stackOverflowCheck;
         stackOverflowCheck->appendSomeRegister(framePointer);
         stackOverflowCheck->clobber(RegisterSet::macroScratchRegisters());
-        if (!useFastTLSForContext()) {
-            // FIXME: Because WasmToWasm call clobbers wasmContext register and does not restore it, we need to restore it in the caller side.
+        if (!Context::useFastTLS()) {
+            // FIXME: Because WasmToWasm call clobbers wasmContextInstance register and does not restore it, we need to restore it in the caller side.
             // This prevents us from using ArgumentReg to this (logically) immutable pinned register.
             stackOverflowCheck->effects.writesPinned = false;
             stackOverflowCheck->effects.readsPinned = true;
-            stackOverflowCheck->resultConstraint = ValueRep::reg(m_wasmContextGPR);
+            stackOverflowCheck->resultConstraint = ValueRep::reg(m_wasmContextInstanceGPR);
         }
         stackOverflowCheck->numGPScratchRegisters = 2;
         stackOverflowCheck->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
@@ -401,7 +412,7 @@ B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure
             bool needUnderflowCheck = static_cast<unsigned>(checkSize) > Options::reservedZoneSize();
             bool needsOverflowCheck = m_makesCalls || wasmFrameSize >= minimumParentCheckSize || needUnderflowCheck;
 
-            GPRReg context = useFastTLSForContext() ? params[0].gpr() : m_wasmContextGPR;
+            GPRReg contextInstance = Context::useFastTLS() ? params[0].gpr() : m_wasmContextInstanceGPR;
 
             // This allows leaf functions to not do stack checks if their frame size is within
             // certain limits since their caller would have already done the check.
@@ -411,10 +422,10 @@ B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure
                 GPRReg scratch1 = params.gpScratch(0);
                 GPRReg scratch2 = params.gpScratch(1);
 
-                if (useFastTLSForContext())
-                    jit.loadWasmContext(context);
+                if (Context::useFastTLS())
+                    jit.loadWasmContextInstance(contextInstance);
 
-                jit.loadPtr(CCallHelpers::Address(context, Context::offsetOfCachedStackLimit()), scratch2);
+                jit.loadPtr(CCallHelpers::Address(contextInstance, JSWebAssemblyInstance::offsetOfCachedStackLimit()), scratch2);
                 jit.addPtr(CCallHelpers::TrustedImm32(-checkSize), fp, scratch1);
                 MacroAssembler::JumpList overflow;
                 if (UNLIKELY(needUnderflowCheck))
@@ -423,10 +434,10 @@ B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure
                 jit.addLinkTask([overflow] (LinkBuffer& linkBuffer) {
                     linkBuffer.link(overflow, CodeLocationLabel(Thunks::singleton().stub(throwStackOverflowFromWasmThunkGenerator).code()));
                 });
-            } else if (m_usesInstanceValue && useFastTLSForContext()) {
+            } else if (m_usesInstanceValue && Context::useFastTLS()) {
                 // No overflow check is needed, but the instance values still needs to be correct.
-                AllowMacroScratchRegisterUsageIf allowScratch(jit, CCallHelpers::loadWasmContextNeedsMacroScratchRegister());
-                jit.loadWasmContext(context);
+                AllowMacroScratchRegisterUsageIf allowScratch(jit, CCallHelpers::loadWasmContextInstanceNeedsMacroScratchRegister());
+                jit.loadWasmContextInstance(contextInstance);
             } else {
                 // We said we'd return a pointer. We don't actually need to because it isn't used, but the patchpoint conservatively said it had effects (potential stack check) which prevent it from getting removed.
             }
@@ -438,7 +449,7 @@ B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure
 
 void B3IRGenerator::restoreWebAssemblyGlobalState(const MemoryInformation& memory, Value* instance, Procedure& proc, BasicBlock* block)
 {
-    restoreWasmContext(proc, block, instance);
+    restoreWasmContextInstance(proc, block, instance);
 
     if (!!memory) {
         const PinnedRegisterInfo* pinnedRegs = &PinnedRegisterInfo::get();
@@ -458,12 +469,12 @@ void B3IRGenerator::restoreWebAssemblyGlobalState(const MemoryInformation& memor
 
         patchpoint->setGenerator([pinnedRegs] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
             GPRReg baseMemory = pinnedRegs->baseMemoryPointer;
-            jit.loadPtr(CCallHelpers::Address(params[0].gpr(), JSWebAssemblyInstance::offsetOfMemory()), baseMemory);
+            jit.loadPtr(CCallHelpers::Address(params[0].gpr(), JSWebAssemblyInstance::offsetOfWasmMemory()), baseMemory);
             const auto& sizeRegs = pinnedRegs->sizeRegisters;
             ASSERT(sizeRegs.size() >= 1);
             ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0.
-            jit.loadPtr(CCallHelpers::Address(baseMemory, JSWebAssemblyMemory::offsetOfSize()), sizeRegs[0].sizeRegister);
-            jit.loadPtr(CCallHelpers::Address(baseMemory, JSWebAssemblyMemory::offsetOfMemory()), baseMemory);
+            jit.loadPtr(CCallHelpers::Address(baseMemory, Wasm::Memory::offsetOfSize()), sizeRegs[0].sizeRegister);
+            jit.loadPtr(CCallHelpers::Address(baseMemory, Wasm::Memory::offsetOfMemory()), baseMemory);
             for (unsigned i = 1; i < sizeRegs.size(); ++i)
                 jit.add64(CCallHelpers::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister);
         });
@@ -541,24 +552,22 @@ auto B3IRGenerator::addUnreachable() -> PartialResult
 
 auto B3IRGenerator::addGrowMemory(ExpressionType delta, ExpressionType& result) -> PartialResult
 {
-    int32_t (*growMemory) (Context*, int32_t) = [] (Context* wasmContext, int32_t delta) -> int32_t {
-        VM& vm = *wasmContext->vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-
-        JSWebAssemblyMemory* wasmMemory = wasmContext->memory();
-
+    int32_t (*growMemory)(JSWebAssemblyInstance*, int32_t) = [] (JSWebAssemblyInstance* instance, int32_t delta) -> int32_t {
         if (delta < 0)
             return -1;
 
-        bool shouldThrowExceptionsOnFailure = false;
-        // grow() does not require ExecState* if it doesn't throw exceptions.
-        ExecState* exec = nullptr;
-        PageCount result = wasmMemory->grow(vm, exec, static_cast<uint32_t>(delta), shouldThrowExceptionsOnFailure);
-        scope.releaseAssertNoException();
-        if (!result)
-            return -1;
+        auto grown = instance->internalMemory().grow(PageCount(delta));
+        if (!grown) {
+            switch (grown.error()) {
+            case Memory::GrowFailReason::InvalidDelta:
+            case Memory::GrowFailReason::InvalidGrowSize:
+            case Memory::GrowFailReason::WouldExceedMaximum:
+            case Memory::GrowFailReason::OutOfMemory:
+                return -1;
+            }
+        }
 
-        return result.pageCount();
+        return grown.value().pageCount();
     };
 
     result = m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(),
@@ -572,13 +581,13 @@ auto B3IRGenerator::addGrowMemory(ExpressionType delta, ExpressionType& result)
 
 auto B3IRGenerator::addCurrentMemory(ExpressionType& result) -> PartialResult
 {
-    Value* memoryObject = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), instanceValue(), safeCast<int32_t>(JSWebAssemblyInstance::offsetOfMemory()));
+    Value* memoryObject = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), instanceValue(), safeCast<int32_t>(JSWebAssemblyInstance::offsetOfWasmMemory()));
 
-    static_assert(sizeof(decltype(static_cast<JSWebAssemblyInstance*>(nullptr)->memory()->memory().size())) == sizeof(uint64_t), "codegen relies on this size");
-    Value* size = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), memoryObject, safeCast<int32_t>(JSWebAssemblyMemory::offsetOfSize()));
+    static_assert(sizeof(decltype(static_cast<Wasm::Memory*>(nullptr)->size())) == sizeof(uint64_t), "codegen relies on this size");
+    Value* size = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), memoryObject, safeCast<int32_t>(Wasm::Memory::offsetOfSize()));
     
     constexpr uint32_t shiftValue = 16;
-    static_assert(PageCount::pageSize == 1 << shiftValue, "This must hold for the code below to be correct.");
+    static_assert(PageCount::pageSize == 1ull << shiftValue, "This must hold for the code below to be correct.");
     Value* numPages = m_currentBlock->appendNew<Value>(m_proc, ZShr, origin(),
         size, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), shiftValue));
 
@@ -1069,14 +1078,13 @@ auto B3IRGenerator::addCall(uint32_t functionIndex, const Signature& signature,
         m_maxNumJSCallArguments = std::max(m_maxNumJSCallArguments, static_cast<uint32_t>(args.size()));
 
         // FIXME imports can be linked here, instead of generating a patchpoint, because all import stubs are generated before B3 compilation starts. https://bugs.webkit.org/show_bug.cgi?id=166462
-        Value* functionImport = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), instanceValue(), safeCast<int32_t>(JSWebAssemblyInstance::offsetOfImportFunction(functionIndex)));
-        Value* jsTypeOfImport = m_currentBlock->appendNew<MemoryValue>(m_proc, Load8Z, origin(), functionImport, safeCast<int32_t>(JSCell::typeInfoTypeOffset()));
-        Value* isWasmCall = m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), jsTypeOfImport, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), WebAssemblyFunctionType));
+        Value* targetInstance = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), instanceValue(), safeCast<int32_t>(JSWebAssemblyInstance::offsetOfTargetInstance(functionIndex)));
+        Value* isWasmCall = m_currentBlock->appendNew<Value>(m_proc, NotEqual, origin(), targetInstance, m_currentBlock->appendNew<Const64Value>(m_proc, origin(), 0));
 
         BasicBlock* isWasmBlock = m_proc.addBlock();
-        BasicBlock* isJSBlock = m_proc.addBlock();
+        BasicBlock* isEmbedderBlock = m_proc.addBlock();
         BasicBlock* continuation = m_proc.addBlock();
-        m_currentBlock->appendNewControlValue(m_proc, B3::Branch, origin(), isWasmCall, FrequentedBlock(isWasmBlock), FrequentedBlock(isJSBlock));
+        m_currentBlock->appendNewControlValue(m_proc, B3::Branch, origin(), isWasmCall, FrequentedBlock(isWasmBlock), FrequentedBlock(isEmbedderBlock));
 
         Value* wasmCallResult = wasmCallingConvention().setupCall(m_proc, isWasmBlock, origin(), args, toB3Type(returnType),
             [=] (PatchpointValue* patchpoint) {
@@ -1097,15 +1105,15 @@ auto B3IRGenerator::addCall(uint32_t functionIndex, const Signature& signature,
         UpsilonValue* wasmCallResultUpsilon = returnType == Void ? nullptr : isWasmBlock->appendNew<UpsilonValue>(m_proc, origin(), wasmCallResult);
         isWasmBlock->appendNewControlValue(m_proc, Jump, origin(), continuation);
 
-        // FIXME: Lets remove this indirection by creating a PIC friendly IC
+        // FIXME: Let's remove this indirection by creating a PIC friendly IC
         // for calls out to JS. This shouldn't be that hard to do. We could probably
         // implement the IC to be over Wasm::Context*.
         // https://bugs.webkit.org/show_bug.cgi?id=170375
-        Value* codeBlock = isJSBlock->appendNew<MemoryValue>(m_proc,
-            Load, pointerType(), origin(), instanceValue(), safeCast<int32_t>(JSWebAssemblyInstance::offsetOfCodeBlock()));
-        Value* jumpDestination = isJSBlock->appendNew<MemoryValue>(m_proc,
-            Load, pointerType(), origin(), codeBlock, safeCast<int32_t>(JSWebAssemblyCodeBlock::offsetOfImportWasmToJSStub(functionIndex)));
-        Value* jsCallResult = wasmCallingConvention().setupCall(m_proc, isJSBlock, origin(), args, toB3Type(returnType),
+        Value* codeBlock = isEmbedderBlock->appendNew<MemoryValue>(m_proc,
+            Load, pointerType(), origin(), instanceValue(), safeCast<int32_t>(JSWebAssemblyInstance::offsetOfWasmCodeBlock()));
+        Value* jumpDestination = isEmbedderBlock->appendNew<MemoryValue>(m_proc,
+            Load, pointerType(), origin(), codeBlock, safeCast<int32_t>(CodeBlock::offsetOfImportWasmToEmbedderStub(functionIndex)));
+        Value* embedderCallResult = wasmCallingConvention().setupCall(m_proc, isEmbedderBlock, origin(), args, toB3Type(returnType),
             [&] (PatchpointValue* patchpoint) {
                 patchpoint->effects.writesPinned = true;
                 patchpoint->effects.readsPinned = true;
@@ -1119,8 +1127,8 @@ auto B3IRGenerator::addCall(uint32_t functionIndex, const Signature& signature,
                     jit.call(params[returnType == Void ? 0 : 1].gpr());
                 });
             });
-        UpsilonValue* jsCallResultUpsilon = returnType == Void ? nullptr : isJSBlock->appendNew<UpsilonValue>(m_proc, origin(), jsCallResult);
-        isJSBlock->appendNewControlValue(m_proc, Jump, origin(), continuation);
+        UpsilonValue* embedderCallResultUpsilon = returnType == Void ? nullptr : isEmbedderBlock->appendNew<UpsilonValue>(m_proc, origin(), embedderCallResult);
+        isEmbedderBlock->appendNewControlValue(m_proc, Jump, origin(), continuation);
 
         m_currentBlock = continuation;
 
@@ -1129,7 +1137,7 @@ auto B3IRGenerator::addCall(uint32_t functionIndex, const Signature& signature,
         else {
             result = continuation->appendNew<Value>(m_proc, Phi, toB3Type(returnType), origin());
             wasmCallResultUpsilon->setPhi(result);
-            jsCallResultUpsilon->setPhi(result);
+            embedderCallResultUpsilon->setPhi(result);
         }
 
         // The call could have been to another WebAssembly instance, and / or could have modified our Memory.
@@ -1165,17 +1173,17 @@ auto B3IRGenerator::addCallIndirect(const Signature& signature, Vector<Expressio
     m_maxNumJSCallArguments = std::max(m_maxNumJSCallArguments, static_cast<uint32_t>(args.size()));
 
     ExpressionType callableFunctionBuffer;
-    ExpressionType jsFunctionBuffer;
+    ExpressionType instancesBuffer;
     ExpressionType callableFunctionBufferSize;
     {
         ExpressionType table = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
-            instanceValue(), safeCast<int32_t>(JSWebAssemblyInstance::offsetOfTable()));
+            instanceValue(), safeCast<int32_t>(JSWebAssemblyInstance::offsetOfWasmTable()));
         callableFunctionBuffer = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
-            table, safeCast<int32_t>(JSWebAssemblyTable::offsetOfFunctions()));
-        jsFunctionBuffer = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
-            table, safeCast<int32_t>(JSWebAssemblyTable::offsetOfJSFunctions()));
+            table, safeCast<int32_t>(Wasm::Table::offsetOfFunctions()));
+        instancesBuffer = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
+            table, safeCast<int32_t>(Wasm::Table::offsetOfInstances()));
         callableFunctionBufferSize = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(),
-            table, safeCast<int32_t>(JSWebAssemblyTable::offsetOfSize()));
+            table, safeCast<int32_t>(Wasm::Table::offsetOfSize()));
     }
 
     // Check the index we are looking for is valid.
@@ -1195,6 +1203,7 @@ auto B3IRGenerator::addCallIndirect(const Signature& signature, Vector<Expressio
     ExpressionType callableFunction = m_currentBlock->appendNew<Value>(m_proc, Add, origin(), callableFunctionBuffer, offset);
 
     // Check that the CallableFunction is initialized. We trap if it isn't. An "invalid" SignatureIndex indicates it's not initialized.
+    // FIXME: when we have trap handlers, we can just let the call fail because Signature::invalidIndex is 0. https://bugs.webkit.org/show_bug.cgi?id=177210
     static_assert(sizeof(CallableFunction::signatureIndex) == sizeof(uint32_t), "Load codegen assumes i32");
     ExpressionType calleeSignatureIndex = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(), callableFunction, safeCast<int32_t>(OBJECT_OFFSETOF(CallableFunction, signatureIndex)));
     {
@@ -1223,19 +1232,17 @@ auto B3IRGenerator::addCallIndirect(const Signature& signature, Vector<Expressio
     {
         Value* offset = m_currentBlock->appendNew<Value>(m_proc, Mul, origin(),
             m_currentBlock->appendNew<Value>(m_proc, ZExt32, origin(), calleeIndex),
-            constant(pointerType(), sizeof(WriteBarrier<JSObject>)));
-        Value* jsObject = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
-            m_currentBlock->appendNew<Value>(m_proc, Add, origin(), jsFunctionBuffer, offset));
+            constant(pointerType(), sizeof(Wasm::Instance*)));
+        Value* newContextInstance = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
+            m_currentBlock->appendNew<Value>(m_proc, Add, origin(), instancesBuffer, offset));
 
         BasicBlock* continuation = m_proc.addBlock();
         BasicBlock* doContextSwitch = m_proc.addBlock();
 
-        Value* newContext = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
-            jsObject, safeCast<int32_t>(WebAssemblyFunctionBase::offsetOfInstance()));
-        Value* isSameContext = m_currentBlock->appendNew<Value>(m_proc, Equal, origin(),
-            newContext, instanceValue());
+        Value* isSameContextInstance = m_currentBlock->appendNew<Value>(m_proc, Equal, origin(),
+            newContextInstance, instanceValue());
         m_currentBlock->appendNewControlValue(m_proc, B3::Branch, origin(),
-            isSameContext, FrequentedBlock(continuation), FrequentedBlock(doContextSwitch));
+            isSameContextInstance, FrequentedBlock(continuation), FrequentedBlock(doContextSwitch));
 
         PatchpointValue* patchpoint = doContextSwitch->appendNew<PatchpointValue>(m_proc, B3::Void, origin());
         patchpoint->effects.writesPinned = true;
@@ -1243,26 +1250,26 @@ auto B3IRGenerator::addCallIndirect(const Signature& signature, Vector<Expressio
         // FIXME: We shouldn't have to do this: https://bugs.webkit.org/show_bug.cgi?id=172181
         patchpoint->clobber(PinnedRegisterInfo::get().toSave(MemoryMode::BoundsChecking));
         patchpoint->clobber(RegisterSet::macroScratchRegisters());
-        patchpoint->append(newContext, ValueRep::SomeRegister);
+        patchpoint->append(newContextInstance, ValueRep::SomeRegister);
         patchpoint->append(instanceValue(), ValueRep::SomeRegister);
         patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
             AllowMacroScratchRegisterUsage allowScratch(jit);
-            GPRReg newContext = params[0].gpr();
-            GPRReg oldContext = params[1].gpr();
+            GPRReg newContextInstance = params[0].gpr();
+            GPRReg oldContextInstance = params[1].gpr();
             const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get();
             const auto& sizeRegs = pinnedRegs.sizeRegisters;
             GPRReg baseMemory = pinnedRegs.baseMemoryPointer;
-            ASSERT(newContext != baseMemory);
-            jit.loadPtr(CCallHelpers::Address(oldContext, Context::offsetOfCachedStackLimit()), baseMemory);
-            jit.storePtr(baseMemory, CCallHelpers::Address(newContext, Context::offsetOfCachedStackLimit()));
-            jit.storeWasmContext(newContext);
-            jit.loadPtr(CCallHelpers::Address(newContext, Context::offsetOfMemory()), baseMemory); // JSWebAssemblyMemory*.
+            ASSERT(newContextInstance != baseMemory);
+            jit.loadPtr(CCallHelpers::Address(oldContextInstance, JSWebAssemblyInstance::offsetOfCachedStackLimit()), baseMemory);
+            jit.storePtr(baseMemory, CCallHelpers::Address(newContextInstance, JSWebAssemblyInstance::offsetOfCachedStackLimit()));
+            jit.storeWasmContextInstance(newContextInstance);
+            jit.loadPtr(CCallHelpers::Address(newContextInstance, JSWebAssemblyInstance::offsetOfWasmMemory()), baseMemory); // Wasm::Memory*.
             ASSERT(sizeRegs.size() == 1);
             ASSERT(sizeRegs[0].sizeRegister != baseMemory);
-            ASSERT(sizeRegs[0].sizeRegister != newContext);
+            ASSERT(sizeRegs[0].sizeRegister != newContextInstance);
             ASSERT(!sizeRegs[0].sizeOffset);
-            jit.loadPtr(CCallHelpers::Address(baseMemory, JSWebAssemblyMemory::offsetOfSize()), sizeRegs[0].sizeRegister); // Memory size.
-            jit.loadPtr(CCallHelpers::Address(baseMemory, JSWebAssemblyMemory::offsetOfMemory()), baseMemory); // WasmMemory::void*.
+            jit.loadPtr(CCallHelpers::Address(baseMemory, Wasm::Memory::offsetOfSize()), sizeRegs[0].sizeRegister); // Memory size.
+            jit.loadPtr(CCallHelpers::Address(baseMemory, Wasm::Memory::offsetOfMemory()), baseMemory); // Wasm::Memory::void*.
         });
         doContextSwitch->appendNewControlValue(m_proc, Jump, origin(), continuation);
 
@@ -1339,194 +1346,6 @@ void B3IRGenerator::dump(const Vector<ControlEntry>& controlStack, const Express
     dataLogLn();
 }
 
-std::unique_ptr<InternalFunction> createJSToWasmWrapper(CompilationContext& compilationContext, const Signature& signature, Vector<UnlinkedWasmToWasmCall>* unlinkedWasmToWasmCalls, const ModuleInformation& info, MemoryMode mode, unsigned functionIndex)
-{
-    CCallHelpers& jit = *compilationContext.jsEntrypointJIT;
-
-    auto result = std::make_unique<InternalFunction>();
-    jit.emitFunctionPrologue();
-
-    // FIXME Stop using 0 as codeBlocks. https://bugs.webkit.org/show_bug.cgi?id=165321
-    jit.store64(CCallHelpers::TrustedImm64(0), CCallHelpers::Address(GPRInfo::callFrameRegister, CallFrameSlot::codeBlock * static_cast<int>(sizeof(Register))));
-    MacroAssembler::DataLabelPtr calleeMoveLocation = jit.moveWithPatch(MacroAssembler::TrustedImmPtr(nullptr), GPRInfo::nonPreservedNonReturnGPR);
-    jit.storePtr(GPRInfo::nonPreservedNonReturnGPR, CCallHelpers::Address(GPRInfo::callFrameRegister, CallFrameSlot::callee * static_cast<int>(sizeof(Register))));
-    CodeLocationDataLabelPtr* linkedCalleeMove = &result->calleeMoveLocation;
-    jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
-        *linkedCalleeMove = linkBuffer.locationOf(calleeMoveLocation);
-    });
-
-    const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get();
-    RegisterSet toSave = pinnedRegs.toSave(mode);
-
-#if !ASSERT_DISABLED
-    unsigned toSaveSize = toSave.numberOfSetGPRs();
-    // They should all be callee saves.
-    toSave.filter(RegisterSet::calleeSaveRegisters());
-    ASSERT(toSave.numberOfSetGPRs() == toSaveSize);
-#endif
-
-    RegisterAtOffsetList registersToSpill(toSave, RegisterAtOffsetList::OffsetBaseType::FramePointerBased);
-    result->entrypoint.calleeSaveRegisters = registersToSpill;
-
-    unsigned totalFrameSize = registersToSpill.size() * sizeof(void*);
-    totalFrameSize += WasmCallingConvention::headerSizeInBytes();
-    totalFrameSize -= sizeof(CallerFrameAndPC);
-    unsigned numGPRs = 0;
-    unsigned numFPRs = 0;
-    for (unsigned i = 0; i < signature.argumentCount(); i++) {
-        switch (signature.argument(i)) {
-        case Wasm::I64:
-        case Wasm::I32:
-            if (numGPRs >= wasmCallingConvention().m_gprArgs.size())
-                totalFrameSize += sizeof(void*);
-            ++numGPRs;
-            break;
-        case Wasm::F32:
-        case Wasm::F64:
-            if (numFPRs >= wasmCallingConvention().m_fprArgs.size())
-                totalFrameSize += sizeof(void*);
-            ++numFPRs;
-            break;
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-        }
-    }
-
-    totalFrameSize = WTF::roundUpToMultipleOf(stackAlignmentBytes(), totalFrameSize);
-    jit.subPtr(MacroAssembler::TrustedImm32(totalFrameSize), MacroAssembler::stackPointerRegister);
-
-    // We save all these registers regardless of having a memory or not.
-    // The reason is that we use one of these as a scratch. That said,
-    // almost all real wasm programs use memory, so it's not really
-    // worth optimizing for the case that they don't.
-    for (const RegisterAtOffset& regAtOffset : registersToSpill) {
-        GPRReg reg = regAtOffset.reg().gpr();
-        ptrdiff_t offset = regAtOffset.offset();
-        jit.storePtr(reg, CCallHelpers::Address(GPRInfo::callFrameRegister, offset));
-    }
-
-    GPRReg wasmContextGPR = pinnedRegs.wasmContextPointer;
-
-    {
-        CCallHelpers::Address calleeFrame = CCallHelpers::Address(MacroAssembler::stackPointerRegister, -static_cast<ptrdiff_t>(sizeof(CallerFrameAndPC)));
-        numGPRs = 0;
-        numFPRs = 0;
-        // We're going to set the pinned registers after this. So
-        // we can use this as a scratch for now since we saved it above.
-        GPRReg scratchReg = pinnedRegs.baseMemoryPointer;
-
-        ptrdiff_t jsOffset = CallFrameSlot::thisArgument * sizeof(EncodedJSValue);
-
-        // vmEntryToWasm passes Wasm::Context* as the first JS argument when we're
-        // not using fast TLS to hold the Wasm::Context*.
-        if (!useFastTLSForContext()) {
-            jit.loadPtr(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), wasmContextGPR);
-            jsOffset += sizeof(EncodedJSValue);
-        }
-
-        ptrdiff_t wasmOffset = CallFrame::headerSizeInRegisters * sizeof(void*);
-        for (unsigned i = 0; i < signature.argumentCount(); i++) {
-            switch (signature.argument(i)) {
-            case Wasm::I32:
-            case Wasm::I64:
-                if (numGPRs >= wasmCallingConvention().m_gprArgs.size()) {
-                    if (signature.argument(i) == Wasm::I32) {
-                        jit.load32(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchReg);
-                        jit.store32(scratchReg, calleeFrame.withOffset(wasmOffset));
-                    } else {
-                        jit.load64(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchReg);
-                        jit.store64(scratchReg, calleeFrame.withOffset(wasmOffset));
-                    }
-                    wasmOffset += sizeof(void*);
-                } else {
-                    if (signature.argument(i) == Wasm::I32)
-                        jit.load32(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), wasmCallingConvention().m_gprArgs[numGPRs].gpr());
-                    else
-                        jit.load64(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), wasmCallingConvention().m_gprArgs[numGPRs].gpr());
-                }
-                ++numGPRs;
-                break;
-            case Wasm::F32:
-            case Wasm::F64:
-                if (numFPRs >= wasmCallingConvention().m_fprArgs.size()) {
-                    if (signature.argument(i) == Wasm::F32) {
-                        jit.load32(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchReg);
-                        jit.store32(scratchReg, calleeFrame.withOffset(wasmOffset));
-                    } else {
-                        jit.load64(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchReg);
-                        jit.store64(scratchReg, calleeFrame.withOffset(wasmOffset));
-                    }
-                    wasmOffset += sizeof(void*);
-                } else {
-                    if (signature.argument(i) == Wasm::F32)
-                        jit.loadFloat(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), wasmCallingConvention().m_fprArgs[numFPRs].fpr());
-                    else
-                        jit.loadDouble(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), wasmCallingConvention().m_fprArgs[numFPRs].fpr());
-                }
-                ++numFPRs;
-                break;
-            default:
-                RELEASE_ASSERT_NOT_REACHED();
-            }
-
-            jsOffset += sizeof(EncodedJSValue);
-        }
-    }
-
-    if (!!info.memory) {
-        GPRReg baseMemory = pinnedRegs.baseMemoryPointer;
-
-        if (!useFastTLSForContext())
-            jit.loadPtr(CCallHelpers::Address(wasmContextGPR, JSWebAssemblyInstance::offsetOfMemory()), baseMemory);
-        else {
-            jit.loadWasmContext(baseMemory);
-            jit.loadPtr(CCallHelpers::Address(baseMemory, JSWebAssemblyInstance::offsetOfMemory()), baseMemory);
-        }
-
-        if (mode != MemoryMode::Signaling) {
-            const auto& sizeRegs = pinnedRegs.sizeRegisters;
-            ASSERT(sizeRegs.size() >= 1);
-            ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0.
-            jit.loadPtr(CCallHelpers::Address(baseMemory, JSWebAssemblyMemory::offsetOfSize()), sizeRegs[0].sizeRegister);
-            for (unsigned i = 1; i < sizeRegs.size(); ++i)
-                jit.add64(CCallHelpers::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister);
-        }
-
-        jit.loadPtr(CCallHelpers::Address(baseMemory, JSWebAssemblyMemory::offsetOfMemory()), baseMemory);
-    }
-
-    CCallHelpers::Call call = jit.threadSafePatchableNearCall();
-    unsigned functionIndexSpace = functionIndex + info.importFunctionCount();
-    ASSERT(functionIndexSpace < info.functionIndexSpaceSize());
-    jit.addLinkTask([unlinkedWasmToWasmCalls, call, functionIndexSpace] (LinkBuffer& linkBuffer) {
-        unlinkedWasmToWasmCalls->append({ linkBuffer.locationOfNearCall(call), functionIndexSpace });
-    });
-
-
-    for (const RegisterAtOffset& regAtOffset : registersToSpill) {
-        GPRReg reg = regAtOffset.reg().gpr();
-        ASSERT(reg != GPRInfo::returnValueGPR);
-        ptrdiff_t offset = regAtOffset.offset();
-        jit.loadPtr(CCallHelpers::Address(GPRInfo::callFrameRegister, offset), reg);
-    }
-
-    switch (signature.returnType()) {
-    case Wasm::F32:
-        jit.moveFloatTo32(FPRInfo::returnValueFPR, GPRInfo::returnValueGPR);
-        break;
-    case Wasm::F64:
-        jit.moveDoubleTo64(FPRInfo::returnValueFPR, GPRInfo::returnValueGPR);
-        break;
-    default:
-        break;
-    }
-
-    jit.emitFunctionEpilogue();
-    jit.ret();
-
-    return result;
-}
-
 auto B3IRGenerator::origin() -> Origin
 {
     OpcodeOrigin origin(m_parser->currentOpcode(), m_parser->currentOpcodeStartingOffset());
@@ -1534,7 +1353,7 @@ auto B3IRGenerator::origin() -> Origin
     return bitwise_cast<Origin>(origin);
 }
 
-Expected<std::unique_ptr<InternalFunction>, String> parseAndCompile(CompilationContext& compilationContext, const uint8_t* functionStart, size_t functionLength, const Signature& signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const ModuleInformation& info, MemoryMode mode, CompilationMode compilationMode, uint32_t functionIndex, TierUpCount* tierUp)
+Expected<std::unique_ptr<InternalFunction>, String> parseAndCompile(CompilationContext& compilationContext, const uint8_t* functionStart, size_t functionLength, const Signature& signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const ModuleInformation& info, MemoryMode mode, CompilationMode compilationMode, uint32_t functionIndex, TierUpCount* tierUp, ThrowWasmException throwWasmException)
 {
     auto result = std::make_unique<InternalFunction>();
 
@@ -1558,11 +1377,11 @@ Expected<std::unique_ptr<InternalFunction>, String> parseAndCompile(CompilationC
         ? Options::webAssemblyBBQOptimizationLevel()
         : Options::webAssemblyOMGOptimizationLevel());
 
-    B3IRGenerator context(info, procedure, result.get(), unlinkedWasmToWasmCalls, mode, compilationMode, functionIndex, tierUp);
-    FunctionParser<B3IRGenerator> parser(context, functionStart, functionLength, signature, info);
+    B3IRGenerator irGenerator(info, procedure, result.get(), unlinkedWasmToWasmCalls, mode, compilationMode, functionIndex, tierUp, throwWasmException);
+    FunctionParser<B3IRGenerator> parser(irGenerator, functionStart, functionLength, signature, info);
     WASM_FAIL_IF_HELPER_FAILS(parser.parse());
 
-    context.insertConstants();
+    irGenerator.insertConstants();
 
     procedure.resetReachability();
     if (!ASSERT_DISABLED)
index e2c6adb..69be448 100644 (file)
@@ -31,6 +31,7 @@
 #include "B3Compilation.h"
 #include "B3OpaqueByproducts.h"
 #include "CCallHelpers.h"
+#include "WasmEmbedder.h"
 #include "WasmMemory.h"
 #include "WasmModuleInformation.h"
 #include "WasmTierUpCount.h"
@@ -54,9 +55,7 @@ struct CompilationContext {
     std::unique_ptr<B3::OpaqueByproducts> wasmEntrypointByproducts;
 };
 
-Expected<std::unique_ptr<InternalFunction>, String> parseAndCompile(CompilationContext&, const uint8_t*, size_t, const Signature&, Vector<UnlinkedWasmToWasmCall>&, const ModuleInformation&, MemoryMode, CompilationMode, uint32_t functionIndex, TierUpCount* = nullptr);
-
-std::unique_ptr<InternalFunction> createJSToWasmWrapper(CompilationContext&, const Signature&, Vector<UnlinkedWasmToWasmCall>*, const ModuleInformation&, MemoryMode, uint32_t functionIndex);
+Expected<std::unique_ptr<InternalFunction>, String> parseAndCompile(CompilationContext&, const uint8_t*, size_t, const Signature&, Vector<UnlinkedWasmToWasmCall>&, const ModuleInformation&, MemoryMode, CompilationMode, uint32_t functionIndex, TierUpCount* = nullptr, ThrowWasmException = nullptr);
 
 } } // namespace JSC::Wasm
 
index 22edd16..d0eafa1 100644 (file)
@@ -29,8 +29,6 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "B3Compilation.h"
-#include "JSCInlines.h"
-#include "JSGlobalObject.h"
 #include "WasmB3IRGenerator.h"
 #include "WasmBinding.h"
 #include "WasmCallee.h"
@@ -53,21 +51,21 @@ namespace WasmBBQPlanInternal {
 static const bool verbose = false;
 }
 
-BBQPlan::BBQPlan(VM* vm, Ref<ModuleInformation> info, AsyncWork work, CompletionTask&& task)
-    : Base(vm, WTFMove(info), WTFMove(task))
+BBQPlan::BBQPlan(Context* context, Ref<ModuleInformation> info, AsyncWork work, CompletionTask&& task, CreateEmbedderWrapper&& createEmbedderWrapper, ThrowWasmException throwWasmException)
+    : Base(context, WTFMove(info), WTFMove(task), WTFMove(createEmbedderWrapper), throwWasmException)
     , m_state(State::Validated)
     , m_asyncWork(work)
 {
 }
 
-BBQPlan::BBQPlan(VM* vm, Vector<uint8_t>&& source, AsyncWork work, CompletionTask&& task)
-    : BBQPlan(vm, adoptRef(*new ModuleInformation(WTFMove(source))), work, WTFMove(task))
+BBQPlan::BBQPlan(Context* context, Vector<uint8_t>&& source, AsyncWork work, CompletionTask&& task, CreateEmbedderWrapper&& createEmbedderWrapper, ThrowWasmException throwWasmException)
+    : BBQPlan(context, adoptRef(*new ModuleInformation(WTFMove(source))), work, WTFMove(task), WTFMove(createEmbedderWrapper), throwWasmException)
 {
     m_state = State::Initial;
 }
 
-BBQPlan::BBQPlan(VM* vm, const uint8_t* source, size_t sourceLength, AsyncWork work, CompletionTask&& task)
-    : Base(vm, source, sourceLength, WTFMove(task))
+BBQPlan::BBQPlan(Context* context, const uint8_t* source, size_t sourceLength, AsyncWork work, CompletionTask&& task)
+    : Base(context, source, sourceLength, WTFMove(task))
     , m_state(State::Initial)
     , m_asyncWork(work)
 {
@@ -269,7 +267,7 @@ void BBQPlan::compileFunctions(CompilationEffort effort)
 
         m_unlinkedWasmToWasmCalls[functionIndex] = Vector<UnlinkedWasmToWasmCall>();
         TierUpCount* tierUp = Options::useBBQTierUpChecks() ? &m_tierUpCounts[functionIndex] : nullptr;
-        auto parseAndCompileResult = parseAndCompile(m_compilationContexts[functionIndex], functionStart, functionLength, signature, m_unlinkedWasmToWasmCalls[functionIndex], m_moduleInformation.get(), m_mode, CompilationMode::BBQMode, functionIndex, tierUp);
+        auto parseAndCompileResult = parseAndCompile(m_compilationContexts[functionIndex], functionStart, functionLength, signature, m_unlinkedWasmToWasmCalls[functionIndex], m_moduleInformation.get(), m_mode, CompilationMode::BBQMode, functionIndex, tierUp, m_throwWasmException);
 
         if (UNLIKELY(!parseAndCompileResult)) {
             auto locker = holdLock(m_lock);
@@ -285,7 +283,7 @@ void BBQPlan::compileFunctions(CompilationEffort effort)
 
         if (m_exportedFunctionIndices.contains(functionIndex)) {
             auto locker = holdLock(m_lock);
-            auto result = m_jsToWasmInternalFunctions.add(functionIndex, createJSToWasmWrapper(m_compilationContexts[functionIndex], signature, &m_unlinkedWasmToWasmCalls[functionIndex], m_moduleInformation.get(), m_mode, functionIndex));
+            auto result = m_embedderToWasmInternalFunctions.add(functionIndex, m_createEmbedderWrapper(m_compilationContexts[functionIndex], signature, &m_unlinkedWasmToWasmCalls[functionIndex], m_moduleInformation.get(), m_mode, functionIndex));
             ASSERT_UNUSED(result, result.isNewEntry);
         }
 
@@ -314,14 +312,14 @@ void BBQPlan::complete(const AbstractLocker& locker)
                     WTFMove(context.wasmEntrypointByproducts));
             }
 
-            if (auto jsToWasmInternalFunction = m_jsToWasmInternalFunctions.get(functionIndex)) {
+            if (auto embedderToWasmInternalFunction = m_embedderToWasmInternalFunctions.get(functionIndex)) {
                 LinkBuffer linkBuffer(*context.jsEntrypointJIT, nullptr, JITCompilationCanFail);
                 if (UNLIKELY(linkBuffer.didFailToAllocate())) {
                     Base::fail(locker, makeString("Out of executable memory in function entrypoint at index ", String::number(functionIndex)));
                     return;
                 }
 
-                jsToWasmInternalFunction->entrypoint.compilation = std::make_unique<B3::Compilation>(
+                embedderToWasmInternalFunction->entrypoint.compilation = std::make_unique<B3::Compilation>(
                     FINALIZE_CODE(linkBuffer, ("JavaScript->WebAssembly entrypoint[%i] %s", functionIndex, SignatureInformation::get(signatureIndex).toString().ascii().data())),
                     WTFMove(context.jsEntrypointByproducts));
             }
index 359f13b..c6ea497 100644 (file)
 #if ENABLE(WEBASSEMBLY)
 
 #include "CompilationResult.h"
-#include "VM.h"
 #include "WasmB3IRGenerator.h"
 #include "WasmModuleInformation.h"
 #include "WasmPlan.h"
 #include "WasmTierUpCount.h"
 #include <wtf/Bag.h>
+#include <wtf/Function.h>
 #include <wtf/SharedTask.h>
 #include <wtf/ThreadSafeRefCounted.h>
 #include <wtf/Vector.h>
@@ -41,8 +41,6 @@
 namespace JSC {
 
 class CallLinkInfo;
-class JSGlobalObject;
-class JSPromiseDeferred;
 
 namespace Wasm {
 
@@ -50,12 +48,13 @@ class BBQPlan final : public Plan {
 public:
     using Base = Plan;
     enum AsyncWork : uint8_t { FullCompile, Validation };
+
     // Note: CompletionTask should not hold a reference to the Plan otherwise there will be a reference cycle.
-    BBQPlan(VM*, Ref<ModuleInformation>, AsyncWork, CompletionTask&&);
-    JS_EXPORT_PRIVATE BBQPlan(VM*, Vector<uint8_t>&&, AsyncWork, CompletionTask&&);
+    BBQPlan(Context*, Ref<ModuleInformation>, AsyncWork, CompletionTask&&, CreateEmbedderWrapper&&, ThrowWasmException);
+    JS_EXPORT_PRIVATE BBQPlan(Context*, Vector<uint8_t>&&, AsyncWork, CompletionTask&&, CreateEmbedderWrapper&&, ThrowWasmException);
     // Note: This constructor should only be used if you are not actually building a module e.g. validation/function tests
     // FIXME: When we get rid of function tests we should remove AsyncWork from this constructor.
-    JS_EXPORT_PRIVATE BBQPlan(VM*, const uint8_t*, size_t, AsyncWork, CompletionTask&&);
+    JS_EXPORT_PRIVATE BBQPlan(Context*, const uint8_t*, size_t, AsyncWork, CompletionTask&&);
 
     bool parseAndValidateModule();
 
@@ -141,7 +140,7 @@ private:
     Vector<MacroAssemblerCodeRef> m_wasmToWasmExitStubs;
     Vector<std::unique_ptr<InternalFunction>> m_wasmInternalFunctions;
     HashSet<uint32_t, typename DefaultHash<uint32_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>> m_exportedFunctionIndices;
-    HashMap<uint32_t, std::unique_ptr<InternalFunction>, typename DefaultHash<uint32_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>> m_jsToWasmInternalFunctions;
+    HashMap<uint32_t, std::unique_ptr<InternalFunction>, typename DefaultHash<uint32_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>> m_embedderToWasmInternalFunctions;
     Vector<CompilationContext> m_compilationContexts;
     Vector<TierUpCount> m_tierUpCounts;
 
index 1b8b56f..444790b 100644 (file)
@@ -39,10 +39,10 @@ void BBQPlan::initializeCallees(const Functor& callback)
     ASSERT(!failed());
     for (unsigned internalFunctionIndex = 0; internalFunctionIndex < m_wasmInternalFunctions.size(); ++internalFunctionIndex) {
 
-        RefPtr<Wasm::Callee> jsEntrypointCallee;
-        if (auto jsToWasmFunction = m_jsToWasmInternalFunctions.get(internalFunctionIndex)) {
-            jsEntrypointCallee = Wasm::Callee::create(WTFMove(jsToWasmFunction->entrypoint));
-            MacroAssembler::repatchPointer(jsToWasmFunction->calleeMoveLocation, CalleeBits::boxWasm(jsEntrypointCallee.get()));
+        RefPtr<Wasm::Callee> embedderEntrypointCallee;
+        if (auto embedderToWasmFunction = m_embedderToWasmInternalFunctions.get(internalFunctionIndex)) {
+            embedderEntrypointCallee = Wasm::Callee::create(WTFMove(embedderToWasmFunction->entrypoint));
+            MacroAssembler::repatchPointer(embedderToWasmFunction->calleeMoveLocation, CalleeBits::boxWasm(embedderEntrypointCallee.get()));
         }
 
         InternalFunction* function = m_wasmInternalFunctions[internalFunctionIndex].get();
@@ -50,7 +50,7 @@ void BBQPlan::initializeCallees(const Functor& callback)
         Ref<Wasm::Callee> wasmEntrypointCallee = Wasm::Callee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection.get(functionIndexSpace));
         MacroAssembler::repatchPointer(function->calleeMoveLocation, CalleeBits::boxWasm(wasmEntrypointCallee.ptr()));
 
-        callback(internalFunctionIndex, WTFMove(jsEntrypointCallee), WTFMove(wasmEntrypointCallee));
+        callback(internalFunctionIndex, WTFMove(embedderEntrypointCallee), WTFMove(wasmEntrypointCallee));
     }
 }
 
index 67ccf5e..4910c83 100644 (file)
 #if ENABLE(WEBASSEMBLY)
 
 #include "CCallHelpers.h"
-#include "FrameTracers.h"
-#include "JITExceptions.h"
 #include "JSCInlines.h"
 #include "JSWebAssemblyInstance.h"
 #include "LinkBuffer.h"
-#include "NativeErrorConstructor.h"
-#include "ThunkGenerators.h"
-#include "WasmCallingConvention.h"
-#include "WasmContext.h"
-#include "WasmExceptionType.h"
 
 namespace JSC { namespace Wasm {
 
 using JIT = CCallHelpers;
 
-static void materializeImportJSCell(JIT& jit, unsigned importIndex, GPRReg result)
-{
-    // We're calling out of the current WebAssembly.Instance. That Instance has a list of all its import functions.
-    jit.loadWasmContext(result);
-    jit.loadPtr(JIT::Address(result, JSWebAssemblyInstance::offsetOfImportFunction(importIndex)), result);
-}
-
-Expected<MacroAssemblerCodeRef, BindingFailure> wasmToJs(VM* vm, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex)
-{
-    // FIXME: This function doesn't properly abstract away the calling convention.
-    // It'd be super easy to do so: https://bugs.webkit.org/show_bug.cgi?id=169401
-    const WasmCallingConvention& wasmCC = wasmCallingConvention();
-    const JSCCallingConvention& jsCC = jscCallingConvention();
-    const Signature& signature = SignatureInformation::get(signatureIndex);
-    unsigned argCount = signature.argumentCount();
-    JIT jit;
-
-    // Note: WasmB3IRGenerator assumes that this stub treats SP as a callee save.
-    // If we ever change this, we will also need to change WasmB3IRGenerator.
-
-    // Below, we assume that the JS calling convention is always on the stack.
-    ASSERT(!jsCC.m_gprArgs.size());
-    ASSERT(!jsCC.m_fprArgs.size());
-
-    jit.emitFunctionPrologue();
-    jit.store64(JIT::TrustedImm32(0), JIT::Address(GPRInfo::callFrameRegister, CallFrameSlot::codeBlock * static_cast<int>(sizeof(Register)))); // FIXME Stop using 0 as codeBlocks. https://bugs.webkit.org/show_bug.cgi?id=165321
-
-    {
-        bool hasBadI64Use = false;
-        hasBadI64Use |= signature.returnType() == I64;
-        for (unsigned argNum = 0; argNum < argCount && !hasBadI64Use; ++argNum) {
-            Type argType = signature.argument(argNum);
-            switch (argType) {
-            case Void:
-            case Func:
-            case Anyfunc:
-                RELEASE_ASSERT_NOT_REACHED();
-
-            case I64: {
-                hasBadI64Use = true;
-                break;
-            }
-
-            default:
-                break;
-            }
-        }
-
-        if (hasBadI64Use) {
-            jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm);
-            jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
-            jit.loadWasmContext(GPRInfo::argumentGPR1);
-
-            // Store Callee.
-            jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR1, JSWebAssemblyInstance::offsetOfCallee()), GPRInfo::argumentGPR2);
-            jit.storePtr(GPRInfo::argumentGPR2, JIT::Address(GPRInfo::callFrameRegister, CallFrameSlot::callee * static_cast<int>(sizeof(Register))));
-
-            auto call = jit.call();
-            jit.jumpToExceptionHandler(*vm);
-
-            void (*throwBadI64)(ExecState*, JSWebAssemblyInstance*) = [] (ExecState* exec, JSWebAssemblyInstance* wasmContext) -> void {
-                VM* vm = &exec->vm();
-                NativeCallFrameTracer tracer(vm, exec);
-
-                {
-                    auto throwScope = DECLARE_THROW_SCOPE(*vm);
-                    JSGlobalObject* globalObject = wasmContext->globalObject();
-                    auto* error = ErrorInstance::create(exec, *vm, globalObject->typeErrorConstructor()->errorStructure(), ASCIILiteral("i64 not allowed as return type or argument to an imported function"));
-                    throwException(exec, throwScope, error);
-                }
-
-                genericUnwind(vm, exec);
-                ASSERT(!!vm->callFrameForCatch);
-            };
-
-            LinkBuffer linkBuffer(jit, GLOBAL_THUNK_ID, JITCompilationCanFail);
-            if (UNLIKELY(linkBuffer.didFailToAllocate()))
-                return makeUnexpected(BindingFailure::OutOfMemory);
-
-            linkBuffer.link(call, throwBadI64);
-            return FINALIZE_CODE(linkBuffer, ("WebAssembly->JavaScript invalid i64 use in import[%i]", importIndex));
-        }
-    }
-
-    // Here we assume that the JS calling convention saves at least all the wasm callee saved. We therefore don't need to save and restore more registers since the wasm callee already took care of this.
-    RegisterSet missingCalleeSaves = wasmCC.m_calleeSaveRegisters;
-    missingCalleeSaves.exclude(jsCC.m_calleeSaveRegisters);
-    ASSERT(missingCalleeSaves.isEmpty());
-
-    if (!Options::useCallICsForWebAssemblyToJSCalls()) {
-        ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(argCount * sizeof(uint64_t));
-        char* buffer = argCount ? static_cast<char*>(scratchBuffer->dataBuffer()) : nullptr;
-        unsigned marshalledGPRs = 0;
-        unsigned marshalledFPRs = 0;
-        unsigned bufferOffset = 0;
-        unsigned frOffset = CallFrame::headerSizeInRegisters * static_cast<int>(sizeof(Register));
-        const GPRReg scratchGPR = GPRInfo::regCS0;
-        jit.subPtr(MacroAssembler::TrustedImm32(WTF::roundUpToMultipleOf(stackAlignmentBytes(), sizeof(Register))), MacroAssembler::stackPointerRegister);
-        jit.storePtr(scratchGPR, MacroAssembler::Address(MacroAssembler::stackPointerRegister));
-
-        for (unsigned argNum = 0; argNum < argCount; ++argNum) {
-            Type argType = signature.argument(argNum);
-            switch (argType) {
-            case Void:
-            case Func:
-            case Anyfunc:
-            case I64:
-                RELEASE_ASSERT_NOT_REACHED();
-            case I32: {
-                GPRReg gprReg;
-                if (marshalledGPRs < wasmCC.m_gprArgs.size())
-                    gprReg = wasmCC.m_gprArgs[marshalledGPRs].gpr();
-                else {
-                    // We've already spilled all arguments, these registers are available as scratch.
-                    gprReg = GPRInfo::argumentGPR0;
-                    jit.load64(JIT::Address(GPRInfo::callFrameRegister, frOffset), gprReg);
-                    frOffset += sizeof(Register);
-                }
-                jit.zeroExtend32ToPtr(gprReg, gprReg);
-                jit.store64(gprReg, buffer + bufferOffset);
-                ++marshalledGPRs;
-                break;
-            }
-            case F32: {
-                FPRReg fprReg;
-                if (marshalledFPRs < wasmCC.m_fprArgs.size())
-                    fprReg = wasmCC.m_fprArgs[marshalledFPRs].fpr();
-                else {
-                    // We've already spilled all arguments, these registers are available as scratch.
-                    fprReg = FPRInfo::argumentFPR0;
-                    jit.loadFloat(JIT::Address(GPRInfo::callFrameRegister, frOffset), fprReg);
-                    frOffset += sizeof(Register);
-                }
-                jit.convertFloatToDouble(fprReg, fprReg);
-                jit.moveDoubleTo64(fprReg, scratchGPR);
-                jit.store64(scratchGPR, buffer + bufferOffset);
-                ++marshalledFPRs;
-                break;
-            }
-            case F64: {
-                FPRReg fprReg;
-                if (marshalledFPRs < wasmCC.m_fprArgs.size())
-                    fprReg = wasmCC.m_fprArgs[marshalledFPRs].fpr();
-                else {
-                    // We've already spilled all arguments, these registers are available as scratch.
-                    fprReg = FPRInfo::argumentFPR0;
-                    jit.loadDouble(JIT::Address(GPRInfo::callFrameRegister, frOffset), fprReg);
-                    frOffset += sizeof(Register);
-                }
-                jit.moveDoubleTo64(fprReg, scratchGPR);
-                jit.store64(scratchGPR, buffer + bufferOffset);
-                ++marshalledFPRs;
-                break;
-            }
-            }
-
-            bufferOffset += sizeof(Register);
-        }
-        jit.loadPtr(MacroAssembler::Address(MacroAssembler::stackPointerRegister), scratchGPR);
-        if (argCount) {
-            // The GC should not look at this buffer at all, these aren't JSValues.
-            jit.move(CCallHelpers::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::argumentGPR0);
-            jit.storePtr(CCallHelpers::TrustedImmPtr(0), GPRInfo::argumentGPR0);
-        }
-
-        uint64_t (*callFunc)(ExecState*, JSObject*, SignatureIndex, uint64_t*) =
-            [] (ExecState* exec, JSObject* callee, SignatureIndex signatureIndex, uint64_t* buffer) -> uint64_t { 
-                VM* vm = &exec->vm();
-                NativeCallFrameTracer tracer(vm, exec);
-                auto throwScope = DECLARE_THROW_SCOPE(*vm);
-                const Signature& signature = SignatureInformation::get(signatureIndex);
-                MarkedArgumentBuffer args;
-                for (unsigned argNum = 0; argNum < signature.argumentCount(); ++argNum) {
-                    Type argType = signature.argument(argNum);
-                    JSValue arg;
-                    switch (argType) {
-                    case Void:
-                    case Func:
-                    case Anyfunc:
-                    case I64:
-                        RELEASE_ASSERT_NOT_REACHED();
-                    case I32:
-                        arg = jsNumber(static_cast<int32_t>(buffer[argNum]));
-                        break;
-                    case F32:
-                    case F64:
-                        arg = jsNumber(bitwise_cast<double>(buffer[argNum]));
-                        break;
-                    }
-                    args.append(arg);
-                }
-
-                CallData callData;
-                CallType callType = callee->methodTable(*vm)->getCallData(callee, callData);
-                RELEASE_ASSERT(callType != CallType::None);
-                JSValue result = call(exec, callee, callType, callData, jsUndefined(), args);
-                RETURN_IF_EXCEPTION(throwScope, 0);
-
-                uint64_t realResult;
-                switch (signature.returnType()) {
-                case Func:
-                case Anyfunc:
-                case I64:
-                    RELEASE_ASSERT_NOT_REACHED();
-                    break;
-                case Void:
-                    break;
-                case I32: {
-                    realResult = static_cast<uint64_t>(static_cast<uint32_t>(result.toInt32(exec)));
-                    break;
-                }
-                case F64:
-                case F32: {
-                    realResult = bitwise_cast<uint64_t>(result.toNumber(exec));
-                    break;
-                }
-                }
-
-                RETURN_IF_EXCEPTION(throwScope, 0);
-                return realResult;
-            };
-        
-        jit.loadWasmContext(GPRInfo::argumentGPR0);
-        jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, JSWebAssemblyInstance::offsetOfCallee()), GPRInfo::argumentGPR0);
-        jit.storePtr(GPRInfo::argumentGPR0, JIT::Address(GPRInfo::callFrameRegister, CallFrameSlot::callee * static_cast<int>(sizeof(Register))));
-        
-        materializeImportJSCell(jit, importIndex, GPRInfo::argumentGPR1);
-        static_assert(GPRInfo::numberOfArgumentRegisters >= 4, "We rely on this with the call below.");
-        jit.setupArgumentsWithExecState(GPRInfo::argumentGPR1, CCallHelpers::TrustedImm32(signatureIndex), CCallHelpers::TrustedImmPtr(buffer));
-        auto call = jit.call();
-        auto noException = jit.emitExceptionCheck(*vm, AssemblyHelpers::InvertedExceptionCheck);
-
-        // exception here.
-        jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm);
-        jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
-        void (*doUnwinding)(ExecState*) = [] (ExecState* exec) -> void {
-            VM* vm = &exec->vm();
-            NativeCallFrameTracer tracer(vm, exec);
-            genericUnwind(vm, exec);
-            ASSERT(!!vm->callFrameForCatch);
-        };
-        auto exceptionCall = jit.call();
-        jit.jumpToExceptionHandler(*vm);
-
-        noException.link(&jit);
-        switch (signature.returnType()) {
-        case F64: {
-            jit.move64ToDouble(GPRInfo::returnValueGPR, FPRInfo::returnValueFPR);
-            break;
-        }
-        case F32: {
-            jit.move64ToDouble(GPRInfo::returnValueGPR, FPRInfo::returnValueFPR);
-            jit.convertDoubleToFloat(FPRInfo::returnValueFPR, FPRInfo::returnValueFPR);
-            break;
-        }
-        default:
-            break;
-        }
-
-        jit.emitFunctionEpilogue();
-        jit.ret();
-
-        LinkBuffer linkBuffer(jit, GLOBAL_THUNK_ID, JITCompilationCanFail);
-        if (UNLIKELY(linkBuffer.didFailToAllocate()))
-            return makeUnexpected(BindingFailure::OutOfMemory);
-
-        linkBuffer.link(call, callFunc);
-        linkBuffer.link(exceptionCall, doUnwinding);
-
-        return FINALIZE_CODE(linkBuffer, ("WebAssembly->JavaScript import[%i] %s", importIndex, signature.toString().ascii().data()));
-    }
-
-    // Note: We don't need to perform a stack check here since WasmB3IRGenerator
-    // will do the stack check for us. Whenever it detects that it might make
-    // a call to this thunk, it'll make sure its stack check includes space
-    // for us here.
-
-    const unsigned numberOfParameters = argCount + 1; // There is a "this" argument.
-    const unsigned numberOfRegsForCall = CallFrame::headerSizeInRegisters + numberOfParameters;
-    const unsigned numberOfBytesForCall = numberOfRegsForCall * sizeof(Register) - sizeof(CallerFrameAndPC);
-    const unsigned stackOffset = WTF::roundUpToMultipleOf(stackAlignmentBytes(), numberOfBytesForCall);
-    jit.subPtr(MacroAssembler::TrustedImm32(stackOffset), MacroAssembler::stackPointerRegister);
-    JIT::Address calleeFrame = CCallHelpers::Address(MacroAssembler::stackPointerRegister, -static_cast<ptrdiff_t>(sizeof(CallerFrameAndPC)));
-
-    // FIXME make these loops which switch on Signature if there are many arguments on the stack. It'll otherwise be huge for huge signatures. https://bugs.webkit.org/show_bug.cgi?id=165547
-    
-    // First go through the integer parameters, freeing up their register for use afterwards.
-    {
-        unsigned marshalledGPRs = 0;
-        unsigned marshalledFPRs = 0;
-        unsigned calleeFrameOffset = CallFrameSlot::firstArgument * static_cast<int>(sizeof(Register));
-        unsigned frOffset = CallFrame::headerSizeInRegisters * static_cast<int>(sizeof(Register));
-        for (unsigned argNum = 0; argNum < argCount; ++argNum) {
-            Type argType = signature.argument(argNum);
-            switch (argType) {
-            case Void:
-            case Func:
-            case Anyfunc:
-            case I64:
-                RELEASE_ASSERT_NOT_REACHED(); // Handled above.
-            case I32: {
-                GPRReg gprReg;
-                if (marshalledGPRs < wasmCC.m_gprArgs.size())
-                    gprReg = wasmCC.m_gprArgs[marshalledGPRs].gpr();
-                else {
-                    // We've already spilled all arguments, these registers are available as scratch.
-                    gprReg = GPRInfo::argumentGPR0;
-                    jit.load64(JIT::Address(GPRInfo::callFrameRegister, frOffset), gprReg);
-                    frOffset += sizeof(Register);
-                }
-                ++marshalledGPRs;
-                jit.zeroExtend32ToPtr(gprReg, gprReg); // Clear non-int32 and non-tag bits.
-                jit.boxInt32(gprReg, JSValueRegs(gprReg), DoNotHaveTagRegisters);
-                jit.store64(gprReg, calleeFrame.withOffset(calleeFrameOffset));
-                calleeFrameOffset += sizeof(Register);
-                break;
-            }
-            case F32:
-            case F64:
-                // Skipped: handled below.
-                if (marshalledFPRs >= wasmCC.m_fprArgs.size())
-                    frOffset += sizeof(Register);
-                ++marshalledFPRs;
-                calleeFrameOffset += sizeof(Register);
-                break;
-            }
-        }
-    }
-    
-    {
-        // Integer registers have already been spilled, these are now available.
-        GPRReg doubleEncodeOffsetGPRReg = GPRInfo::argumentGPR0;
-        GPRReg scratch = GPRInfo::argumentGPR1;
-        bool hasMaterializedDoubleEncodeOffset = false;
-        auto materializeDoubleEncodeOffset = [&hasMaterializedDoubleEncodeOffset, &jit] (GPRReg dest) {
-            if (!hasMaterializedDoubleEncodeOffset) {
-                static_assert(DoubleEncodeOffset == 1ll << 48, "codegen assumes this below");
-                jit.move(JIT::TrustedImm32(1), dest);
-                jit.lshift64(JIT::TrustedImm32(48), dest);
-                hasMaterializedDoubleEncodeOffset = true;
-            }
-        };
-
-        unsigned marshalledGPRs = 0;
-        unsigned marshalledFPRs = 0;
-        unsigned calleeFrameOffset = CallFrameSlot::firstArgument * static_cast<int>(sizeof(Register));
-        unsigned frOffset = CallFrame::headerSizeInRegisters * static_cast<int>(sizeof(Register));
-        for (unsigned argNum = 0; argNum < argCount; ++argNum) {
-            Type argType = signature.argument(argNum);
-            switch (argType) {
-            case Void:
-            case Func:
-            case Anyfunc:
-            case I64:
-                RELEASE_ASSERT_NOT_REACHED(); // Handled above.
-            case I32:
-                // Skipped: handled above.
-                if (marshalledGPRs >= wasmCC.m_gprArgs.size())
-                    frOffset += sizeof(Register);
-                ++marshalledGPRs;
-                calleeFrameOffset += sizeof(Register);
-                break;
-            case F32: {
-                FPRReg fprReg;
-                if (marshalledFPRs < wasmCC.m_fprArgs.size())
-                    fprReg = wasmCC.m_fprArgs[marshalledFPRs].fpr();
-                else {
-                    // We've already spilled all arguments, these registers are available as scratch.
-                    fprReg = FPRInfo::argumentFPR0;
-                    jit.loadFloat(JIT::Address(GPRInfo::callFrameRegister, frOffset), fprReg);
-                    frOffset += sizeof(Register);
-                }
-                jit.convertFloatToDouble(fprReg, fprReg);
-                jit.purifyNaN(fprReg);
-                jit.moveDoubleTo64(fprReg, scratch);
-                materializeDoubleEncodeOffset(doubleEncodeOffsetGPRReg);
-                jit.add64(doubleEncodeOffsetGPRReg, scratch);
-                jit.store64(scratch, calleeFrame.withOffset(calleeFrameOffset));
-                calleeFrameOffset += sizeof(Register);
-                ++marshalledFPRs;
-                break;
-            }
-            case F64: {
-                FPRReg fprReg;
-                if (marshalledFPRs < wasmCC.m_fprArgs.size())
-                    fprReg = wasmCC.m_fprArgs[marshalledFPRs].fpr();
-                else {
-                    // We've already spilled all arguments, these registers are available as scratch.
-                    fprReg = FPRInfo::argumentFPR0;
-                    jit.loadDouble(JIT::Address(GPRInfo::callFrameRegister, frOffset), fprReg);
-                    frOffset += sizeof(Register);
-                }
-                jit.purifyNaN(fprReg);
-                jit.moveDoubleTo64(fprReg, scratch);
-                materializeDoubleEncodeOffset(doubleEncodeOffsetGPRReg);
-                jit.add64(doubleEncodeOffsetGPRReg, scratch);
-                jit.store64(scratch, calleeFrame.withOffset(calleeFrameOffset));
-                calleeFrameOffset += sizeof(Register);
-                ++marshalledFPRs;
-                break;
-            }
-            }
-        }
-    }
-
-    jit.loadWasmContext(GPRInfo::argumentGPR0);
-    jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, JSWebAssemblyInstance::offsetOfCallee()), GPRInfo::argumentGPR0);
-    jit.storePtr(GPRInfo::argumentGPR0, JIT::Address(GPRInfo::callFrameRegister, CallFrameSlot::callee * static_cast<int>(sizeof(Register))));
-
-    GPRReg importJSCellGPRReg = GPRInfo::regT0; // Callee needs to be in regT0 for slow path below.
-    ASSERT(!wasmCC.m_calleeSaveRegisters.get(importJSCellGPRReg));
-
-    materializeImportJSCell(jit, importIndex, importJSCellGPRReg);
-
-    jit.store64(importJSCellGPRReg, calleeFrame.withOffset(CallFrameSlot::callee * static_cast<int>(sizeof(Register))));
-    jit.store32(JIT::TrustedImm32(numberOfParameters), calleeFrame.withOffset(CallFrameSlot::argumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset));
-    jit.store64(JIT::TrustedImm64(ValueUndefined), calleeFrame.withOffset(CallFrameSlot::thisArgument * static_cast<int>(sizeof(Register))));
-
-    // FIXME Tail call if the wasm return type is void and no registers were spilled. https://bugs.webkit.org/show_bug.cgi?id=165488
-
-    CallLinkInfo* callLinkInfo = callLinkInfos.add();
-    callLinkInfo->setUpCall(CallLinkInfo::Call, CodeOrigin(), importJSCellGPRReg);
-    JIT::DataLabelPtr targetToCheck;
-    JIT::TrustedImmPtr initialRightValue(0);
-    JIT::Jump slowPath = jit.branchPtrWithPatch(MacroAssembler::NotEqual, importJSCellGPRReg, targetToCheck, initialRightValue);
-    JIT::Call fastCall = jit.nearCall();
-    JIT::Jump done = jit.jump();
-    slowPath.link(&jit);
-    // Callee needs to be in regT0 here.
-    jit.move(MacroAssembler::TrustedImmPtr(callLinkInfo), GPRInfo::regT2); // Link info needs to be in regT2.
-    JIT::Call slowCall = jit.nearCall();
-    done.link(&jit);
-
-    CCallHelpers::JumpList exceptionChecks;
-
-    switch (signature.returnType()) {
-    case Void:
-        // Discard.
-        break;
-    case Func:
-    case Anyfunc:
-        // For the JavaScript embedding, imports with these types in their signature return are a WebAssembly.Module validation error.
-        RELEASE_ASSERT_NOT_REACHED();
-        break;
-    case I64: {
-        RELEASE_ASSERT_NOT_REACHED(); // Handled above.
-    }
-    case I32: {
-        CCallHelpers::JumpList done;
-        CCallHelpers::JumpList slowPath;
-
-        slowPath.append(jit.branchIfNotNumber(GPRInfo::returnValueGPR, DoNotHaveTagRegisters));
-        slowPath.append(jit.branchIfNotInt32(JSValueRegs(GPRInfo::returnValueGPR), DoNotHaveTagRegisters));
-        jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, GPRInfo::returnValueGPR);
-        done.append(jit.jump());
-
-        slowPath.link(&jit);
-        jit.setupArgumentsWithExecState(GPRInfo::returnValueGPR);
-        auto call = jit.call();
-        exceptionChecks.append(jit.emitJumpIfException(*vm));
-
-        int32_t (*convertToI32)(ExecState*, JSValue) = [] (ExecState* exec, JSValue v) -> int32_t { 
-            VM* vm = &exec->vm();
-            NativeCallFrameTracer tracer(vm, exec);
-            return v.toInt32(exec);
-        };
-        jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
-            linkBuffer.link(call, convertToI32);
-        });
-
-        done.link(&jit);
-        break;
-    }
-    case F32: {
-        CCallHelpers::JumpList done;
-        auto notANumber = jit.branchIfNotNumber(GPRInfo::returnValueGPR, DoNotHaveTagRegisters);
-        auto isDouble = jit.branchIfNotInt32(JSValueRegs(GPRInfo::returnValueGPR), DoNotHaveTagRegisters);
-        // We're an int32
-        jit.signExtend32ToPtr(GPRInfo::returnValueGPR, GPRInfo::returnValueGPR);
-        jit.convertInt64ToFloat(GPRInfo::returnValueGPR, FPRInfo::returnValueFPR);
-        done.append(jit.jump());
-
-        isDouble.link(&jit);
-        jit.move(JIT::TrustedImm64(TagTypeNumber), GPRInfo::returnValueGPR2);
-        jit.add64(GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
-        jit.move64ToDouble(GPRInfo::returnValueGPR, FPRInfo::returnValueFPR);
-        jit.convertDoubleToFloat(FPRInfo::returnValueFPR, FPRInfo::returnValueFPR);
-        done.append(jit.jump());
-
-        notANumber.link(&jit);
-        jit.setupArgumentsWithExecState(GPRInfo::returnValueGPR);
-        auto call = jit.call();
-        exceptionChecks.append(jit.emitJumpIfException(*vm));
-
-        float (*convertToF32)(ExecState*, JSValue) = [] (ExecState* exec, JSValue v) -> float { 
-            VM* vm = &exec->vm();
-            NativeCallFrameTracer tracer(vm, exec);
-            return static_cast<float>(v.toNumber(exec));
-        };
-        jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
-            linkBuffer.link(call, convertToF32);
-        });
-
-        done.link(&jit);
-        break;
-    }
-    case F64: {
-        CCallHelpers::JumpList done;
-        auto notANumber = jit.branchIfNotNumber(GPRInfo::returnValueGPR, DoNotHaveTagRegisters);
-        auto isDouble = jit.branchIfNotInt32(JSValueRegs(GPRInfo::returnValueGPR), DoNotHaveTagRegisters);
-        // We're an int32
-        jit.signExtend32ToPtr(GPRInfo::returnValueGPR, GPRInfo::returnValueGPR);
-        jit.convertInt64ToDouble(GPRInfo::returnValueGPR, FPRInfo::returnValueFPR);
-        done.append(jit.jump());
-
-        isDouble.link(&jit);
-        jit.move(JIT::TrustedImm64(TagTypeNumber), GPRInfo::returnValueGPR2);
-        jit.add64(GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
-        jit.move64ToDouble(GPRInfo::returnValueGPR, FPRInfo::returnValueFPR);
-        done.append(jit.jump());
-
-        notANumber.link(&jit);
-        jit.setupArgumentsWithExecState(GPRInfo::returnValueGPR);
-        auto call = jit.call();
-        exceptionChecks.append(jit.emitJumpIfException(*vm));
-
-        double (*convertToF64)(ExecState*, JSValue) = [] (ExecState* exec, JSValue v) -> double { 
-            VM* vm = &exec->vm();
-            NativeCallFrameTracer tracer(vm, exec);
-            return v.toNumber(exec);
-        };
-        jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
-            linkBuffer.link(call, convertToF64);
-        });
-
-        done.link(&jit);
-        break;
-    }
-    }
-
-    jit.emitFunctionEpilogue();
-    jit.ret();
-
-    if (!exceptionChecks.empty()) {
-        exceptionChecks.link(&jit);
-        jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm);
-        jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
-        auto call = jit.call();
-        jit.jumpToExceptionHandler(*vm);
-
-        void (*doUnwinding)(ExecState*) = [] (ExecState* exec) -> void {
-            VM* vm = &exec->vm();
-            NativeCallFrameTracer tracer(vm, exec);
-            genericUnwind(vm, exec);
-            ASSERT(!!vm->callFrameForCatch);
-        };
-
-        jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
-            linkBuffer.link(call, doUnwinding);
-        });
-    }
-
-    LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, JITCompilationCanFail);
-    if (UNLIKELY(patchBuffer.didFailToAllocate()))
-        return makeUnexpected(BindingFailure::OutOfMemory);
-
-    patchBuffer.link(slowCall, FunctionPtr(vm->getCTIStub(linkCallThunkGenerator).code().executableAddress()));
-    CodeLocationLabel callReturnLocation(patchBuffer.locationOfNearCall(slowCall));
-    CodeLocationLabel hotPathBegin(patchBuffer.locationOf(targetToCheck));
-    CodeLocationNearCall hotPathOther = patchBuffer.locationOfNearCall(fastCall);
-    callLinkInfo->setCallLocations(callReturnLocation, hotPathBegin, hotPathOther);
-
-    return FINALIZE_CODE(patchBuffer, ("WebAssembly->JavaScript import[%i] %s", importIndex, signature.toString().ascii().data()));
-}
-
 Expected<MacroAssemblerCodeRef, BindingFailure> wasmToWasm(unsigned importIndex)
 {
     const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get();
@@ -633,24 +51,23 @@ Expected<MacroAssemblerCodeRef, BindingFailure> wasmToWasm(unsigned importIndex)
     ASSERT(sizeRegs[0].sizeRegister != scratch);
     GPRReg sizeRegAsScratch = sizeRegs[0].sizeRegister;
 
-    static_assert(std::is_same<Context, JSWebAssemblyInstance>::value, "This is assumed in the code below.");
     // B3's call codegen ensures that the JSCell is a WebAssemblyFunction.
-    jit.loadWasmContext(sizeRegAsScratch); // Old Instance*
-    jit.loadPtr(JIT::Address(sizeRegAsScratch, JSWebAssemblyInstance::offsetOfImportFunction(importIndex)), scratch);
-
-    // Get the callee's WebAssembly.Instance and set it as WasmContext. The caller will take care of restoring its own Instance.
-    jit.loadPtr(JIT::Address(scratch, WebAssemblyFunction::offsetOfInstance()), baseMemory); // Instance*.
-    jit.storeWasmContext(baseMemory);
+    jit.loadWasmContextInstance(sizeRegAsScratch); // Old Instance*
+    // Get the callee's WebAssembly.Instance and set it as WasmContext's instance. The caller will take care of restoring its own Instance.
+    jit.loadPtr(JIT::Address(sizeRegAsScratch, JSWebAssemblyInstance::offsetOfTargetInstance(importIndex)), baseMemory); // JSWebAssemblyInstance*.
+    // While we're accessing that cacheline, also get the wasm entrypoint so we can tail call to it below.
+    jit.loadPtr(JIT::Address(sizeRegAsScratch, JSWebAssemblyInstance::offsetOfWasmEntrypoint(importIndex)), scratch); // Wasm::WasmEntrypointLoadLocation.
+    jit.storeWasmContextInstance(baseMemory);
 
     jit.loadPtr(JIT::Address(sizeRegAsScratch, JSWebAssemblyInstance::offsetOfCachedStackLimit()), sizeRegAsScratch);
     jit.storePtr(sizeRegAsScratch, JIT::Address(baseMemory, JSWebAssemblyInstance::offsetOfCachedStackLimit()));
 
     // FIXME the following code assumes that all WebAssembly.Instance have the same pinned registers. https://bugs.webkit.org/show_bug.cgi?id=162952
     // Set up the callee's baseMemory register as well as the memory size registers.
-    jit.loadPtr(JIT::Address(baseMemory, JSWebAssemblyInstance::offsetOfMemory()), baseMemory); // JSWebAssemblyMemory*.
+    jit.loadPtr(JIT::Address(baseMemory, JSWebAssemblyInstance::offsetOfWasmMemory()), baseMemory); // Wasm::Memory*.
     ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0.
-    jit.loadPtr(JIT::Address(baseMemory, JSWebAssemblyMemory::offsetOfSize()), sizeRegs[0].sizeRegister); // Memory size.
-    jit.loadPtr(JIT::Address(baseMemory, JSWebAssemblyMemory::offsetOfMemory()), baseMemory); // WasmMemory::void*.
+    jit.loadPtr(JIT::Address(baseMemory, Wasm::Memory::offsetOfSize()), sizeRegs[0].sizeRegister); // Memory size.
+    jit.loadPtr(JIT::Address(baseMemory, Wasm::Memory::offsetOfMemory()), baseMemory); // Wasm::Memory::void*.
     for (unsigned i = 1; i < sizeRegs.size(); ++i) {
         ASSERT(sizeRegs[i].sizeRegister != baseMemory);
         ASSERT(sizeRegs[i].sizeRegister != scratch);
@@ -658,7 +75,6 @@ Expected<MacroAssemblerCodeRef, BindingFailure> wasmToWasm(unsigned importIndex)
     }
 
     // Tail call into the callee WebAssembly function.
-    jit.loadPtr(JIT::Address(scratch, WebAssemblyFunction::offsetOfWasmEntrypointLoadLocation()), scratch);
     jit.loadPtr(scratch, scratch);
     jit.jump(scratch);
 
index 4e262ba..fec6bd7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,9 +28,7 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "B3Compilation.h"
-#include "VM.h"
 #include "WasmFormat.h"
-#include <wtf/Bag.h>
 #include <wtf/Expected.h>
 
 namespace JSC {
@@ -44,7 +42,6 @@ enum class BindingFailure {
 };
 
 Expected<MacroAssemblerCodeRef, BindingFailure> wasmToWasm(unsigned importIndex);
-Expected<MacroAssemblerCodeRef, BindingFailure> wasmToJs(VM*, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex, unsigned importIndex);
 
 } } // namespace JSC::Wasm
 
index 70fefb0..e51367a 100644 (file)
 
 #include "WasmBBQPlanInlines.h"
 #include "WasmCallee.h"
+#include "WasmFormat.h"
 #include "WasmWorklist.h"
 
 namespace JSC { namespace Wasm {
 
-CodeBlock::CodeBlock(MemoryMode mode, ModuleInformation& moduleInformation)
+Ref<CodeBlock> CodeBlock::create(Context* context, MemoryMode mode, ModuleInformation& moduleInformation, CreateEmbedderWrapper&& createEmbedderWrapper, ThrowWasmException throwWasmException)
+{
+    size_t importFunctionCount = moduleInformation.importFunctionCount();
+    auto* result = new (NotNull, fastMalloc(allocationSize(importFunctionCount))) CodeBlock(context, mode, moduleInformation, WTFMove(createEmbedderWrapper), throwWasmException);
+    for (size_t i = 0; i < importFunctionCount; ++i)
+        result->importWasmToEmbedderStub(i) = nullptr;
+    return adoptRef(*result);
+}
+
+CodeBlock::CodeBlock(Context* context, MemoryMode mode, ModuleInformation& moduleInformation, CreateEmbedderWrapper&& createEmbedderWrapper, ThrowWasmException throwWasmException)
     : m_calleeCount(moduleInformation.internalFunctionCount())
     , m_mode(mode)
 {
     RefPtr<CodeBlock> protectedThis = this;
-    m_plan = adoptRef(*new BBQPlan(nullptr, makeRef(moduleInformation), BBQPlan::FullCompile, createSharedTask<Plan::CallbackType>([this, protectedThis = WTFMove(protectedThis)] (VM*, Plan&) {
+
+    m_plan = adoptRef(*new BBQPlan(context, makeRef(moduleInformation), BBQPlan::FullCompile, createSharedTask<Plan::CallbackType>([this, protectedThis = WTFMove(protectedThis)] (Plan&) {
         auto locker = holdLock(m_lock);
         if (m_plan->failed()) {
             m_errorMessage = m_plan->errorMessage();
-            m_plan = nullptr;
+            setCompilationFinished();
             return;
         }
 
@@ -66,10 +77,10 @@ CodeBlock::CodeBlock(MemoryMode mode, ModuleInformation& moduleInformation)
         m_wasmToWasmCallsites = m_plan->takeWasmToWasmCallsites();
         m_tierUpCounts = m_plan->takeTierUpCounts();
 
-        m_plan = nullptr;
-    })));
-
+        setCompilationFinished();
+    }), WTFMove(createEmbedderWrapper), throwWasmException));
     m_plan->setMode(mode);
+
     auto& worklist = Wasm::ensureWorklist();
     // Note, immediately after we enqueue the plan, there is a chance the above callback will be called.
     worklist.enqueue(makeRef(*m_plan.get()));
@@ -92,7 +103,7 @@ void CodeBlock::waitUntilFinished()
     // else, if we don't have a plan, we're already compiled.
 }
 
-void CodeBlock::compileAsync(VM& vm, AsyncCompilationCallback&& task)
+void CodeBlock::compileAsync(Context* context, AsyncCompilationCallback&& task)
 {
     RefPtr<Plan> plan;
     {
@@ -104,12 +115,11 @@ void CodeBlock::compileAsync(VM& vm, AsyncCompilationCallback&& task)
         // We don't need to keep a RefPtr on the Plan because the worklist will keep
         // a RefPtr on the Plan until the plan finishes notifying all of its callbacks.
         RefPtr<CodeBlock> protectedThis = this;
-        plan->addCompletionTask(vm, createSharedTask<Plan::CallbackType>([this, task = WTFMove(task), protectedThis = WTFMove(protectedThis)] (VM* vm, Plan&) {
-            ASSERT(vm);
-            task->run(*vm, makeRef(*this));
+        plan->addCompletionTask(context, createSharedTask<Plan::CallbackType>([this, task = WTFMove(task), protectedThis = WTFMove(protectedThis)] (Plan&) {
+            task->run(makeRef(*this));
         }));
     } else
-        task->run(vm, makeRef(*this));
+        task->run(makeRef(*this));
 }
 
 bool CodeBlock::isSafeToRun(MemoryMode memoryMode)
@@ -130,6 +140,13 @@ bool CodeBlock::isSafeToRun(MemoryMode memoryMode)
     return false;
 }
 
+
+void CodeBlock::setCompilationFinished()
+{
+    m_plan = nullptr;
+    m_compilationFinished.store(true);
+}
+
 } } // namespace JSC::Wasm
 
 #endif // ENABLE(WEBASSEMBLY)
index 2dbf7e4..b168aac 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "MacroAssemblerCodeRef.h"
+#include "WasmEmbedder.h"
 #include "WasmTierUpCount.h"
 #include <wtf/Lock.h>
 #include <wtf/RefPtr.h>
 
 namespace JSC {
 
-class VM;
-
 namespace Wasm {
 
 class Callee;
+struct Context;
 class BBQPlan;
 class OMGPlan;
 struct ModuleInformation;
@@ -51,20 +51,42 @@ enum class MemoryMode : uint8_t;
     
 class CodeBlock : public ThreadSafeRefCounted<CodeBlock> {
 public:
-    typedef void CallbackType(VM&, Ref<CodeBlock>&&);
+    typedef void CallbackType(Ref<CodeBlock>&&);
     using AsyncCompilationCallback = RefPtr<WTF::SharedTask<CallbackType>>;
-    static Ref<CodeBlock> create(MemoryMode mode, ModuleInformation& moduleInformation)
+    static Ref<CodeBlock> create(Context*, MemoryMode, ModuleInformation&, CreateEmbedderWrapper&&, ThrowWasmException);
+
+    static size_t offsetOfImportStubs()
+    {
+        return WTF::roundUpToMultipleOf<sizeof(void*)>(sizeof(CodeBlock));
+    }
+
+    static size_t allocationSize(Checked<size_t> functionImportCount)
+    {
+        return (offsetOfImportStubs() + sizeof(void*) * functionImportCount).unsafeGet();
+    }
+
+    void*& importWasmToEmbedderStub(unsigned importIndex)
     {
-        return adoptRef(*new CodeBlock(mode, moduleInformation));
+        return *bitwise_cast<void**>(bitwise_cast<char*>(this) + offsetOfImportWasmToEmbedderStub(importIndex));
+    }
+
+    static ptrdiff_t offsetOfImportWasmToEmbedderStub(unsigned importIndex)
+    {
+        return offsetOfImportStubs() + sizeof(void*) * importIndex;
+    }
+
+    Wasm::WasmEntrypointLoadLocation wasmToJSCallStubForImport(unsigned importIndex)
+    {
+        ASSERT(runnable());
+        return &importWasmToEmbedderStub(importIndex);
     }
 
     void waitUntilFinished();
-    void compileAsync(VM&, AsyncCompilationCallback&&);
+    void compileAsync(Context*, AsyncCompilationCallback&&);
 
     bool compilationFinished()
     {
-        auto locker = holdLock(m_lock);
-        return !m_plan;
+        return m_compilationFinished.load();
     }
     bool runnable() { return compilationFinished() && !m_errorMessage; }
 
@@ -79,8 +101,11 @@ public:
 
     unsigned functionImportCount() const { return m_wasmToWasmExitStubs.size(); }
 
+    // These two callee getters are only valid once the callees have been populated.
+
     Callee& jsEntrypointCalleeFromFunctionIndexSpace(unsigned functionIndexSpace)
     {
+        ASSERT(runnable());
         RELEASE_ASSERT(functionIndexSpace >= functionImportCount());
         unsigned calleeIndex = functionIndexSpace - functionImportCount();
 
@@ -90,6 +115,7 @@ public:
     }
     Callee& wasmEntrypointCalleeFromFunctionIndexSpace(unsigned functionIndexSpace)
     {
+        ASSERT(runnable());
         RELEASE_ASSERT(functionIndexSpace >= functionImportCount());
         unsigned calleeIndex = functionIndexSpace - functionImportCount();
         if (m_optimizedCallees[calleeIndex])
@@ -117,7 +143,8 @@ public:
 private:
     friend class OMGPlan;
 
-    CodeBlock(MemoryMode, ModuleInformation&);
+    CodeBlock(Context*, MemoryMode, ModuleInformation&, CreateEmbedderWrapper&&, ThrowWasmException);
+    void setCompilationFinished();
     unsigned m_calleeCount;
     MemoryMode m_mode;
     Vector<RefPtr<Callee>> m_callees;
@@ -128,6 +155,7 @@ private:
     Vector<Vector<UnlinkedWasmToWasmCall>> m_wasmToWasmCallsites;
     Vector<MacroAssemblerCodeRef> m_wasmToWasmExitStubs;
     RefPtr<BBQPlan> m_plan;
+    std::atomic<bool> m_compilationFinished { false };
     String m_errorMessage;
     Lock m_lock;
 };
index fea16de..e059fc1 100644 (file)
 
 #if ENABLE(WEBASSEMBLY)
 
-#include "VM.h"
+#include "JSWebAssemblyInstance.h"
+#include "Options.h"
+
 #include <mutex>
 #include <wtf/FastTLS.h>
 
 namespace JSC { namespace Wasm {
 
-Context* loadContext(VM& vm)
+bool Context::useFastTLS()
+{
+#if ENABLE(FAST_TLS_JIT)
+    return Options::useFastTLSForWasmContext();
+#else
+    return false;
+#endif
+}
+
+JSWebAssemblyInstance* Context::load() const
 {
 #if ENABLE(FAST_TLS_JIT)
-    if (useFastTLSForContext())
-        return bitwise_cast<Context*>(_pthread_getspecific_direct(WTF_WASM_CONTEXT_KEY));
+    if (useFastTLS())
+        return bitwise_cast<JSWebAssemblyInstance*>(_pthread_getspecific_direct(WTF_WASM_CONTEXT_KEY));
 #endif
-    return vm.wasmContext;
+    return instance;
 }
 
-void storeContext(VM& vm, Context* context)
+void Context::store(JSWebAssemblyInstance* i, void* softStackLimit)
 {
 #if ENABLE(FAST_TLS_JIT)
-    if (useFastTLSForContext())
-        _pthread_setspecific_direct(WTF_WASM_CONTEXT_KEY, bitwise_cast<void*>(context));
+    if (useFastTLS())
+        _pthread_setspecific_direct(WTF_WASM_CONTEXT_KEY, bitwise_cast<void*>(i));
 #endif
-    vm.wasmContext = context;
-    if (context)
-        context->setCachedStackLimit(vm.softStackLimit());
+    instance = i;
+    if (instance)
+        instance->setCachedStackLimit(softStackLimit);
 }
 
 } } // namespace JSC::Wasm
index 3cf65fb..c2b51df 100644 (file)
 
 #if ENABLE(WEBASSEMBLY)
 
-#include "JSWebAssemblyInstance.h"
-#include "Options.h"
-
 namespace JSC {
 
-class VM;
+class JSWebAssemblyInstance;
 
 namespace Wasm {
 
-// FIXME: We might want this to be something else at some point:
-// https://bugs.webkit.org/show_bug.cgi?id=170260
-using Context = JSWebAssemblyInstance;
-
-inline bool useFastTLS()
-{
-#if ENABLE(FAST_TLS_JIT)
-    return Options::useWebAssemblyFastTLS();
-#else
-    return false;
-#endif
-}
+struct Context {
+    JSWebAssemblyInstance* instance { nullptr };
 
-inline bool useFastTLSForContext()
-{
-    if (useFastTLS())
-        return Options::useFastTLSForWasmContext();
-    return false;
-}
+    JSWebAssemblyInstance* load() const;
+    void store(JSWebAssemblyInstance*, void* softStackLimit);
 
-Context* loadContext(VM&);
-void storeContext(VM&, Context*);
+    static bool useFastTLS();
+};
 
 } } // namespace JSC::Wasm
 
diff --git a/Source/JavaScriptCore/wasm/WasmEmbedder.h b/Source/JavaScriptCore/wasm/WasmEmbedder.h
new file mode 100644 (file)
index 0000000..228794f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmExceptionType.h"
+#include "WasmMemory.h"
+#include <wtf/Forward.h>
+#include <wtf/Function.h>
+
+#include <memory>
+
+namespace JSC {
+
+class ExecState;
+class JSWebAssemblyInstance; // FIXME this should be Wasm::Instance, so should use below. https://webkit.org/b/177472
+
+namespace Wasm {
+
+struct CompilationContext;
+struct InternalFunction;
+struct ModuleInformation;
+class Signature;
+struct UnlinkedWasmToWasmCall;
+
+// Create wrapper code to call from embedder -> WebAssembly.
+using CreateEmbedderWrapper = WTF::Function<std::unique_ptr<InternalFunction>(CompilationContext&, const Signature&, Vector<UnlinkedWasmToWasmCall>*, const ModuleInformation&, MemoryMode, uint32_t)>;
+
+// Called as soon as an exception is detected. The return value is the PC to continue at.
+using ThrowWasmException = void* (*)(ExecState*, Wasm::ExceptionType, JSWebAssemblyInstance*);
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
index 2b1d828..cc1e7d1 100644 (file)
 
 #include "ExecutableAllocator.h"
 #include "MachineContext.h"
-#include "VM.h"
 #include "WasmExceptionType.h"
 #include "WasmMemory.h"
 #include "WasmThunks.h"
 
+#include <wtf/HashSet.h>
 #include <wtf/Lock.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/threads/Signals.h>
index 3812836..e5e07a9 100644 (file)
@@ -27,8 +27,6 @@
 
 namespace JSC {
 
-class VM;
-
 namespace Wasm {
 
 void registerCode(void* start, void* end);
index b222217..e7b3df5 100644 (file)
 
 namespace JSC {
 
-class JSFunction;
-
 namespace B3 {
 class Compilation;
 }
 
 namespace Wasm {
 
+struct CompilationContext;
+struct ModuleInformation;
+
 inline bool isValueType(Type type)
 {
     switch (type) {
diff --git a/Source/JavaScriptCore/wasm/WasmInstance.cpp b/Source/JavaScriptCore/wasm/WasmInstance.cpp
new file mode 100644 (file)
index 0000000..34be0e7
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WasmInstance.h"
+
+#include "Register.h"
+#include "WasmModuleInformation.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC { namespace Wasm {
+
+namespace {
+size_t globalMemoryByteSize(Module& module)
+{
+    return module.moduleInformation().globals.size() * sizeof(Register);
+}
+}
+
+Instance::Instance(Ref<Module>&& module)
+    : m_module(WTFMove(module))
+    , m_globals(MallocPtr<uint64_t>::malloc(globalMemoryByteSize(m_module.get())))
+{
+}
+
+Instance::~Instance() { }
+
+size_t Instance::extraMemoryAllocated() const
+{
+    return globalMemoryByteSize(m_module.get());
+}
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
diff --git a/Source/JavaScriptCore/wasm/WasmInstance.h b/Source/JavaScriptCore/wasm/WasmInstance.h
new file mode 100644 (file)
index 0000000..06fb891
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmFormat.h"
+#include "WasmMemory.h"
+#include "WasmModule.h"
+#include "WasmTable.h"
+#include <wtf/Optional.h>
+#include <wtf/Ref.h>
+#include <wtf/RefPtr.h>
+#include <wtf/ThreadSafeRefCounted.h>
+
+namespace JSC { namespace Wasm {
+
+class Instance : public ThreadSafeRefCounted<Instance> {
+public:
+    static Ref<Instance> create(Ref<Module>&& module)
+    {
+        return adoptRef(*new Instance(WTFMove(module)));
+    }
+
+    void finalizeCreation(Ref<CodeBlock>&& codeBlock)
+    {
+        m_codeBlock = WTFMove(codeBlock);
+    }
+
+    JS_EXPORT_PRIVATE ~Instance();
+
+    size_t extraMemoryAllocated() const;
+
+    Module& module() { return m_module.get(); }
+    CodeBlock* codeBlock() { return m_codeBlock.get(); }
+    Memory* memory() { return m_memory.get(); }
+    Table* table() { return m_table.get(); }
+
+    int32_t loadI32Global(unsigned i) const { return m_globals.get()[i]; }
+    int64_t loadI64Global(unsigned i) const { return m_globals.get()[i]; }
+    float loadF32Global(unsigned i) const { return bitwise_cast<float>(loadI32Global(i)); }
+    double loadF64Global(unsigned i) const { return bitwise_cast<double>(loadI64Global(i)); }
+    void setGlobal(unsigned i, int64_t bits) { m_globals.get()[i] = bits; }
+
+    static ptrdiff_t offsetOfCachedStackLimit() { return OBJECT_OFFSETOF(Instance, m_cachedStackLimit); }
+    void* cachedStackLimit() const { return m_cachedStackLimit; }
+    void setCachedStackLimit(void* limit) { m_cachedStackLimit = limit; }
+
+    friend class JSC::JSWebAssemblyInstance; // FIXME remove this once refactored https://webkit.org/b/177472.
+
+private:
+    Instance(Ref<Module>&&);
+
+    Ref<Module> m_module;
+    RefPtr<CodeBlock> m_codeBlock;
+    RefPtr<Memory> m_memory;
+    RefPtr<Table> m_table;
+    MallocPtr<uint64_t> m_globals;
+    void* m_cachedStackLimit { bitwise_cast<void*>(std::numeric_limits<uintptr_t>::max()) };
+};
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
index c5f48e9..1c1cf59 100644 (file)
 
 #if ENABLE(WEBASSEMBLY)
 
-#include "VM.h"
-#include "WasmThunks.h"
+#include "Options.h"
+#include <wtf/DataLog.h>
 #include <wtf/Gigacage.h>
 #include <wtf/Lock.h>
+#include <wtf/OSAllocator.h>
+#include <wtf/PageBlock.h>
 #include <wtf/Platform.h>
 #include <wtf/PrintStream.h>
 #include <wtf/RAMSize.h>
+#include <wtf/Vector.h>
+
+#include <cstring>
+#include <mutex>
 
 namespace JSC { namespace Wasm {
 
@@ -51,19 +57,19 @@ NEVER_INLINE NO_RETURN_DUE_TO_CRASH void webAssemblyCouldntGetFastMemory() { CRA
 struct MemoryResult {
     enum Kind {
         Success,
-        SuccessAndAsyncGC,
-        SyncGCAndRetry
+        SuccessAndNotifyMemoryPressure,
+        SyncTryToReclaimMemory
     };
-    
+
     static const char* toString(Kind kind)
     {
         switch (kind) {
         case Success:
             return "Success";
-        case SuccessAndAsyncGC:
-            return "SuccessAndAsyncGC";
-        case SyncGCAndRetry:
-            return "SyncGCAndRetry";
+        case SuccessAndNotifyMemoryPressure:
+            return "SuccessAndNotifyMemoryPressure";
+        case SyncTryToReclaimMemory:
+            return "SyncTryToReclaimMemory";
         }
         RELEASE_ASSERT_NOT_REACHED();
         return nullptr;
@@ -98,17 +104,17 @@ public:
         MemoryResult result = [&] {
             auto holder = holdLock(m_lock);
             if (m_memories.size() >= m_maxCount)
-                return MemoryResult(nullptr, MemoryResult::SyncGCAndRetry);
+                return MemoryResult(nullptr, MemoryResult::SyncTryToReclaimMemory);
             
             void* result = Gigacage::tryAllocateVirtualPages(Gigacage::Primitive, Memory::fastMappedBytes());
             if (!result)
-                return MemoryResult(nullptr, MemoryResult::SyncGCAndRetry);
+                return MemoryResult(nullptr, MemoryResult::SyncTryToReclaimMemory);
             
             m_memories.append(result);
             
             return MemoryResult(
                 result,
-                m_memories.size() >= m_maxCount / 2 ? MemoryResult::SuccessAndAsyncGC : MemoryResult::Success);
+                m_memories.size() >= m_maxCount / 2 ? MemoryResult::SuccessAndNotifyMemoryPressure : MemoryResult::Success);
         }();
         
         if (Options::logWebAssemblyMemory())
@@ -153,12 +159,12 @@ public:
         MemoryResult::Kind result = [&] {
             auto holder = holdLock(m_lock);
             if (m_physicalBytes + bytes > memoryLimit())
-                return MemoryResult::SyncGCAndRetry;
+                return MemoryResult::SyncTryToReclaimMemory;
             
             m_physicalBytes += bytes;
             
             if (m_physicalBytes >= memoryLimit() / 2)
-                return MemoryResult::SuccessAndAsyncGC;
+                return MemoryResult::SuccessAndNotifyMemoryPressure;
             
             return MemoryResult::Success;
         }();
@@ -205,7 +211,7 @@ static MemoryManager& memoryManager()
 }
 
 template<typename Func>
-bool tryAndGC(VM& vm, const Func& allocate)
+bool tryAllocate(const Func& allocate, const WTF::Function<void(Memory::NotifyPressure)>& notifyMemoryPressure, const WTF::Function<void(Memory::SyncTryToReclaim)>& syncTryToReclaimMemory)
 {
     unsigned numTries = 2;
     bool done = false;
@@ -214,14 +220,16 @@ bool tryAndGC(VM& vm, const Func& allocate)
         case MemoryResult::Success:
             done = true;
             break;
-        case MemoryResult::SuccessAndAsyncGC:
-            vm.heap.collectAsync(CollectionScope::Full);
+        case MemoryResult::SuccessAndNotifyMemoryPressure:
+            if (notifyMemoryPressure)
+                notifyMemoryPressure(Memory::NotifyPressureTag);
             done = true;
             break;
-        case MemoryResult::SyncGCAndRetry:
+        case MemoryResult::SyncTryToReclaimMemory:
             if (i + 1 == numTries)
                 break;
-            vm.heap.collectSync(CollectionScope::Full);
+            if (syncTryToReclaimMemory)
+                syncTryToReclaimMemory(Memory::SyncTryToReclaimTag);
             break;
         }
     }
@@ -230,32 +238,32 @@ bool tryAndGC(VM& vm, const Func& allocate)
 
 } // anonymous namespace
 
-const char* makeString(MemoryMode mode)
+Memory::Memory()
 {
-    switch (mode) {
-    case MemoryMode::BoundsChecking: return "BoundsChecking";
-    case MemoryMode::Signaling: return "Signaling";
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-    return "";
 }
 
-Memory::Memory(PageCount initial, PageCount maximum)
+Memory::Memory(PageCount initial, PageCount maximum, Function<void(NotifyPressure)>&& notifyMemoryPressure, Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback)
     : m_initial(initial)
     , m_maximum(maximum)
+    , m_notifyMemoryPressure(WTFMove(notifyMemoryPressure))
+    , m_syncTryToReclaimMemory(WTFMove(syncTryToReclaimMemory))
+    , m_growSuccessCallback(WTFMove(growSuccessCallback))
 {
     ASSERT(!initial.bytes());
     ASSERT(m_mode == MemoryMode::BoundsChecking);
     dataLogLnIf(verbose, "Memory::Memory allocating ", *this);
 }
 
-Memory::Memory(void* memory, PageCount initial, PageCount maximum, size_t mappedCapacity, MemoryMode mode)
+Memory::Memory(void* memory, PageCount initial, PageCount maximum, size_t mappedCapacity, MemoryMode mode, Function<void(NotifyPressure)>&& notifyMemoryPressure, Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback)
     : m_memory(memory)
     , m_size(initial.bytes())
     , m_initial(initial)
     , m_maximum(maximum)
     , m_mappedCapacity(mappedCapacity)
     , m_mode(mode)
+    , m_notifyMemoryPressure(WTFMove(notifyMemoryPressure))
+    , m_syncTryToReclaimMemory(WTFMove(syncTryToReclaimMemory))
+    , m_growSuccessCallback(WTFMove(growSuccessCallback))
 {
     dataLogLnIf(verbose, "Memory::Memory allocating ", *this);
 }
@@ -275,7 +283,12 @@ static void commitZeroPages(void* startAddress, size_t sizeInBytes)
 #endif
 }
 
-RefPtr<Memory> Memory::create(VM& vm, PageCount initial, PageCount maximum)
+RefPtr<Memory> Memory::create()
+{
+    return adoptRef(new Memory());
+}
+
+RefPtr<Memory> Memory::create(PageCount initial, PageCount maximum, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback)
 {
     ASSERT(initial);
     RELEASE_ASSERT(!maximum || maximum >= initial); // This should be guaranteed by our caller.
@@ -283,33 +296,27 @@ RefPtr<Memory> Memory::create(VM& vm, PageCount initial, PageCount maximum)
     const size_t initialBytes = initial.bytes();
     const size_t maximumBytes = maximum ? maximum.bytes() : 0;
 
-    // We need to be sure we have a stub prior to running code.
-    if (UNLIKELY(!Thunks::singleton().stub(throwExceptionFromWasmThunkGenerator)))
-        return nullptr;
-
     if (maximum && !maximumBytes) {
         // User specified a zero maximum, initial size must also be zero.
         RELEASE_ASSERT(!initialBytes);
-        return adoptRef(new Memory(initial, maximum));
+        return adoptRef(new Memory(initial, maximum, WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
     }
     
-    bool done = tryAndGC(
-        vm,
+    bool done = tryAllocate(
         [&] () -> MemoryResult::Kind {
             return memoryManager().tryAllocatePhysicalBytes(initialBytes);
-        });
+        }, notifyMemoryPressure, syncTryToReclaimMemory);
     if (!done)
         return nullptr;
         
     char* fastMemory = nullptr;
     if (Options::useWebAssemblyFastMemory()) {
-        tryAndGC(
-            vm,
+        tryAllocate(
             [&] () -> MemoryResult::Kind {
                 auto result = memoryManager().tryAllocateVirtualPages();
                 fastMemory = bitwise_cast<char*>(result.basePtr);
                 return result.kind;
-            });
+            }, notifyMemoryPressure, syncTryToReclaimMemory);
     }
     
     if (fastMemory) {
@@ -320,15 +327,15 @@ RefPtr<Memory> Memory::create(VM& vm, PageCount initial, PageCount maximum)
         }
 
         commitZeroPages(fastMemory, initialBytes);
-        
-        return adoptRef(new Memory(fastMemory, initial, maximum, Memory::fastMappedBytes(), MemoryMode::Signaling));
+
+        return adoptRef(new Memory(fastMemory, initial, maximum, Memory::fastMappedBytes(), MemoryMode::Signaling, WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
     }
     
     if (UNLIKELY(Options::crashIfWebAssemblyCantFastMemory()))
         webAssemblyCouldntGetFastMemory();
 
     if (!initialBytes)
-        return adoptRef(new Memory(initial, maximum));
+        return adoptRef(new Memory(initial, maximum, WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
     
     void* slowMemory = Gigacage::tryAlignedMalloc(Gigacage::Primitive, WTF::pageSize(), initialBytes);
     if (!slowMemory) {
@@ -336,7 +343,7 @@ RefPtr<Memory> Memory::create(VM& vm, PageCount initial, PageCount maximum)
         return nullptr;
     }
     memset(slowMemory, 0, initialBytes);
-    return adoptRef(new Memory(slowMemory, initial, maximum, initialBytes, MemoryMode::BoundsChecking));
+    return adoptRef(new Memory(slowMemory, initial, maximum, initialBytes, MemoryMode::BoundsChecking, WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
 }
 
 Memory::~Memory()
@@ -345,7 +352,10 @@ Memory::~Memory()
         memoryManager().freePhysicalBytes(m_size);
         switch (m_mode) {
         case MemoryMode::Signaling:
-            mprotect(m_memory, Memory::fastMappedBytes(), PROT_READ | PROT_WRITE);
+            if (mprotect(m_memory, Memory::fastMappedBytes(), PROT_READ | PROT_WRITE)) {
+                dataLog("mprotect failed: ", strerror(errno), "\n");
+                RELEASE_ASSERT_NOT_REACHED();
+            }
             memoryManager().freeVirtualPages(m_memory);
             break;
         case MemoryMode::BoundsChecking:
@@ -371,34 +381,50 @@ bool Memory::addressIsInActiveFastMemory(void* address)
     return memoryManager().containsAddress(address);
 }
 
-bool Memory::grow(VM& vm, PageCount newSize)
+Expected<PageCount, Memory::GrowFailReason> Memory::grow(PageCount delta)
 {
-    RELEASE_ASSERT(newSize > PageCount::fromBytes(m_size));
+    const Wasm::PageCount oldPageCount = sizeInPages();
 
-    dataLogLnIf(verbose, "Memory::grow to ", newSize, " from ", *this);
+    if (!delta.isValid())
+        return makeUnexpected(GrowFailReason::InvalidDelta);
+    
+    const Wasm::PageCount newPageCount = oldPageCount + delta;
+    if (!newPageCount)
+        return makeUnexpected(GrowFailReason::InvalidGrowSize);
 
-    if (maximum() && newSize > maximum())
-        return false;
+    auto success = [&] () {
+        m_growSuccessCallback(GrowSuccessTag, oldPageCount, newPageCount);
+        return oldPageCount;
+    };
 
-    size_t desiredSize = newSize.bytes();
+    if (delta.pageCount() == 0)
+        return success();
+
+    dataLogLnIf(verbose, "Memory::grow(", delta, ") to ", newPageCount, " from ", *this);
+    RELEASE_ASSERT(newPageCount > PageCount::fromBytes(m_size));
+
+    if (maximum() && newPageCount > maximum())
+        return makeUnexpected(GrowFailReason::WouldExceedMaximum);
+
+    size_t desiredSize = newPageCount.bytes();
     RELEASE_ASSERT(desiredSize > m_size);
     size_t extraBytes = desiredSize - m_size;
     RELEASE_ASSERT(extraBytes);
-    bool success = tryAndGC(
-        vm,
+    bool allocationSuccess = tryAllocate(
         [&] () -> MemoryResult::Kind {
             return memoryManager().tryAllocatePhysicalBytes(extraBytes);
-        });
-    if (!success)
-        return false;
-        
+        }, m_notifyMemoryPressure, m_syncTryToReclaimMemory);
+    if (!allocationSuccess)
+        return makeUnexpected(GrowFailReason::OutOfMemory);
+
     switch (mode()) {
     case MemoryMode::BoundsChecking: {
         RELEASE_ASSERT(maximum().bytes() != 0);
-        
+
         void* newMemory = Gigacage::tryAlignedMalloc(Gigacage::Primitive, WTF::pageSize(), desiredSize);
         if (!newMemory)
-            return false;
+            return makeUnexpected(GrowFailReason::OutOfMemory);
+
         memcpy(newMemory, m_memory, m_size);
         memset(static_cast<char*>(newMemory) + m_size, 0, desiredSize - m_size);
         if (m_memory)
@@ -406,7 +432,7 @@ bool Memory::grow(VM& vm, PageCount newSize)
         m_memory = newMemory;
         m_mappedCapacity = desiredSize;
         m_size = desiredSize;
-        return true;
+        return success();
     }
     case MemoryMode::Signaling: {
         RELEASE_ASSERT(m_memory);
@@ -415,16 +441,17 @@ bool Memory::grow(VM& vm, PageCount newSize)
         
         dataLogLnIf(verbose, "Marking WebAssembly memory's ", RawPointer(m_memory), " as read+write in range [", RawPointer(startAddress), ", ", RawPointer(startAddress + extraBytes), ")");
         if (mprotect(startAddress, extraBytes, PROT_READ | PROT_WRITE)) {
-            dataLogLnIf(verbose, "Memory::grow in-place failed ", *this);
-            return false;
+            dataLog("mprotect failed: ", strerror(errno), "\n");
+            RELEASE_ASSERT_NOT_REACHED();
         }
         commitZeroPages(startAddress, extraBytes);
         m_size = desiredSize;
-        return true;
-    } }
-    
+        return success();
+    }
+    }
+
     RELEASE_ASSERT_NOT_REACHED();
-    return false;
+    return oldPageCount;
 }
 
 void Memory::dump(PrintStream& out) const
index 60a9bb7..cd586a8 100644 (file)
 
 #if ENABLE(WEBASSEMBLY)
 
+#include "WasmMemoryMode.h"
 #include "WasmPageCount.h"
 
+#include <wtf/Expected.h>
+#include <wtf/Function.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 
@@ -38,18 +41,8 @@ class PrintStream;
 
 namespace JSC {
 
-class VM;
-
 namespace Wasm {
 
-// FIXME: We should support other modes. see: https://bugs.webkit.org/show_bug.cgi?id=162693
-enum class MemoryMode : uint8_t {
-    BoundsChecking,
-    Signaling
-};
-static constexpr size_t NumberOfMemoryModes = 2;
-JS_EXPORT_PRIVATE const char* makeString(MemoryMode);
-
 class Memory : public RefCounted<Memory> {
     WTF_MAKE_NONCOPYABLE(Memory);
     WTF_MAKE_FAST_ALLOCATED;
@@ -58,7 +51,12 @@ public:
 
     explicit operator bool() const { return !!m_memory; }
     
-    static RefPtr<Memory> create(VM&, PageCount initial, PageCount maximum);
+    enum NotifyPressure { NotifyPressureTag };
+    enum SyncTryToReclaim { SyncTryToReclaimTag };
+    enum GrowSuccess { GrowSuccessTag };
+
+    static RefPtr<Memory> create();
+    static RefPtr<Memory> create(PageCount initial, PageCount maximum, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback);
 
     ~Memory();
 
@@ -75,22 +73,34 @@ public:
 
     MemoryMode mode() const { return m_mode; }
 
-    // grow() should only be called from the JSWebAssemblyMemory object since that object needs to update internal
-    // pointers with the current base and size.
-    bool grow(VM&, PageCount);
+    enum class GrowFailReason {
+        InvalidDelta,
+        InvalidGrowSize,
+        WouldExceedMaximum,
+        OutOfMemory,
+    };
+    Expected<PageCount, GrowFailReason> grow(PageCount);
 
     void check() {  ASSERT(!deletionHasBegun()); }
+
+    static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(Memory, m_memory); }
+    static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(Memory, m_size); }
+
 private:
-    Memory(void* memory, PageCount initial, PageCount maximum, size_t mappedCapacity, MemoryMode);
-    Memory(PageCount initial, PageCount maximum);
+    Memory();
+    Memory(void* memory, PageCount initial, PageCount maximum, size_t mappedCapacity, MemoryMode, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback);
+    Memory(PageCount initial, PageCount maximum, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback);
 
-    // FIXME: we should move these to the instance to avoid a load on instance->instance calls.
+    // FIXME: we cache these on the instances to avoid a load on instance->instance calls. This will require updating all the instances when grow is called. https://bugs.webkit.org/show_bug.cgi?id=177305
     void* m_memory { nullptr };
     size_t m_size { 0 };
     PageCount m_initial;
     PageCount m_maximum;
     size_t m_mappedCapacity { 0 };
     MemoryMode m_mode { MemoryMode::BoundsChecking };
+    WTF::Function<void(NotifyPressure)> m_notifyMemoryPressure;
+    WTF::Function<void(SyncTryToReclaim)> m_syncTryToReclaimMemory;
+    WTF::Function<void(GrowSuccess, PageCount, PageCount)> m_growSuccessCallback;
 };
 
 } } // namespace JSC::Wasm
index bf565f0..b5c34bd 100644 (file)
@@ -57,7 +57,7 @@ const PinnedRegisterInfo& PinnedRegisterInfo::get()
     std::call_once(staticPinnedRegisterInfoFlag, [] () {
         Vector<PinnedSizeRegisterInfo> sizeRegisters;
         GPRReg baseMemoryPointer = InvalidGPRReg;
-        GPRReg wasmContextPointer = InvalidGPRReg;
+        GPRReg wasmContextInstancePointer = InvalidGPRReg;
 
         // FIXME: We should support more than one memory size register, and we should allow different
         //        WebAssembly.Instance to have different pins. Right now we take a vector with only one entry.
@@ -65,27 +65,27 @@ const PinnedRegisterInfo& PinnedRegisterInfo::get()
         //        see: https://bugs.webkit.org/show_bug.cgi?id=162952
         Vector<unsigned> pinnedSizes = { 0 };
         unsigned numberOfPinnedRegisters = pinnedSizes.size() + 1;
-        if (!useFastTLSForContext())
+        if (!Context::useFastTLS())
             ++numberOfPinnedRegisters;
         Vector<GPRReg> pinnedRegs = getPinnedRegisters(numberOfPinnedRegisters);
 
         baseMemoryPointer = pinnedRegs.takeLast();
-        if (!useFastTLSForContext())
-            wasmContextPointer = pinnedRegs.takeLast();
+        if (!Context::useFastTLS())
+            wasmContextInstancePointer = pinnedRegs.takeLast();
 
         ASSERT(pinnedSizes.size() == pinnedRegs.size());
         for (unsigned i = 0; i < pinnedSizes.size(); ++i)
             sizeRegisters.append({ pinnedRegs[i], pinnedSizes[i] });
-        staticPinnedRegisterInfo.construct(WTFMove(sizeRegisters), baseMemoryPointer, wasmContextPointer);
+        staticPinnedRegisterInfo.construct(WTFMove(sizeRegisters), baseMemoryPointer, wasmContextInstancePointer);
     });
 
     return staticPinnedRegisterInfo.get();
 }
 
-PinnedRegisterInfo::PinnedRegisterInfo(Vector<PinnedSizeRegisterInfo>&& sizeRegisters, GPRReg baseMemoryPointer, GPRReg wasmContextPointer)
+PinnedRegisterInfo::PinnedRegisterInfo(Vector<PinnedSizeRegisterInfo>&& sizeRegisters, GPRReg baseMemoryPointer, GPRReg wasmContextInstancePointer)
     : sizeRegisters(WTFMove(sizeRegisters))
     , baseMemoryPointer(baseMemoryPointer)
-    , wasmContextPointer(wasmContextPointer)
+    , wasmContextInstancePointer(wasmContextInstancePointer)
 {
 }
 
index 4237bac..23329eb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -44,7 +44,7 @@ struct PinnedSizeRegisterInfo {
 struct PinnedRegisterInfo {
     Vector<PinnedSizeRegisterInfo> sizeRegisters;
     GPRReg baseMemoryPointer;
-    GPRReg wasmContextPointer;
+    GPRReg wasmContextInstancePointer;
     static const PinnedRegisterInfo& get();
     PinnedRegisterInfo(Vector<PinnedSizeRegisterInfo>&&, GPRReg, GPRReg);
 
@@ -52,8 +52,8 @@ struct PinnedRegisterInfo {
     {
         RegisterSet result;
         result.set(baseMemoryPointer);
-        if (wasmContextPointer != InvalidGPRReg)
-            result.set(wasmContextPointer);
+        if (wasmContextInstancePointer != InvalidGPRReg)
+            result.set(wasmContextInstancePointer);
         if (mode != MemoryMode::Signaling) {
             for (const auto& info : sizeRegisters)
                 result.set(info.sizeRegister);
diff --git a/Source/JavaScriptCore/wasm/WasmMemoryMode.cpp b/Source/JavaScriptCore/wasm/WasmMemoryMode.cpp
new file mode 100644 (file)
index 0000000..b1bc985
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WasmMemoryMode.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+#include <wtf/Assertions.h>
+
+namespace JSC { namespace Wasm {
+
+const char* makeString(MemoryMode mode)
+{
+    switch (mode) {
+    case MemoryMode::BoundsChecking: return "BoundsChecking";
+    case MemoryMode::Signaling: return "Signaling";
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return "";
+}
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
diff --git a/Source/JavaScriptCore/wasm/WasmMemoryMode.h b/Source/JavaScriptCore/wasm/WasmMemoryMode.h
new file mode 100644 (file)
index 0000000..14fc896
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "JSExportMacros.h"
+
+namespace JSC {
+
+namespace Wasm {
+
+// FIXME: We should support other modes. see: https://bugs.webkit.org/show_bug.cgi?id=162693
+enum class MemoryMode : uint8_t {
+    BoundsChecking,
+    Signaling
+};
+
+static constexpr size_t NumberOfMemoryModes = 2;
+JS_EXPORT_PRIVATE const char* makeString(MemoryMode);
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMLY)
index 8e366f4..992e3d6 100644 (file)
@@ -56,27 +56,26 @@ static Module::ValidationResult makeValidationResult(BBQPlan& plan)
 
 static Plan::CompletionTask makeValidationCallback(Module::AsyncValidationCallback&& callback)
 {
-    return createSharedTask<Plan::CallbackType>([callback = WTFMove(callback)] (VM* vm, Plan& plan) {
+    return createSharedTask<Plan::CallbackType>([callback = WTFMove(callback)] (Plan& plan) {
         ASSERT(!plan.hasWork());
-        ASSERT(vm);
-        callback->run(*vm, makeValidationResult(static_cast<BBQPlan&>(plan)));
+        callback->run(makeValidationResult(static_cast<BBQPlan&>(plan)));
     });
 }
 
-Module::ValidationResult Module::validateSync(VM& vm, Vector<uint8_t>&& source)
+Module::ValidationResult Module::validateSync(Context* context, Vector<uint8_t>&& source)
 {
-    Ref<BBQPlan> plan = adoptRef(*new BBQPlan(&vm, WTFMove(source), BBQPlan::Validation, Plan::dontFinalize()));
+    Ref<BBQPlan> plan = adoptRef(*new BBQPlan(context, WTFMove(source), BBQPlan::Validation, Plan::dontFinalize(), nullptr, nullptr));
     plan->parseAndValidateModule();
     return makeValidationResult(plan.get());
 }
 
-void Module::validateAsync(VM& vm, Vector<uint8_t>&& source, Module::AsyncValidationCallback&& callback)
+void Module::validateAsync(Context* context, Vector<uint8_t>&& source, Module::AsyncValidationCallback&& callback)
 {
-    Ref<Plan> plan = adoptRef(*new BBQPlan(&vm, WTFMove(source), BBQPlan::Validation, makeValidationCallback(WTFMove(callback))));
+    Ref<Plan> plan = adoptRef(*new BBQPlan(context, WTFMove(source), BBQPlan::Validation, makeValidationCallback(WTFMove(callback)), nullptr, nullptr));
     Wasm::ensureWorklist().enqueue(WTFMove(plan));
 }
 
-Ref<CodeBlock> Module::getOrCreateCodeBlock(MemoryMode mode)
+Ref<CodeBlock> Module::getOrCreateCodeBlock(Context* context, MemoryMode mode, CreateEmbedderWrapper&& createEmbedderWrapper, ThrowWasmException throwWasmException)
 {
     RefPtr<CodeBlock> codeBlock;
     auto locker = holdLock(m_lock);
@@ -87,23 +86,23 @@ Ref<CodeBlock> Module::getOrCreateCodeBlock(MemoryMode mode)
     // FIXME: We might want to back off retrying at some point:
     // https://bugs.webkit.org/show_bug.cgi?id=170607
     if (!codeBlock || (codeBlock->compilationFinished() && !codeBlock->runnable())) {
-        codeBlock = CodeBlock::create(mode, const_cast<ModuleInformation&>(moduleInformation()));
+        codeBlock = CodeBlock::create(context, mode, const_cast<ModuleInformation&>(moduleInformation()), WTFMove(createEmbedderWrapper), throwWasmException);
         m_codeBlocks[static_cast<uint8_t>(mode)] = codeBlock;
     }
     return codeBlock.releaseNonNull();
 }
 
-Ref<CodeBlock> Module::compileSync(MemoryMode mode)
+Ref<CodeBlock> Module::compileSync(Context* context, MemoryMode mode, CreateEmbedderWrapper&& createEmbedderWrapper, ThrowWasmException throwWasmException)
 {
-    Ref<CodeBlock> codeBlock = getOrCreateCodeBlock(mode);
+    Ref<CodeBlock> codeBlock = getOrCreateCodeBlock(context, mode, WTFMove(createEmbedderWrapper), throwWasmException);
     codeBlock->waitUntilFinished();
     return codeBlock;
 }
 
-void Module::compileAsync(VM& vm, MemoryMode mode, CodeBlock::AsyncCompilationCallback&& task)
+void Module::compileAsync(Context* context, MemoryMode mode, CodeBlock::AsyncCompilationCallback&& task, CreateEmbedderWrapper&& createEmbedderWrapper, ThrowWasmException throwWasmException)
 {
-    Ref<CodeBlock> codeBlock = getOrCreateCodeBlock(mode);
-    codeBlock->compileAsync(vm, WTFMove(task));
+    Ref<CodeBlock> codeBlock = getOrCreateCodeBlock(context, mode, WTFMove(createEmbedderWrapper), throwWasmException);
+    codeBlock->compileAsync(context, WTFMove(task));
 }
 
 } } // namespace JSC::Wasm
index a1af758..a6ae29f 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "WasmCodeBlock.h"
+#include "WasmEmbedder.h"
 #include "WasmMemory.h"
 #include <wtf/Expected.h>
 #include <wtf/Lock.h>
 
 namespace JSC { namespace Wasm {
 
+struct Context;
 struct ModuleInformation;
 class Plan;
 
 using SignatureIndex = uint32_t;
-    
+
 class Module : public ThreadSafeRefCounted<Module> {
 public:
     using ValidationResult = WTF::Expected<RefPtr<Module>, String>;
-    typedef void CallbackType(VM&, ValidationResult&&);
+    typedef void CallbackType(ValidationResult&&);
     using AsyncValidationCallback = RefPtr<SharedTask<CallbackType>>;
 
-    static ValidationResult validateSync(VM&, Vector<uint8_t>&& source);
-    static void validateAsync(VM&, Vector<uint8_t>&& source, Module::AsyncValidationCallback&&);
+    static ValidationResult validateSync(Context*, Vector<uint8_t>&& source);
+    static void validateAsync(Context*, Vector<uint8_t>&& source, Module::AsyncValidationCallback&&);
 
     static Ref<Module> create(Ref<ModuleInformation>&& moduleInformation)
     {
@@ -58,14 +60,14 @@ public:
     Wasm::SignatureIndex signatureIndexFromFunctionIndexSpace(unsigned functionIndexSpace) const;
     const Wasm::ModuleInformation& moduleInformation() const { return m_moduleInformation.get(); }
 
-    Ref<CodeBlock> compileSync(MemoryMode);
-    void compileAsync(VM&, MemoryMode, CodeBlock::AsyncCompilationCallback&&);
+    Ref<CodeBlock> compileSync(Context*, MemoryMode, CreateEmbedderWrapper&&, ThrowWasmException);
+    void compileAsync(Context*, MemoryMode, CodeBlock::AsyncCompilationCallback&&, CreateEmbedderWrapper&&, ThrowWasmException);
 
     JS_EXPORT_PRIVATE ~Module();
 
     CodeBlock* codeBlockFor(MemoryMode mode) { return m_codeBlocks[static_cast<uint8_t>(mode)].get(); }
 private:
-    Ref<CodeBlock> getOrCreateCodeBlock(MemoryMode);
+    Ref<CodeBlock> getOrCreateCodeBlock(Context*, MemoryMode, CreateEmbedderWrapper&&, ThrowWasmException);
 
     Module(Ref<ModuleInformation>&&);
     Ref<ModuleInformation> m_moduleInformation;
index 6c948b5..6d44ac2 100644 (file)
@@ -29,7 +29,6 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "IdentifierInlines.h"
-#include "JSWebAssemblyTable.h"
 #include "WasmMemoryInformation.h"
 #include "WasmNameSectionParser.h"
 #include "WasmOps.h"
@@ -265,7 +264,7 @@ auto ModuleParser::parseTableHelper(bool isImport) -> PartialResult
     PartialResult limits = parseResizableLimits(initial, maximum);
     if (UNLIKELY(!limits))
         return limits.getUnexpected();
-    WASM_PARSER_FAIL_IF(!JSWebAssemblyTable::isValidSize(initial), "Table's initial page count of ", initial, " is invalid");
+    WASM_PARSER_FAIL_IF(initial > maxTableEntries, "Table's initial page count of ", initial, " is too big, maximum ", maxTableEntries);
 
     ASSERT(!maximum || *maximum >= initial);
 
diff --git a/Source/JavaScriptCore/wasm/WasmNameSection.h b/Source/JavaScriptCore/wasm/WasmNameSection.h
new file mode 100644 (file)
index 0000000..137f652
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WasmName.h"
+#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Vector.h>
+
+namespace JSC { namespace Wasm {
+
+struct NameSection : ThreadSafeRefCounted<NameSection> {
+    static Ref<NameSection> create()
+    {
+        return adoptRef(*new NameSection());
+    }
+
+    Name moduleName;
+    Vector<Name> functionNames;
+    const Name* get(size_t functionIndexSpace)
+    {
+        return functionIndexSpace < functionNames.size() ? &functionNames[functionIndexSpace] : nullptr;
+    }
+};
+
+} } // namespace JSC::Wasm
index 74cf653..ccdf72d 100644 (file)
 #include "B3Compilation.h"
 #include "B3OpaqueByproducts.h"
 #include "JSCInlines.h"
-#include "JSWebAssemblyModule.h"
+#include "JSWebAssemblyInstance.h"
 #include "LinkBuffer.h"
 #include "WasmB3IRGenerator.h"
+#include "WasmCallee.h"
 #include "WasmContext.h"
 #include "WasmMachineThreads.h"
 #include "WasmMemory.h"
@@ -51,10 +52,10 @@ namespace WasmOMGPlanInternal {
 static const bool verbose = false;
 }
 
-OMGPlan::OMGPlan(Ref<Module> module, uint32_t functionIndex, MemoryMode mode, CompletionTask&& task)
-    : Base(nullptr, makeRef(const_cast<ModuleInformation&>(module->moduleInformation())), WTFMove(task))
-    , m_module(module.copyRef())
-    , m_codeBlock(*module->codeBlockFor(mode))
+OMGPlan::OMGPlan(Context* context, Ref<Module>&& module, uint32_t functionIndex, MemoryMode mode, CompletionTask&& task)
+    : Base(context, makeRef(const_cast<ModuleInformation&>(module->moduleInformation())), WTFMove(task))
+    , m_module(WTFMove(module))
+    , m_codeBlock(*m_module->codeBlockFor(mode))
     , m_functionIndex(functionIndex)
 {
     setMode(mode);
@@ -162,13 +163,13 @@ void OMGPlan::work(CompilationEffort)
     complete(holdLock(m_lock));
 }
 
-void runOMGPlanForIndex(Context* context, uint32_t functionIndex)
+void OMGPlan::runForIndex(JSWebAssemblyInstance* instance, uint32_t functionIndex)
 {
-    JSWebAssemblyCodeBlock* codeBlock = context->codeBlock();
-    ASSERT(context->memoryMode() == codeBlock->m_codeBlock->mode());
+    Wasm::CodeBlock& codeBlock = instance->wasmCodeBlock();
+    ASSERT(instance->wasmMemory()->mode() == codeBlock.mode());
 
-    if (codeBlock->m_codeBlock->tierUpCount(functionIndex).shouldStartTierUp()) {
-        Ref<Plan> plan = adoptRef(*new OMGPlan(context->module()->module(), functionIndex, codeBlock->m_codeBlock->mode(), Plan::dontFinalize()));
+    if (codeBlock.tierUpCount(functionIndex).shouldStartTierUp()) {
+        Ref<Plan> plan = adoptRef(*new OMGPlan(instance->context(), Ref<Wasm::Module>(instance->wasmModule()), functionIndex, codeBlock.mode(), Plan::dontFinalize()));
         ensureWorklist().enqueue(plan.copyRef());
         if (UNLIKELY(!Options::useConcurrentJIT()))
             plan->waitForCompletion();
index 7164a9e..b808251 100644 (file)
@@ -27,7 +27,6 @@
 
 #if ENABLE(WEBASSEMBLY)
 
-#include "VM.h"
 #include "WasmContext.h"
 #include "WasmModule.h"
 #include "WasmPlan.h"
@@ -41,17 +40,20 @@ namespace Wasm {
 class OMGPlan final : public Plan {
 public:
     using Base = Plan;
-    // Note: CompletionTask should not hold a reference to the Plan otherwise there will be a reference cycle.
-    OMGPlan(Ref<Module>, uint32_t functionIndex, MemoryMode, CompletionTask&&);
 
     bool hasWork() const override { return !m_completed; }
     void work(CompilationEffort) override;
     bool multiThreaded() const override { return false; }
 
+    static void runForIndex(JSWebAssemblyInstance*, uint32_t functionIndex);
+
 private:
     // For some reason friendship doesn't extend to parent classes...
     using Base::m_lock;
 
+    // Note: CompletionTask should not hold a reference to the Plan otherwise there will be a reference cycle.
+    OMGPlan(Context*, Ref<Module>&&, uint32_t functionIndex, MemoryMode, CompletionTask&&);
+
     bool isComplete() const override { return m_completed; }
     void complete(const AbstractLocker& locker) override
     {
@@ -65,8 +67,6 @@ private:
     uint32_t m_functionIndex;
 };
 
-void runOMGPlanForIndex(Context*, uint32_t functionIndex);
-
 } } // namespace JSC::Wasm
 
 #endif // ENABLE(WEBASSEMBLY)
index e43847c..ef05f33 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -57,6 +57,11 @@ public:
     {
         return pageCount <= maxPageCount;
     }
+    
+    bool isValid() const
+    {
+        return isValid(m_pageCount);
+    }
 
     static PageCount fromBytes(uint64_t bytes)
     {
index ba27cf9..d063cc1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,8 +29,6 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "B3Compilation.h"
-#include "JSCInlines.h"
-#include "JSGlobalObject.h"
 #include "WasmB3IRGenerator.h"
 #include "WasmBinding.h"
 #include "WasmCallee.h"
@@ -51,20 +49,27 @@ namespace WasmPlanInternal {
 static const bool verbose = false;
 }
 
-Plan::Plan(VM* vm, Ref<ModuleInformation> info, CompletionTask&& task)
+Plan::Plan(Context* context, Ref<ModuleInformation> info, CompletionTask&& task, CreateEmbedderWrapper&& createEmbedderWrapper, ThrowWasmException throwWasmException)
     : m_moduleInformation(WTFMove(info))
+    , m_createEmbedderWrapper(WTFMove(createEmbedderWrapper))
+    , m_throwWasmException(throwWasmException)
     , m_source(m_moduleInformation->source.data())
     , m_sourceLength(m_moduleInformation->source.size())
 {
-    m_completionTasks.append(std::make_pair(vm, WTFMove(task)));
+    m_completionTasks.append(std::make_pair(context, WTFMove(task)));
 }
 
-Plan::Plan(VM* vm, const uint8_t* source, size_t sourceLength, CompletionTask&& task)
+Plan::Plan(Context* context, Ref<ModuleInformation> info, CompletionTask&& task)
+    : Plan(context, WTFMove(info), WTFMove(task), nullptr, nullptr)
+{
+}
+
+Plan::Plan(Context* context, const uint8_t* source, size_t sourceLength, CompletionTask&& task)
     : m_moduleInformation(adoptRef(*new ModuleInformation(Vector<uint8_t>())))
     , m_source(source)
     , m_sourceLength(sourceLength)
 {
-    m_completionTasks.append(std::make_pair(vm, WTFMove(task)));
+    m_completionTasks.append(std::make_pair(context, WTFMove(task)));
 }
 
 void Plan::runCompletionTasks(const AbstractLocker&)
@@ -72,18 +77,18 @@ void Plan::runCompletionTasks(const AbstractLocker&)
     ASSERT(isComplete() && !hasWork());
 
     for (auto& task : m_completionTasks)
-        task.second->run(task.first, *this);
+        task.second->run(*this);
     m_completionTasks.clear();
     m_completed.notifyAll();
 }
 
-void Plan::addCompletionTask(VM& vm, CompletionTask&& task)
+void Plan::addCompletionTask(Context* context, CompletionTask&& task)
 {
     LockHolder locker(m_lock);
     if (!isComplete())
-        m_completionTasks.append(std::make_pair(&vm, WTFMove(task)));
+        m_completionTasks.append(std::make_pair(context, WTFMove(task)));
     else
-        task->run(&vm, *this);
+        task->run(*this);
 }
 
 void Plan::waitForCompletion()
@@ -94,19 +99,19 @@ void Plan::waitForCompletion()
     }
 }
 
-bool Plan::tryRemoveVMAndCancelIfLast(VM& vm)
+bool Plan::tryRemoveContextAndCancelIfLast(Context& context)
 {
     LockHolder locker(m_lock);
 
     if (!ASSERT_DISABLED) {
-        // We allow the first completion task to not have a vm.
+        // We allow the first completion task to not have a Context.
         for (unsigned i = 1; i < m_completionTasks.size(); ++i)
             ASSERT(m_completionTasks[i].first);
     }
 
     bool removedAnyTasks = false;
-    m_completionTasks.removeAllMatching([&] (const std::pair<VM*, CompletionTask>& pair) {
-        bool shouldRemove = pair.first == &vm;
+    m_completionTasks.removeAllMatching([&] (const std::pair<Context*, CompletionTask>& pair) {
+        bool shouldRemove = pair.first == &context;
         removedAnyTasks |= shouldRemove;
         return shouldRemove;
     });
index 10f8a1b..7a07bfd 100644 (file)
@@ -28,8 +28,8 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "CompilationResult.h"
-#include "VM.h"
 #include "WasmB3IRGenerator.h"
+#include "WasmEmbedder.h"
 #include "WasmModuleInformation.h"
 #include <wtf/Bag.h>
 #include <wtf/SharedTask.h>
 namespace JSC {
 
 class CallLinkInfo;
-class JSGlobalObject;
-class JSPromiseDeferred;
 
 namespace Wasm {
 
+struct Context;
+
 class Plan : public ThreadSafeRefCounted<Plan> {
 public:
-    typedef void CallbackType(VM*, Plan&);
+    typedef void CallbackType(Plan&);
     using CompletionTask = RefPtr<SharedTask<CallbackType>>;
-    static CompletionTask dontFinalize() { return createSharedTask<CallbackType>([](VM*, Plan&) { }); }
-    Plan(VM*, Ref<ModuleInformation>, CompletionTask&&);
+
+    static CompletionTask dontFinalize() { return createSharedTask<CallbackType>([](Plan&) { }); }
+    Plan(Context*, Ref<ModuleInformation>, CompletionTask&&, CreateEmbedderWrapper&&, ThrowWasmException);
+    Plan(Context*, Ref<ModuleInformation>, CompletionTask&&);
 
     // Note: This constructor should only be used if you are not actually building a module e.g. validation/function tests
-    JS_EXPORT_PRIVATE Plan(VM*, const uint8_t*, size_t, CompletionTask&&);
+    JS_EXPORT_PRIVATE Plan(Context*, const uint8_t*, size_t, CompletionTask&&);
     virtual JS_EXPORT_PRIVATE ~Plan();
 
     // If you guarantee the ordering here, you can rely on FIFO of the
     // completion tasks being called.
-    void addCompletionTask(VM&, CompletionTask&&);
+    void addCompletionTask(Context*, CompletionTask&&);
 
     void setMode(MemoryMode mode) { m_mode = mode; }
     MemoryMode mode() const { return m_mode; }
@@ -72,7 +74,7 @@ public:
 
     void waitForCompletion();
     // Returns true if it cancelled the plan.
-    bool tryRemoveVMAndCancelIfLast(VM&);
+    bool tryRemoveContextAndCancelIfLast(Context&);
 
 protected:
     void runCompletionTasks(const AbstractLocker&);
@@ -83,7 +85,10 @@ protected:
 
     Ref<ModuleInformation> m_moduleInformation;
 
-    Vector<std::pair<VM*, CompletionTask>, 1> m_completionTasks;
+    Vector<std::pair<Context*, CompletionTask>, 1> m_completionTasks;
+
+    CreateEmbedderWrapper m_createEmbedderWrapper;
+    ThrowWasmException m_throwWasmException { nullptr };
 
     const uint8_t* m_source;
     const size_t m_sourceLength;
index 8b600ed..6a42d51 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(WEBASSEMBLY)
 
-#include "VM.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/HashFunctions.h>
 #include <wtf/PrintStream.h>
+#include <wtf/text/WTFString.h>
 
 namespace JSC { namespace Wasm {
 
index e413b25..aaced5d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,8 +43,6 @@ class PrintStream;
 
 namespace JSC {
 
-class VM;
-
 namespace Wasm {
 
 using SignatureArgCount = uint32_t;
@@ -156,7 +154,7 @@ template<> struct HashTraits<JSC::Wasm::SignatureHash> : SimpleClassHashTraits<J
 
 namespace JSC { namespace Wasm {
 
-// Signature information is held globally and shared by VMs to allow all signatures to be unique. This is required when wasm calls another wasm instance, and must work when modules are shared between multiple VMs.
+// Signature information is held globally and shared by the entire process to allow all signatures to be unique. This is required when wasm calls another wasm instance, and must work when modules are shared between multiple VMs.
 // Note: signatures are never removed because that would require accounting for all WebAssembly.Module and which signatures they use. The maximum number of signatures is bounded, and isn't worth the counting overhead. We could clear everything when we reach zero outstanding WebAssembly.Module. https://bugs.webkit.org/show_bug.cgi?id=166037
 class SignatureInformation {
     WTF_MAKE_NONCOPYABLE(SignatureInformation);
diff --git a/Source/JavaScriptCore/wasm/WasmTable.cpp b/Source/JavaScriptCore/wasm/WasmTable.cpp
new file mode 100644 (file)
index 0000000..c701a70
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WasmTable.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+#include <wtf/CheckedArithmetic.h>
+#include <wtf/StdLibExtras.h>
+#include <type_traits>
+
+namespace JSC { namespace Wasm {
+
+RefPtr<Table> Table::create(uint32_t initial, std::optional<uint32_t> maximum)
+{
+    if (!isValidSize(initial))
+        return nullptr;
+    return adoptRef(new (NotNull, fastMalloc(sizeof(Table))) Table(initial, maximum));
+}
+
+Table::~Table()
+{
+}
+
+Table::Table(uint32_t initial, std::optional<uint32_t> maximum)
+{
+    m_size = initial;
+    m_maximum = maximum;
+    ASSERT(isValidSize(m_size));
+    ASSERT(!m_maximum || *m_maximum >= m_size);
+
+    // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.
+    // But for now, we're not doing that.
+    m_functions = MallocPtr<Wasm::CallableFunction>::malloc(sizeof(Wasm::CallableFunction) * static_cast<size_t>(size()));
+    m_instances = MallocPtr<JSWebAssemblyInstance*>::malloc(sizeof(JSWebAssemblyInstance*) * static_cast<size_t>(size()));
+    for (uint32_t i = 0; i < size(); ++i) {
+        default_construct_at(&m_functions.get()[i]);
+        ASSERT(m_functions.get()[i].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code.
+        m_instances.get()[i] = nullptr;
+    }
+}
+
+std::optional<uint32_t> Table::grow(uint32_t delta)
+{
+    if (delta == 0)
+        return size();
+
+    using Checked = Checked<uint32_t, RecordOverflow>;
+    Checked newSizeChecked = size();
+    newSizeChecked += delta;
+    uint32_t newSize;
+    if (newSizeChecked.safeGet(newSize) == CheckedState::DidOverflow)
+        return std::nullopt;
+
+    if (maximum() && newSize > *maximum())
+        return std::nullopt;
+    if (!isValidSize(newSize))
+        return std::nullopt;
+
+    auto checkedGrow = [&] (auto& container) {
+        Checked reallocSizeChecked = newSizeChecked;
+        reallocSizeChecked *= sizeof(*container.get());
+        uint32_t reallocSize;
+        if (reallocSizeChecked.safeGet(reallocSize) == CheckedState::DidOverflow)
+            return false;
+        container.realloc(reallocSize);
+        for (uint32_t i = m_size; i < newSize; ++i)
+            default_construct_at(&container.get()[i]);
+        return true;
+    };
+
+    if (!checkedGrow(m_functions))
+        return std::nullopt;
+    if (!checkedGrow(m_instances))
+        return std::nullopt;
+
+    m_size = newSize;
+
+    return newSize;
+}
+
+void Table::clearFunction(uint32_t index)
+{
+    RELEASE_ASSERT(index < size());
+    m_functions.get()[index] = Wasm::CallableFunction();
+    ASSERT(m_functions.get()[index].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code.
+    m_instances.get()[index] = nullptr;
+}
+
+void Table::setFunction(uint32_t index, CallableFunction function, JSWebAssemblyInstance* instance)
+{
+    RELEASE_ASSERT(index < size());
+    m_functions.get()[index] = function;
+    m_instances.get()[index] = instance;
+}
+
+} } // namespace JSC::Table
+
+#endif // ENABLE(WEBASSEMBLY)
diff --git a/Source/JavaScriptCore/wasm/WasmTable.h b/Source/JavaScriptCore/wasm/WasmTable.h
new file mode 100644 (file)
index 0000000..b908ec8
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmFormat.h"
+#include "WasmLimits.h"
+#include <wtf/MallocPtr.h>
+#include <wtf/Optional.h>
+#include <wtf/Ref.h>
+#include <wtf/ThreadSafeRefCounted.h>
+
+namespace JSC {
+
+class JSWebAssemblyInstance; // FIXME this should be Wasm::Instance https://webkit.org/b/177472
+
+namespace Wasm {
+
+class Table : public ThreadSafeRefCounted<Table> {
+public:
+    enum class CreateFail {
+        InvalidSize,
+    };
+    static RefPtr<Table> create(uint32_t initial, std::optional<uint32_t> maximum);
+
+    JS_EXPORT_PRIVATE ~Table();
+
+    std::optional<uint32_t> maximum() const { return m_maximum; }
+    uint32_t size() const { return m_size; }
+    std::optional<uint32_t> grow(uint32_t delta) WARN_UNUSED_RETURN;
+    void clearFunction(uint32_t);
+    void setFunction(uint32_t, CallableFunction, JSWebAssemblyInstance*); // FIXME make this Wasm::Instance. https://webkit.org/b/177472
+
+    static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(Table, m_size); }
+    static ptrdiff_t offsetOfFunctions() { return OBJECT_OFFSETOF(Table, m_functions); }
+    static ptrdiff_t offsetOfInstances() { return OBJECT_OFFSETOF(Table, m_instances); }
+
+    static bool isValidSize(uint32_t size) { return size < maxTableEntries; }
+
+private:
+    Table(uint32_t initial, std::optional<uint32_t> maximum);
+
+    std::optional<uint32_t> m_maximum;
+    uint32_t m_size;
+    MallocPtr<CallableFunction> m_functions;
+    // call_indirect needs to do an Instance check to potentially context switch when calling a function to another instance. We can hold raw pointers to Instance here because the embedder ensures that Table keeps all the instances alive. We couldn't hold a Ref here because it would cause cycles.
+    MallocPtr<JSWebAssemblyInstance*> m_instances; // FIXME make this a Wasm::Instance. https://webkit.org/b/177472
+};
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
index 977b01b..c235980 100644 (file)
 #if ENABLE(WEBASSEMBLY)
 
 #include "CCallHelpers.h"
-#include "FrameTracers.h"
 #include "HeapCellInlines.h"
 #include "JITExceptions.h"
 #include "JSWebAssemblyInstance.h"
-#include "JSWebAssemblyRuntimeError.h"
 #include "LinkBuffer.h"
 #include "ScratchRegisterAllocator.h"
 #include "WasmContext.h"
@@ -48,46 +46,18 @@ MacroAssemblerCodeRef throwExceptionFromWasmThunkGenerator(const AbstractLocker&
 
     // The thing that jumps here must move ExceptionType into the argumentGPR1 before jumping here.
     // We're allowed to use temp registers here. We are not allowed to use callee saves.
-    jit.loadWasmContext(GPRInfo::argumentGPR2);
-    jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR2, Context::offsetOfVM()), GPRInfo::argumentGPR0);
+    jit.loadWasmContextInstance(GPRInfo::argumentGPR2);
+    jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR2, JSWebAssemblyInstance::offsetOfVM()), GPRInfo::argumentGPR0);
     jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(GPRInfo::argumentGPR0);
     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     CCallHelpers::Call call = jit.call();
     jit.jump(GPRInfo::returnValueGPR);
     jit.breakpoint(); // We should not reach this.
 
-    void* (*throwWasmException)(ExecState*, Wasm::ExceptionType, Wasm::Context*) = [] (ExecState* exec, Wasm::ExceptionType type, Wasm::Context* wasmContext) -> void* {
-        VM* vm = wasmContext->vm();
-        NativeCallFrameTracer tracer(vm, exec);
-
-        {
-            auto throwScope = DECLARE_THROW_SCOPE(*vm);
-            JSGlobalObject* globalObject = wasmContext->globalObject();
-
-            JSObject* error; 
-            if (type == ExceptionType::StackOverflow)
-                error = createStackOverflowError(exec, globalObject);
-            else
-                error = JSWebAssemblyRuntimeError::create(exec, *vm, globalObject->WebAssemblyRuntimeErrorStructure(), Wasm::errorMessageForExceptionType(type));
-            throwException(exec, throwScope, error);
-        }
-
-        genericUnwind(vm, exec);
-        ASSERT(!!vm->callFrameForCatch);
-        ASSERT(!!vm->targetMachinePCForThrow);
-        // FIXME: We could make this better:
-        // This is a total hack, but the llint (both op_catch and handleUncaughtException)
-        // require a cell in the callee field to load the VM. (The baseline JIT does not require
-        // this since it is compiled with a constant VM pointer.) We could make the calling convention
-        // for exceptions first load callFrameForCatch info call frame register before jumping
-        // to the exception handler. If we did this, we could remove this terrible hack.
-        // https://bugs.webkit.org/show_bug.cgi?id=170440
-        bitwise_cast<uint64_t*>(exec)[CallFrameSlot::callee] = bitwise_cast<uint64_t>(wasmContext->webAssemblyToJSCallee());
-        return vm->targetMachinePCForThrow;
-    };
-
+    ThrowWasmException throwWasmException = Thunks::singleton().throwWasmException();
+    RELEASE_ASSERT(throwWasmException);
     LinkBuffer linkBuffer(jit, GLOBAL_THUNK_ID);
-    linkBuffer.link(call, throwWasmException);
+    linkBuffer.link(call, FunctionPtr(throwWasmException));
     return FINALIZE_CODE(linkBuffer, ("Throw exception from Wasm"));