Create WebAssembly functions
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Aug 2015 21:07:22 +0000 (21:07 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Aug 2015 21:07:22 +0000 (21:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148373

Patch by Sukolsak Sakshuwong <sukolsak@gmail.com> on 2015-08-28
Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Create functions from WebAssembly files generated by pack-asmjs
<https://github.com/WebAssembly/polyfill-prototype-1>.
WebAssembly functions created by this patch can only return 0.
Actual code generation will be implemented in subsequent patches.

This patch introduces WebAssemblyExecutable, a new subclass of
ExecutableBase for WebAssembly functions. CodeBlocks can now have
an owner that is not a ScriptExecutable. This patch changes the
return type of CodeBlock::ownerExecutable() from ScriptExecutable*
to ExecutableBase*. It also changes code that calls ScriptExecutable's
methods on CodeBlock::ownerExecutable() to use
CodeBlock::ownerScriptExecutable(), which does jsCast<ScriptExecutable*>.

Since ownerScriptExecutable() is called from WebCore and it uses
jsCast<ScriptExecutable*>, this patch needs to export
ScriptExecutable::info(). This should fix the build error in
https://bugs.webkit.org/show_bug.cgi?id=148555

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::hash):
(JSC::CodeBlock::sourceCodeForTools):
(JSC::CodeBlock::dumpAssumingJITType):
(JSC::CodeBlock::dumpSource):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::lineNumberForBytecodeOffset):
(JSC::CodeBlock::expressionRangeForBytecodeOffset):
(JSC::CodeBlock::install):
(JSC::CodeBlock::newReplacement):
(JSC::WebAssemblyCodeBlock::replacement):
(JSC::WebAssemblyCodeBlock::capabilityLevelInternal):
(JSC::CodeBlock::updateAllPredictions):
(JSC::CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::ownerExecutable):
(JSC::CodeBlock::ownerScriptExecutable):
(JSC::CodeBlock::codeType):
(JSC::WebAssemblyCodeBlock::WebAssemblyCodeBlock):
* debugger/Debugger.cpp:
(JSC::Debugger::toggleBreakpoint):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::sourceIDForCallFrame):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::InlineStackEntry::executable):
(JSC::DFG::ByteCodeParser::inliningCost):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseCodeBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::isSupportedForInlining):
(JSC::DFG::mightCompileEval):
(JSC::DFG::mightCompileProgram):
(JSC::DFG::mightCompileFunctionForCall):
(JSC::DFG::mightCompileFunctionForConstruct):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::executableFor):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* inspector/ScriptCallStackFactory.cpp:
(Inspector::CreateScriptCallStackFunctor::operator()):
* interpreter/Interpreter.cpp:
(JSC::eval):
(JSC::isWebAssemblyExecutable):
(JSC::GetStackTraceFunctor::operator()):
(JSC::UnwindFunctor::operator()):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::Frame::sourceURL):
(JSC::StackVisitor::Frame::computeLineAndColumn):
* jit/JITOperations.cpp:
* jit/Repatch.cpp:
(JSC::linkPolymorphicCall):
* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setUpCall):
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/Executable.cpp:
(JSC::WebAssemblyExecutable::WebAssemblyExecutable):
(JSC::WebAssemblyExecutable::destroy):
(JSC::WebAssemblyExecutable::visitChildren):
(JSC::WebAssemblyExecutable::clearCode):
(JSC::WebAssemblyExecutable::prepareForExecution):
* runtime/Executable.h:
(JSC::ExecutableBase::isEvalExecutable):
(JSC::ExecutableBase::isFunctionExecutable):
(JSC::ExecutableBase::isProgramExecutable):
(JSC::ExecutableBase::isWebAssemblyExecutable):
(JSC::ExecutableBase::clearCodeVirtual):
* runtime/JSFunction.cpp:
(JSC::JSFunction::create):
* runtime/JSFunction.h:
* runtime/JSFunctionInlines.h:
(JSC::JSFunction::JSFunction):
(JSC::JSFunction::isBuiltinFunction):
* runtime/JSType.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* wasm/JSWASMModule.h:
(JSC::JSWASMModule::functions):
* wasm/WASMFunctionParser.cpp:
(JSC::WASMFunctionParser::compile):
* wasm/WASMFunctionParser.h:
* wasm/WASMModuleParser.cpp:
(JSC::WASMModuleParser::WASMModuleParser):
(JSC::WASMModuleParser::parse):
(JSC::WASMModuleParser::parseFunctionDeclarationSection):
(JSC::WASMModuleParser::parseFunctionDefinition):
(JSC::WASMModuleParser::parseExportSection):
(JSC::parseWebAssembly):
* wasm/WASMModuleParser.h:

Source/WebCore:

No new tests, because it is a function rename.

* testing/Internals.cpp:
(WebCore::Internals::parserMetaData):

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

33 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/debugger/Debugger.cpp
Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGCapabilities.cpp
Source/JavaScriptCore/dfg/DFGGraph.h
Source/JavaScriptCore/dfg/DFGOSREntry.cpp
Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/interpreter/StackVisitor.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/jit/Repatch.cpp
Source/JavaScriptCore/llint/LLIntData.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/Executable.cpp
Source/JavaScriptCore/runtime/Executable.h
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSFunction.h
Source/JavaScriptCore/runtime/JSFunctionInlines.h
Source/JavaScriptCore/runtime/JSType.h
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/JavaScriptCore/wasm/JSWASMModule.h
Source/JavaScriptCore/wasm/WASMFunctionParser.cpp
Source/JavaScriptCore/wasm/WASMFunctionParser.h
Source/JavaScriptCore/wasm/WASMModuleParser.cpp
Source/JavaScriptCore/wasm/WASMModuleParser.h
Source/WebCore/ChangeLog
Source/WebCore/testing/Internals.cpp

index 2f9d83f..3d75e85 100644 (file)
@@ -1,3 +1,123 @@
+2015-08-28  Sukolsak Sakshuwong  <sukolsak@gmail.com>
+
+        Create WebAssembly functions
+        https://bugs.webkit.org/show_bug.cgi?id=148373
+
+        Reviewed by Filip Pizlo.
+
+        Create functions from WebAssembly files generated by pack-asmjs
+        <https://github.com/WebAssembly/polyfill-prototype-1>.
+        WebAssembly functions created by this patch can only return 0.
+        Actual code generation will be implemented in subsequent patches.
+
+        This patch introduces WebAssemblyExecutable, a new subclass of
+        ExecutableBase for WebAssembly functions. CodeBlocks can now have
+        an owner that is not a ScriptExecutable. This patch changes the
+        return type of CodeBlock::ownerExecutable() from ScriptExecutable*
+        to ExecutableBase*. It also changes code that calls ScriptExecutable's
+        methods on CodeBlock::ownerExecutable() to use
+        CodeBlock::ownerScriptExecutable(), which does jsCast<ScriptExecutable*>.
+
+        Since ownerScriptExecutable() is called from WebCore and it uses
+        jsCast<ScriptExecutable*>, this patch needs to export
+        ScriptExecutable::info(). This should fix the build error in
+        https://bugs.webkit.org/show_bug.cgi?id=148555
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::hash):
+        (JSC::CodeBlock::sourceCodeForTools):
+        (JSC::CodeBlock::dumpAssumingJITType):
+        (JSC::CodeBlock::dumpSource):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::lineNumberForBytecodeOffset):
+        (JSC::CodeBlock::expressionRangeForBytecodeOffset):
+        (JSC::CodeBlock::install):
+        (JSC::CodeBlock::newReplacement):
+        (JSC::WebAssemblyCodeBlock::replacement):
+        (JSC::WebAssemblyCodeBlock::capabilityLevelInternal):
+        (JSC::CodeBlock::updateAllPredictions):
+        (JSC::CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::ownerExecutable):
+        (JSC::CodeBlock::ownerScriptExecutable):
+        (JSC::CodeBlock::codeType):
+        (JSC::WebAssemblyCodeBlock::WebAssemblyCodeBlock):
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::toggleBreakpoint):
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::sourceIDForCallFrame):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::executable):
+        (JSC::DFG::ByteCodeParser::inliningCost):
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::isSupportedForInlining):
+        (JSC::DFG::mightCompileEval):
+        (JSC::DFG::mightCompileProgram):
+        (JSC::DFG::mightCompileFunctionForCall):
+        (JSC::DFG::mightCompileFunctionForConstruct):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::executableFor):
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::prepareOSREntry):
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::CreateScriptCallStackFunctor::operator()):
+        * interpreter/Interpreter.cpp:
+        (JSC::eval):
+        (JSC::isWebAssemblyExecutable):
+        (JSC::GetStackTraceFunctor::operator()):
+        (JSC::UnwindFunctor::operator()):
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::sourceURL):
+        (JSC::StackVisitor::Frame::computeLineAndColumn):
+        * jit/JITOperations.cpp:
+        * jit/Repatch.cpp:
+        (JSC::linkPolymorphicCall):
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::setUpCall):
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/Executable.cpp:
+        (JSC::WebAssemblyExecutable::WebAssemblyExecutable):
+        (JSC::WebAssemblyExecutable::destroy):
+        (JSC::WebAssemblyExecutable::visitChildren):
+        (JSC::WebAssemblyExecutable::clearCode):
+        (JSC::WebAssemblyExecutable::prepareForExecution):
+        * runtime/Executable.h:
+        (JSC::ExecutableBase::isEvalExecutable):
+        (JSC::ExecutableBase::isFunctionExecutable):
+        (JSC::ExecutableBase::isProgramExecutable):
+        (JSC::ExecutableBase::isWebAssemblyExecutable):
+        (JSC::ExecutableBase::clearCodeVirtual):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::create):
+        * runtime/JSFunction.h:
+        * runtime/JSFunctionInlines.h:
+        (JSC::JSFunction::JSFunction):
+        (JSC::JSFunction::isBuiltinFunction):
+        * runtime/JSType.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        * wasm/JSWASMModule.h:
+        (JSC::JSWASMModule::functions):
+        * wasm/WASMFunctionParser.cpp:
+        (JSC::WASMFunctionParser::compile):
+        * wasm/WASMFunctionParser.h:
+        * wasm/WASMModuleParser.cpp:
+        (JSC::WASMModuleParser::WASMModuleParser):
+        (JSC::WASMModuleParser::parse):
+        (JSC::WASMModuleParser::parseFunctionDeclarationSection):
+        (JSC::WASMModuleParser::parseFunctionDefinition):
+        (JSC::WASMModuleParser::parseExportSection):
+        (JSC::parseWebAssembly):
+        * wasm/WASMModuleParser.h:
+
 2015-08-28  Mark Lam  <mark.lam@apple.com>
 
         [Follow up] ScratchRegisterAllocator::preserveReusedRegistersByPushing() should allow room for C helper calls and keep sp properly aligned.
index 01f11da..f8a0f4b 100644 (file)
@@ -107,7 +107,7 @@ CodeBlockHash CodeBlock::hash() const
 {
     if (!m_hash) {
         RELEASE_ASSERT(isSafeToComputeHash());
-        m_hash = CodeBlockHash(ownerExecutable()->source(), specializationKind());
+        m_hash = CodeBlockHash(ownerScriptExecutable()->source(), specializationKind());
     }
     return m_hash;
 }
@@ -115,7 +115,7 @@ CodeBlockHash CodeBlock::hash() const
 CString CodeBlock::sourceCodeForTools() const
 {
     if (codeType() != FunctionCode)
-        return ownerExecutable()->source().toUTF8();
+        return ownerScriptExecutable()->source().toUTF8();
     
     SourceProvider* provider = source();
     FunctionExecutable* executable = jsCast<FunctionExecutable*>(ownerExecutable());
@@ -155,13 +155,13 @@ void CodeBlock::dumpAssumingJITType(PrintStream& out, JITCode::JITType jitType)
     out.print(", ", instructionCount());
     if (this->jitType() == JITCode::BaselineJIT && m_shouldAlwaysBeInlined)
         out.print(" (ShouldAlwaysBeInlined)");
-    if (ownerExecutable()->neverInline())
+    if (ownerScriptExecutable()->neverInline())
         out.print(" (NeverInline)");
-    if (ownerExecutable()->neverOptimize())
+    if (ownerScriptExecutable()->neverOptimize())
         out.print(" (NeverOptimize)");
-    if (ownerExecutable()->didTryToEnterInLoop())
+    if (ownerScriptExecutable()->didTryToEnterInLoop())
         out.print(" (DidTryToEnterInLoop)");
-    if (ownerExecutable()->isStrictMode())
+    if (ownerScriptExecutable()->isStrictMode())
         out.print(" (StrictMode)");
     if (this->jitType() == JITCode::BaselineJIT && m_didFailFTLCompilation)
         out.print(" (FTLFail)");
@@ -554,7 +554,7 @@ void CodeBlock::dumpSource()
 
 void CodeBlock::dumpSource(PrintStream& out)
 {
-    ScriptExecutable* executable = ownerExecutable();
+    ScriptExecutable* executable = ownerScriptExecutable();
     if (executable->isFunctionExecutable()) {
         FunctionExecutable* functionExecutable = reinterpret_cast<FunctionExecutable*>(executable);
         String source = functionExecutable->source().provider()->getRange(
@@ -1753,7 +1753,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
     setNumParameters(unlinkedCodeBlock->numParameters());
 
     if (vm()->typeProfiler() || vm()->controlFlowProfiler())
-        vm()->functionHasExecutedCache()->removeUnexecutedRange(m_ownerExecutable->sourceID(), m_ownerExecutable->typeProfilingStartOffset(), m_ownerExecutable->typeProfilingEndOffset());
+        vm()->functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(), ownerExecutable->typeProfilingEndOffset());
 
     setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
     if (unlinkedCodeBlock->usesGlobalObject())
@@ -1787,7 +1787,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
     for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
         if (vm()->typeProfiler() || vm()->controlFlowProfiler())
-            vm()->functionHasExecutedCache()->insertUnexecutedRange(m_ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
+            vm()->functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
         m_functionDecls[i].set(*m_vm, ownerExecutable, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
     }
 
@@ -1795,7 +1795,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
     for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) {
         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
         if (vm()->typeProfiler() || vm()->controlFlowProfiler())
-            vm()->functionHasExecutedCache()->insertUnexecutedRange(m_ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
+            vm()->functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
         m_functionExprs[i].set(*m_vm, ownerExecutable, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
     }
 
@@ -1927,7 +1927,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
 
             instructions[i + opLength - 1] = objectAllocationProfile;
             objectAllocationProfile->initialize(*vm(),
-                m_ownerExecutable.get(), m_globalObject->objectPrototype(), inferredInlineCapacity);
+                ownerExecutable, m_globalObject->objectPrototype(), inferredInlineCapacity);
             break;
         }
 
@@ -2108,7 +2108,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
                     // the user's program, give the type profiler some range to identify these return statements.
                     // Currently, the text offset that is used as identification is "f" in the function keyword
                     // and is stored on TypeLocation's m_divotForFunctionOffsetIfReturnStatement member variable.
-                    divotStart = divotEnd = m_ownerExecutable->typeProfilingStartOffset();
+                    divotStart = divotEnd = ownerExecutable->typeProfilingStartOffset();
                     shouldAnalyze = true;
                 }
                 break;
@@ -2116,12 +2116,12 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
             }
 
             std::pair<TypeLocation*, bool> locationPair = vm()->typeProfiler()->typeLocationCache()->getTypeLocation(globalVariableID,
-                m_ownerExecutable->sourceID(), divotStart, divotEnd, globalTypeSet, vm());
+                ownerExecutable->sourceID(), divotStart, divotEnd, globalTypeSet, vm());
             TypeLocation* location = locationPair.first;
             bool isNewLocation = locationPair.second;
 
             if (flag == ProfileTypeBytecodeFunctionReturnStatement)
-                location->m_divotForFunctionOffsetIfReturnStatement = m_ownerExecutable->typeProfilingStartOffset();
+                location->m_divotForFunctionOffsetIfReturnStatement = ownerExecutable->typeProfilingStartOffset();
 
             if (shouldAnalyze && isNewLocation)
                 vm()->typeProfiler()->insertNewLocation(location);
@@ -2165,6 +2165,39 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
     m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock) + m_instructions.size() * sizeof(Instruction));
 }
 
+#if ENABLE(WEBASSEMBLY)
+CodeBlock::CodeBlock(WebAssemblyExecutable* ownerExecutable, VM& vm, JSGlobalObject* globalObject)
+    : m_globalObject(globalObject->vm(), ownerExecutable, globalObject)
+    , m_heap(&m_globalObject->vm().heap)
+    , m_numCalleeRegisters(0)
+    , m_numVars(0)
+    , m_isConstructor(false)
+    , m_shouldAlwaysBeInlined(false)
+    , m_didFailFTLCompilation(false)
+    , m_hasBeenCompiledWithFTL(false)
+    , m_hasDebuggerStatement(false)
+    , m_steppingMode(SteppingModeDisabled)
+    , m_numBreakpoints(0)
+    , m_ownerExecutable(m_globalObject->vm(), ownerExecutable, ownerExecutable)
+    , m_vm(&vm)
+    , m_isStrictMode(false)
+    , m_needsActivation(false)
+    , m_mayBeExecuting(false)
+    , m_codeType(FunctionCode)
+    , m_osrExitCounter(0)
+    , m_optimizationDelayCounter(0)
+    , m_reoptimizationRetryCounter(0)
+#if ENABLE(JIT)
+    , m_capabilityLevelState(DFG::CannotCompile)
+#endif
+{
+    ASSERT(m_heap->isDeferred());
+
+    m_heap->m_codeBlocks.add(this);
+    m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock));
+}
+#endif
+
 CodeBlock::~CodeBlock()
 {
     if (m_vm->m_perBytecodeProfiler)
@@ -2510,7 +2543,11 @@ void CodeBlock::visitWeakReferences(SlotVisitor& visitor)
 void CodeBlock::finalizeUnconditionally()
 {
     Interpreter* interpreter = m_vm->interpreter;
-    if (JITCode::couldBeInterpreted(jitType())) {
+    bool ownedByWebAssemblyExecutable = false;
+#if ENABLE(WEBASSEMBLY)
+    ownedByWebAssemblyExecutable = m_ownerExecutable->isWebAssemblyExecutable();
+#endif
+    if (JITCode::couldBeInterpreted(jitType()) && !ownedByWebAssemblyExecutable) {
         const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
         for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
             Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]];
@@ -2915,7 +2952,7 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset, Requir
 unsigned CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
 {
     RELEASE_ASSERT(bytecodeOffset < instructions().size());
-    return m_ownerExecutable->firstLine() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset);
+    return ownerScriptExecutable()->firstLine() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset);
 }
 
 unsigned CodeBlock::columnNumberForBytecodeOffset(unsigned bytecodeOffset)
@@ -2934,7 +2971,7 @@ void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& d
     m_unlinkedCode->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
     divot += m_sourceOffset;
     column += line ? 1 : firstLineColumnOffset();
-    line += m_ownerExecutable->firstLine();
+    line += ownerScriptExecutable()->firstLine();
 }
 
 bool CodeBlock::hasOpDebugForLineAndColumn(unsigned line, unsigned column)
@@ -3011,12 +3048,12 @@ void CodeBlock::linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo* inco
 
 void CodeBlock::install()
 {
-    ownerExecutable()->installCode(this);
+    ownerScriptExecutable()->installCode(this);
 }
 
 PassRefPtr<CodeBlock> CodeBlock::newReplacement()
 {
-    return ownerExecutable()->newReplacementCodeBlockFor(specializationKind());
+    return ownerScriptExecutable()->newReplacementCodeBlockFor(specializationKind());
 }
 
 #if ENABLE(JIT)
@@ -3051,6 +3088,18 @@ DFG::CapabilityLevel FunctionCodeBlock::capabilityLevelInternal()
         return DFG::functionForConstructCapabilityLevel(this);
     return DFG::functionForCallCapabilityLevel(this);
 }
+
+#if ENABLE(WEBASSEMBLY)
+CodeBlock* WebAssemblyCodeBlock::replacement()
+{
+    return nullptr;
+}
+
+DFG::CapabilityLevel WebAssemblyCodeBlock::capabilityLevelInternal()
+{
+    return DFG::CannotCompile;
+}
+#endif
 #endif
 
 void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail)
@@ -3603,6 +3652,10 @@ void CodeBlock::updateAllArrayPredictions()
 
 void CodeBlock::updateAllPredictions()
 {
+#if ENABLE(WEBASSEMBLY)
+    if (m_ownerExecutable->isWebAssemblyExecutable())
+        return;
+#endif
     updateAllValueProfilePredictions();
     updateAllArrayPredictions();
 }
@@ -3920,7 +3973,7 @@ void CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler(Vector<Instruct
             RELEASE_ASSERT(vm()->interpreter->getOpcodeID(instructions[endIdx].u.opcode) == op_profile_control_flow);
             basicBlockEndOffset = instructions[endIdx + 1].u.operand - 1;
         } else {
-            basicBlockEndOffset = m_sourceOffset + m_ownerExecutable->source().length() - 1; // Offset before the closing brace.
+            basicBlockEndOffset = m_sourceOffset + ownerScriptExecutable()->source().length() - 1; // Offset before the closing brace.
             basicBlockStartOffset = std::min(basicBlockStartOffset, basicBlockEndOffset); // Some start offsets may be at the closing brace, ensure it is the offset before.
         }
 
@@ -3948,7 +4001,7 @@ void CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler(Vector<Instruct
             continue;
         }
 
-        BasicBlockLocation* basicBlockLocation = vm()->controlFlowProfiler()->getBasicBlockLocation(m_ownerExecutable->sourceID(), basicBlockStartOffset, basicBlockEndOffset);
+        BasicBlockLocation* basicBlockLocation = vm()->controlFlowProfiler()->getBasicBlockLocation(ownerScriptExecutable()->sourceID(), basicBlockStartOffset, basicBlockEndOffset);
 
         // Find all functions that are enclosed within the range: [basicBlockStartOffset, basicBlockEndOffset]
         // and insert these functions' start/end offsets as gaps in the current BasicBlockLocation.
index 9499405..cb9ebd6 100644 (file)
@@ -96,6 +96,9 @@ protected:
     CodeBlock(CopyParsedBlockTag, CodeBlock& other);
         
     CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*, PassRefPtr<SourceProvider>, unsigned sourceOffset, unsigned firstLineColumnOffset);
+#if ENABLE(WEBASSEMBLY)
+    CodeBlock(WebAssemblyExecutable* ownerExecutable, VM&, JSGlobalObject*);
+#endif
 
     WriteBarrier<JSGlobalObject> m_globalObject;
     Heap* m_heap;
@@ -303,7 +306,8 @@ public:
 
     void jettison(Profiler::JettisonReason, ReoptimizationMode = DontCountReoptimization, const FireDetail* = nullptr);
     
-    ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); }
+    ExecutableBase* ownerExecutable() const { return m_ownerExecutable.get(); }
+    ScriptExecutable* ownerScriptExecutable() const { return jsCast<ScriptExecutable*>(m_ownerExecutable.get()); }
 
     void setVM(VM* vm) { m_vm = vm; }
     VM* vm() { return m_vm; }
@@ -346,7 +350,15 @@ public:
         return m_needsActivation;
     }
     
-    CodeType codeType() const { return m_unlinkedCode->codeType(); }
+    CodeType codeType() const
+    {
+#if ENABLE(WEBASSEMBLY)
+        if (m_ownerExecutable->isWebAssemblyExecutable())
+            return FunctionCode;
+#endif
+        return m_unlinkedCode->codeType();
+    }
+
     PutPropertySlot::Context putByIdContext() const
     {
         if (codeType() == EvalCode)
@@ -983,7 +995,7 @@ private:
             unsigned m_numBreakpoints : 30;
         };
     };
-    WriteBarrier<ScriptExecutable> m_ownerExecutable;
+    WriteBarrier<ExecutableBase> m_ownerExecutable;
     VM* m_vm;
 
     RefCountedArray<Instruction> m_instructions;
@@ -1134,6 +1146,27 @@ protected:
 #endif
 };
 
+#if ENABLE(WEBASSEMBLY)
+class WebAssemblyCodeBlock : public CodeBlock {
+public:
+    WebAssemblyCodeBlock(CopyParsedBlockTag, WebAssemblyCodeBlock& other)
+        : CodeBlock(CopyParsedBlock, other)
+    {
+    }
+
+    WebAssemblyCodeBlock(WebAssemblyExecutable* ownerExecutable, VM& vm, JSGlobalObject* globalObject)
+        : CodeBlock(ownerExecutable, vm, globalObject)
+    {
+    }
+
+#if ENABLE(JIT)
+protected:
+    virtual CodeBlock* replacement() override;
+    virtual DFG::CapabilityLevel capabilityLevelInternal() override;
+#endif
+};
+#endif
+
 inline Register& ExecState::r(int index)
 {
     CodeBlock* codeBlock = this->codeBlock();
index 3538372..c6f14a9 100644 (file)
@@ -227,7 +227,7 @@ void Debugger::registerCodeBlock(CodeBlock* codeBlock)
 
 void Debugger::toggleBreakpoint(CodeBlock* codeBlock, Breakpoint& breakpoint, BreakpointState enabledOrNot)
 {
-    ScriptExecutable* executable = codeBlock->ownerExecutable();
+    ScriptExecutable* executable = codeBlock->ownerScriptExecutable();
 
     SourceID sourceID = static_cast<SourceID>(executable->sourceID());
     if (breakpoint.sourceID != sourceID)
index bf093e8..d383c3f 100644 (file)
@@ -242,7 +242,7 @@ SourceID DebuggerCallFrame::sourceIDForCallFrame(CallFrame* callFrame)
     CodeBlock* codeBlock = callFrame->codeBlock();
     if (!codeBlock)
         return noSourceID;
-    return codeBlock->ownerExecutable()->sourceID();
+    return codeBlock->ownerScriptExecutable()->sourceID();
 }
 
 JSValue DebuggerCallFrame::thisValueForCallFrame(CallFrame* callFrame)
index 0a1624e..7f65052 100644 (file)
@@ -939,7 +939,7 @@ private:
         CodeBlock* m_profiledBlock;
         InlineCallFrame* m_inlineCallFrame;
         
-        ScriptExecutable* executable() { return m_codeBlock->ownerExecutable(); }
+        ScriptExecutable* executable() { return m_codeBlock->ownerScriptExecutable(); }
         
         QueryableExitProfile m_exitProfile;
         
@@ -1252,8 +1252,8 @@ unsigned ByteCodeParser::inliningCost(CallVariant callee, int argumentCountInclu
         dataLog("    Might inline function: ", mightInlineFunctionFor(codeBlock, kind), "\n");
         dataLog("    Might compile function: ", mightCompileFunctionFor(codeBlock, kind), "\n");
         dataLog("    Is supported for inlining: ", isSupportedForInlining(codeBlock), "\n");
-        dataLog("    Needs activation: ", codeBlock->ownerExecutable()->needsActivation(), "\n");
-        dataLog("    Is inlining candidate: ", codeBlock->ownerExecutable()->isInliningCandidate(), "\n");
+        dataLog("    Needs activation: ", codeBlock->ownerScriptExecutable()->needsActivation(), "\n");
+        dataLog("    Is inlining candidate: ", codeBlock->ownerScriptExecutable()->isInliningCandidate(), "\n");
     }
     if (!canInline(capabilityLevel)) {
         if (verbose)
@@ -4436,7 +4436,7 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
         byteCodeParser->m_graph.freeze(codeBlock->ownerExecutable());
         // The owner is the machine code block, and we already have a barrier on that when the
         // plan finishes.
-        m_inlineCallFrame->executable.setWithoutWriteBarrier(codeBlock->ownerExecutable());
+        m_inlineCallFrame->executable.setWithoutWriteBarrier(codeBlock->ownerScriptExecutable());
         m_inlineCallFrame->setStackOffset(inlineCallFrameStart.offset() - JSStack::CallFrameHeaderSize);
         if (callee) {
             m_inlineCallFrame->calleeRecovery = ValueRecovery::constant(callee);
@@ -4529,7 +4529,7 @@ void ByteCodeParser::parseCodeBlock()
         }
         dataLog(
             ": needsActivation = ", codeBlock->needsActivation(),
-            ", isStrictMode = ", codeBlock->ownerExecutable()->isStrictMode(), "\n");
+            ", isStrictMode = ", codeBlock->ownerScriptExecutable()->isStrictMode(), "\n");
         codeBlock->baselineVersion()->dumpBytecode();
     }
     
index 9044a07..be62b9f 100644 (file)
@@ -44,32 +44,36 @@ bool isSupported()
 
 bool isSupportedForInlining(CodeBlock* codeBlock)
 {
-    return codeBlock->ownerExecutable()->isInliningCandidate();
+#if ENABLE(WEBASSEMBLY)
+    if (codeBlock->ownerExecutable()->isWebAssemblyExecutable())
+        return false;
+#endif
+    return codeBlock->ownerScriptExecutable()->isInliningCandidate();
 }
 
 bool mightCompileEval(CodeBlock* codeBlock)
 {
     return isSupported()
         && codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount()
-        && codeBlock->ownerExecutable()->isOkToOptimize();
+        && codeBlock->ownerScriptExecutable()->isOkToOptimize();
 }
 bool mightCompileProgram(CodeBlock* codeBlock)
 {
     return isSupported()
         && codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount()
-        && codeBlock->ownerExecutable()->isOkToOptimize();
+        && codeBlock->ownerScriptExecutable()->isOkToOptimize();
 }
 bool mightCompileFunctionForCall(CodeBlock* codeBlock)
 {
     return isSupported()
         && codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount()
-        && codeBlock->ownerExecutable()->isOkToOptimize();
+        && codeBlock->ownerScriptExecutable()->isOkToOptimize();
 }
 bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
 {
     return isSupported()
         && codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount()
-        && codeBlock->ownerExecutable()->isOkToOptimize();
+        && codeBlock->ownerScriptExecutable()->isOkToOptimize();
 }
 
 bool mightInlineFunctionForCall(CodeBlock* codeBlock)
index 4db471b..46476d4 100644 (file)
@@ -345,7 +345,7 @@ public:
     ScriptExecutable* executableFor(InlineCallFrame* inlineCallFrame)
     {
         if (!inlineCallFrame)
-            return m_codeBlock->ownerExecutable();
+            return m_codeBlock->ownerScriptExecutable();
         
         return inlineCallFrame->executable.get();
     }
index 02dbe4f..d85765f 100644 (file)
@@ -112,7 +112,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
     sanitizeStackForVM(vm);
     
     if (bytecodeIndex)
-        codeBlock->ownerExecutable()->setDidTryToEnterInLoop(true);
+        codeBlock->ownerScriptExecutable()->setDidTryToEnterInLoop(true);
     
     if (codeBlock->jitType() != JITCode::DFGJIT) {
         RELEASE_ASSERT(codeBlock->jitType() == JITCode::FTLJIT);
index f33d405..fd71274 100644 (file)
@@ -66,6 +66,10 @@ public:
         }
 
         if (m_remainingCapacityForFrameCapture) {
+#if ENABLE(WEBASSEMBLY)
+            if (visitor->codeBlock()->ownerExecutable()->isWebAssemblyExecutable())
+                return StackVisitor::Continue;
+#endif
             unsigned line;
             unsigned column;
             visitor->computeLineAndColumn(line, column);
index 10501c1..66fa8ec 100644 (file)
@@ -168,7 +168,7 @@ JSValue eval(CallFrame* callFrame)
         ASSERT(!callFrame->vm().exception());
 
         ThisTDZMode thisTDZMode = callerCodeBlock->unlinkedCodeBlock()->constructorKind() == ConstructorKind::Derived ? ThisTDZMode::AlwaysCheck : ThisTDZMode::CheckIfNeeded;
-        eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), thisTDZMode, programSource, callerScopeChain);
+        eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerScriptExecutable(), callerCodeBlock->isStrictMode(), thisTDZMode, programSource, callerScopeChain);
         if (!eval)
             return jsUndefined();
     }
@@ -515,6 +515,16 @@ String StackFrame::toString(CallFrame* callFrame)
     return traceBuild.toString().impl();
 }
 
+static inline bool isWebAssemblyExecutable(ExecutableBase* executable)
+{
+#if !ENABLE(WEBASSEMBLY)
+    UNUSED_PARAM(executable);
+    return false;
+#else
+    return executable->isWebAssemblyExecutable();
+#endif
+}
+
 class GetStackTraceFunctor {
 public:
     GetStackTraceFunctor(VM& vm, Vector<StackFrame>& results, size_t remainingCapacity)
@@ -528,15 +538,17 @@ public:
     {
         VM& vm = m_vm;
         if (m_remainingCapacityForFrameCapture) {
-            if (visitor->isJSFrame() && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) {
+            if (visitor->isJSFrame()
+                && !isWebAssemblyExecutable(visitor->codeBlock()->ownerExecutable())
+                && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) {
                 CodeBlock* codeBlock = visitor->codeBlock();
                 StackFrame s = {
                     Strong<JSObject>(vm, visitor->callee()),
                     getStackFrameCodeType(visitor),
-                    Strong<ScriptExecutable>(vm, codeBlock->ownerExecutable()),
+                    Strong<ScriptExecutable>(vm, codeBlock->ownerScriptExecutable()),
                     Strong<UnlinkedCodeBlock>(vm, codeBlock->unlinkedCodeBlock()),
                     codeBlock->source(),
-                    codeBlock->ownerExecutable()->firstLine(),
+                    codeBlock->ownerScriptExecutable()->firstLine(),
                     codeBlock->firstLineColumnOffset(),
                     codeBlock->sourceOffset(),
                     visitor->bytecodeOffset(),
@@ -629,7 +641,7 @@ public:
         m_codeBlock = visitor->codeBlock();
         unsigned bytecodeOffset = visitor->bytecodeOffset();
 
-        if (m_isTermination || !(m_handler = m_codeBlock ? m_codeBlock->handlerForBytecodeOffset(bytecodeOffset) : nullptr)) {
+        if (m_isTermination || !(m_handler = (m_codeBlock && !isWebAssemblyExecutable(m_codeBlock->ownerExecutable())) ? m_codeBlock->handlerForBytecodeOffset(bytecodeOffset) : nullptr)) {
             if (!unwindCallFrame(visitor)) {
                 if (LegacyProfiler* profiler = vm.enabledProfiler())
                     profiler->exceptionUnwind(m_callFrame);
index d376db4..3f2b914 100644 (file)
@@ -221,7 +221,7 @@ String StackVisitor::Frame::sourceURL()
     case CodeType::Eval:
     case CodeType::Function:
     case CodeType::Global: {
-        String sourceURL = codeBlock()->ownerExecutable()->sourceURL();
+        String sourceURL = codeBlock()->ownerScriptExecutable()->sourceURL();
         if (!sourceURL.isEmpty())
             traceLine = sourceURL.impl();
         break;
@@ -292,11 +292,11 @@ void StackVisitor::Frame::computeLineAndColumn(unsigned& line, unsigned& column)
     unsigned divotColumn = 0;
     retrieveExpressionInfo(divot, unusedStartOffset, unusedEndOffset, divotLine, divotColumn);
 
-    line = divotLine + codeBlock->ownerExecutable()->firstLine();
+    line = divotLine + codeBlock->ownerScriptExecutable()->firstLine();
     column = divotColumn + (divotLine ? 1 : codeBlock->firstLineColumnOffset());
 
-    if (codeBlock->ownerExecutable()->hasOverrideLineNumber())
-        line = codeBlock->ownerExecutable()->overrideLineNumber();
+    if (codeBlock->ownerScriptExecutable()->hasOverrideLineNumber())
+        line = codeBlock->ownerScriptExecutable()->overrideLineNumber();
 }
 
 void StackVisitor::Frame::retrieveExpressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
index a1f7656..cb7bbf6 100644 (file)
@@ -848,9 +848,22 @@ char* JIT_OPERATION operationLinkCall(ExecState* execCallee, CallLinkInfo* callL
 
     MacroAssemblerCodePtr codePtr;
     CodeBlock* codeBlock = 0;
-    if (executable->isHostFunction())
+    if (executable->isHostFunction()) {
         codePtr = executable->entrypointFor(*vm, kind, MustCheckArity, callLinkInfo->registerPreservationMode());
-    else {
+#if ENABLE(WEBASSEMBLY)
+    } else if (executable->isWebAssemblyExecutable()) {
+        WebAssemblyExecutable* webAssemblyExecutable = static_cast<WebAssemblyExecutable*>(executable);
+        webAssemblyExecutable->prepareForExecution(execCallee);
+        codeBlock = webAssemblyExecutable->codeBlockForCall();
+        ASSERT(codeBlock);
+        ArityCheckMode arity;
+        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
+            arity = MustCheckArity;
+        else
+            arity = ArityCheckNotRequired;
+        codePtr = webAssemblyExecutable->entrypointFor(*vm, kind, arity, callLinkInfo->registerPreservationMode());
+#endif
+    } else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
 
         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct) {
@@ -896,17 +909,33 @@ inline char* virtualForWithFunction(
     JSScope* scope = function->scopeUnchecked();
     ExecutableBase* executable = function->executable();
     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
-        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
+        bool isWebAssemblyExecutable = false;
+#if ENABLE(WEBASSEMBLY)
+        isWebAssemblyExecutable = executable->isWebAssemblyExecutable();
+#endif
+        if (!isWebAssemblyExecutable) {
+            FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
 
-        if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct) {
-            exec->vm().throwException(exec, createNotAConstructorError(exec, function));
-            return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
-        }
+            if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct) {
+                exec->vm().throwException(exec, createNotAConstructorError(exec, function));
+                return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
+            }
 
-        JSObject* error = functionExecutable->prepareForExecution(execCallee, function, scope, kind);
-        if (error) {
-            exec->vm().throwException(exec, error);
-            return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
+            JSObject* error = functionExecutable->prepareForExecution(execCallee, function, scope, kind);
+            if (error) {
+                exec->vm().throwException(exec, error);
+                return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
+            }
+        } else {
+#if ENABLE(WEBASSEMBLY)
+            if (!isCall(kind)) {
+                exec->vm().throwException(exec, createNotAConstructorError(exec, function));
+                return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
+            }
+
+            WebAssemblyExecutable* webAssemblyExecutable = static_cast<WebAssemblyExecutable*>(executable);
+            webAssemblyExecutable->prepareForExecution(execCallee);
+#endif
         }
     }
     return reinterpret_cast<char*>(executable->entrypointFor(
index 3d7cbb3..c5db53b 100644 (file)
@@ -1742,8 +1742,13 @@ void linkPolymorphicCall(
         if (variant.executable()->isHostFunction())
             codeBlock = nullptr;
         else {
-            codeBlock = jsCast<FunctionExecutable*>(variant.executable())->codeBlockForCall();
-            
+            ExecutableBase* executable = variant.executable();
+#if ENABLE(WEBASSEMBLY)
+            if (executable->isWebAssemblyExecutable())
+                codeBlock = jsCast<WebAssemblyExecutable*>(executable)->codeBlockForCall();
+            else
+#endif
+                codeBlock = jsCast<FunctionExecutable*>(executable)->codeBlockForCall();
             // If we cannot handle a callee, assume that it's better for this whole thing to be a
             // virtual call.
             if (exec->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.callType() == CallLinkInfo::CallVarargs || callLinkInfo.callType() == CallLinkInfo::ConstructVarargs) {
index e926f52..7313fce 100644 (file)
@@ -132,8 +132,8 @@ void Data::performAssertions(VM& vm)
     ASSERT(maxFrameExtentForSlowPathCall == 64);
 #endif
     ASSERT(StringType == 6);
-    ASSERT(ObjectType == 18);
-    ASSERT(FinalObjectType == 19);
+    ASSERT(ObjectType == 19);
+    ASSERT(FinalObjectType == 20);
     ASSERT(MasqueradesAsUndefined == 1);
     ASSERT(ImplementsHasInstance == 2);
     ASSERT(ImplementsDefaultHasInstance == 8);
index 2a24883..27cbcc5 100644 (file)
@@ -1116,9 +1116,14 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
 
     MacroAssemblerCodePtr codePtr;
     CodeBlock* codeBlock = 0;
-    if (executable->isHostFunction())
+    bool isWebAssemblyExecutable = false;
+#if ENABLE(WEBASSEMBLY)
+    isWebAssemblyExecutable = executable->isWebAssemblyExecutable();
+#endif
+
+    if (executable->isHostFunction()) {
         codePtr = executable->entrypointFor(vm, kind, MustCheckArity, RegisterPreservationNotRequired);
-    else {
+    } else if (!isWebAssemblyExecutable) {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
 
         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct)
@@ -1135,6 +1140,19 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
         else
             arity = ArityCheckNotRequired;
         codePtr = functionExecutable->entrypointFor(vm, kind, arity, RegisterPreservationNotRequired);
+    } else {
+#if ENABLE(WEBASSEMBLY)
+        WebAssemblyExecutable* webAssemblyExecutable = static_cast<WebAssemblyExecutable*>(executable);
+        webAssemblyExecutable->prepareForExecution(execCallee);
+        codeBlock = webAssemblyExecutable->codeBlockForCall();
+        ASSERT(codeBlock);
+        ArityCheckMode arity;
+        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
+            arity = MustCheckArity;
+        else
+            arity = ArityCheckNotRequired;
+        codePtr = webAssemblyExecutable->entrypointFor(vm, kind, arity, RegisterPreservationNotRequired);
+#endif
     }
     
     ASSERT(!!codePtr);
index 5ad8346..136c916 100644 (file)
@@ -161,8 +161,8 @@ const SlowPutArrayStorageShape = 30
 
 # Type constants.
 const StringType = 6
-const ObjectType = 18
-const FinalObjectType = 19
+const ObjectType = 19
+const FinalObjectType = 20
 
 # Type flags constants.
 const MasqueradesAsUndefined = 1
index acbe146..7580833 100644 (file)
@@ -525,7 +525,7 @@ SLOW_PATH_DECL(slow_path_to_primitive)
 SLOW_PATH_DECL(slow_path_enter)
 {
     BEGIN();
-    ScriptExecutable* ownerExecutable = exec->codeBlock()->ownerExecutable();
+    ExecutableBase* ownerExecutable = exec->codeBlock()->ownerExecutable();
     Heap::heap(ownerExecutable)->writeBarrier(ownerExecutable);
     END();
 }
index 1b9a73d..e485479 100644 (file)
 #include "DFGDriver.h"
 #include "JIT.h"
 #include "JSCInlines.h"
+#include "JSWASMModule.h"
 #include "LLIntEntrypoint.h"
 #include "Parser.h"
 #include "ProfilerDatabase.h"
 #include "TypeProfiler.h"
+#include "WASMFunctionParser.h"
 #include <wtf/CommaPrinter.h>
 #include <wtf/Vector.h>
 #include <wtf/text/StringBuilder.h>
@@ -562,6 +564,62 @@ FunctionExecutable* FunctionExecutable::fromGlobalCode(
     return unlinkedExecutable->link(exec.vm(), source, overrideLineNumber);
 }
 
+#if ENABLE(WEBASSEMBLY)
+const ClassInfo WebAssemblyExecutable::s_info = { "WebAssemblyExecutable", &ExecutableBase::s_info, 0, CREATE_METHOD_TABLE(WebAssemblyExecutable) };
+
+WebAssemblyExecutable::WebAssemblyExecutable(VM& vm, const SourceCode& source, JSWASMModule* module, unsigned functionIndex)
+    : ExecutableBase(vm, vm.webAssemblyExecutableStructure.get(), NUM_PARAMETERS_NOT_COMPILED)
+    , m_source(source)
+    , m_module(vm, this, module)
+    , m_functionIndex(functionIndex)
+{
+}
+
+void WebAssemblyExecutable::destroy(JSCell* cell)
+{
+    static_cast<WebAssemblyExecutable*>(cell)->WebAssemblyExecutable::~WebAssemblyExecutable();
+}
+
+void WebAssemblyExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    WebAssemblyExecutable* thisObject = jsCast<WebAssemblyExecutable*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    ExecutableBase::visitChildren(thisObject, visitor);
+    if (thisObject->m_codeBlockForCall)
+        thisObject->m_codeBlockForCall->visitAggregate(visitor);
+    visitor.append(&thisObject->m_module);
+}
+
+void WebAssemblyExecutable::clearCode()
+{
+    m_codeBlockForCall = nullptr;
+    Base::clearCode();
+}
+
+void WebAssemblyExecutable::prepareForExecution(ExecState* exec)
+{
+    if (hasJITCodeForCall())
+        return;
+
+    VM& vm = exec->vm();
+    DeferGC deferGC(vm.heap);
+
+    RefPtr<WebAssemblyCodeBlock> codeBlock = adoptRef(new WebAssemblyCodeBlock(
+        this, vm, exec->lexicalGlobalObject()));
+
+    WASMFunctionParser::compile(vm, codeBlock.get(), m_module.get(), m_source, m_functionIndex);
+
+    m_jitCodeForCall = codeBlock->jitCode();
+    m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr();
+    m_jitCodeForCallWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr();
+    m_numParametersForCall = codeBlock->numParameters();
+
+    m_codeBlockForCall = codeBlock;
+
+    Heap::heap(this)->writeBarrier(this);
+}
+#endif
+
 void ExecutableBase::dump(PrintStream& out) const
 {
     ExecutableBase* realThis = const_cast<ExecutableBase*>(this);
index 234f2cd..a9c41c4 100644 (file)
@@ -50,9 +50,11 @@ class CodeBlock;
 class Debugger;
 class EvalCodeBlock;
 class FunctionCodeBlock;
+class JSScope;
+class JSWASMModule;
 class LLIntOffsetsExtractor;
 class ProgramCodeBlock;
-class JSScope;
+class WebAssemblyCodeBlock;
     
 enum CompilationKind { FirstCompilation, OptimizingCompilation };
 
@@ -92,15 +94,15 @@ public:
         
     CodeBlockHash hashFor(CodeSpecializationKind) const;
 
-    bool isEvalExecutable()
+    bool isEvalExecutable() const
     {
         return type() == EvalExecutableType;
     }
-    bool isFunctionExecutable()
+    bool isFunctionExecutable() const
     {
         return type() == FunctionExecutableType;
     }
-    bool isProgramExecutable()
+    bool isProgramExecutable() const
     {
         return type() == ProgramExecutableType;
     }
@@ -111,6 +113,13 @@ public:
         return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
     }
 
+#if ENABLE(WEBASSEMBLY)
+    bool isWebAssemblyExecutable() const
+    {
+        return type() == WebAssemblyExecutableType;
+    }
+#endif
+
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); }
         
     void clearCode();
@@ -386,7 +395,7 @@ public:
 
     CodeFeatures features() const { return m_features; }
         
-    DECLARE_INFO;
+    DECLARE_EXPORT_INFO;
 
     void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine, unsigned startColumn, unsigned endColumn)
     {
@@ -562,7 +571,7 @@ public:
 
     static void destroy(JSCell*);
         
-    UnlinkedFunctionExecutable* unlinkedExecutable()
+    UnlinkedFunctionExecutable* unlinkedExecutable() const
     {
         return m_unlinkedExecutable.get();
     }
@@ -676,6 +685,50 @@ private:
     WriteBarrier<InferredValue> m_singletonFunction;
 };
 
+#if ENABLE(WEBASSEMBLY)
+class WebAssemblyExecutable final : public ExecutableBase {
+public:
+    typedef ExecutableBase Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
+    static WebAssemblyExecutable* create(VM& vm, const SourceCode& source, JSWASMModule* module, unsigned functionIndex)
+    {
+        WebAssemblyExecutable* executable = new (NotNull, allocateCell<WebAssemblyExecutable>(vm.heap)) WebAssemblyExecutable(vm, source, module, functionIndex);
+        executable->finishCreation(vm);
+        return executable;
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
+    {
+        return Structure::create(vm, globalObject, proto, TypeInfo(WebAssemblyExecutableType, StructureFlags), info());
+    }
+
+    static void destroy(JSCell*);
+
+    DECLARE_INFO;
+
+    void clearCode();
+
+    void prepareForExecution(ExecState*);
+
+    WebAssemblyCodeBlock* codeBlockForCall()
+    {
+        return m_codeBlockForCall.get();
+    }
+
+private:
+    WebAssemblyExecutable(VM&, const SourceCode&, JSWASMModule*, unsigned functionIndex);
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+    SourceCode m_source;
+    WriteBarrier<JSWASMModule> m_module;
+    unsigned m_functionIndex;
+
+    RefPtr<WebAssemblyCodeBlock> m_codeBlockForCall;
+};
+#endif
+
 inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
 {
     switch (executable->type()) {
@@ -685,6 +738,10 @@ inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
         return jsCast<ProgramExecutable*>(executable)->clearCode();
     case FunctionExecutableType:
         return jsCast<FunctionExecutable*>(executable)->clearCode();
+#if ENABLE(WEBASSEMBLY)
+    case WebAssemblyExecutableType:
+        return jsCast<WebAssemblyExecutable*>(executable)->clearCode();
+#endif
     default:
         return jsCast<NativeExecutable*>(executable)->clearCode();
     }
index 0f7354e..f83adf8 100644 (file)
@@ -67,6 +67,16 @@ JSFunction* JSFunction::create(VM& vm, FunctionExecutable* executable, JSScope*
     return result;
 }
 
+#if ENABLE(WEBASSEMBLY)
+JSFunction* JSFunction::create(VM& vm, WebAssemblyExecutable* executable, JSScope* scope)
+{
+    JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
+    ASSERT(function->structure()->globalObject());
+    function->finishCreation(vm);
+    return function;
+}
+#endif
+
 static inline NativeExecutable* getNativeExecutable(VM& vm, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
 {
 #if !ENABLE(JIT)
index 928350e..01ce36a 100644 (file)
@@ -40,6 +40,7 @@ class JSGlobalObject;
 class LLIntOffsetsExtractor;
 class NativeExecutable;
 class SourceCode;
+class WebAssemblyExecutable;
 namespace DFG {
 class SpeculativeJIT;
 class JITCompiler;
@@ -73,6 +74,9 @@ public:
     JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeStdFunction&&, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
 
     static JSFunction* create(VM&, FunctionExecutable*, JSScope*);
+#if ENABLE(WEBASSEMBLY)
+    static JSFunction* create(VM&, WebAssemblyExecutable*, JSScope*);
+#endif
 
     static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*);
     static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*, const String& name);
@@ -143,6 +147,10 @@ protected:
     JSFunction(VM&, FunctionExecutable*, JSScope*);
     JSFunction(VM&, FunctionExecutable*, JSScope*, Structure*);
 
+#if ENABLE(WEBASSEMBLY)
+    JSFunction(VM&, WebAssemblyExecutable*, JSScope*);
+#endif
+
     void finishCreation(VM&, NativeExecutable*, int length, const String& name);
     using Base::finishCreation;
 
index f059584..4f75ab9 100644 (file)
@@ -52,6 +52,15 @@ inline JSFunction::JSFunction(VM& vm, FunctionExecutable* executable, JSScope* s
 {
 }
 
+#if ENABLE(WEBASSEMBLY)
+inline JSFunction::JSFunction(VM& vm, WebAssemblyExecutable* executable, JSScope* scope)
+    : Base(vm, scope, scope->globalObject()->functionStructure())
+    , m_executable(vm, this, executable)
+    , m_rareData()
+{
+}
+#endif
+
 inline FunctionExecutable* JSFunction::jsExecutable() const
 {
     ASSERT(!isHostFunctionNonInline());
@@ -66,6 +75,10 @@ inline bool JSFunction::isHostFunction() const
 
 inline bool JSFunction::isBuiltinFunction() const
 {
+#if ENABLE(WEBASSEMBLY)
+    if (m_executable->isWebAssemblyExecutable())
+        return false;
+#endif
     return !isHostFunction() && jsExecutable()->isBuiltinFunction();
 }
 
index 40326ce..1596e65 100644 (file)
@@ -42,6 +42,7 @@ enum JSType : uint8_t {
     EvalExecutableType,
     ProgramExecutableType,
     FunctionExecutableType,
+    WebAssemblyExecutableType,
 
     UnlinkedFunctionExecutableType,
     UnlinkedProgramCodeBlockType,
index 5af6caf..c637e56 100644 (file)
@@ -221,6 +221,9 @@ VM::VM(VMType vmType, HeapType heapType)
     evalExecutableStructure.set(*this, EvalExecutable::createStructure(*this, 0, jsNull()));
     programExecutableStructure.set(*this, ProgramExecutable::createStructure(*this, 0, jsNull()));
     functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, 0, jsNull()));
+#if ENABLE(WEBASSEMBLY)
+    webAssemblyExecutableStructure.set(*this, WebAssemblyExecutable::createStructure(*this, 0, jsNull()));
+#endif
     regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull()));
     symbolStructure.set(*this, Symbol::createStructure(*this, 0, jsNull()));
     symbolTableStructure.set(*this, SymbolTable::createStructure(*this, 0, jsNull()));
index bf925b5..ea3f856 100644 (file)
@@ -279,6 +279,9 @@ public:
     Strong<Structure> evalExecutableStructure;
     Strong<Structure> programExecutableStructure;
     Strong<Structure> functionExecutableStructure;
+#if ENABLE(WEBASSEMBLY)
+    Strong<Structure> webAssemblyExecutableStructure;
+#endif
     Strong<Structure> regExpStructure;
     Strong<Structure> symbolStructure;
     Strong<Structure> symbolTableStructure;
index a7266b5..467b3e6 100644 (file)
@@ -64,6 +64,8 @@ public:
     Vector<WASMFunctionDeclaration>& functionDeclarations() { return m_functionDeclarations; }
     Vector<WASMFunctionPointerTable>& functionPointerTables() { return m_functionPointerTables; }
 
+    Vector<WriteBarrier<JSFunction>>& functions() { return m_functions; }
+
 private:
     JSWASMModule(VM& vm, Structure* structure)
         : Base(vm, structure)
index d689f56..78a1a19 100644 (file)
@@ -28,7 +28,9 @@
 
 #if ENABLE(WEBASSEMBLY)
 
+#include "CCallHelpers.h"
 #include "JSWASMModule.h"
+#include "LinkBuffer.h"
 #include "WASMFunctionSyntaxChecker.h"
 
 #define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return 0; } while (0)
@@ -59,6 +61,27 @@ bool WASMFunctionParser::checkSyntax(JSWASMModule* module, const SourceCode& sou
     return true;
 }
 
+void WASMFunctionParser::compile(VM& vm, CodeBlock* codeBlock, JSWASMModule* module, const SourceCode&, size_t functionIndex)
+{
+    // FIXME: Actually compile the code.
+    CCallHelpers jit(&vm, codeBlock);
+    MacroAssembler::Label beginLabel = jit.label();
+    jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(0))), GPRInfo::returnValueGPR);
+    jit.ret();
+    MacroAssembler::Label arityCheck = jit.label();
+    jit.jump(beginLabel);
+
+    LinkBuffer patchBuffer(vm, jit, codeBlock, JITCompilationMustSucceed);
+    MacroAssemblerCodePtr withArityCheck = patchBuffer.locationOf(arityCheck);
+    MacroAssembler::CodeRef result = FINALIZE_CODE(patchBuffer, ("Baseline JIT code for WebAssembly"));
+    codeBlock->setJITCode(adoptRef(new DirectJITCode(result, withArityCheck, JITCode::BaselineJIT)));
+    codeBlock->capabilityLevel();
+
+    uint32_t signatureIndex = module->functionDeclarations()[functionIndex].signatureIndex;
+    const WASMSignature& signature = module->signatures()[signatureIndex];
+    codeBlock->setNumParameters(1 + signature.arguments.size());
+}
+
 template <class Context>
 bool WASMFunctionParser::parseFunction(Context& context)
 {
index 4d6313a..704c46c 100644 (file)
 
 namespace JSC {
 
+class CodeBlock;
 class JSWASMModule;
+class VM;
 
 class WASMFunctionParser {
 public:
     static bool checkSyntax(JSWASMModule*, const SourceCode&, size_t functionIndex, unsigned startOffsetInSource, unsigned& endOffsetInSource, String& errorMessage);
+    static void compile(VM&, CodeBlock*, JSWASMModule*, const SourceCode&, size_t functionIndex);
 
 private:
     WASMFunctionParser(JSWASMModule* module, const SourceCode& source, size_t functionIndex)
index 50dbb8e..67e3aa6 100644 (file)
 
 namespace JSC {
 
-WASMModuleParser::WASMModuleParser(const SourceCode& source)
-    : m_source(source)
+WASMModuleParser::WASMModuleParser(VM& vm, JSGlobalObject* globalObject, const SourceCode& source)
+    : m_vm(vm)
+    , m_globalObject(vm, globalObject)
+    , m_source(source)
     , m_reader(static_cast<WebAssemblySourceProvider*>(source.provider())->data())
 {
 }
 
-JSWASMModule* WASMModuleParser::parse(VM& vm, JSGlobalObject* globalObject, String& errorMessage)
+JSWASMModule* WASMModuleParser::parse(String& errorMessage)
 {
-    m_module.set(vm, JSWASMModule::create(vm, globalObject->wasmModuleStructure()));
+    m_module.set(m_vm, JSWASMModule::create(m_vm, m_globalObject->wasmModuleStructure()));
     parseModule();
     if (!m_errorMessage.isNull()) {
         errorMessage = m_errorMessage;
@@ -217,6 +219,7 @@ void WASMModuleParser::parseFunctionDeclarationSection()
     uint32_t numberOfFunctionDeclarations;
     READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionDeclarations, "Cannot read the number of function declarations.");
     m_module->functionDeclarations().reserveInitialCapacity(numberOfFunctionDeclarations);
+    m_module->functions().reserveInitialCapacity(numberOfFunctionDeclarations);
     for (uint32_t i = 0; i < numberOfFunctionDeclarations; ++i) {
         WASMFunctionDeclaration functionDeclaration;
         READ_COMPACT_UINT32_OR_FAIL(functionDeclaration.signatureIndex, "Cannot read the signature index.");
@@ -265,6 +268,10 @@ void WASMModuleParser::parseFunctionDefinition(size_t functionIndex)
         return;
     }
     m_reader.setOffset(endOffsetInSource);
+
+    WebAssemblyExecutable* webAssemblyExecutable = WebAssemblyExecutable::create(m_vm, m_source, m_module.get(), functionIndex);
+    JSFunction* function = JSFunction::create(m_vm, webAssemblyExecutable, m_globalObject.get());
+    m_module->functions().uncheckedAppend(WriteBarrier<JSFunction>(m_vm, m_module.get(), function));
 }
 
 void WASMModuleParser::parseExportSection()
@@ -285,11 +292,11 @@ void WASMModuleParser::parseExportSection()
         for (uint32_t exportIndex = 0; exportIndex < numberOfExports; ++exportIndex) {
             String exportName;
             READ_STRING_OR_FAIL(exportName, "Cannot read the function export name.");
-            // FIXME: Check that exportName is legal.
             uint32_t functionIndex;
             READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
             FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
-            // FIXME: Export the function.
+            Identifier identifier = Identifier::fromString(&m_vm, exportName);
+            m_module->putDirect(m_vm, identifier, m_module->functions()[functionIndex].get());
         }
         break;
     }
@@ -300,8 +307,8 @@ void WASMModuleParser::parseExportSection()
 
 JSWASMModule* parseWebAssembly(ExecState* exec, const SourceCode& source, String& errorMessage)
 {
-    WASMModuleParser WASMModuleParser(source);
-    return WASMModuleParser.parse(exec->vm(), exec->lexicalGlobalObject(), errorMessage);
+    WASMModuleParser moduleParser(exec->vm(), exec->lexicalGlobalObject(), source);
+    return moduleParser.parse(errorMessage);
 }
 
 } // namespace JSC
index 30f1a56..e2f4fb7 100644 (file)
@@ -42,8 +42,8 @@ class VM;
 
 class WASMModuleParser {
 public:
-    WASMModuleParser(const SourceCode&);
-    JSWASMModule* parse(VM&, JSGlobalObject*, String& errorMessage);
+    WASMModuleParser(VM&, JSGlobalObject*, const SourceCode&);
+    JSWASMModule* parse(String& errorMessage);
 
 private:
     void parseModule();
@@ -57,6 +57,8 @@ private:
     void parseFunctionDefinition(size_t functionIndex);
     void parseExportSection();
 
+    VM& m_vm;
+    Strong<JSGlobalObject> m_globalObject;
     const SourceCode& m_source;
     WASMReader m_reader;
     Strong<JSWASMModule> m_module;
index 0064a57..b908af4 100644 (file)
@@ -1,3 +1,15 @@
+2015-08-28  Sukolsak Sakshuwong  <sukolsak@gmail.com>
+
+        Create WebAssembly functions
+        https://bugs.webkit.org/show_bug.cgi?id=148373
+
+        Reviewed by Filip Pizlo.
+
+        No new tests, because it is a function rename.
+
+        * testing/Internals.cpp:
+        (WebCore::Internals::parserMetaData):
+
 2015-08-28  Jer Noble  <jer.noble@apple.com>
 
         [iOS] Make the AllowsInlineMediaPlayback preference work in WebKit / WebKit2.
index 9812f3b..8f2ac09 100644 (file)
@@ -1463,7 +1463,7 @@ String Internals::parserMetaData(Deprecated::ScriptValue value)
         GetCallerCodeBlockFunctor iter;
         exec->iterate(iter);
         CodeBlock* codeBlock = iter.codeBlock();
-        executable = codeBlock->ownerExecutable(); 
+        executable = codeBlock->ownerScriptExecutable();
     } else if (code.isFunction()) {
         JSFunction* funcObj = JSC::jsCast<JSFunction*>(code.toObject(exec));
         executable = funcObj->jsExecutable();
@@ -1485,10 +1485,14 @@ String Internals::parserMetaData(Deprecated::ScriptValue value)
         result.append('"');
     } else if (executable->isEvalExecutable())
         result.appendLiteral("eval");
-    else {
-        ASSERT(executable->isProgramExecutable());
+    else if (executable->isProgramExecutable())
         result.appendLiteral("program");
-    }
+#if ENABLE(WEBASSEMBLY)
+    else if (executable->isWebAssemblyExecutable())
+        result.appendLiteral("WebAssembly");
+#endif
+    else
+        ASSERT_NOT_REACHED();
 
     result.appendLiteral(" { ");
     result.appendNumber(startLine);