⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interpreter.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1.  Redistributions of source code must retain the above copyright *     notice, this list of conditions and the following disclaimer. * 2.  Redistributions in binary form must reproduce the above copyright *     notice, this list of conditions and the following disclaimer in the *     documentation and/or other materials provided with the distribution. * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of *     its contributors may be used to endorse or promote products derived *     from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "Interpreter.h"#include "Arguments.h"#include "BatchedTransitionOptimizer.h"#include "CodeBlock.h"#include "DebuggerCallFrame.h"#include "EvalCodeCache.h"#include "ExceptionHelpers.h"#include "CallFrame.h"#include "GlobalEvalFunction.h"#include "JSActivation.h"#include "JSArray.h"#include "JSByteArray.h"#include "JSFunction.h"#include "JSNotAnObject.h"#include "JSPropertyNameIterator.h"#include "JSStaticScopeObject.h"#include "JSString.h"#include "ObjectPrototype.h"#include "Parser.h"#include "Profiler.h"#include "RegExpObject.h"#include "RegExpPrototype.h"#include "Register.h"#include "Collector.h"#include "Debugger.h"#include "Operations.h"#include "SamplingTool.h"#include <stdio.h>#if ENABLE(JIT)#include "JIT.h"#endif#if ENABLE(ASSEMBLER)#include "AssemblerBuffer.h"#endifusing namespace std;namespace JSC {static ALWAYS_INLINE unsigned bytecodeOffsetForPC(CallFrame* callFrame, CodeBlock* codeBlock, void* pc){#if ENABLE(JIT)    return codeBlock->getBytecodeIndex(callFrame, pc);#else    UNUSED_PARAM(callFrame);    return static_cast<Instruction*>(pc) - codeBlock->instructions().begin();#endif}// Returns the depth of the scope chain within a given call frame.static int depth(CodeBlock* codeBlock, ScopeChain& sc){    if (!codeBlock->needsFullScopeChain())        return 0;    return sc.localDepth();}NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue){    int dst = (vPC + 1)->u.operand;    int property = (vPC + 2)->u.operand;    ScopeChainNode* scopeChain = callFrame->scopeChain();    ScopeChainIterator iter = scopeChain->begin();    ScopeChainIterator end = scopeChain->end();    ASSERT(iter != end);    CodeBlock* codeBlock = callFrame->codeBlock();    Identifier& ident = codeBlock->identifier(property);    do {        JSObject* o = *iter;        PropertySlot slot(o);        if (o->getPropertySlot(callFrame, ident, slot)) {            JSValuePtr result = slot.getValue(callFrame, ident);            exceptionValue = callFrame->globalData().exception;            if (exceptionValue)                return false;            callFrame[dst] = JSValuePtr(result);            return true;        }    } while (++iter != end);    exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);    return false;}NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue){    CodeBlock* codeBlock = callFrame->codeBlock();    int dst = (vPC + 1)->u.operand;    int property = (vPC + 2)->u.operand;    int skip = (vPC + 3)->u.operand + codeBlock->needsFullScopeChain();    ScopeChainNode* scopeChain = callFrame->scopeChain();    ScopeChainIterator iter = scopeChain->begin();    ScopeChainIterator end = scopeChain->end();    ASSERT(iter != end);    while (skip--) {        ++iter;        ASSERT(iter != end);    }    Identifier& ident = codeBlock->identifier(property);    do {        JSObject* o = *iter;        PropertySlot slot(o);        if (o->getPropertySlot(callFrame, ident, slot)) {            JSValuePtr result = slot.getValue(callFrame, ident);            exceptionValue = callFrame->globalData().exception;            if (exceptionValue)                return false;            callFrame[dst] = JSValuePtr(result);            return true;        }    } while (++iter != end);    exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);    return false;}NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue){    int dst = (vPC + 1)->u.operand;    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>((vPC + 2)->u.jsCell);    ASSERT(globalObject->isGlobalObject());    int property = (vPC + 3)->u.operand;    Structure* structure = (vPC + 4)->u.structure;    int offset = (vPC + 5)->u.operand;    if (structure == globalObject->structure()) {        callFrame[dst] = JSValuePtr(globalObject->getDirectOffset(offset));        return true;    }    CodeBlock* codeBlock = callFrame->codeBlock();    Identifier& ident = codeBlock->identifier(property);    PropertySlot slot(globalObject);    if (globalObject->getPropertySlot(callFrame, ident, slot)) {        JSValuePtr result = slot.getValue(callFrame, ident);        if (slot.isCacheable() && !globalObject->structure()->isDictionary()) {            if (vPC[4].u.structure)                vPC[4].u.structure->deref();            globalObject->structure()->ref();            vPC[4] = globalObject->structure();            vPC[5] = slot.cachedOffset();            callFrame[dst] = JSValuePtr(result);            return true;        }        exceptionValue = callFrame->globalData().exception;        if (exceptionValue)            return false;        callFrame[dst] = JSValuePtr(result);        return true;    }    exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);    return false;}NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC){    int dst = (vPC + 1)->u.operand;    int property = (vPC + 2)->u.operand;    callFrame[dst] = JSValuePtr(JSC::resolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain()));}NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue){    int baseDst = (vPC + 1)->u.operand;    int propDst = (vPC + 2)->u.operand;    int property = (vPC + 3)->u.operand;    ScopeChainNode* scopeChain = callFrame->scopeChain();    ScopeChainIterator iter = scopeChain->begin();    ScopeChainIterator end = scopeChain->end();    // FIXME: add scopeDepthIsZero optimization    ASSERT(iter != end);    CodeBlock* codeBlock = callFrame->codeBlock();    Identifier& ident = codeBlock->identifier(property);    JSObject* base;    do {        base = *iter;        PropertySlot slot(base);        if (base->getPropertySlot(callFrame, ident, slot)) {            JSValuePtr result = slot.getValue(callFrame, ident);            exceptionValue = callFrame->globalData().exception;            if (exceptionValue)                return false;            callFrame[propDst] = JSValuePtr(result);            callFrame[baseDst] = JSValuePtr(base);            return true;        }        ++iter;    } while (iter != end);    exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);    return false;}NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue){    int baseDst = (vPC + 1)->u.operand;    int funcDst = (vPC + 2)->u.operand;    int property = (vPC + 3)->u.operand;    ScopeChainNode* scopeChain = callFrame->scopeChain();    ScopeChainIterator iter = scopeChain->begin();    ScopeChainIterator end = scopeChain->end();    // FIXME: add scopeDepthIsZero optimization    ASSERT(iter != end);    CodeBlock* codeBlock = callFrame->codeBlock();    Identifier& ident = codeBlock->identifier(property);    JSObject* base;    do {        base = *iter;        PropertySlot slot(base);        if (base->getPropertySlot(callFrame, ident, slot)) {                        // ECMA 11.2.3 says that if we hit an activation the this value should be null.            // However, section 10.2.3 says that in the case where the value provided            // by the caller is null, the global object should be used. It also says            // that the section does not apply to internal functions, but for simplicity            // of implementation we use the global object anyway here. This guarantees            // that in host objects you always get a valid object for this.            // We also handle wrapper substitution for the global object at the same time.            JSObject* thisObj = base->toThisObject(callFrame);            JSValuePtr result = slot.getValue(callFrame, ident);            exceptionValue = callFrame->globalData().exception;            if (exceptionValue)                return false;            callFrame[baseDst] = JSValuePtr(thisObj);            callFrame[funcDst] = JSValuePtr(result);            return true;        }        ++iter;    } while (iter != end);    exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);    return false;}ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc){    Register* r = callFrame->registers();    Register* newEnd = r + registerOffset + newCodeBlock->m_numCalleeRegisters;    if (LIKELY(argc == newCodeBlock->m_numParameters)) { // correct number of arguments        if (UNLIKELY(!registerFile->grow(newEnd)))            return 0;        r += registerOffset;    } else if (argc < newCodeBlock->m_numParameters) { // too few arguments -- fill in the blanks        size_t omittedArgCount = newCodeBlock->m_numParameters - argc;        registerOffset += omittedArgCount;        newEnd += omittedArgCount;        if (!registerFile->grow(newEnd))            return 0;        r += registerOffset;        Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;        for (size_t i = 0; i < omittedArgCount; ++i)            argv[i] = jsUndefined();    } else { // too many arguments -- copy expected arguments, leaving the extra arguments behind        size_t numParameters = newCodeBlock->m_numParameters;        registerOffset += numParameters;        newEnd += numParameters;        if (!registerFile->grow(newEnd))            return 0;        r += registerOffset;        Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argc;        for (size_t i = 0; i < numParameters; ++i)            argv[i + argc] = argv[i];    }    return CallFrame::create(r);}static NEVER_INLINE bool isNotObject(CallFrame* callFrame, bool forInstanceOf, CodeBlock* codeBlock, const Instruction* vPC, JSValuePtr value, JSValuePtr& exceptionData){    if (value.isObject())        return false;    exceptionData = createInvalidParamError(callFrame, forInstanceOf ? "instanceof" : "in" , value, vPC - codeBlock->instructions().begin(), codeBlock);    return true;}NEVER_INLINE JSValuePtr Interpreter::callEval(CallFrame* callFrame, RegisterFile* registerFile, Register* argv, int argc, int registerOffset, JSValuePtr& exceptionValue){    if (argc < 2)        return jsUndefined();    JSValuePtr program = argv[1].jsValue(callFrame);    if (!program.isString())        return program;    UString programSource = asString(program)->value();    ScopeChainNode* scopeChain = callFrame->scopeChain();    CodeBlock* codeBlock = callFrame->codeBlock();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -