Ignore:
Timestamp:
Jun 9, 2006, 8:57:13 PM (19 years ago)
Author:
ggaren
Message:

Reviewed by Eric (yay!).


  • Removed Context wrapper for ContextImp, renamed ContextImp to Context, split Context into its own file -- Context.cpp -- renamed _var to m_var, change ' *' to '* '.
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • kjs/Context.cpp: Added. (KJS::Context::Context): (KJS::Context::~Context): (KJS::Context::mark):
  • kjs/context.h: (KJS::Context::scopeChain): (KJS::Context::variableObject): (KJS::Context::setVariableObject): (KJS::Context::thisValue): (KJS::Context::callingContext): (KJS::Context::activationObject): (KJS::Context::currentBody): (KJS::Context::function): (KJS::Context::arguments): (KJS::Context::pushScope): (KJS::Context::seenLabels):
  • kjs/function.cpp: (KJS::FunctionImp::callAsFunction): (KJS::FunctionImp::processParameters): (KJS::FunctionImp::argumentsGetter): (KJS::GlobalFuncImp::callAsFunction):
  • kjs/internal.cpp: (KJS::InterpreterImp::evaluate):
  • kjs/internal.h: (KJS::InterpreterImp::setContext): (KJS::InterpreterImp::context):
  • kjs/interpreter.cpp:
  • kjs/interpreter.h: (KJS::ExecState::context): (KJS::ExecState::ExecState):
  • kjs/nodes.cpp: (currentSourceId): (currentSourceURL): (ThisNode::evaluate): (ResolveNode::evaluate): (FunctionCallResolveNode::evaluate): (PostfixResolveNode::evaluate): (DeleteResolveNode::evaluate): (TypeOfResolveNode::evaluate): (PrefixResolveNode::evaluate): (AssignResolveNode::evaluate): (VarDeclNode::evaluate): (VarDeclNode::processVarDecls): (DoWhileNode::execute): (WhileNode::execute): (ForNode::execute): (ForInNode::execute): (ContinueNode::execute): (BreakNode::execute): (ReturnNode::execute): (WithNode::execute): (SwitchNode::execute): (LabelNode::execute): (TryNode::execute): (FuncDeclNode::processFuncDecl): (FuncExprNode::evaluate):
File:
1 copied

Legend:

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

    r14797 r14799  
     1// -*- c-basic-offset: 2 -*-
    12/*
    23 *  This file is part of the KDE libraries
    3  *  Copyright (C) 1999-2002 Harri Porten ([email protected])
     4 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    45 *  Copyright (C) 2001 Peter Kelly ([email protected])
    5  *  Copyright (C) 2004 Apple Computer, Inc.
     6 *  Copyright (C) 2003, 2006 Apple Computer, Inc.
    67 *
    78 *  This library is free software; you can redistribute it and/or
     
    2223 */
    2324
    24 #include "config.h"
    25 #include "internal.h"
    26 
    27 #include "array_object.h"
    28 #include "bool_object.h"
    29 #include "collector.h"
    3025#include "context.h"
    31 #include "date_object.h"
    32 #include "debugger.h"
    33 #include "error_object.h"
    34 #include "function_object.h"
    35 #include "lexer.h"
    36 #include "math_object.h"
    37 #include "nodes.h"
    38 #include "number_object.h"
    39 #include "object.h"
    40 #include "object_object.h"
    41 #include "operations.h"
    42 #include "regexp_object.h"
    43 #include "string_object.h"
    44 #include <assert.h>
    45 #include <wtf/HashMap.h>
    46 #include <wtf/HashSet.h>
    47 #include <wtf/Vector.h>
    48 #include <math.h>
    49 #include <stdio.h>
    5026
    5127namespace KJS {
    5228
    53 #if PLATFORM(WIN_OS)
    54 #define copysign _copysign
    55 #endif
    56 
    57 // ------------------------------ StringImp ------------------------------------
    58 
    59 JSValue *StringImp::toPrimitive(ExecState *, JSType) const
    60 {
    61   return const_cast<StringImp *>(this);
    62 }
    63 
    64 bool StringImp::toBoolean(ExecState *) const
    65 {
    66   return (val.size() > 0);
    67 }
    68 
    69 double StringImp::toNumber(ExecState *) const
    70 {
    71   return val.toDouble();
    72 }
    73 
    74 UString StringImp::toString(ExecState *) const
    75 {
    76   return val;
    77 }
    78 
    79 JSObject *StringImp::toObject(ExecState *exec) const
    80 {
    81     return new StringInstance(exec->lexicalInterpreter()->builtinStringPrototype(), val);
    82 }
    83 
    84 // ------------------------------ NumberImp ------------------------------------
    85 
    86 JSValue *NumberImp::toPrimitive(ExecState *, JSType) const
    87 {
    88   return const_cast<NumberImp *>(this);
    89 }
    90 
    91 bool NumberImp::toBoolean(ExecState *) const
    92 {
    93   return val < 0.0 || val > 0.0; // false for NaN
    94 }
    95 
    96 double NumberImp::toNumber(ExecState *) const
    97 {
    98   return val;
    99 }
    100 
    101 UString NumberImp::toString(ExecState *) const
    102 {
    103   if (val == 0.0) // +0.0 or -0.0
    104     return "0";
    105   return UString::from(val);
    106 }
    107 
    108 JSObject *NumberImp::toObject(ExecState *exec) const
    109 {
    110   List args;
    111   args.append(const_cast<NumberImp*>(this));
    112   return static_cast<JSObject *>(exec->lexicalInterpreter()->builtinNumber()->construct(exec,args));
    113 }
    114 
    115 // FIXME: We can optimize this to work like JSValue::getUInt32. I'm ignoring it for now
    116 // because it never shows up on profiles.
    117 bool NumberImp::getUInt32(uint32_t& uint32) const
    118 {
    119   uint32 = (uint32_t)val;
    120   return (double)uint32 == val;
    121 }
    122 
    123 // --------------------------- GetterSetterImp ---------------------------------
    124 void GetterSetterImp::mark()
    125 {
    126     JSCell::mark();
    127    
    128     if (getter && !getter->marked())
    129         getter->mark();
    130     if (setter && !setter->marked())
    131         setter->mark();
    132 }
    133 
    134 JSValue *GetterSetterImp::toPrimitive(ExecState*, JSType) const
    135 {
    136     assert(false);
    137     return jsNull();
    138 }
    139 
    140 bool GetterSetterImp::toBoolean(ExecState*) const
    141 {
    142     assert(false);
    143     return false;
    144 }
    145 
    146 double GetterSetterImp::toNumber(ExecState *) const
    147 {
    148     assert(false);
    149     return 0.0;
    150 }
    151 
    152 UString GetterSetterImp::toString(ExecState *) const
    153 {
    154     assert(false);
    155     return UString::null();
    156 }
    157 
    158 JSObject *GetterSetterImp::toObject(ExecState *exec) const
    159 {
    160     assert(false);
    161     return jsNull()->toObject(exec);
    162 }
    163 
    164 // ------------------------------ LabelStack -----------------------------------
    165 
    166 bool LabelStack::push(const Identifier &id)
    167 {
    168   if (contains(id))
    169     return false;
    170 
    171   StackElem *newtos = new StackElem;
    172   newtos->id = id;
    173   newtos->prev = tos;
    174   tos = newtos;
    175   return true;
    176 }
    177 
    178 bool LabelStack::contains(const Identifier &id) const
    179 {
    180   if (id.isEmpty())
    181     return true;
    182 
    183   for (StackElem *curr = tos; curr; curr = curr->prev)
    184     if (curr->id == id)
    185       return true;
    186 
    187   return false;
    188 }
    189 
    190 // ------------------------------ ContextImp -----------------------------------
    191 
    19229// ECMA 10.2
    193 ContextImp::ContextImp(JSObject *glob, InterpreterImp *interpreter, JSObject *thisV, FunctionBodyNode* currentBody,
    194                       
    195                        CodeType type, ContextImp *callingCon, FunctionImp *func, const List *args)
    196     : _interpreter(interpreter)
     30Context::Context(JSObject* glob, InterpreterImp* interpreter, JSObject* thisV,
     31                 FunctionBodyNode* currentBody, CodeType type, Context* callingCon,
     32                 FunctionImp* func, const List* args)
     33    : m_interpreter(interpreter)
    19734    , m_currentBody(currentBody)
    198     , _function(func)
    199     , _arguments(args)
     35    , m_function(func)
     36    , m_arguments(args)
    20037    , m_iterationDepth(0)
    20138    , m_switchDepth(0)
    20239{
    203   m_codeType = type;
    204   _callingContext = callingCon;
    205 
    206   // create and initialize activation object (ECMA 10.1.6)
    207   if (type == FunctionCode || type == AnonymousCode ) {
    208     activation = new ActivationImp(func, *args);
    209     variable = activation;
    210   } else {
    211     activation = NULL;
    212     variable = glob;
    213   }
    214 
    215   // ECMA 10.2
    216   switch(type) {
     40    m_codeType = type;
     41    m_callingContext = callingCon;
     42   
     43    // create and initialize activation object (ECMA 10.1.6)
     44    if (type == FunctionCode || type == AnonymousCode ) {
     45        m_activation = new ActivationImp(func, *args);
     46        m_variable = m_activation;
     47    } else {
     48        m_activation = 0;
     49        m_variable = glob;
     50    }
     51   
     52    // ECMA 10.2
     53    switch(type) {
    21754    case EvalCode:
    218       if (_callingContext) {
    219         scope = _callingContext->scopeChain();
    220         variable = _callingContext->variableObject();
    221         thisVal = _callingContext->thisValue();
     55        if (m_callingContext) {
     56            scope = m_callingContext->scopeChain();
     57            m_variable = m_callingContext->variableObject();
     58            m_thisVal = m_callingContext->thisValue();
     59            break;
     60        } // else same as GlobalCode
     61    case GlobalCode:
     62        scope.clear();
     63        scope.push(glob);
     64        m_thisVal = static_cast<JSObject*>(glob);
    22265        break;
    223       } // else same as GlobalCode
    224     case GlobalCode:
    225       scope.clear();
    226       scope.push(glob);
    227       thisVal = static_cast<JSObject*>(glob);
    228       break;
    22966    case FunctionCode:
    23067    case AnonymousCode:
    231       if (type == FunctionCode) {
    232         scope = func->scope();
    233         scope.push(activation);
    234       } else {
    235         scope.clear();
    236         scope.push(glob);
    237         scope.push(activation);
    238       }
    239       variable = activation; // TODO: DontDelete ? (ECMA 10.2.3)
    240       thisVal = thisV;
    241       break;
     68        if (type == FunctionCode) {
     69            scope = func->scope();
     70            scope.push(m_activation);
     71        } else {
     72            scope.clear();
     73            scope.push(glob);
     74            scope.push(m_activation);
     75        }
     76        m_variable = m_activation; // TODO: DontDelete ? (ECMA 10.2.3)
     77        m_thisVal = thisV;
     78        break;
    24279    }
    243 
    244   _interpreter->setContext(this);
     80   
     81    m_interpreter->setContext(this);
    24582}
    24683
    247 ContextImp::~ContextImp()
     84Context::~Context()
    24885{
    249   _interpreter->setContext(_callingContext);
     86    m_interpreter->setContext(m_callingContext);
    25087}
    25188
    252 void ContextImp::mark()
     89void Context::mark()
    25390{
    254   for (ContextImp *context = this; context; context = context->_callingContext) {
    255     context->scope.mark();
    256   }
     91    for (Context* context = this; context; context = context->m_callingContext)
     92        context->scope.mark();
    25793}
    25894
    259 // ------------------------------ InterpreterImp -------------------------------
    260 
    261 InterpreterImp* InterpreterImp::s_hook = 0L;
    262 
    263 typedef HashMap<JSObject *, InterpreterImp *> InterpreterMap;
    264 
    265 static inline InterpreterMap &interpreterMap()
    266 {
    267     static InterpreterMap *map = new InterpreterMap;
    268     return *map;
    269 }
    270 
    271 InterpreterImp::InterpreterImp(Interpreter *interp, JSObject *glob)
    272     : globExec(interp, 0)
    273     , _context(0)
    274 {
    275   // add this interpreter to the global chain
    276   // as a root set for garbage collection
    277   JSLock lock;
    278 
    279   m_interpreter = interp;
    280   if (s_hook) {
    281     prev = s_hook;
    282     next = s_hook->next;
    283     s_hook->next->prev = this;
    284     s_hook->next = this;
    285   } else {
    286     // This is the first interpreter
    287     s_hook = next = prev = this;
    288   }
    289 
    290   interpreterMap().set(glob, this);
    291 
    292   global = glob;
    293   dbg = 0;
    294   m_compatMode = Interpreter::NativeMode;
    295 
    296   // initialize properties of the global object
    297   initGlobalObject();
    298 
    299   recursion = 0;
    300 }
    301 
    302 void InterpreterImp::initGlobalObject()
    303 {
    304   Identifier::init();
    305  
    306   // Contructor prototype objects (Object.prototype, Array.prototype etc)
    307 
    308   FunctionPrototype *funcProto = new FunctionPrototype(&globExec);
    309   b_FunctionPrototype = funcProto;
    310   ObjectPrototype *objProto = new ObjectPrototype(&globExec, funcProto);
    311   b_ObjectPrototype = objProto;
    312   funcProto->setPrototype(b_ObjectPrototype);
    313 
    314   ArrayPrototype *arrayProto = new ArrayPrototype(&globExec, objProto);
    315   b_ArrayPrototype = arrayProto;
    316   StringPrototype *stringProto = new StringPrototype(&globExec, objProto);
    317   b_StringPrototype = stringProto;
    318   BooleanPrototype *booleanProto = new BooleanPrototype(&globExec, objProto, funcProto);
    319   b_BooleanPrototype = booleanProto;
    320   NumberPrototype *numberProto = new NumberPrototype(&globExec, objProto, funcProto);
    321   b_NumberPrototype = numberProto;
    322   DatePrototype *dateProto = new DatePrototype(&globExec, objProto);
    323   b_DatePrototype = dateProto;
    324   RegExpPrototype *regexpProto = new RegExpPrototype(&globExec, objProto, funcProto);
    325   b_RegExpPrototype = regexpProto;
    326   ErrorPrototype *errorProto = new ErrorPrototype(&globExec, objProto, funcProto);
    327   b_ErrorPrototype = errorProto;
    328 
    329   JSObject* o = global;
    330   while (o->prototype()->isObject())
    331       o = static_cast<JSObject*>(o->prototype());
    332   o->setPrototype(b_ObjectPrototype);
    333 
    334   // Constructors (Object, Array, etc.)
    335   b_Object = new ObjectObjectImp(&globExec, objProto, funcProto);
    336   b_Function = new FunctionObjectImp(&globExec, funcProto);
    337   b_Array = new ArrayObjectImp(&globExec, funcProto, arrayProto);
    338   b_String = new StringObjectImp(&globExec, funcProto, stringProto);
    339   b_Boolean = new BooleanObjectImp(&globExec, funcProto, booleanProto);
    340   b_Number = new NumberObjectImp(&globExec, funcProto, numberProto);
    341   b_Date = new DateObjectImp(&globExec, funcProto, dateProto);
    342   b_RegExp = new RegExpObjectImp(&globExec, funcProto, regexpProto);
    343   b_Error = new ErrorObjectImp(&globExec, funcProto, errorProto);
    344 
    345   // Error object prototypes
    346   b_evalErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, EvalError, "EvalError", "EvalError");
    347   b_rangeErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, RangeError, "RangeError", "RangeError");
    348   b_referenceErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, ReferenceError, "ReferenceError", "ReferenceError");
    349   b_syntaxErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, SyntaxError, "SyntaxError", "SyntaxError");
    350   b_typeErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, TypeError, "TypeError", "TypeError");
    351   b_uriErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, URIError, "URIError", "URIError");
    352 
    353   // Error objects
    354   b_evalError = new NativeErrorImp(&globExec, funcProto, b_evalErrorPrototype);
    355   b_rangeError = new NativeErrorImp(&globExec, funcProto, b_rangeErrorPrototype);
    356   b_referenceError = new NativeErrorImp(&globExec, funcProto, b_referenceErrorPrototype);
    357   b_syntaxError = new NativeErrorImp(&globExec, funcProto, b_syntaxErrorPrototype);
    358   b_typeError = new NativeErrorImp(&globExec, funcProto, b_typeErrorPrototype);
    359   b_uriError = new NativeErrorImp(&globExec, funcProto, b_uriErrorPrototype);
    360 
    361   // ECMA 15.3.4.1
    362   funcProto->put(&globExec, constructorPropertyName, b_Function, DontEnum);
    363 
    364   global->put(&globExec, "Object", b_Object, DontEnum);
    365   global->put(&globExec, "Function", b_Function, DontEnum);
    366   global->put(&globExec, "Array", b_Array, DontEnum);
    367   global->put(&globExec, "Boolean", b_Boolean, DontEnum);
    368   global->put(&globExec, "String", b_String, DontEnum);
    369   global->put(&globExec, "Number", b_Number, DontEnum);
    370   global->put(&globExec, "Date", b_Date, DontEnum);
    371   global->put(&globExec, "RegExp", b_RegExp, DontEnum);
    372   global->put(&globExec, "Error", b_Error, DontEnum);
    373   // Using Internal for those to have something != 0
    374   // (see kjs_window). Maybe DontEnum would be ok too ?
    375   global->put(&globExec, "EvalError",b_evalError, Internal);
    376   global->put(&globExec, "RangeError",b_rangeError, Internal);
    377   global->put(&globExec, "ReferenceError",b_referenceError, Internal);
    378   global->put(&globExec, "SyntaxError",b_syntaxError, Internal);
    379   global->put(&globExec, "TypeError",b_typeError, Internal);
    380   global->put(&globExec, "URIError",b_uriError, Internal);
    381 
    382   // Set the constructorPropertyName property of all builtin constructors
    383   objProto->put(&globExec, constructorPropertyName, b_Object, DontEnum | DontDelete | ReadOnly);
    384   funcProto->put(&globExec, constructorPropertyName, b_Function, DontEnum | DontDelete | ReadOnly);
    385   arrayProto->put(&globExec, constructorPropertyName, b_Array, DontEnum | DontDelete | ReadOnly);
    386   booleanProto->put(&globExec, constructorPropertyName, b_Boolean, DontEnum | DontDelete | ReadOnly);
    387   stringProto->put(&globExec, constructorPropertyName, b_String, DontEnum | DontDelete | ReadOnly);
    388   numberProto->put(&globExec, constructorPropertyName, b_Number, DontEnum | DontDelete | ReadOnly);
    389   dateProto->put(&globExec, constructorPropertyName, b_Date, DontEnum | DontDelete | ReadOnly);
    390   regexpProto->put(&globExec, constructorPropertyName, b_RegExp, DontEnum | DontDelete | ReadOnly);
    391   errorProto->put(&globExec, constructorPropertyName, b_Error, DontEnum | DontDelete | ReadOnly);
    392   b_evalErrorPrototype->put(&globExec, constructorPropertyName, b_evalError, DontEnum | DontDelete | ReadOnly);
    393   b_rangeErrorPrototype->put(&globExec, constructorPropertyName, b_rangeError, DontEnum | DontDelete | ReadOnly);
    394   b_referenceErrorPrototype->put(&globExec, constructorPropertyName, b_referenceError, DontEnum | DontDelete | ReadOnly);
    395   b_syntaxErrorPrototype->put(&globExec, constructorPropertyName, b_syntaxError, DontEnum | DontDelete | ReadOnly);
    396   b_typeErrorPrototype->put(&globExec, constructorPropertyName, b_typeError, DontEnum | DontDelete | ReadOnly);
    397   b_uriErrorPrototype->put(&globExec, constructorPropertyName, b_uriError, DontEnum | DontDelete | ReadOnly);
    398 
    399   // built-in values
    400   global->put(&globExec, "NaN",        jsNaN(), DontEnum|DontDelete);
    401   global->put(&globExec, "Infinity",   jsNumber(Inf), DontEnum|DontDelete);
    402   global->put(&globExec, "undefined",  jsUndefined(), DontEnum|DontDelete);
    403 
    404   // built-in functions
    405   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
    406   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
    407   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
    408   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
    409   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
    410   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
    411   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
    412   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
    413   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
    414   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
    415   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
    416 #ifndef NDEBUG
    417   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
    418 #endif
    419 
    420   // built-in objects
    421   global->put(&globExec, "Math", new MathObjectImp(&globExec, objProto), DontEnum);
    422 }
    423 
    424 InterpreterImp::~InterpreterImp()
    425 {
    426   if (dbg)
    427     dbg->detach(m_interpreter);
    428   clear();
    429 }
    430 
    431 void InterpreterImp::clear()
    432 {
    433   //fprintf(stderr,"InterpreterImp::clear\n");
    434   // remove from global chain (see init())
    435   JSLock lock;
    436 
    437   next->prev = prev;
    438   prev->next = next;
    439   s_hook = next;
    440   if (s_hook == this)
    441   {
    442     // This was the last interpreter
    443     s_hook = 0L;
    444   }
    445   interpreterMap().remove(global);
    446 }
    447 
    448 void InterpreterImp::mark(bool currentThreadIsMainThread)
    449 {
    450   if (m_interpreter)
    451     m_interpreter->mark(currentThreadIsMainThread);
    452   if (_context)
    453     _context->mark();
    454   if (global)
    455       global->mark();
    456   if (globExec.exception())
    457       globExec.exception()->mark();
    458 }
    459 
    460 bool InterpreterImp::checkSyntax(const UString &code)
    461 {
    462   JSLock lock;
    463 
    464   // Parser::parse() returns 0 in a syntax error occurs, so we just check for that
    465   RefPtr<ProgramNode> progNode = Parser::parse(UString(), 0, code.data(), code.size(), 0, 0, 0);
    466   return progNode;
    467 }
    468 
    469 Completion InterpreterImp::evaluate(const UChar* code, int codeLength, JSValue* thisV, const UString& sourceURL, int startingLineNumber)
    470 {
    471   JSLock lock;
    472 
    473   // prevent against infinite recursion
    474   if (recursion >= 20)
    475     return Completion(Throw, Error::create(&globExec, GeneralError, "Recursion too deep"));
    476 
    477   // parse the source code
    478   int sid;
    479   int errLine;
    480   UString errMsg;
    481   RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, &sid, &errLine, &errMsg);
    482 
    483   // notify debugger that source has been parsed
    484   if (dbg) {
    485     bool cont = dbg->sourceParsed(&globExec, sid, sourceURL, UString(code, codeLength), errLine);
    486     if (!cont)
    487       return Completion(Break);
    488   }
    489  
    490   // no program node means a syntax error occurred
    491   if (!progNode)
    492     return Completion(Throw, Error::create(&globExec, SyntaxError, errMsg, errLine, sid, &sourceURL));
    493 
    494   globExec.clearException();
    495 
    496   recursion++;
    497 
    498   JSObject* globalObj = globalObject();
    499   JSObject* thisObj = globalObj;
    500 
    501   // "this" must be an object... use same rules as Function.prototype.apply()
    502   if (thisV && !thisV->isUndefinedOrNull())
    503       thisObj = thisV->toObject(&globExec);
    504 
    505   Completion res;
    506   if (globExec.hadException())
    507     // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
    508     res = Completion(Throw, globExec.exception());
    509   else {
    510     // execute the code
    511     ContextImp ctx(globalObj, this, thisObj, progNode.get());
    512     ExecState newExec(m_interpreter, &ctx);
    513     progNode->processVarDecls(&newExec);
    514     res = progNode->execute(&newExec);
    515   }
    516 
    517   recursion--;
    518 
    519   return res;
    520 }
    521 
    522 void InterpreterImp::saveBuiltins (SavedBuiltins &builtins) const
    523 {
    524   if (!builtins._internal) {
    525     builtins._internal = new SavedBuiltinsInternal;
    526   }
    527 
    528   builtins._internal->b_Object = b_Object;
    529   builtins._internal->b_Function = b_Function;
    530   builtins._internal->b_Array = b_Array;
    531   builtins._internal->b_Boolean = b_Boolean;
    532   builtins._internal->b_String = b_String;
    533   builtins._internal->b_Number = b_Number;
    534   builtins._internal->b_Date = b_Date;
    535   builtins._internal->b_RegExp = b_RegExp;
    536   builtins._internal->b_Error = b_Error;
    537  
    538   builtins._internal->b_ObjectPrototype = b_ObjectPrototype;
    539   builtins._internal->b_FunctionPrototype = b_FunctionPrototype;
    540   builtins._internal->b_ArrayPrototype = b_ArrayPrototype;
    541   builtins._internal->b_BooleanPrototype = b_BooleanPrototype;
    542   builtins._internal->b_StringPrototype = b_StringPrototype;
    543   builtins._internal->b_NumberPrototype = b_NumberPrototype;
    544   builtins._internal->b_DatePrototype = b_DatePrototype;
    545   builtins._internal->b_RegExpPrototype = b_RegExpPrototype;
    546   builtins._internal->b_ErrorPrototype = b_ErrorPrototype;
    547  
    548   builtins._internal->b_evalError = b_evalError;
    549   builtins._internal->b_rangeError = b_rangeError;
    550   builtins._internal->b_referenceError = b_referenceError;
    551   builtins._internal->b_syntaxError = b_syntaxError;
    552   builtins._internal->b_typeError = b_typeError;
    553   builtins._internal->b_uriError = b_uriError;
    554  
    555   builtins._internal->b_evalErrorPrototype = b_evalErrorPrototype;
    556   builtins._internal->b_rangeErrorPrototype = b_rangeErrorPrototype;
    557   builtins._internal->b_referenceErrorPrototype = b_referenceErrorPrototype;
    558   builtins._internal->b_syntaxErrorPrototype = b_syntaxErrorPrototype;
    559   builtins._internal->b_typeErrorPrototype = b_typeErrorPrototype;
    560   builtins._internal->b_uriErrorPrototype = b_uriErrorPrototype;
    561 }
    562 
    563 void InterpreterImp::restoreBuiltins (const SavedBuiltins &builtins)
    564 {
    565   if (!builtins._internal) {
    566     return;
    567   }
    568 
    569   b_Object = builtins._internal->b_Object;
    570   b_Function = builtins._internal->b_Function;
    571   b_Array = builtins._internal->b_Array;
    572   b_Boolean = builtins._internal->b_Boolean;
    573   b_String = builtins._internal->b_String;
    574   b_Number = builtins._internal->b_Number;
    575   b_Date = builtins._internal->b_Date;
    576   b_RegExp = builtins._internal->b_RegExp;
    577   b_Error = builtins._internal->b_Error;
    578  
    579   b_ObjectPrototype = builtins._internal->b_ObjectPrototype;
    580   b_FunctionPrototype = builtins._internal->b_FunctionPrototype;
    581   b_ArrayPrototype = builtins._internal->b_ArrayPrototype;
    582   b_BooleanPrototype = builtins._internal->b_BooleanPrototype;
    583   b_StringPrototype = builtins._internal->b_StringPrototype;
    584   b_NumberPrototype = builtins._internal->b_NumberPrototype;
    585   b_DatePrototype = builtins._internal->b_DatePrototype;
    586   b_RegExpPrototype = builtins._internal->b_RegExpPrototype;
    587   b_ErrorPrototype = builtins._internal->b_ErrorPrototype;
    588  
    589   b_evalError = builtins._internal->b_evalError;
    590   b_rangeError = builtins._internal->b_rangeError;
    591   b_referenceError = builtins._internal->b_referenceError;
    592   b_syntaxError = builtins._internal->b_syntaxError;
    593   b_typeError = builtins._internal->b_typeError;
    594   b_uriError = builtins._internal->b_uriError;
    595  
    596   b_evalErrorPrototype = builtins._internal->b_evalErrorPrototype;
    597   b_rangeErrorPrototype = builtins._internal->b_rangeErrorPrototype;
    598   b_referenceErrorPrototype = builtins._internal->b_referenceErrorPrototype;
    599   b_syntaxErrorPrototype = builtins._internal->b_syntaxErrorPrototype;
    600   b_typeErrorPrototype = builtins._internal->b_typeErrorPrototype;
    601   b_uriErrorPrototype = builtins._internal->b_uriErrorPrototype;
    602 }
    603 
    604 InterpreterImp *InterpreterImp::interpreterWithGlobalObject(JSObject *global)
    605 {
    606     return interpreterMap().get(global);
    607 }
    608 
    609 
    610 // ------------------------------ InternalFunctionImp --------------------------
    611 
    612 const ClassInfo InternalFunctionImp::info = {"Function", 0, 0, 0};
    613 
    614 InternalFunctionImp::InternalFunctionImp()
    615 {
    616 }
    617 
    618 InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto)
    619   : JSObject(funcProto)
    620 {
    621 }
    622 
    623 InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto, const Identifier& name)
    624   : JSObject(funcProto)
    625   , m_name(name)
    626 {
    627 }
    628 
    629 bool InternalFunctionImp::implementsCall() const
    630 {
    631   return true;
    632 }
    633 
    634 bool InternalFunctionImp::implementsHasInstance() const
    635 {
    636   return true;
    637 }
    638 
    639 bool InternalFunctionImp::hasInstance(ExecState *exec, JSValue *value)
    640 {
    641   if (!value->isObject())
    642     return false;
    643 
    644   JSValue *prot = get(exec,prototypePropertyName);
    645   if (!prot->isObject() && !prot->isNull()) {
    646     throwError(exec, TypeError, "Invalid prototype encountered in instanceof operation.");
    647     return false;
    648   }
    649 
    650   JSObject *v = static_cast<JSObject *>(value);
    651   while ((v = v->prototype()->getObject())) {
    652     if (v == prot)
    653       return true;
    654   }
    655   return false;
    656 }
    657 
    658 // ------------------------------ global functions -----------------------------
    659 
    660 double roundValue(ExecState *exec, JSValue *v)
    661 {
    662   double d = v->toNumber(exec);
    663   double ad = fabs(d);
    664   if (ad == 0 || isNaN(d) || isInf(d))
    665     return d;
    666   return copysign(floor(ad), d);
    667 }
    668 
    669 #ifndef NDEBUG
    670 #include <stdio.h>
    671 void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno)
    672 {
    673   if (!o)
    674     fprintf(stderr, "KJS: %s: (null)", s);
    675   else {
    676     JSValue *v = o;
    677 
    678     UString name;
    679     switch (v->type()) {
    680     case UnspecifiedType:
    681       name = "Unspecified";
    682       break;
    683     case UndefinedType:
    684       name = "Undefined";
    685       break;
    686     case NullType:
    687       name = "Null";
    688       break;
    689     case BooleanType:
    690       name = "Boolean";
    691       break;
    692     case StringType:
    693       name = "String";
    694       break;
    695     case NumberType:
    696       name = "Number";
    697       break;
    698     case ObjectType:
    699       name = static_cast<JSObject *>(v)->className();
    700       if (name.isNull())
    701         name = "(unknown class)";
    702       break;
    703     case GetterSetterType:
    704       name = "GetterSetter";
    705       break;
    706     }
    707     UString vString = v->toString(exec);
    708     if ( vString.size() > 50 )
    709       vString = vString.substr( 0, 50 ) + "...";
    710     // Can't use two UString::ascii() in the same fprintf call
    711     CString tempString( vString.cstring() );
    712 
    713     fprintf(stderr, "KJS: %s: %s : %s (%p)",
    714             s, tempString.c_str(), name.ascii(), (void*)v);
    715 
    716     if (lineno >= 0)
    717       fprintf(stderr, ", line %d\n",lineno);
    718     else
    719       fprintf(stderr, "\n");
    720   }
    721 }
    722 #endif
    723 
    724 }
     95} // namespace KJS
Note: See TracChangeset for help on using the changeset viewer.