Changeset 13153 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Mar 5, 2006, 9:29:48 PM (19 years ago)
Author:
darin
Message:

Reviewed by Maciej.

  • kjs/Parser.cpp: Added.
  • kjs/Parser.h: Added.
  • kjs/internal.cpp: Removed the Parser class.
  • kjs/internal.h: Ditto. Also removed unnecessary declarations of classes not used in this header.
  • kjs/nodes.h: Added an include of "Parser.h".
  • kjs/function.h: Added a declaration of FunctionBodyNode.
Location:
trunk/JavaScriptCore/kjs
Files:
4 edited
2 copied

Legend:

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

    r13127 r13153  
     1// -*- c-basic-offset: 4 -*-
    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
     
    2324
    2425#include "config.h"
    25 #include "internal.h"
     26#include "Parser.h"
    2627
    27 #include "array_object.h"
    28 #include "bool_object.h"
    29 #include "collector.h"
    30 #include "context.h"
    31 #include "date_object.h"
    32 #include "debugger.h"
    33 #include "error_object.h"
    34 #include "function_object.h"
    3528#include "lexer.h"
    36 #include "math_object.h"
    3729#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 <kxmlcore/HashMap.h>
    4630#include <kxmlcore/HashSet.h>
    4731#include <kxmlcore/Vector.h>
    48 #include <math.h>
    49 #include <stdio.h>
    5032
    5133extern int kjsyyparse();
     
    5335namespace KJS {
    5436
    55 #if PLATFORM(WIN_OS)
    56 #define copysign _copysign
    57 #endif
    58 
    59 // ------------------------------ StringImp ------------------------------------
    60 
    61 JSValue *StringImp::toPrimitive(ExecState *, JSType) const
    62 {
    63   return const_cast<StringImp *>(this);
    64 }
    65 
    66 bool StringImp::toBoolean(ExecState *) const
    67 {
    68   return (val.size() > 0);
    69 }
    70 
    71 double StringImp::toNumber(ExecState *) const
    72 {
    73   return val.toDouble();
    74 }
    75 
    76 UString StringImp::toString(ExecState *) const
    77 {
    78   return val;
    79 }
    80 
    81 JSObject *StringImp::toObject(ExecState *exec) const
    82 {
    83     return new StringInstance(exec->lexicalInterpreter()->builtinStringPrototype(), val);
    84 }
    85 
    86 // ------------------------------ NumberImp ------------------------------------
    87 
    88 JSValue *NumberImp::toPrimitive(ExecState *, JSType) const
    89 {
    90   return const_cast<NumberImp *>(this);
    91 }
    92 
    93 bool NumberImp::toBoolean(ExecState *) const
    94 {
    95   return val < 0.0 || val > 0.0; // false for NaN
    96 }
    97 
    98 double NumberImp::toNumber(ExecState *) const
    99 {
    100   return val;
    101 }
    102 
    103 UString NumberImp::toString(ExecState *) const
    104 {
    105   if (val == 0.0) // +0.0 or -0.0
    106     return "0";
    107   return UString::from(val);
    108 }
    109 
    110 JSObject *NumberImp::toObject(ExecState *exec) const
    111 {
    112   List args;
    113   args.append(const_cast<NumberImp*>(this));
    114   return static_cast<JSObject *>(exec->lexicalInterpreter()->builtinNumber()->construct(exec,args));
    115 }
    116 
    117 // FIXME: We can optimize this to work like JSValue::getUInt32. I'm ignoring it for now
    118 // because it never shows up on profiles.
    119 bool NumberImp::getUInt32(uint32_t& uint32) const
    120 {
    121   uint32 = (uint32_t)val;
    122   return (double)uint32 == val;
    123 }
    124 
    125 // --------------------------- GetterSetterImp ---------------------------------
    126 void GetterSetterImp::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 
    192 // ECMA 10.2
    193 ContextImp::ContextImp(JSObject *glob, InterpreterImp *interpreter, JSObject *thisV, CodeType type,
    194                        ContextImp *callingCon, FunctionImp *func, const List *args)
    195     : _interpreter(interpreter), _function(func), _arguments(args)
    196 {
    197   m_codeType = type;
    198   _callingContext = callingCon;
    199 
    200   // create and initialize activation object (ECMA 10.1.6)
    201   if (type == FunctionCode || type == AnonymousCode ) {
    202     activation = new ActivationImp(func, *args);
    203     variable = activation;
    204   } else {
    205     activation = NULL;
    206     variable = glob;
    207   }
    208 
    209   // ECMA 10.2
    210   switch(type) {
    211     case EvalCode:
    212       if (_callingContext) {
    213         scope = _callingContext->scopeChain();
    214         variable = _callingContext->variableObject();
    215         thisVal = _callingContext->thisValue();
    216         break;
    217       } // else same as GlobalCode
    218     case GlobalCode:
    219       scope.clear();
    220       scope.push(glob);
    221       thisVal = static_cast<JSObject*>(glob);
    222       break;
    223     case FunctionCode:
    224     case AnonymousCode:
    225       if (type == FunctionCode) {
    226         scope = func->scope();
    227         scope.push(activation);
    228       } else {
    229         scope.clear();
    230         scope.push(glob);
    231         scope.push(activation);
    232       }
    233       variable = activation; // TODO: DontDelete ? (ECMA 10.2.3)
    234       thisVal = thisV;
    235       break;
    236     }
    237 
    238   _interpreter->setContext(this);
    239 }
    240 
    241 ContextImp::~ContextImp()
    242 {
    243   _interpreter->setContext(_callingContext);
    244 }
    245 
    246 void ContextImp::mark()
    247 {
    248   for (ContextImp *context = this; context; context = context->_callingContext) {
    249     context->scope.mark();
    250   }
    251 }
    252 
    253 // ------------------------------ Parser ---------------------------------------
    254 
    255 static RefPtr<ProgramNode> *progNode;
    25637int Parser::sid = 0;
    25738
     39static RefPtr<ProgramNode>* progNode;
    25840static Vector<RefPtr<Node> >* newNodes;
    25941static HashSet<Node*>* nodeCycles;
     
    26345    if (!newNodes)
    26446        newNodes = new Vector<RefPtr<Node> >;
    265 
    26647    newNodes->append(node);
    26748}
     
    29374}
    29475
    295 RefPtr<ProgramNode> Parser::parse(const UString &sourceURL, int startingLineNumber,
    296                                      const UChar *code, unsigned int length, int *sourceId,
    297                                      int *errLine, UString *errMsg)
     76PassRefPtr<ProgramNode> Parser::parse(const UString& sourceURL, int startingLineNumber,
     77    const UChar* code, unsigned length,
     78    int* sourceId, int* errLine, UString* errMsg)
    29879{
    299   if (errLine)
    300     *errLine = -1;
    301   if (errMsg)
    302     *errMsg = 0;
    303   if (!progNode)
    304     progNode = new RefPtr<ProgramNode>;
     80    if (errLine)
     81        *errLine = -1;
     82    if (errMsg)
     83        *errMsg = 0;
     84    if (!progNode)
     85        progNode = new RefPtr<ProgramNode>;
    30586
    306   Lexer::curr()->setCode(sourceURL, startingLineNumber, code, length);
    307   *progNode = 0;
    308   sid++;
    309   if (sourceId)
    310     *sourceId = sid;
    311   // Enable this (and the #define YYDEBUG in grammar.y) to debug a parse error
    312   //extern int kjsyydebug;
    313   //kjsyydebug=1;
    314   int parseError = kjsyyparse();
    315   bool lexError = Lexer::curr()->sawError();
    316   Lexer::curr()->doneParsing();
    317   RefPtr<ProgramNode> prog = *progNode;
    318   *progNode = 0;
     87    Lexer::curr()->setCode(sourceURL, startingLineNumber, code, length);
     88    *progNode = 0;
     89    sid++;
     90    if (sourceId)
     91        *sourceId = sid;
    31992
    320   clearNewNodes();
     93    // Enable this and the #define YYDEBUG in grammar.y to debug a parse error
     94    //extern int kjsyydebug;
     95    //kjsyydebug=1;
    32196
    322   if (parseError || lexError) {
    323     int eline = Lexer::curr()->lineNo();
    324     if (errLine)
    325       *errLine = eline;
    326     if (errMsg)
    327       *errMsg = "Parse error";
    328     return RefPtr<ProgramNode>();
    329   }
     97    int parseError = kjsyyparse();
     98    bool lexError = Lexer::curr()->sawError();
     99    Lexer::curr()->doneParsing();
     100    PassRefPtr<ProgramNode> prog = progNode->release();
     101    *progNode = 0;
    330102
    331   return prog;
     103    clearNewNodes();
     104
     105    if (parseError || lexError) {
     106        int eline = Lexer::curr()->lineNo();
     107        if (errLine)
     108            *errLine = eline;
     109        if (errMsg)
     110            *errMsg = "Parse error";
     111        return 0;
     112    }
     113
     114    return prog;
    332115}
    333116
    334 void Parser::accept(ProgramNode *prog)
     117void Parser::accept(PassRefPtr<ProgramNode> prog)
    335118{
    336   *progNode = prog;
     119    *progNode = prog;
    337120}
    338121
    339 // ------------------------------ InterpreterImp -------------------------------
    340 
    341 InterpreterImp* InterpreterImp::s_hook = 0L;
    342 
    343 typedef HashMap<JSObject *, InterpreterImp *> InterpreterMap;
    344 
    345 static inline InterpreterMap &interpreterMap()
    346 {
    347     static InterpreterMap *map = new InterpreterMap;
    348     return *map;
    349122}
    350 
    351 InterpreterImp::InterpreterImp(Interpreter *interp, JSObject *glob)
    352     : globExec(interp, 0)
    353     , _context(0)
    354 {
    355   // add this interpreter to the global chain
    356   // as a root set for garbage collection
    357   JSLock lock;
    358 
    359   m_interpreter = interp;
    360   if (s_hook) {
    361     prev = s_hook;
    362     next = s_hook->next;
    363     s_hook->next->prev = this;
    364     s_hook->next = this;
    365   } else {
    366     // This is the first interpreter
    367     s_hook = next = prev = this;
    368   }
    369 
    370   interpreterMap().set(glob, this);
    371 
    372   global = glob;
    373   dbg = 0;
    374   m_compatMode = Interpreter::NativeMode;
    375 
    376   // initialize properties of the global object
    377   initGlobalObject();
    378 
    379   recursion = 0;
    380 }
    381 
    382 void InterpreterImp::initGlobalObject()
    383 {
    384   Identifier::init();
    385  
    386   // Contructor prototype objects (Object.prototype, Array.prototype etc)
    387 
    388   FunctionPrototype *funcProto = new FunctionPrototype(&globExec);
    389   b_FunctionPrototype = funcProto;
    390   ObjectPrototype *objProto = new ObjectPrototype(&globExec, funcProto);
    391   b_ObjectPrototype = objProto;
    392   funcProto->setPrototype(b_ObjectPrototype);
    393 
    394   ArrayPrototype *arrayProto = new ArrayPrototype(&globExec, objProto);
    395   b_ArrayPrototype = arrayProto;
    396   StringPrototype *stringProto = new StringPrototype(&globExec, objProto);
    397   b_StringPrototype = stringProto;
    398   BooleanPrototype *booleanProto = new BooleanPrototype(&globExec, objProto, funcProto);
    399   b_BooleanPrototype = booleanProto;
    400   NumberPrototype *numberProto = new NumberPrototype(&globExec, objProto, funcProto);
    401   b_NumberPrototype = numberProto;
    402   DatePrototype *dateProto = new DatePrototype(&globExec, objProto);
    403   b_DatePrototype = dateProto;
    404   RegExpPrototype *regexpProto = new RegExpPrototype(&globExec, objProto, funcProto);
    405   b_RegExpPrototype = regexpProto;
    406   ErrorPrototype *errorProto = new ErrorPrototype(&globExec, objProto, funcProto);
    407   b_ErrorPrototype = errorProto;
    408 
    409   static_cast<JSObject*>(global)->setPrototype(b_ObjectPrototype);
    410 
    411   // Constructors (Object, Array, etc.)
    412   b_Object = new ObjectObjectImp(&globExec, objProto, funcProto);
    413   b_Function = new FunctionObjectImp(&globExec, funcProto);
    414   b_Array = new ArrayObjectImp(&globExec, funcProto, arrayProto);
    415   b_String = new StringObjectImp(&globExec, funcProto, stringProto);
    416   b_Boolean = new BooleanObjectImp(&globExec, funcProto, booleanProto);
    417   b_Number = new NumberObjectImp(&globExec, funcProto, numberProto);
    418   b_Date = new DateObjectImp(&globExec, funcProto, dateProto);
    419   b_RegExp = new RegExpObjectImp(&globExec, funcProto, regexpProto);
    420   b_Error = new ErrorObjectImp(&globExec, funcProto, errorProto);
    421 
    422   // Error object prototypes
    423   b_evalErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, EvalError, "EvalError", "EvalError");
    424   b_rangeErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, RangeError, "RangeError", "RangeError");
    425   b_referenceErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, ReferenceError, "ReferenceError", "ReferenceError");
    426   b_syntaxErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, SyntaxError, "SyntaxError", "SyntaxError");
    427   b_typeErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, TypeError, "TypeError", "TypeError");
    428   b_uriErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, URIError, "URIError", "URIError");
    429 
    430   // Error objects
    431   b_evalError = new NativeErrorImp(&globExec, funcProto, b_evalErrorPrototype);
    432   b_rangeError = new NativeErrorImp(&globExec, funcProto, b_rangeErrorPrototype);
    433   b_referenceError = new NativeErrorImp(&globExec, funcProto, b_referenceErrorPrototype);
    434   b_syntaxError = new NativeErrorImp(&globExec, funcProto, b_syntaxErrorPrototype);
    435   b_typeError = new NativeErrorImp(&globExec, funcProto, b_typeErrorPrototype);
    436   b_uriError = new NativeErrorImp(&globExec, funcProto, b_uriErrorPrototype);
    437 
    438   // ECMA 15.3.4.1
    439   funcProto->put(&globExec, constructorPropertyName, b_Function, DontEnum);
    440 
    441   global->put(&globExec, "Object", b_Object, DontEnum);
    442   global->put(&globExec, "Function", b_Function, DontEnum);
    443   global->put(&globExec, "Array", b_Array, DontEnum);
    444   global->put(&globExec, "Boolean", b_Boolean, DontEnum);
    445   global->put(&globExec, "String", b_String, DontEnum);
    446   global->put(&globExec, "Number", b_Number, DontEnum);
    447   global->put(&globExec, "Date", b_Date, DontEnum);
    448   global->put(&globExec, "RegExp", b_RegExp, DontEnum);
    449   global->put(&globExec, "Error", b_Error, DontEnum);
    450   // Using Internal for those to have something != 0
    451   // (see kjs_window). Maybe DontEnum would be ok too ?
    452   global->put(&globExec, "EvalError",b_evalError, Internal);
    453   global->put(&globExec, "RangeError",b_rangeError, Internal);
    454   global->put(&globExec, "ReferenceError",b_referenceError, Internal);
    455   global->put(&globExec, "SyntaxError",b_syntaxError, Internal);
    456   global->put(&globExec, "TypeError",b_typeError, Internal);
    457   global->put(&globExec, "URIError",b_uriError, Internal);
    458 
    459   // Set the constructorPropertyName property of all builtin constructors
    460   objProto->put(&globExec, constructorPropertyName, b_Object, DontEnum | DontDelete | ReadOnly);
    461   funcProto->put(&globExec, constructorPropertyName, b_Function, DontEnum | DontDelete | ReadOnly);
    462   arrayProto->put(&globExec, constructorPropertyName, b_Array, DontEnum | DontDelete | ReadOnly);
    463   booleanProto->put(&globExec, constructorPropertyName, b_Boolean, DontEnum | DontDelete | ReadOnly);
    464   stringProto->put(&globExec, constructorPropertyName, b_String, DontEnum | DontDelete | ReadOnly);
    465   numberProto->put(&globExec, constructorPropertyName, b_Number, DontEnum | DontDelete | ReadOnly);
    466   dateProto->put(&globExec, constructorPropertyName, b_Date, DontEnum | DontDelete | ReadOnly);
    467   regexpProto->put(&globExec, constructorPropertyName, b_RegExp, DontEnum | DontDelete | ReadOnly);
    468   errorProto->put(&globExec, constructorPropertyName, b_Error, DontEnum | DontDelete | ReadOnly);
    469   b_evalErrorPrototype->put(&globExec, constructorPropertyName, b_evalError, DontEnum | DontDelete | ReadOnly);
    470   b_rangeErrorPrototype->put(&globExec, constructorPropertyName, b_rangeError, DontEnum | DontDelete | ReadOnly);
    471   b_referenceErrorPrototype->put(&globExec, constructorPropertyName, b_referenceError, DontEnum | DontDelete | ReadOnly);
    472   b_syntaxErrorPrototype->put(&globExec, constructorPropertyName, b_syntaxError, DontEnum | DontDelete | ReadOnly);
    473   b_typeErrorPrototype->put(&globExec, constructorPropertyName, b_typeError, DontEnum | DontDelete | ReadOnly);
    474   b_uriErrorPrototype->put(&globExec, constructorPropertyName, b_uriError, DontEnum | DontDelete | ReadOnly);
    475 
    476   // built-in values
    477   global->put(&globExec, "NaN",        jsNaN(), DontEnum|DontDelete);
    478   global->put(&globExec, "Infinity",   jsNumber(Inf), DontEnum|DontDelete);
    479   global->put(&globExec, "undefined",  jsUndefined(), DontEnum|DontDelete);
    480 
    481   // built-in functions
    482   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
    483   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
    484   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
    485   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
    486   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
    487   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
    488   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
    489   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
    490   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
    491   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
    492   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
    493 #ifndef NDEBUG
    494   global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
    495 #endif
    496 
    497   // built-in objects
    498   global->put(&globExec, "Math", new MathObjectImp(&globExec, objProto), DontEnum);
    499 }
    500 
    501 InterpreterImp::~InterpreterImp()
    502 {
    503   if (dbg)
    504     dbg->detach(m_interpreter);
    505   clear();
    506 }
    507 
    508 void InterpreterImp::clear()
    509 {
    510   //fprintf(stderr,"InterpreterImp::clear\n");
    511   // remove from global chain (see init())
    512   JSLock lock;
    513 
    514   next->prev = prev;
    515   prev->next = next;
    516   s_hook = next;
    517   if (s_hook == this)
    518   {
    519     // This was the last interpreter
    520     s_hook = 0L;
    521   }
    522   interpreterMap().remove(global);
    523 }
    524 
    525 void InterpreterImp::mark()
    526 {
    527   if (m_interpreter)
    528     m_interpreter->mark();
    529   if (_context)
    530     _context->mark();
    531   if (global)
    532       global->mark();
    533   if (globExec._exception)
    534       globExec._exception->mark();
    535 }
    536 
    537 bool InterpreterImp::checkSyntax(const UString &code)
    538 {
    539   JSLock lock;
    540 
    541   // Parser::parse() returns 0 in a syntax error occurs, so we just check for that
    542   RefPtr<ProgramNode> progNode = Parser::parse(UString(), 0, code.data(), code.size(), 0, 0, 0);
    543   return progNode;
    544 }
    545 
    546 Completion InterpreterImp::evaluate(const UChar* code, int codeLength, JSValue* thisV, const UString& sourceURL, int startingLineNumber)
    547 {
    548   JSLock lock;
    549 
    550   // prevent against infinite recursion
    551   if (recursion >= 20)
    552     return Completion(Throw, Error::create(&globExec, GeneralError, "Recursion too deep"));
    553 
    554   // parse the source code
    555   int sid;
    556   int errLine;
    557   UString errMsg;
    558   RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, &sid, &errLine, &errMsg);
    559 
    560   // notify debugger that source has been parsed
    561   if (dbg) {
    562     bool cont = dbg->sourceParsed(&globExec, sid, sourceURL, UString(code, codeLength), errLine);
    563     if (!cont)
    564       return Completion(Break);
    565   }
    566  
    567   // no program node means a syntax error occurred
    568   if (!progNode)
    569     return Completion(Throw, Error::create(&globExec, SyntaxError, errMsg, errLine, sid, &sourceURL));
    570 
    571   globExec.clearException();
    572 
    573   recursion++;
    574 
    575   JSObject* globalObj = globalObject();
    576   JSObject* thisObj = globalObj;
    577 
    578   // "this" must be an object... use same rules as Function.prototype.apply()
    579   if (thisV && !thisV->isUndefinedOrNull())
    580       thisObj = thisV->toObject(&globExec);
    581 
    582   Completion res;
    583   if (globExec.hadException())
    584     // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
    585     res = Completion(Throw, globExec.exception());
    586   else {
    587     // execute the code
    588     ContextImp ctx(globalObj, this, thisObj);
    589     ExecState newExec(m_interpreter, &ctx);
    590     progNode->processVarDecls(&newExec);
    591     res = progNode->execute(&newExec);
    592   }
    593 
    594   recursion--;
    595 
    596   return res;
    597 }
    598 
    599 void InterpreterImp::saveBuiltins (SavedBuiltins &builtins) const
    600 {
    601   if (!builtins._internal) {
    602     builtins._internal = new SavedBuiltinsInternal;
    603   }
    604 
    605   builtins._internal->b_Object = b_Object;
    606   builtins._internal->b_Function = b_Function;
    607   builtins._internal->b_Array = b_Array;
    608   builtins._internal->b_Boolean = b_Boolean;
    609   builtins._internal->b_String = b_String;
    610   builtins._internal->b_Number = b_Number;
    611   builtins._internal->b_Date = b_Date;
    612   builtins._internal->b_RegExp = b_RegExp;
    613   builtins._internal->b_Error = b_Error;
    614  
    615   builtins._internal->b_ObjectPrototype = b_ObjectPrototype;
    616   builtins._internal->b_FunctionPrototype = b_FunctionPrototype;
    617   builtins._internal->b_ArrayPrototype = b_ArrayPrototype;
    618   builtins._internal->b_BooleanPrototype = b_BooleanPrototype;
    619   builtins._internal->b_StringPrototype = b_StringPrototype;
    620   builtins._internal->b_NumberPrototype = b_NumberPrototype;
    621   builtins._internal->b_DatePrototype = b_DatePrototype;
    622   builtins._internal->b_RegExpPrototype = b_RegExpPrototype;
    623   builtins._internal->b_ErrorPrototype = b_ErrorPrototype;
    624  
    625   builtins._internal->b_evalError = b_evalError;
    626   builtins._internal->b_rangeError = b_rangeError;
    627   builtins._internal->b_referenceError = b_referenceError;
    628   builtins._internal->b_syntaxError = b_syntaxError;
    629   builtins._internal->b_typeError = b_typeError;
    630   builtins._internal->b_uriError = b_uriError;
    631  
    632   builtins._internal->b_evalErrorPrototype = b_evalErrorPrototype;
    633   builtins._internal->b_rangeErrorPrototype = b_rangeErrorPrototype;
    634   builtins._internal->b_referenceErrorPrototype = b_referenceErrorPrototype;
    635   builtins._internal->b_syntaxErrorPrototype = b_syntaxErrorPrototype;
    636   builtins._internal->b_typeErrorPrototype = b_typeErrorPrototype;
    637   builtins._internal->b_uriErrorPrototype = b_uriErrorPrototype;
    638 }
    639 
    640 void InterpreterImp::restoreBuiltins (const SavedBuiltins &builtins)
    641 {
    642   if (!builtins._internal) {
    643     return;
    644   }
    645 
    646   b_Object = builtins._internal->b_Object;
    647   b_Function = builtins._internal->b_Function;
    648   b_Array = builtins._internal->b_Array;
    649   b_Boolean = builtins._internal->b_Boolean;
    650   b_String = builtins._internal->b_String;
    651   b_Number = builtins._internal->b_Number;
    652   b_Date = builtins._internal->b_Date;
    653   b_RegExp = builtins._internal->b_RegExp;
    654   b_Error = builtins._internal->b_Error;
    655  
    656   b_ObjectPrototype = builtins._internal->b_ObjectPrototype;
    657   b_FunctionPrototype = builtins._internal->b_FunctionPrototype;
    658   b_ArrayPrototype = builtins._internal->b_ArrayPrototype;
    659   b_BooleanPrototype = builtins._internal->b_BooleanPrototype;
    660   b_StringPrototype = builtins._internal->b_StringPrototype;
    661   b_NumberPrototype = builtins._internal->b_NumberPrototype;
    662   b_DatePrototype = builtins._internal->b_DatePrototype;
    663   b_RegExpPrototype = builtins._internal->b_RegExpPrototype;
    664   b_ErrorPrototype = builtins._internal->b_ErrorPrototype;
    665  
    666   b_evalError = builtins._internal->b_evalError;
    667   b_rangeError = builtins._internal->b_rangeError;
    668   b_referenceError = builtins._internal->b_referenceError;
    669   b_syntaxError = builtins._internal->b_syntaxError;
    670   b_typeError = builtins._internal->b_typeError;
    671   b_uriError = builtins._internal->b_uriError;
    672  
    673   b_evalErrorPrototype = builtins._internal->b_evalErrorPrototype;
    674   b_rangeErrorPrototype = builtins._internal->b_rangeErrorPrototype;
    675   b_referenceErrorPrototype = builtins._internal->b_referenceErrorPrototype;
    676   b_syntaxErrorPrototype = builtins._internal->b_syntaxErrorPrototype;
    677   b_typeErrorPrototype = builtins._internal->b_typeErrorPrototype;
    678   b_uriErrorPrototype = builtins._internal->b_uriErrorPrototype;
    679 }
    680 
    681 InterpreterImp *InterpreterImp::interpreterWithGlobalObject(JSObject *global)
    682 {
    683     return interpreterMap().get(global);
    684 }
    685 
    686 
    687 // ------------------------------ InternalFunctionImp --------------------------
    688 
    689 const ClassInfo InternalFunctionImp::info = {"Function", 0, 0, 0};
    690 
    691 InternalFunctionImp::InternalFunctionImp()
    692 {
    693 }
    694 
    695 InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto)
    696   : JSObject(funcProto)
    697 {
    698 }
    699 
    700 InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto, const Identifier& name)
    701   : JSObject(funcProto)
    702   , m_name(name)
    703 {
    704 }
    705 
    706 bool InternalFunctionImp::implementsCall() const
    707 {
    708   return true;
    709 }
    710 
    711 bool InternalFunctionImp::implementsHasInstance() const
    712 {
    713   return true;
    714 }
    715 
    716 bool InternalFunctionImp::hasInstance(ExecState *exec, JSValue *value)
    717 {
    718   if (!value->isObject())
    719     return false;
    720 
    721   JSValue *prot = get(exec,prototypePropertyName);
    722   if (!prot->isObject() && !prot->isNull()) {
    723     throwError(exec, TypeError, "Invalid prototype encountered in instanceof operation.");
    724     return false;
    725   }
    726 
    727   JSObject *v = static_cast<JSObject *>(value);
    728   while ((v = v->prototype()->getObject())) {
    729     if (v == prot)
    730       return true;
    731   }
    732   return false;
    733 }
    734 
    735 // ------------------------------ global functions -----------------------------
    736 
    737 double roundValue(ExecState *exec, JSValue *v)
    738 {
    739   double d = v->toNumber(exec);
    740   double ad = fabs(d);
    741   if (ad == 0 || isNaN(d) || isInf(d))
    742     return d;
    743   return copysign(floor(ad), d);
    744 }
    745 
    746 #ifndef NDEBUG
    747 #include <stdio.h>
    748 void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno)
    749 {
    750   if (!o)
    751     fprintf(stderr, "KJS: %s: (null)", s);
    752   else {
    753     JSValue *v = o;
    754 
    755     UString name;
    756     switch (v->type()) {
    757     case UnspecifiedType:
    758       name = "Unspecified";
    759       break;
    760     case UndefinedType:
    761       name = "Undefined";
    762       break;
    763     case NullType:
    764       name = "Null";
    765       break;
    766     case BooleanType:
    767       name = "Boolean";
    768       break;
    769     case StringType:
    770       name = "String";
    771       break;
    772     case NumberType:
    773       name = "Number";
    774       break;
    775     case ObjectType:
    776       name = static_cast<JSObject *>(v)->className();
    777       if (name.isNull())
    778         name = "(unknown class)";
    779       break;
    780     case GetterSetterType:
    781       name = "GetterSetter";
    782       break;
    783     }
    784     UString vString = v->toString(exec);
    785     if ( vString.size() > 50 )
    786       vString = vString.substr( 0, 50 ) + "...";
    787     // Can't use two UString::ascii() in the same fprintf call
    788     CString tempString( vString.cstring() );
    789 
    790     fprintf(stderr, "KJS: %s: %s : %s (%p)",
    791             s, tempString.c_str(), name.ascii(), (void*)v);
    792 
    793     if (lineno >= 0)
    794       fprintf(stderr, ", line %d\n",lineno);
    795     else
    796       fprintf(stderr, "\n");
    797   }
    798 }
    799 #endif
    800 
    801 }
  • trunk/JavaScriptCore/kjs/Parser.h

    r13127 r13153  
    1 // -*- c-basic-offset: 2 -*-
     1// -*- c-basic-offset: 4 -*-
    22/*
    33 *  This file is part of the KDE libraries
    44 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    55 *  Copyright (C) 2001 Peter Kelly ([email protected])
    6  *  Copyright (C) 2003 Apple Computer, Inc.
     6 *  Copyright (C) 2003, 2006 Apple Computer, Inc.
    77 *
    88 *  This library is free software; you can redistribute it and/or
     
    2323 */
    2424
    25 #ifndef INTERNAL_H
    26 #define INTERNAL_H
     25#ifndef Parser_h
     26#define Parser_h
    2727
    28 #include "JSType.h"
    29 #include "interpreter.h"
    30 #include "object.h"
    31 #include "protect.h"
    32 #include "scope_chain.h"
    33 #include "types.h"
    34 #include "ustring.h"
    35 
    36 #include <kxmlcore/Noncopyable.h>
    37 #include <kxmlcore/RefPtr.h>
    38 
    39 #define I18N_NOOP(s) s
     28#include <kxmlcore/PassRefPtr.h>
    4029
    4130namespace KJS {
    4231
    43   class Node;
    44   class ProgramNode;
    45   class FunctionBodyNode;
    46   class FunctionPrototype;
    47   class FunctionImp;
    48   class Debugger;
    49 
    50   // ---------------------------------------------------------------------------
    51   //                            Primitive impls
    52   // ---------------------------------------------------------------------------
    53 
    54   class StringImp : public JSCell {
    55   public:
    56     StringImp(const UString& v) : val(v) { }
    57     UString value() const { return val; }
    58 
    59     JSType type() const { return StringType; }
    60 
    61     JSValue *toPrimitive(ExecState *exec, JSType preferred = UnspecifiedType) const;
    62     bool toBoolean(ExecState *exec) const;
    63     double toNumber(ExecState *exec) const;
    64     UString toString(ExecState *exec) const;
    65     JSObject *toObject(ExecState *exec) const;
    66 
    67   private:
    68     UString val;
    69   };
    70 
    71   class NumberImp : public JSCell {
    72     friend class ConstantValues;
    73     friend class InterpreterImp;
    74     friend JSValue *jsNumberCell(double);
    75   public:
    76     double value() const { return val; }
    77 
    78     JSType type() const { return NumberType; }
    79 
    80     JSValue *toPrimitive(ExecState *exec, JSType preferred = UnspecifiedType) const;
    81     bool toBoolean(ExecState *exec) const;
    82     double toNumber(ExecState *exec) const;
    83     UString toString(ExecState *exec) const;
    84     JSObject *toObject(ExecState *exec) const;
    85 
    86   private:
    87     NumberImp(double v) : val(v) { }
    88 
    89     virtual bool getUInt32(uint32_t&) const;
    90 
    91     double val;
    92   };
    93  
    94 
    95   /**
    96    * @short The "label set" in Ecma-262 spec
    97    */
    98   class LabelStack : Noncopyable {
    99   public:
    100     LabelStack(): tos(0), iterationDepth(0), switchDepth(0) {}
    101     ~LabelStack();
     32    class Node;
     33    class ProgramNode;
     34    class UChar;
     35    class UString;
    10236
    10337    /**
    104      * If id is not empty and is not in the stack already, puts it on top of
    105      * the stack and returns true, otherwise returns false
     38     * @internal
     39     *
     40     * Parses ECMAScript source code and converts into ProgramNode objects, which
     41     * represent the root of a parse tree. This class provides a convenient workaround
     42     * for the problem of the bison parser working in a static context.
    10643     */
    107     bool push(const Identifier &id);
    108     /**
    109      * Is the id in the stack?
    110      */
    111     bool contains(const Identifier &id) const;
    112     /**
    113      * Removes from the stack the last pushed id (what else?)
    114      */
    115     void pop();
    116    
    117     void pushIteration() { iterationDepth++; }
    118     void popIteration() { iterationDepth--; }
    119     bool inIteration() const { return (iterationDepth > 0); }
    120    
    121     void pushSwitch() { switchDepth++; }
    122     void popSwitch() { switchDepth--; }
    123     bool inSwitch() const { return (switchDepth > 0); }
    124    
    125   private:
    126     struct StackElem {
    127       Identifier id;
    128       StackElem *prev;
     44    class Parser {
     45    public:
     46        static PassRefPtr<ProgramNode> parse(const UString& sourceURL, int startingLineNumber,
     47            const UChar* code, unsigned length,
     48            int* sourceId = 0, int* errLine = 0, UString* errMsg = 0);
     49
     50        static void accept(PassRefPtr<ProgramNode>);
     51
     52        static void saveNewNode(Node*);
     53        static void noteNodeCycle(Node*);
     54        static void removeNodeCycle(Node*);
     55
     56        static int sid;
    12957    };
    130 
    131     StackElem *tos;
    132     int iterationDepth;
    133     int switchDepth;
    134   };
    135 
    136 
    137   // ---------------------------------------------------------------------------
    138   //                            Parsing & evaluation
    139   // ---------------------------------------------------------------------------
    140 
    141   enum CodeType { GlobalCode,
    142                   EvalCode,
    143                   FunctionCode,
    144                   AnonymousCode };
    145 
    146   /**
    147    * @internal
    148    *
    149    * Parses ECMAScript source code and converts into ProgramNode objects, which
    150    * represent the root of a parse tree. This class provides a conveniant workaround
    151    * for the problem of the bison parser working in a static context.
    152    */
    153   class Parser {
    154   public:
    155     static RefPtr<ProgramNode> parse(const UString &sourceURL, int startingLineNumber,
    156                                         const UChar *code, unsigned int length, int *sourceId = 0,
    157                                         int *errLine = 0, UString *errMsg = 0);
    158     static void accept(ProgramNode *prog);
    159 
    160     static void saveNewNode(Node *node);
    161     static void noteNodeCycle(Node *node);
    162     static void removeNodeCycle(Node *node);
    163 
    164     static int sid;
    165   };
    166 
    167   class SavedBuiltinsInternal {
    168     friend class InterpreterImp;
    169   private:
    170     ProtectedPtr<JSObject> b_Object;
    171     ProtectedPtr<JSObject> b_Function;
    172     ProtectedPtr<JSObject> b_Array;
    173     ProtectedPtr<JSObject> b_Boolean;
    174     ProtectedPtr<JSObject> b_String;
    175     ProtectedPtr<JSObject> b_Number;
    176     ProtectedPtr<JSObject> b_Date;
    177     ProtectedPtr<JSObject> b_RegExp;
    178     ProtectedPtr<JSObject> b_Error;
    179 
    180     ProtectedPtr<JSObject> b_ObjectPrototype;
    181     ProtectedPtr<JSObject> b_FunctionPrototype;
    182     ProtectedPtr<JSObject> b_ArrayPrototype;
    183     ProtectedPtr<JSObject> b_BooleanPrototype;
    184     ProtectedPtr<JSObject> b_StringPrototype;
    185     ProtectedPtr<JSObject> b_NumberPrototype;
    186     ProtectedPtr<JSObject> b_DatePrototype;
    187     ProtectedPtr<JSObject> b_RegExpPrototype;
    188     ProtectedPtr<JSObject> b_ErrorPrototype;
    189 
    190     ProtectedPtr<JSObject> b_evalError;
    191     ProtectedPtr<JSObject> b_rangeError;
    192     ProtectedPtr<JSObject> b_referenceError;
    193     ProtectedPtr<JSObject> b_syntaxError;
    194     ProtectedPtr<JSObject> b_typeError;
    195     ProtectedPtr<JSObject> b_uriError;
    196 
    197     ProtectedPtr<JSObject> b_evalErrorPrototype;
    198     ProtectedPtr<JSObject> b_rangeErrorPrototype;
    199     ProtectedPtr<JSObject> b_referenceErrorPrototype;
    200     ProtectedPtr<JSObject> b_syntaxErrorPrototype;
    201     ProtectedPtr<JSObject> b_typeErrorPrototype;
    202     ProtectedPtr<JSObject> b_uriErrorPrototype;
    203   };
    204 
    205   class InterpreterImp {
    206     friend class Collector;
    207   public:
    208     InterpreterImp(Interpreter *interp, JSObject *glob);
    209     ~InterpreterImp();
    210 
    211     JSObject *globalObject() { return global; }
    212     Interpreter *interpreter() const { return m_interpreter; }
    213 
    214     void initGlobalObject();
    215 
    216     void mark();
    217 
    218     ExecState *globalExec() { return &globExec; }
    219     bool checkSyntax(const UString &code);
    220     Completion evaluate(const UChar* code, int codeLength, JSValue* thisV, const UString& sourceURL, int startingLineNumber);
    221     Debugger *debugger() const { return dbg; }
    222     void setDebugger(Debugger *d) { dbg = d; }
    223 
    224     JSObject *builtinObject() const { return b_Object; }
    225     JSObject *builtinFunction() const { return b_Function; }
    226     JSObject *builtinArray() const { return b_Array; }
    227     JSObject *builtinBoolean() const { return b_Boolean; }
    228     JSObject *builtinString() const { return b_String; }
    229     JSObject *builtinNumber() const { return b_Number; }
    230     JSObject *builtinDate() const { return b_Date; }
    231     JSObject *builtinRegExp() const { return b_RegExp; }
    232     JSObject *builtinError() const { return b_Error; }
    233 
    234     JSObject *builtinObjectPrototype() const { return b_ObjectPrototype; }
    235     JSObject *builtinFunctionPrototype() const { return b_FunctionPrototype; }
    236     JSObject *builtinArrayPrototype() const { return b_ArrayPrototype; }
    237     JSObject *builtinBooleanPrototype() const { return b_BooleanPrototype; }
    238     JSObject *builtinStringPrototype() const { return b_StringPrototype; }
    239     JSObject *builtinNumberPrototype() const { return b_NumberPrototype; }
    240     JSObject *builtinDatePrototype() const { return b_DatePrototype; }
    241     JSObject *builtinRegExpPrototype() const { return b_RegExpPrototype; }
    242     JSObject *builtinErrorPrototype() const { return b_ErrorPrototype; }
    243 
    244     JSObject *builtinEvalError() const { return b_evalError; }
    245     JSObject *builtinRangeError() const { return b_rangeError; }
    246     JSObject *builtinReferenceError() const { return b_referenceError; }
    247     JSObject *builtinSyntaxError() const { return b_syntaxError; }
    248     JSObject *builtinTypeError() const { return b_typeError; }
    249     JSObject *builtinURIError() const { return b_uriError; }
    250 
    251     JSObject *builtinEvalErrorPrototype() const { return b_evalErrorPrototype; }
    252     JSObject *builtinRangeErrorPrototype() const { return b_rangeErrorPrototype; }
    253     JSObject *builtinReferenceErrorPrototype() const { return b_referenceErrorPrototype; }
    254     JSObject *builtinSyntaxErrorPrototype() const { return b_syntaxErrorPrototype; }
    255     JSObject *builtinTypeErrorPrototype() const { return b_typeErrorPrototype; }
    256     JSObject *builtinURIErrorPrototype() const { return b_uriErrorPrototype; }
    257 
    258     void setCompatMode(Interpreter::CompatMode mode) { m_compatMode = mode; }
    259     Interpreter::CompatMode compatMode() const { return m_compatMode; }
    260 
    261     // Chained list of interpreters (ring)
    262     static InterpreterImp* firstInterpreter() { return s_hook; }
    263     InterpreterImp *nextInterpreter() const { return next; }
    264     InterpreterImp *prevInterpreter() const { return prev; }
    265 
    266     static InterpreterImp *interpreterWithGlobalObject(JSObject *);
    267    
    268     void setContext(ContextImp *c) { _context = c; }
    269     ContextImp *context() const { return _context; }
    270 
    271     void saveBuiltins (SavedBuiltins &builtins) const;
    272     void restoreBuiltins (const SavedBuiltins &builtins);
    273 
    274   private:
    275     void clear();
    276     Interpreter *m_interpreter;
    277     JSObject *global;
    278     Debugger *dbg;
    279 
    280     // Built-in properties of the object prototype. These are accessible
    281     // from here even if they are replaced by js code (e.g. assigning to
    282     // Array.prototype)
    283 
    284     ProtectedPtr<JSObject> b_Object;
    285     ProtectedPtr<JSObject> b_Function;
    286     ProtectedPtr<JSObject> b_Array;
    287     ProtectedPtr<JSObject> b_Boolean;
    288     ProtectedPtr<JSObject> b_String;
    289     ProtectedPtr<JSObject> b_Number;
    290     ProtectedPtr<JSObject> b_Date;
    291     ProtectedPtr<JSObject> b_RegExp;
    292     ProtectedPtr<JSObject> b_Error;
    293 
    294     ProtectedPtr<JSObject> b_ObjectPrototype;
    295     ProtectedPtr<JSObject> b_FunctionPrototype;
    296     ProtectedPtr<JSObject> b_ArrayPrototype;
    297     ProtectedPtr<JSObject> b_BooleanPrototype;
    298     ProtectedPtr<JSObject> b_StringPrototype;
    299     ProtectedPtr<JSObject> b_NumberPrototype;
    300     ProtectedPtr<JSObject> b_DatePrototype;
    301     ProtectedPtr<JSObject> b_RegExpPrototype;
    302     ProtectedPtr<JSObject> b_ErrorPrototype;
    303 
    304     ProtectedPtr<JSObject> b_evalError;
    305     ProtectedPtr<JSObject> b_rangeError;
    306     ProtectedPtr<JSObject> b_referenceError;
    307     ProtectedPtr<JSObject> b_syntaxError;
    308     ProtectedPtr<JSObject> b_typeError;
    309     ProtectedPtr<JSObject> b_uriError;
    310 
    311     ProtectedPtr<JSObject> b_evalErrorPrototype;
    312     ProtectedPtr<JSObject> b_rangeErrorPrototype;
    313     ProtectedPtr<JSObject> b_referenceErrorPrototype;
    314     ProtectedPtr<JSObject> b_syntaxErrorPrototype;
    315     ProtectedPtr<JSObject> b_typeErrorPrototype;
    316     ProtectedPtr<JSObject> b_uriErrorPrototype;
    317 
    318     ExecState globExec;
    319     Interpreter::CompatMode m_compatMode;
    320 
    321     // Chained list of interpreters (ring) - for collector
    322     static InterpreterImp* s_hook;
    323     InterpreterImp *next, *prev;
    324    
    325     ContextImp *_context;
    326 
    327     int recursion;
    328   };
    329 
    330   class AttachedInterpreter;
    331   class DebuggerImp {
    332   public:
    333 
    334     DebuggerImp() {
    335       interps = 0;
    336       isAborted = false;
    337     }
    338 
    339     void abort() { isAborted = true; }
    340     bool aborted() const { return isAborted; }
    341 
    342     AttachedInterpreter *interps;
    343     bool isAborted;
    344   };
    345 
    346   class InternalFunctionImp : public JSObject {
    347   public:
    348     InternalFunctionImp();
    349     InternalFunctionImp(FunctionPrototype*);
    350     InternalFunctionImp(FunctionPrototype*, const Identifier&);
    351 
    352     virtual bool implementsCall() const;
    353     virtual JSValue* callAsFunction(ExecState*, JSObject* thisObjec, const List& args) = 0;
    354     virtual bool implementsHasInstance() const;
    355     virtual bool hasInstance(ExecState*, JSValue*);
    356 
    357     virtual const ClassInfo* classInfo() const { return &info; }
    358     static const ClassInfo info;
    359     const Identifier& functionName() const { return m_name; }
    360 
    361   private:
    362     Identifier m_name;
    363   };
    364 
    365   // helper function for toInteger, toInt32, toUInt32 and toUInt16
    366   double roundValue(ExecState *, JSValue *);
    367 
    368 #ifndef NDEBUG
    369   void printInfo(ExecState *exec, const char *s, JSValue *, int lineno = -1);
    370 #endif
    371 
    372 inline LabelStack::~LabelStack()
    373 {
    374     StackElem *prev;
    375     for (StackElem *e = tos; e; e = prev) {
    376         prev = e->prev;
    377         delete e;
    378     }
    379 }
    380 
    381 inline void LabelStack::pop()
    382 {
    383     if (StackElem *e = tos) {
    384         tos = e->prev;
    385         delete e;
    386     }
    387 }
    38858
    38959} // namespace
    39060
    391 #endif //  INTERNAL_H
     61#endif
  • trunk/JavaScriptCore/kjs/function.h

    r12921 r13153  
    3030namespace KJS {
    3131
     32  class ActivationImp;
     33  class FunctionBodyNode;
    3234  class Parameter;
    33   class ActivationImp;
    3435
    3536  /**
  • trunk/JavaScriptCore/kjs/internal.cpp

    r13089 r13153  
    4949#include <stdio.h>
    5050
    51 extern int kjsyyparse();
    52 
    5351namespace KJS {
    5452
     
    249247    context->scope.mark();
    250248  }
    251 }
    252 
    253 // ------------------------------ Parser ---------------------------------------
    254 
    255 static RefPtr<ProgramNode> *progNode;
    256 int Parser::sid = 0;
    257 
    258 static Vector<RefPtr<Node> >* newNodes;
    259 static HashSet<Node*>* nodeCycles;
    260 
    261 void Parser::saveNewNode(Node *node)
    262 {
    263     if (!newNodes)
    264         newNodes = new Vector<RefPtr<Node> >;
    265 
    266     newNodes->append(node);
    267 }
    268 
    269 void Parser::noteNodeCycle(Node *node)
    270 {
    271     if (!nodeCycles)
    272         nodeCycles = new HashSet<Node*>;
    273     nodeCycles->add(node);
    274 }
    275 
    276 void Parser::removeNodeCycle(Node *node)
    277 {
    278     ASSERT(nodeCycles);
    279     nodeCycles->remove(node);
    280 }
    281 
    282 static void clearNewNodes()
    283 {
    284     if (nodeCycles) {
    285         for (HashSet<Node*>::iterator it = nodeCycles->begin(); it != nodeCycles->end(); ++it)
    286             (*it)->breakCycle();
    287         delete nodeCycles;
    288         nodeCycles = 0;
    289     }
    290 
    291     delete newNodes;
    292     newNodes = 0;
    293 }
    294 
    295 RefPtr<ProgramNode> Parser::parse(const UString &sourceURL, int startingLineNumber,
    296                                      const UChar *code, unsigned int length, int *sourceId,
    297                                      int *errLine, UString *errMsg)
    298 {
    299   if (errLine)
    300     *errLine = -1;
    301   if (errMsg)
    302     *errMsg = 0;
    303   if (!progNode)
    304     progNode = new RefPtr<ProgramNode>;
    305 
    306   Lexer::curr()->setCode(sourceURL, startingLineNumber, code, length);
    307   *progNode = 0;
    308   sid++;
    309   if (sourceId)
    310     *sourceId = sid;
    311   // Enable this (and the #define YYDEBUG in grammar.y) to debug a parse error
    312   //extern int kjsyydebug;
    313   //kjsyydebug=1;
    314   int parseError = kjsyyparse();
    315   bool lexError = Lexer::curr()->sawError();
    316   Lexer::curr()->doneParsing();
    317   RefPtr<ProgramNode> prog = *progNode;
    318   *progNode = 0;
    319 
    320   clearNewNodes();
    321 
    322   if (parseError || lexError) {
    323     int eline = Lexer::curr()->lineNo();
    324     if (errLine)
    325       *errLine = eline;
    326     if (errMsg)
    327       *errMsg = "Parse error";
    328     return RefPtr<ProgramNode>();
    329   }
    330 
    331   return prog;
    332 }
    333 
    334 void Parser::accept(ProgramNode *prog)
    335 {
    336   *progNode = prog;
    337249}
    338250
  • trunk/JavaScriptCore/kjs/internal.h

    r12921 r13153  
    44 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    55 *  Copyright (C) 2001 Peter Kelly ([email protected])
    6  *  Copyright (C) 2003 Apple Computer, Inc.
     6 *  Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
    77 *
    88 *  This library is free software; you can redistribute it and/or
     
    4141namespace KJS {
    4242
    43   class Node;
    44   class ProgramNode;
    45   class FunctionBodyNode;
     43  class Debugger;
    4644  class FunctionPrototype;
    47   class FunctionImp;
    48   class Debugger;
    4945
    5046  // ---------------------------------------------------------------------------
     
    136132
    137133  // ---------------------------------------------------------------------------
    138   //                            Parsing & evaluation
     134  //                            Evaluation
    139135  // ---------------------------------------------------------------------------
    140136
     
    143139                  FunctionCode,
    144140                  AnonymousCode };
    145 
    146   /**
    147    * @internal
    148    *
    149    * Parses ECMAScript source code and converts into ProgramNode objects, which
    150    * represent the root of a parse tree. This class provides a conveniant workaround
    151    * for the problem of the bison parser working in a static context.
    152    */
    153   class Parser {
    154   public:
    155     static RefPtr<ProgramNode> parse(const UString &sourceURL, int startingLineNumber,
    156                                         const UChar *code, unsigned int length, int *sourceId = 0,
    157                                         int *errLine = 0, UString *errMsg = 0);
    158     static void accept(ProgramNode *prog);
    159 
    160     static void saveNewNode(Node *node);
    161     static void noteNodeCycle(Node *node);
    162     static void removeNodeCycle(Node *node);
    163 
    164     static int sid;
    165   };
    166141
    167142  class SavedBuiltinsInternal {
  • trunk/JavaScriptCore/kjs/nodes.h

    r13138 r13153  
    44 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
    55 *  Copyright (C) 2001 Peter Kelly ([email protected])
    6  *  Copyright (C) 2003 Apple Computer, Inc.
     6 *  Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
    77 *
    88 *  This library is free software; you can redistribute it and/or
     
    2323 */
    2424
    25 #ifndef _NODES_H_
    26 #define _NODES_H_
    27 
     25#ifndef NODES_H_
     26#define NODES_H_
     27
     28#include "Parser.h"
     29#include "internal.h"
     30#include <kxmlcore/ListRefPtr.h>
    2831#include <kxmlcore/RefPtr.h>
    29 #include <kxmlcore/ListRefPtr.h>
    30 
    31 #include "internal.h"
    3232
    3333namespace KJS {
Note: See TracChangeset for help on using the changeset viewer.