Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2009 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "Executable.h"
     28 
     29 #include "BytecodeGenerator.h"
     30 #include "CodeBlock.h"
     31 #include "JIT.h"
     32 #include "Parser.h"
     33 #include "StringBuilder.h"
     34 #include "Vector.h"
     35 
     36 namespace JSC {
     37 
     38 #if ENABLE(JIT)
     39 NativeExecutable::~NativeExecutable()
     40 {
     41 }
     42 #endif
     43 
     44 VPtrHackExecutable::~VPtrHackExecutable()
     45 {
     46 }
     47 
     48 EvalExecutable::~EvalExecutable()
     49 {
     50     delete m_evalCodeBlock;
     51 }
     52 
     53 ProgramExecutable::~ProgramExecutable()
     54 {
     55     delete m_programCodeBlock;
     56 }
     57 
     58 FunctionExecutable::~FunctionExecutable()
     59 {
     60     delete m_codeBlock;
     61 }
     62 
     63 JSObject* EvalExecutable::compile(ExecState* exec, ScopeChainNode* scopeChainNode)
     64 {
     65     int errLine;
     66     UString errMsg;
     67     RefPtr<EvalNode> evalNode = exec->globalData().parser->parse<EvalNode>(&exec->globalData(), exec->lexicalGlobalObject()->debugger(), exec, m_source, &errLine, &errMsg);
     68     if (!evalNode)
     69         return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url());
     70     recordParse(evalNode->features(), evalNode->lineNo(), evalNode->lastLine());
     71 
     72     ScopeChain scopeChain(scopeChainNode);
     73     JSGlobalObject* globalObject = scopeChain.globalObject();
     74 
     75     ASSERT(!m_evalCodeBlock);
     76     m_evalCodeBlock = new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth());
     77     OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(evalNode.get(), globalObject->debugger(), scopeChain, m_evalCodeBlock->symbolTable(), m_evalCodeBlock));
     78     generator->generate();
     79 
     80     evalNode->destroyData();
     81     return 0;
     82 }
     83 
     84 JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
     85 {
     86     int errLine;
     87     UString errMsg;
     88     RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), exec->lexicalGlobalObject()->debugger(), exec, m_source, &errLine, &errMsg);
     89     if (!programNode)
     90         return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url());
     91     return 0;
     92 }
     93 
     94 JSObject* ProgramExecutable::compile(ExecState* exec, ScopeChainNode* scopeChainNode)
     95 {
     96     int errLine;
     97     UString errMsg;
     98     RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), exec->lexicalGlobalObject()->debugger(), exec, m_source, &errLine, &errMsg);
     99     if (!programNode)
    100         return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url());
    101     recordParse(programNode->features(), programNode->lineNo(), programNode->lastLine());
    102 
    103     ScopeChain scopeChain(scopeChainNode);
    104     JSGlobalObject* globalObject = scopeChain.globalObject();
    105 
    106     ASSERT(!m_programCodeBlock);
    107     m_programCodeBlock = new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider());
    108     OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(programNode.get(), globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock));
    109     generator->generate();
    110 
    111     programNode->destroyData();
    112     return 0;
    113 }
    114 
    115 void FunctionExecutable::compile(ExecState*, ScopeChainNode* scopeChainNode)
    116 {
    117     JSGlobalData* globalData = scopeChainNode->globalData;
    118     RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source);
    119     if (m_forceUsesArguments)
    120         body->setUsesArguments();
    121     body->finishParsing(m_parameters, m_name);
    122     recordParse(body->features(), body->lineNo(), body->lastLine());
    123 
    124     ScopeChain scopeChain(scopeChainNode);
    125     JSGlobalObject* globalObject = scopeChain.globalObject();
    126 
    127     ASSERT(!m_codeBlock);
    128     m_codeBlock = new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset());
    129     OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlock->symbolTable(), m_codeBlock));
    130     generator->generate();
    131     m_numParameters = m_codeBlock->m_numParameters;
    132     ASSERT(m_numParameters);
    133     m_numVariables = m_codeBlock->m_numVars;
    134 
    135     body->destroyData();
    136 }
    137 
    138 #if ENABLE(JIT)
    139 
    140 void EvalExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
    141 {
    142     CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
    143     m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
    144 
    145 #if !ENABLE(OPCODE_SAMPLING)
    146     if (!BytecodeGenerator::dumpsGeneratedCode())
    147         codeBlock->discardBytecode();
    148 #endif
    149 }
    150 
    151 void ProgramExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
    152 {
    153     CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
    154     m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
    155 
    156 #if !ENABLE(OPCODE_SAMPLING)
    157     if (!BytecodeGenerator::dumpsGeneratedCode())
    158         codeBlock->discardBytecode();
    159 #endif
    160 }
    161 
    162 void FunctionExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
    163 {
    164     CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
    165     m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
    166 
    167 #if !ENABLE(OPCODE_SAMPLING)
    168     if (!BytecodeGenerator::dumpsGeneratedCode())
    169         codeBlock->discardBytecode();
    170 #endif
    171 }
    172 
    173 #endif
    174 
    175 void FunctionExecutable::markAggregate(MarkStack& markStack)
    176 {
    177     if (m_codeBlock)
    178         m_codeBlock->markAggregate(markStack);
    179 }
    180 
    181 ExceptionInfo* FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
    182 {
    183     RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source);
    184     if (m_forceUsesArguments)
    185         newFunctionBody->setUsesArguments();
    186     newFunctionBody->finishParsing(m_parameters, m_name);
    187 
    188     ScopeChain scopeChain(scopeChainNode);
    189     JSGlobalObject* globalObject = scopeChain.globalObject();
    190 
    191     OwnPtr<CodeBlock> newCodeBlock(new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
    192     globalData->functionCodeBlockBeingReparsed = newCodeBlock.get();
    193 
    194     OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(newFunctionBody.get(), globalObject->debugger(), scopeChain, newCodeBlock->symbolTable(), newCodeBlock.get()));
    195     generator->setRegeneratingForExceptionInfo(static_cast<FunctionCodeBlock*>(codeBlock));
    196     generator->generate();
    197 
    198     ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
    199 
    200 #if ENABLE(JIT)
    201     JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
    202     ASSERT(newJITCode.size() == generatedJITCode().size());
    203 #endif
    204 
    205     globalData->functionCodeBlockBeingReparsed = 0;
    206 
    207     return newCodeBlock->extractExceptionInfo();
    208 }
    209 
    210 ExceptionInfo* EvalExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
    211 {
    212     RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(globalData, 0, 0, m_source);
    213 
    214     ScopeChain scopeChain(scopeChainNode);
    215     JSGlobalObject* globalObject = scopeChain.globalObject();
    216 
    217     OwnPtr<EvalCodeBlock> newCodeBlock(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
    218 
    219     OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(newEvalBody.get(), globalObject->debugger(), scopeChain, newCodeBlock->symbolTable(), newCodeBlock.get()));
    220     generator->setRegeneratingForExceptionInfo(static_cast<EvalCodeBlock*>(codeBlock));
    221     generator->generate();
    222 
    223     ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
    224 
    225 #if ENABLE(JIT)
    226     JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
    227     ASSERT(newJITCode.size() == generatedJITCode().size());
    228 #endif
    229 
    230     return newCodeBlock->extractExceptionInfo();
    231 }
    232 
    233 void FunctionExecutable::recompile(ExecState*)
    234 {
    235     delete m_codeBlock;
    236     m_codeBlock = 0;
    237     m_numParameters = NUM_PARAMETERS_NOT_COMPILED;
    238 #if ENABLE(JIT)
    239     m_jitCode = JITCode();
    240 #endif
    241 }
    242 
    243 PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg)
    244 {
    245     RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), debugger, exec, source, errLine, errMsg);
    246     if (!program)
    247         return 0;
    248 
    249     StatementNode* exprStatement = program->singleStatement();
    250     ASSERT(exprStatement);
    251     ASSERT(exprStatement->isExprStatement());
    252     if (!exprStatement || !exprStatement->isExprStatement())
    253         return 0;
    254 
    255     ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
    256     ASSERT(funcExpr);
    257     ASSERT(funcExpr->isFuncExprNode());
    258     if (!funcExpr || !funcExpr->isFuncExprNode())
    259         return 0;
    260 
    261     FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
    262     ASSERT(body);
    263     return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine());
    264 }
    265 
    266 UString FunctionExecutable::paramString() const
    267 {
    268     FunctionParameters& parameters = *m_parameters;
    269     StringBuilder builder;
    270     for (size_t pos = 0; pos < parameters.size(); ++pos) {
    271         if (!builder.isEmpty())
    272             builder.append(", ");
    273         builder.append(parameters[pos].ustring());
    274     }
    275     return builder.build();
    276 }
    277 
    278 };
    279 
    280 
    281