Changeset 29810 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Jan 26, 2008, 10:55:52 AM (17 years ago)
Author:
Darin Adler
Message:

Reviewed by Eric Seidel.

  • JavaScriptCore.exp: Export the GlobalExecState constructor instead of the global flavor of the ExecState constructor. It'd probably be cleaner to not export either one, but JSGlobalObject inlines the code that constructs the ExecState. If we changed that, we could remove this export.
  • JavaScriptCore.xcodeproj/project.pbxproj: Re-sorted a few things and put the new source files into the kjs group rather than at the top level.
  • kjs/ExecState.cpp: (KJS::ExecState::ExecState): Marked inline and updated for data member name changes. This is now only for use for the derived classes. Also removed code that sets the unused m_savedExec data member for the global case. That data member is only used for the other two types. (KJS::ExecState::~ExecState): Marked inline and removed all the code. The derived class destructors now inclde the appropriate code. (KJS::ExecState::lexicalGlobalObject): Removed unneeded special case for an empty scope chain. The bottom function already returns 0 for that case, so the general case code handles it fine. Also changed to use data members directly rather than calling functions. (KJS::GlobalExecState::GlobalExecState): Added. Calls through to the base class constructor. (KJS::GlobalExecState::~GlobalExecState): Added. (KJS::InterpreterExecState::InterpreterExecState): Added. Moved code to manipulate activeExecStates here since we don't want to have to check for the special case of globalExec. (KJS::InterpreterExecState::~InterpreterExecState): Added. (KJS::EvalExecState::EvalExecState): Added. (KJS::EvalExecState::~EvalExecState): Added. (KJS::FunctionExecState::FunctionExecState): Added. (KJS::FunctionExecState::~FunctionExecState): Added.
  • kjs/ExecState.h: Tweaked the header, includes, and declarations a bit. Made ExecState inherit from Noncopyable. Reformatted some comments and made them a bit more brief. Rearranged declarations a little bit and removed unused savedExec function. Changed seenLabels function to return a reference rather than a pointer. Made constructors and destructor protected, and also did the same with all data members. Renamed m_thisVal to m_thisValue and ls to m_labelStack. Added three new derived classes for each of the types of ExecState. The primary goal here was to remove a branch from the code in the destructor, but it's also clearer than overloading the arguments to the ExecState constructor.
  • kjs/JSGlobalObject.cpp: (KJS::getCurrentTime): Fixed formatting. (KJS::JSGlobalObject::pushActivation): Removed parentheses that don't make the expression clearer -- other similar sites didn't have these parentheses, even the one a couple lines earlier that sets stackEntry. (KJS::JSGlobalObject::tearOffActivation): Got rid of unneeded static_cast (I think I mentioned this during patch review) and used an early exit so that the entire contents of the function aren't nested inside an if statement. Also removed the check of codeType, instead checking Activation for 0. For now, I kept the codeType check, but inside an assertion.
  • kjs/JSGlobalObject.h: Changed type of globalExec to GlobalExecState.
  • kjs/function.cpp: (KJS::FunctionImp::callAsFunction): Changed type to FunctionExecState. (KJS::GlobalFuncImp::callAsFunction): Changed type to EvalExecState.
  • kjs/interpreter.cpp: (KJS::Interpreter::evaluate): Changed type to GlobalExecState.
  • kjs/nodes.cpp: (KJS::ContinueNode::execute): Changed code since seenLabels() returns a reference now instead of a pointer. (KJS::BreakNode::execute): Ditto. (KJS::LabelNode::execute): Ditto.
Location:
trunk/JavaScriptCore/kjs
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/ExecState.cpp

    r29710 r29810  
    11// -*- mode: c++; c-basic-offset: 4 -*-
    22/*
    3  *  This file is part of the KDE libraries
    43 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    54 *  Copyright (C) 2001 Peter Kelly ([email protected])
    6  *  Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
     5 *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
    76 *
    87 *  This library is free software; you can redistribute it and/or
     
    4342
    4443// The constructor for the globalExec pseudo-ExecState
    45 ExecState::ExecState(JSGlobalObject* globalObject)
     44inline ExecState::ExecState(JSGlobalObject* globalObject)
    4645    : m_globalObject(globalObject)
    4746    , m_exception(0)
     
    5554    , m_localStorage(&globalObject->localStorage())
    5655    , m_variableObject(globalObject)
    57     , m_thisVal(globalObject)
     56    , m_thisValue(globalObject)
    5857    , m_iterationDepth(0)
    5958    , m_switchDepth(0)
     
    6362}
    6463
    65 ExecState::ExecState(JSGlobalObject* globalObject, JSObject* /*thisObject*/, ProgramNode* programNode)
     64inline ExecState::ExecState(JSGlobalObject* globalObject, JSObject* /*thisObject*/, ProgramNode* programNode)
    6665    : m_globalObject(globalObject)
    6766    , m_exception(0)
     
    7574    , m_localStorage(&globalObject->localStorage())
    7675    , m_variableObject(globalObject)
    77     , m_thisVal(globalObject)
     76    , m_thisValue(globalObject)
    7877    , m_iterationDepth(0)
    7978    , m_switchDepth(0)
     
    8483    // has been for some time.
    8584    ASSERT(m_scopeNode);
    86     activeExecStates().append(this);
    8785    m_scopeChain.push(globalObject);
    8886}
    8987
    90 ExecState::ExecState(JSGlobalObject* globalObject, EvalNode* evalNode, ExecState* callingExec)
     88inline ExecState::ExecState(JSGlobalObject* globalObject, EvalNode* evalNode, ExecState* callingExec)
    9189    : m_globalObject(globalObject)
    9290    , m_exception(0)
     
    10199    , m_scopeChain(callingExec->m_scopeChain)
    102100    , m_variableObject(callingExec->m_variableObject)
    103     , m_thisVal(callingExec->m_thisVal)
     101    , m_thisValue(callingExec->m_thisValue)
    104102    , m_iterationDepth(0)
    105103    , m_switchDepth(0)
     
    107105{   
    108106    ASSERT(m_scopeNode);
    109     activeExecStates().append(this);
    110 }
    111 
    112 ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisObject,
    113                      FunctionBodyNode* functionBodyNode, ExecState* callingExec,
    114                      FunctionImp* func, const List& args)
     107}
     108
     109inline ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisObject,
     110         FunctionBodyNode* functionBodyNode, ExecState* callingExec,
     111         FunctionImp* func, const List& args)
    115112    : m_globalObject(globalObject)
    116113    , m_exception(0)
     
    122119    , m_arguments(&args)
    123120    , m_scopeChain(func->scope())
    124     , m_thisVal(thisObject)
     121    , m_thisValue(thisObject)
    125122    , m_iterationDepth(0)
    126123    , m_switchDepth(0)
     
    128125{
    129126    ASSERT(m_scopeNode);
    130     activeExecStates().append(this);
    131127
    132128    ActivationImp* activation = globalObject->pushActivation(this);
     
    137133}
    138134
    139 ExecState::~ExecState()
    140 {
    141     ASSERT(m_scopeNode && activeExecStates().last() == this || !m_scopeNode);
    142     if (m_scopeNode)
    143         activeExecStates().removeLast();
    144 
    145     if (m_activation && m_activation->needsPop())
    146         m_globalObject->popActivation();
     135inline ExecState::~ExecState()
     136{
    147137}
    148138
    149139JSGlobalObject* ExecState::lexicalGlobalObject() const
    150140{
    151     if (scopeChain().isEmpty())
    152         return dynamicGlobalObject();
    153    
    154     JSObject* object = scopeChain().bottom();
     141    JSObject* object = m_scopeChain.bottom();
    155142    if (object && object->isGlobalObject())
    156143        return static_cast<JSGlobalObject*>(object);
    157 
    158     return dynamicGlobalObject();
     144    return m_globalObject;
    159145}
    160146
     
    166152}
    167153
    168 ExecStateStack& ExecState::activeExecStates()
     154static inline ExecStateStack& inlineActiveExecStates()
    169155{
    170156    static ExecStateStack staticActiveExecStates;
     
    172158}
    173159
     160ExecStateStack& ExecState::activeExecStates()
     161{
     162    return inlineActiveExecStates();
     163}
     164
     165GlobalExecState::GlobalExecState(JSGlobalObject* globalObject)
     166    : ExecState(globalObject)
     167{
     168}
     169
     170GlobalExecState::~GlobalExecState()
     171{
     172}
     173
     174InterpreterExecState::InterpreterExecState(JSGlobalObject* globalObject, JSObject* thisObject, ProgramNode* programNode)
     175    : ExecState(globalObject, thisObject, programNode)
     176{
     177    inlineActiveExecStates().append(this);
     178}
     179
     180InterpreterExecState::~InterpreterExecState()
     181{
     182    ASSERT(inlineActiveExecStates().last() == this);
     183    inlineActiveExecStates().removeLast();
     184}
     185
     186EvalExecState::EvalExecState(JSGlobalObject* globalObject, EvalNode* evalNode, ExecState* callingExec)
     187    : ExecState(globalObject, evalNode, callingExec)
     188{
     189    inlineActiveExecStates().append(this);
     190}
     191
     192EvalExecState::~EvalExecState()
     193{
     194    ASSERT(inlineActiveExecStates().last() == this);
     195    inlineActiveExecStates().removeLast();
     196}
     197
     198FunctionExecState::FunctionExecState(JSGlobalObject* globalObject, JSObject* thisObject,
     199         FunctionBodyNode* functionBodyNode, ExecState* callingExec,
     200         FunctionImp* func, const List& args)
     201    : ExecState(globalObject, thisObject, functionBodyNode, callingExec, func, args)
     202{
     203    inlineActiveExecStates().append(this);
     204}
     205
     206FunctionExecState::~FunctionExecState()
     207{
     208    ASSERT(inlineActiveExecStates().last() == this);
     209    inlineActiveExecStates().removeLast();
     210
     211    if (m_activation->needsPop())
     212        m_globalObject->popActivation();
     213}
     214
    174215} // namespace KJS
  • trunk/JavaScriptCore/kjs/ExecState.h

    r29710 r29810  
    33 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    44 *  Copyright (C) 2001 Peter Kelly ([email protected])
    5  *  Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
     5 *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
    66 *
    77 *  This library is free software; you can redistribute it and/or
     
    2222 */
    2323
    24 #ifndef ExecState_H
    25 #define ExecState_H
     24#ifndef ExecState_h
     25#define ExecState_h
    2626
    2727#include "LabelStack.h"
    2828#include "LocalStorage.h"
     29#include "completion.h"
     30#include "list.h"
    2931#include "scope_chain.h"
    30 #include "types.h"
    3132
    3233namespace KJS  {
    3334
    34     enum CodeType {
    35         GlobalCode,
    36         EvalCode,
    37         FunctionCode,
    38     };
    39    
    4035    class ActivationImp;
    4136    class CommonIdentifiers;
     
    4843    class JSVariableObject;
    4944    class ProgramNode;
    50     class ScopeChain;
    5145    class ScopeNode;
    52     struct LocalStorageEntry;
     46   
     47    enum CodeType { GlobalCode, EvalCode, FunctionCode };
    5348   
    5449    typedef Vector<ExecState*, 16> ExecStateStack;
    5550
    56     /**
    57      * Represents the current state of script execution. This is
    58      * passed as the first argument to most functions.
    59      */
    60     class ExecState {
    61         friend class Interpreter;
    62         friend class FunctionImp;
    63         friend class GlobalFuncImp;
    64     public:
    65         /**
    66          * Returns the global object that was in scope when the current script started executing.
    67          */
     51    // Represents the current state of script execution.
     52    // Passed as the first argument to most functions.
     53    class ExecState : Noncopyable {
     54    public:
     55        // Global object that was in scope when the current script started executing.
    6856        JSGlobalObject* dynamicGlobalObject() const { return m_globalObject; }
    6957       
    70         /**
    71          * Returns the global object that was in scope when the current body of code was defined.
    72          */
     58        // Global object that was in scope when the current body of code was defined.
    7359        JSGlobalObject* lexicalGlobalObject() const;
    7460               
     
    8066       
    8167        const ScopeChain& scopeChain() const { return m_scopeChain; }
     68        void pushScope(JSObject* s) { m_scopeChain.push(s); }
     69        void popScope() { m_scopeChain.pop(); }
    8270        void replaceScopeChainTop(JSObject* o) { m_scopeChain.replaceTop(o); }
    8371       
     
    8573        void setVariableObject(JSVariableObject* v) { m_variableObject = v; }
    8674       
    87         JSObject* thisValue() const { return m_thisVal; }
     75        JSObject* thisValue() const { return m_thisValue; }
    8876       
    8977        ExecState* callingExecState() { return m_callingExec; }
     
    9684        const List* arguments() const { return m_arguments; }
    9785       
    98         void pushScope(JSObject* s) { m_scopeChain.push(s); }
    99         void popScope() { m_scopeChain.pop(); }
    100         LabelStack* seenLabels() { return &ls; }
     86        LabelStack& seenLabels() { return m_labelStack; }
    10187       
    10288        void pushIteration() { m_iterationDepth++; }
     
    178164        }
    179165
     166        static void markActiveExecStates();
     167        static ExecStateStack& activeExecStates();
     168
     169    protected:
    180170        ExecState(JSGlobalObject*);
    181171        ExecState(JSGlobalObject*, JSObject* thisObject, ProgramNode*);
     
    185175        ~ExecState();
    186176
    187         static void markActiveExecStates();
    188         static ExecStateStack& activeExecStates();
    189 
    190     private:
    191177        // ExecStates are always stack-allocated, and the garbage collector
    192178        // marks the stack, so we don't need to protect the objects below from GC.
     
    208194        ScopeChain m_scopeChain;
    209195        JSVariableObject* m_variableObject;
    210         JSObject* m_thisVal;
    211        
    212         LabelStack ls;
     196        JSObject* m_thisValue;
     197       
     198        LabelStack m_labelStack;
    213199        int m_iterationDepth;
    214200        int m_switchDepth;
     
    219205    };
    220206
     207    class GlobalExecState : public ExecState {
     208    public:
     209        GlobalExecState(JSGlobalObject*);
     210        ~GlobalExecState();
     211    };
     212
     213    class InterpreterExecState : public ExecState {
     214    public:
     215        InterpreterExecState(JSGlobalObject*, JSObject* thisObject, ProgramNode*);
     216        ~InterpreterExecState();
     217    };
     218
     219    class EvalExecState : public ExecState {
     220    public:
     221        EvalExecState(JSGlobalObject*, EvalNode*, ExecState* callingExecState);
     222        ~EvalExecState();
     223    };
     224
     225    class FunctionExecState : public ExecState {
     226    public:
     227        FunctionExecState(JSGlobalObject*, JSObject* thisObject, FunctionBodyNode*,
     228            ExecState* callingExecState, FunctionImp*, const List& args);
     229        ~FunctionExecState();
     230    };
     231
    221232} // namespace KJS
    222233
    223 #endif // ExecState_H
     234#endif // ExecState_h
  • trunk/JavaScriptCore/kjs/JSGlobalObject.cpp

    r29710 r29810  
    7474// It doesn't matter what "current time" is here, just as long as
    7575// it's possible to measure the time difference correctly.
    76 static inline unsigned getCurrentTime() {
     76static inline unsigned getCurrentTime()
     77{
    7778#if HAVE(SYS_TIME_H)
    7879    struct timeval tv;
     
    523524    StackActivation* stackEntry = &d()->activations->data[d()->activationCount++];
    524525    stackEntry->activationStorage.init(exec);
    525    
    526     return &(stackEntry->activationStorage);
     526    return &stackEntry->activationStorage;
    527527}
    528528
     
    545545void JSGlobalObject::tearOffActivation(ExecState* exec, bool leaveRelic)
    546546{
    547     if (exec->codeType() == FunctionCode && static_cast<ActivationImp*>(exec->activationObject())->isOnStack()) {
    548         ActivationImp* oldActivation = static_cast<ActivationImp*>(exec->activationObject());
    549         ActivationImp* newActivation = new ActivationImp(*oldActivation->d(), leaveRelic);
    550        
    551         if (!leaveRelic) {
    552             checkActivationCount();
    553             d()->activationCount--;
    554         }
    555        
    556         oldActivation->d()->localStorage.shrink(0);
    557        
    558         exec->setActivationObject(newActivation);
    559         exec->setVariableObject(newActivation);
    560         exec->setLocalStorage(&(newActivation->localStorage()));
    561         exec->replaceScopeChainTop(newActivation);
     547    ActivationImp* oldActivation = exec->activationObject();
     548    if (!oldActivation || !oldActivation->isOnStack())
     549        return;
     550
     551    ASSERT(exec->codeType() == FunctionCode);
     552    ActivationImp* newActivation = new ActivationImp(*oldActivation->d(), leaveRelic);
     553   
     554    if (!leaveRelic) {
     555        checkActivationCount();
     556        d()->activationCount--;
    562557    }
     558   
     559    oldActivation->d()->localStorage.shrink(0);
     560   
     561    exec->setActivationObject(newActivation);
     562    exec->setVariableObject(newActivation);
     563    exec->setLocalStorage(&newActivation->localStorage());
     564    exec->replaceScopeChainTop(newActivation);
    563565}
    564566
  • trunk/JavaScriptCore/kjs/JSGlobalObject.h

    r29710 r29810  
    8787            CompatMode compatMode;
    8888           
    89             ExecState globalExec;
     89            GlobalExecState globalExec;
    9090            int recursion;
    9191
  • trunk/JavaScriptCore/kjs/function.cpp

    r29588 r29810  
    7373JSValue* FunctionImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    7474{
    75     ExecState newExec(exec->dynamicGlobalObject(), thisObj, body.get(), exec, this, args);
     75    FunctionExecState newExec(exec->dynamicGlobalObject(), thisObj, body.get(), exec, this, args);
    7676    JSValue* result = body->execute(&newExec);
    7777    if (newExec.completionType() == Throw) {
     
    722722    exec->dynamicGlobalObject()->tearOffActivation(exec);
    723723    JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject();
    724     ExecState newExec(globalObject, evalNode.get(), exec);
     724    EvalExecState newExec(globalObject, evalNode.get(), exec);
    725725
    726726    if (switchGlobal) {
  • trunk/JavaScriptCore/kjs/interpreter.cpp

    r28907 r29810  
    120120    else {
    121121        // execute the code
    122         ExecState newExec(globalObject, thisObj, progNode.get());
     122        InterpreterExecState newExec(globalObject, thisObj, progNode.get());
    123123        JSValue* value = progNode->execute(&newExec);
    124124        res = Completion(newExec.completionType(), value);
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r29428 r29810  
    10141014      KJS_CHECKEXCEPTIONVALUE
    10151015       
    1016       JSObject *thisObj = base;
     1016      JSObject* thisObj = base;
    10171017      // ECMA 11.2.3 says that in this situation the this value should be null.
    10181018      // However, section 10.2.3 says that in the case where the value provided
    10191019      // by the caller is null, the global object should be used. It also says
    1020       // that the section does not apply to interal functions, but for simplicity
     1020      // that the section does not apply to internal functions, but for simplicity
    10211021      // of implementation we use the global object anyway here. This guarantees
    10221022      // that in host objects you always get a valid object for this.
     
    39543954  if (ident.isEmpty() && !exec->inIteration())
    39553955    return setErrorCompletion(exec, SyntaxError, "Invalid continue statement.");
    3956   if (!ident.isEmpty() && !exec->seenLabels()->contains(ident))
     3956  if (!ident.isEmpty() && !exec->seenLabels().contains(ident))
    39573957    return setErrorCompletion(exec, SyntaxError, "Label %s not found.", ident);
    39583958  return exec->setContinueCompletion(&ident);
     
    39663966  if (ident.isEmpty() && !exec->inIteration() && !exec->inSwitch())
    39673967    return setErrorCompletion(exec, SyntaxError, "Invalid break statement.");
    3968   if (!ident.isEmpty() && !exec->seenLabels()->contains(ident))
     3968  if (!ident.isEmpty() && !exec->seenLabels().contains(ident))
    39693969    return setErrorCompletion(exec, SyntaxError, "Label %s not found.");
    39703970  return exec->setBreakCompletion(&ident);
     
    41614161JSValue* LabelNode::execute(ExecState *exec)
    41624162{
    4163   if (!exec->seenLabels()->push(label))
     4163  if (!exec->seenLabels().push(label))
    41644164    return setErrorCompletion(exec, SyntaxError, "Duplicated label %s found.", label);
    41654165  JSValue* result = statement->execute(exec);
    4166   exec->seenLabels()->pop();
     4166  exec->seenLabels().pop();
    41674167
    41684168  if (exec->completionType() == Break && exec->breakOrContinueTarget() == label)
Note: See TracChangeset for help on using the changeset viewer.