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