Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (189122 => 189123)
--- trunk/Source/_javascript_Core/ChangeLog 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-08-28 21:07:22 UTC (rev 189123)
@@ -1,3 +1,123 @@
+2015-08-28 Sukolsak Sakshuwong <sukol...@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....@apple.com>
[Follow up] ScratchRegisterAllocator::preserveReusedRegistersByPushing() should allow room for C helper calls and keep sp properly aligned.
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -107,7 +107,7 @@
{
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 @@
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 @@
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(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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
}
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 @@
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::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 @@
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 @@
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::install()
{
- ownerExecutable()->installCode(this);
+ ownerScriptExecutable()->installCode(this);
}
PassRefPtr<CodeBlock> CodeBlock::newReplacement()
{
- return ownerExecutable()->newReplacementCodeBlockFor(specializationKind());
+ return ownerScriptExecutable()->newReplacementCodeBlockFor(specializationKind());
}
#if ENABLE(JIT)
@@ -3051,7 +3088,19 @@
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::updateAllPredictions()
{
+#if ENABLE(WEBASSEMBLY)
+ if (m_ownerExecutable->isWebAssemblyExecutable())
+ return;
+#endif
updateAllValueProfilePredictions();
updateAllArrayPredictions();
}
@@ -3920,7 +3973,7 @@
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 @@
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.
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (189122 => 189123)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2015-08-28 21:07:22 UTC (rev 189123)
@@ -96,6 +96,9 @@
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 @@
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 @@
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 @@
unsigned m_numBreakpoints : 30;
};
};
- WriteBarrier<ScriptExecutable> m_ownerExecutable;
+ WriteBarrier<ExecutableBase> m_ownerExecutable;
VM* m_vm;
RefCountedArray<Instruction> m_instructions;
@@ -1134,6 +1146,27 @@
#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();
Modified: trunk/Source/_javascript_Core/debugger/Debugger.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/debugger/Debugger.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/debugger/Debugger.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -227,7 +227,7 @@
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)
Modified: trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -242,7 +242,7 @@
CodeBlock* codeBlock = callFrame->codeBlock();
if (!codeBlock)
return noSourceID;
- return codeBlock->ownerExecutable()->sourceID();
+ return codeBlock->ownerScriptExecutable()->sourceID();
}
JSValue DebuggerCallFrame::thisValueForCallFrame(CallFrame* callFrame)
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -939,7 +939,7 @@
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 @@
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->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 @@
}
dataLog(
": needsActivation = ", codeBlock->needsActivation(),
- ", isStrictMode = ", codeBlock->ownerExecutable()->isStrictMode(), "\n");
+ ", isStrictMode = ", codeBlock->ownerScriptExecutable()->isStrictMode(), "\n");
codeBlock->baselineVersion()->dumpBytecode();
}
Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -44,32 +44,36 @@
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)
Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (189122 => 189123)
--- trunk/Source/_javascript_Core/dfg/DFGGraph.h 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h 2015-08-28 21:07:22 UTC (rev 189123)
@@ -345,7 +345,7 @@
ScriptExecutable* executableFor(InlineCallFrame* inlineCallFrame)
{
if (!inlineCallFrame)
- return m_codeBlock->ownerExecutable();
+ return m_codeBlock->ownerScriptExecutable();
return inlineCallFrame->executable.get();
}
Modified: trunk/Source/_javascript_Core/dfg/DFGOSREntry.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/dfg/DFGOSREntry.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/dfg/DFGOSREntry.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -112,7 +112,7 @@
sanitizeStackForVM(vm);
if (bytecodeIndex)
- codeBlock->ownerExecutable()->setDidTryToEnterInLoop(true);
+ codeBlock->ownerScriptExecutable()->setDidTryToEnterInLoop(true);
if (codeBlock->jitType() != JITCode::DFGJIT) {
RELEASE_ASSERT(codeBlock->jitType() == JITCode::FTLJIT);
Modified: trunk/Source/_javascript_Core/inspector/ScriptCallStackFactory.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/inspector/ScriptCallStackFactory.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/inspector/ScriptCallStackFactory.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -66,6 +66,10 @@
}
if (m_remainingCapacityForFrameCapture) {
+#if ENABLE(WEBASSEMBLY)
+ if (visitor->codeBlock()->ownerExecutable()->isWebAssemblyExecutable())
+ return StackVisitor::Continue;
+#endif
unsigned line;
unsigned column;
visitor->computeLineAndColumn(line, column);
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -168,7 +168,7 @@
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 @@
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 @@
{
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 @@
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);
Modified: trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -221,7 +221,7 @@
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 @@
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)
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -848,9 +848,22 @@
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 @@
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(
Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/jit/Repatch.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -1742,8 +1742,13 @@
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) {
Modified: trunk/Source/_javascript_Core/llint/LLIntData.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/llint/LLIntData.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/llint/LLIntData.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -132,8 +132,8 @@
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);
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -1116,9 +1116,14 @@
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 @@
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);
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (189122 => 189123)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2015-08-28 21:07:22 UTC (rev 189123)
@@ -161,8 +161,8 @@
# Type constants.
const StringType = 6
-const ObjectType = 18
-const FinalObjectType = 19
+const ObjectType = 19
+const FinalObjectType = 20
# Type flags constants.
const MasqueradesAsUndefined = 1
Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -525,7 +525,7 @@
SLOW_PATH_DECL(slow_path_enter)
{
BEGIN();
- ScriptExecutable* ownerExecutable = exec->codeBlock()->ownerExecutable();
+ ExecutableBase* ownerExecutable = exec->codeBlock()->ownerExecutable();
Heap::heap(ownerExecutable)->writeBarrier(ownerExecutable);
END();
}
Modified: trunk/Source/_javascript_Core/runtime/Executable.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/runtime/Executable.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/runtime/Executable.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -31,10 +31,12 @@
#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 @@
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);
Modified: trunk/Source/_javascript_Core/runtime/Executable.h (189122 => 189123)
--- trunk/Source/_javascript_Core/runtime/Executable.h 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/runtime/Executable.h 2015-08-28 21:07:22 UTC (rev 189123)
@@ -50,9 +50,11 @@
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 @@
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 @@
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 @@
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 @@
static void destroy(JSCell*);
- UnlinkedFunctionExecutable* unlinkedExecutable()
+ UnlinkedFunctionExecutable* unlinkedExecutable() const
{
return m_unlinkedExecutable.get();
}
@@ -676,6 +685,50 @@
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 @@
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();
}
Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -67,6 +67,16 @@
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)
Modified: trunk/Source/_javascript_Core/runtime/JSFunction.h (189122 => 189123)
--- trunk/Source/_javascript_Core/runtime/JSFunction.h 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.h 2015-08-28 21:07:22 UTC (rev 189123)
@@ -40,6 +40,7 @@
class LLIntOffsetsExtractor;
class NativeExecutable;
class SourceCode;
+class WebAssemblyExecutable;
namespace DFG {
class SpeculativeJIT;
class JITCompiler;
@@ -73,6 +74,9 @@
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 @@
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;
Modified: trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h (189122 => 189123)
--- trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h 2015-08-28 21:07:22 UTC (rev 189123)
@@ -52,6 +52,15 @@
{
}
+#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::isBuiltinFunction() const
{
+#if ENABLE(WEBASSEMBLY)
+ if (m_executable->isWebAssemblyExecutable())
+ return false;
+#endif
return !isHostFunction() && jsExecutable()->isBuiltinFunction();
}
Modified: trunk/Source/_javascript_Core/runtime/JSType.h (189122 => 189123)
--- trunk/Source/_javascript_Core/runtime/JSType.h 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/runtime/JSType.h 2015-08-28 21:07:22 UTC (rev 189123)
@@ -42,6 +42,7 @@
EvalExecutableType,
ProgramExecutableType,
FunctionExecutableType,
+ WebAssemblyExecutableType,
UnlinkedFunctionExecutableType,
UnlinkedProgramCodeBlockType,
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -221,6 +221,9 @@
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()));
Modified: trunk/Source/_javascript_Core/runtime/VM.h (189122 => 189123)
--- trunk/Source/_javascript_Core/runtime/VM.h 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2015-08-28 21:07:22 UTC (rev 189123)
@@ -279,6 +279,9 @@
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;
Modified: trunk/Source/_javascript_Core/wasm/JSWASMModule.h (189122 => 189123)
--- trunk/Source/_javascript_Core/wasm/JSWASMModule.h 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/wasm/JSWASMModule.h 2015-08-28 21:07:22 UTC (rev 189123)
@@ -64,6 +64,8 @@
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)
Modified: trunk/Source/_javascript_Core/wasm/WASMFunctionParser.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/wasm/WASMFunctionParser.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/wasm/WASMFunctionParser.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -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 @@
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)
{
Modified: trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h (189122 => 189123)
--- trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h 2015-08-28 21:07:22 UTC (rev 189123)
@@ -36,11 +36,14 @@
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)
Modified: trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp (189122 => 189123)
--- trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -49,15 +49,17 @@
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 @@
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 @@
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 @@
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 @@
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
Modified: trunk/Source/_javascript_Core/wasm/WASMModuleParser.h (189122 => 189123)
--- trunk/Source/_javascript_Core/wasm/WASMModuleParser.h 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/_javascript_Core/wasm/WASMModuleParser.h 2015-08-28 21:07:22 UTC (rev 189123)
@@ -42,8 +42,8 @@
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 @@
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;
Modified: trunk/Source/WebCore/ChangeLog (189122 => 189123)
--- trunk/Source/WebCore/ChangeLog 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/WebCore/ChangeLog 2015-08-28 21:07:22 UTC (rev 189123)
@@ -1,3 +1,15 @@
+2015-08-28 Sukolsak Sakshuwong <sukol...@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.no...@apple.com>
[iOS] Make the AllowsInlineMediaPlayback preference work in WebKit / WebKit2.
Modified: trunk/Source/WebCore/testing/Internals.cpp (189122 => 189123)
--- trunk/Source/WebCore/testing/Internals.cpp 2015-08-28 20:35:28 UTC (rev 189122)
+++ trunk/Source/WebCore/testing/Internals.cpp 2015-08-28 21:07:22 UTC (rev 189123)
@@ -1463,7 +1463,7 @@
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 @@
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);