1231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block/* 2e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. 3231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 4231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Redistribution and use in source and binary forms, with or without 5231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * modification, are permitted provided that the following conditions 6231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * are met: 7231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 1. Redistributions of source code must retain the above copyright 8231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * notice, this list of conditions and the following disclaimer. 9231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 2. Redistributions in binary form must reproduce the above copyright 10231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * notice, this list of conditions and the following disclaimer in the 11231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * documentation and/or other materials provided with the distribution. 12231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 13231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block */ 25231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "config.h" 27231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Executable.h" 28231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "BytecodeGenerator.h" 30231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "CodeBlock.h" 31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "JIT.h" 32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Parser.h" 33a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "UStringBuilder.h" 34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Vector.h" 35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 362bde8e466a4451c7319e3a072d118917957d6554Steve Block#if ENABLE(DFG_JIT) 372bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "DFGByteCodeParser.h" 382bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "DFGJITCompiler.h" 392bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif 402bde8e466a4451c7319e3a072d118917957d6554Steve Block 41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocknamespace JSC { 42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochconst ClassInfo ExecutableBase::s_info = { "Executable", 0, 0, 0 }; 442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochconst ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, 0, 0 }; 462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockNativeExecutable::~NativeExecutable() 48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochconst ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0 }; 52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 53a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochEvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext) 542bde8e466a4451c7319e3a072d118917957d6554Steve Block : ScriptExecutable(exec->globalData().evalExecutableStructure.get(), exec, source, inStrictContext) 55967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 56967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 57967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockEvalExecutable::~EvalExecutable() 59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 60967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 61967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochconst ClassInfo ProgramExecutable::s_info = { "ProgramExecutable", &ScriptExecutable::s_info, 0, 0 }; 632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 64967717af5423377c967781471ee106e2bb4e11c8Ben MurdochProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source) 652bde8e466a4451c7319e3a072d118917957d6554Steve Block : ScriptExecutable(exec->globalData().programExecutableStructure.get(), exec, source, false) 66967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockProgramExecutable::~ProgramExecutable() 70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 71967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 72967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochconst ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0 }; 742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 75a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochFunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine) 762bde8e466a4451c7319e3a072d118917957d6554Steve Block : ScriptExecutable(globalData->functionExecutableStructure.get(), globalData, source, inStrictContext) 77bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_numCapturedVariables(0) 78967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_forceUsesArguments(forceUsesArguments) 79967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_parameters(parameters) 80967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_name(name) 81967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_symbolTable(0) 82967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 83967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_firstLine = firstLine; 84967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_lastLine = lastLine; 85967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 86967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 87a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochFunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine) 882bde8e466a4451c7319e3a072d118917957d6554Steve Block : ScriptExecutable(exec->globalData().functionExecutableStructure.get(), exec, source, inStrictContext) 89bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_numCapturedVariables(0) 90967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_forceUsesArguments(forceUsesArguments) 91967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_parameters(parameters) 92967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_name(name) 93967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_symbolTable(0) 94967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 95967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_firstLine = firstLine; 96967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_lastLine = lastLine; 97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 100967717af5423377c967781471ee106e2bb4e11c8Ben MurdochJSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode) 101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 102967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* exception = 0; 103545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch JSGlobalData* globalData = &exec->globalData(); 104545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception); 106967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!evalNode) { 107967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ASSERT(exception); 108967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return exception; 109967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 11068513a70bcd92384395513322f1b801e7bf9c729Steve Block recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine()); 111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 11281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); 113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(!m_evalCodeBlock); 11581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth())); 11681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get()))); 11765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if ((exception = generator->generate())) { 11865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_evalCodeBlock.clear(); 11965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch evalNode->destroyData(); 12065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return exception; 12165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 12265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block evalNode->destroyData(); 124967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 125967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(JIT) 126967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (exec->globalData().canUseJIT()) { 127967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_evalCodeBlock.get()); 128967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if !ENABLE(OPCODE_SAMPLING) 129967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!BytecodeGenerator::dumpsGeneratedCode()) 130967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_evalCodeBlock->discardBytecode(); 131967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif 132967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 133967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif 134967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return 0; 136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1382bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid EvalExecutable::markChildren(MarkStack& markStack) 1392bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1402bde8e466a4451c7319e3a072d118917957d6554Steve Block ScriptExecutable::markChildren(markStack); 1412bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_evalCodeBlock) 1422bde8e466a4451c7319e3a072d118917957d6554Steve Block m_evalCodeBlock->markAggregate(markStack); 1432bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1442bde8e466a4451c7319e3a072d118917957d6554Steve Block 145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockJSObject* ProgramExecutable::checkSyntax(ExecState* exec) 146231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 147967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* exception = 0; 148545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch JSGlobalData* globalData = &exec->globalData(); 149545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 150a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, JSParseNormal, &exception); 151967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (programNode) 152967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return 0; 153967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ASSERT(exception); 154967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return exception; 155231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 156231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 157967717af5423377c967781471ee106e2bb4e11c8Ben MurdochJSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode) 158231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 159967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ASSERT(!m_programCodeBlock); 160967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 161967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* exception = 0; 162545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch JSGlobalData* globalData = &exec->globalData(); 163545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 164a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception); 165967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!programNode) { 166967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ASSERT(exception); 167967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return exception; 168967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 16968513a70bcd92384395513322f1b801e7bf9c729Steve Block recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine()); 170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 17181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); 172231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 173967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider())); 17481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChainNode, &globalObject->symbolTable(), m_programCodeBlock.get()))); 17565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if ((exception = generator->generate())) { 17665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_programCodeBlock.clear(); 17765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch programNode->destroyData(); 17865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return exception; 17965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block programNode->destroyData(); 182967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 183967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(JIT) 184967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (exec->globalData().canUseJIT()) { 185967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_programCodeBlock.get()); 186967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if !ENABLE(OPCODE_SAMPLING) 187967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!BytecodeGenerator::dumpsGeneratedCode()) 188967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_programCodeBlock->discardBytecode(); 189967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif 190967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 191967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif 192967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 193967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return 0; 194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1962bde8e466a4451c7319e3a072d118917957d6554Steve Block#if ENABLE(JIT) 1972bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic bool tryDFGCompile(JSGlobalData* globalData, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck) 1982bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1992bde8e466a4451c7319e3a072d118917957d6554Steve Block#if ENABLE(DFG_JIT) 2002bde8e466a4451c7319e3a072d118917957d6554Steve Block#if ENABLE(DFG_JIT_RESTRICTIONS) 2012bde8e466a4451c7319e3a072d118917957d6554Steve Block // FIXME: No flow control yet supported, don't bother scanning the bytecode if there are any jump targets. 2022bde8e466a4451c7319e3a072d118917957d6554Steve Block // FIXME: temporarily disable property accesses until we fix regressions. 2032bde8e466a4451c7319e3a072d118917957d6554Steve Block if (codeBlock->numberOfJumpTargets() || codeBlock->numberOfStructureStubInfos()) 2042bde8e466a4451c7319e3a072d118917957d6554Steve Block return false; 2052bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif 2062bde8e466a4451c7319e3a072d118917957d6554Steve Block 2072bde8e466a4451c7319e3a072d118917957d6554Steve Block DFG::Graph dfg; 2082bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!parse(dfg, globalData, codeBlock)) 2092bde8e466a4451c7319e3a072d118917957d6554Steve Block return false; 2102bde8e466a4451c7319e3a072d118917957d6554Steve Block 2112bde8e466a4451c7319e3a072d118917957d6554Steve Block DFG::JITCompiler dataFlowJIT(globalData, dfg, codeBlock); 2122bde8e466a4451c7319e3a072d118917957d6554Steve Block dataFlowJIT.compileFunction(jitCode, jitCodeWithArityCheck); 2132bde8e466a4451c7319e3a072d118917957d6554Steve Block return true; 2142bde8e466a4451c7319e3a072d118917957d6554Steve Block#else 2152bde8e466a4451c7319e3a072d118917957d6554Steve Block UNUSED_PARAM(globalData); 2162bde8e466a4451c7319e3a072d118917957d6554Steve Block UNUSED_PARAM(codeBlock); 2172bde8e466a4451c7319e3a072d118917957d6554Steve Block UNUSED_PARAM(jitCode); 2182bde8e466a4451c7319e3a072d118917957d6554Steve Block UNUSED_PARAM(jitCodeWithArityCheck); 2192bde8e466a4451c7319e3a072d118917957d6554Steve Block return false; 2202bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif 2212bde8e466a4451c7319e3a072d118917957d6554Steve Block} 2222bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif 2232bde8e466a4451c7319e3a072d118917957d6554Steve Block 2242bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid ProgramExecutable::markChildren(MarkStack& markStack) 2252bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 2262bde8e466a4451c7319e3a072d118917957d6554Steve Block ScriptExecutable::markChildren(markStack); 2272bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_programCodeBlock) 2282bde8e466a4451c7319e3a072d118917957d6554Steve Block m_programCodeBlock->markAggregate(markStack); 2292bde8e466a4451c7319e3a072d118917957d6554Steve Block} 2302bde8e466a4451c7319e3a072d118917957d6554Steve Block 231967717af5423377c967781471ee106e2bb4e11c8Ben MurdochJSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode) 232231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 233967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* exception = 0; 234231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block JSGlobalData* globalData = scopeChainNode->globalData; 235a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception); 236967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!body) { 237967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ASSERT(exception); 238967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return exception; 239967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 240231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_forceUsesArguments) 241231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block body->setUsesArguments(); 242231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block body->finishParsing(m_parameters, m_name); 24368513a70bcd92384395513322f1b801e7bf9c729Steve Block recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine()); 244231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 24581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); 246231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 2476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ASSERT(!m_codeBlockForCall); 248dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch m_codeBlockForCall = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), false)); 24981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scopeChainNode, m_codeBlockForCall->symbolTable(), m_codeBlockForCall.get()))); 25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if ((exception = generator->generate())) { 25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_codeBlockForCall.clear(); 25265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch body->destroyData(); 25365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return exception; 25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 25565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_numParametersForCall = m_codeBlockForCall->m_numParameters; 2576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ASSERT(m_numParametersForCall); 258bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_numCapturedVariables = m_codeBlockForCall->m_numCapturedVars; 2596c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_symbolTable = m_codeBlockForCall->sharedSymbolTable(); 2606c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 2616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen body->destroyData(); 262967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 263967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(JIT) 264967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (exec->globalData().canUseJIT()) { 2652bde8e466a4451c7319e3a072d118917957d6554Steve Block bool dfgCompiled = tryDFGCompile(&exec->globalData(), m_codeBlockForCall.get(), m_jitCodeForCall, m_jitCodeForCallWithArityCheck); 2662bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!dfgCompiled) 2672bde8e466a4451c7319e3a072d118917957d6554Steve Block m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_codeBlockForCall.get(), &m_jitCodeForCallWithArityCheck); 2682bde8e466a4451c7319e3a072d118917957d6554Steve Block 269967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if !ENABLE(OPCODE_SAMPLING) 270967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!BytecodeGenerator::dumpsGeneratedCode()) 271967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_codeBlockForCall->discardBytecode(); 272967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif 273967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 274967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif 275967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 276967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return 0; 2776c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen} 2786c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 279967717af5423377c967781471ee106e2bb4e11c8Ben MurdochJSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode) 2806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{ 281967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* exception = 0; 2826c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen JSGlobalData* globalData = scopeChainNode->globalData; 283a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception); 284967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!body) { 285967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ASSERT(exception); 286967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return exception; 287967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 2886c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (m_forceUsesArguments) 2896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen body->setUsesArguments(); 2906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen body->finishParsing(m_parameters, m_name); 29168513a70bcd92384395513322f1b801e7bf9c729Steve Block recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine()); 2926c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 29381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); 2946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 2956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ASSERT(!m_codeBlockForConstruct); 296dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch m_codeBlockForConstruct = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), true)); 29781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scopeChainNode, m_codeBlockForConstruct->symbolTable(), m_codeBlockForConstruct.get()))); 29865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if ((exception = generator->generate())) { 29965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_codeBlockForConstruct.clear(); 30065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch body->destroyData(); 30165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return exception; 30265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 30365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 3046c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_numParametersForConstruct = m_codeBlockForConstruct->m_numParameters; 3056c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ASSERT(m_numParametersForConstruct); 306bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_numCapturedVariables = m_codeBlockForConstruct->m_numCapturedVars; 3076c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable(); 308231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 309231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block body->destroyData(); 310231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 311231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(JIT) 312967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (exec->globalData().canUseJIT()) { 313967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_jitCodeForConstruct = JIT::compile(scopeChainNode->globalData, m_codeBlockForConstruct.get(), &m_jitCodeForConstructWithArityCheck); 3146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#if !ENABLE(OPCODE_SAMPLING) 315967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!BytecodeGenerator::dumpsGeneratedCode()) 316967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_codeBlockForConstruct->discardBytecode(); 3176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#endif 318967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 319e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 320231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 321967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return 0; 322231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 323231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 3242bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid FunctionExecutable::markChildren(MarkStack& markStack) 325231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 3262bde8e466a4451c7319e3a072d118917957d6554Steve Block ScriptExecutable::markChildren(markStack); 3276c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (m_codeBlockForCall) 3286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_codeBlockForCall->markAggregate(markStack); 3296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (m_codeBlockForConstruct) 3306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_codeBlockForConstruct->markAggregate(markStack); 331231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 332231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 333f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid FunctionExecutable::discardCode() 334231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 335967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_codeBlockForCall.clear(); 336967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_codeBlockForConstruct.clear(); 3376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED; 3386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED; 339231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(JIT) 3406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_jitCodeForCall = JITCode(); 3416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_jitCodeForConstruct = JITCode(); 342231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 343231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 344231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 3452bde8e466a4451c7319e3a072d118917957d6554Steve BlockFunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception) 346231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 347967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 348a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(lexicalGlobalObject, debugger, exec, source, 0, JSParseNormal, exception); 349967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!program) { 350967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ASSERT(*exception); 351231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return 0; 352967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 353231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 354967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch // Uses of this function that would not result in a single function expression are invalid. 355231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block StatementNode* exprStatement = program->singleStatement(); 356231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(exprStatement); 357231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(exprStatement->isExprStatement()); 358231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr(); 359231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(funcExpr); 360231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(funcExpr->isFuncExprNode()); 361231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body(); 362231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(body); 363967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 364a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine()); 365231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 366231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 367231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockUString FunctionExecutable::paramString() const 368231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 369231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FunctionParameters& parameters = *m_parameters; 370a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch UStringBuilder builder; 371231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (size_t pos = 0; pos < parameters.size(); ++pos) { 372d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!builder.isEmpty()) 373d0825bca7fe65beaee391d30da42e937db621564Steve Block builder.append(", "); 374d0825bca7fe65beaee391d30da42e937db621564Steve Block builder.append(parameters[pos].ustring()); 375231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 376a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return builder.toUString(); 377231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 378231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 379e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 380