Changeset 27842 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Nov 15, 2007, 10:54:09 PM (18 years ago)
Author:
[email protected]
Message:

Reviewed by Eric Seidel.

Another round of grammar / parsing cleanup.


  1. Created distinct parser calls for parsing function bodies vs programs. This will help later with optimizing global variable access.


  1. Turned Parser into a singleton. Cleaned up Lexer's singleton interface.


  1. Modified Lexer to free a little more memory when done lexing. (Added FIXMEs for similar issues that I didn't fix.)


  1. Changed Lexer::makeIdentifier and Lexer::makeUString to start respecting the arguments passed to them. (No behavior change, but this problem could have caused serious problems for an unsuspecting user of these functions.)


  1. Removed KJS_DEBUG_MEM because it was bit-rotted.


  1. Removed Parser::prettyPrint because the same work was simpler to do at the call site.


  1. Some renames:


"Parser::accept" => "Parser::didFinishParsing"
"Parser::sid" => "Parser::m_sourceID"
"Lexer::doneParsing" => "Lexer::clear"
"sid" => "sourceId"
"lineno" => "lineNo"


  • JavaScriptCore.exp:
  • kjs/Parser.cpp: (KJS::Parser::Parser): (KJS::Parser::parseProgram): (KJS::Parser::parseFunctionBody): (KJS::Parser::parse): (KJS::Parser::didFinishParsing): (KJS::parser):
  • kjs/Parser.h: (KJS::Parser::sourceId):
  • kjs/function.cpp: (KJS::GlobalFuncImp::callAsFunction):
  • kjs/function_object.cpp: (FunctionObjectImp::construct):
  • kjs/grammar.y:
  • kjs/interpreter.cpp: (KJS::Interpreter::checkSyntax): (KJS::Interpreter::evaluate):
  • kjs/interpreter.h:
  • kjs/lexer.cpp: (kjsyylex): (KJS::lexer): (KJS::Lexer::Lexer): (KJS::Lexer::~Lexer): (KJS::Lexer::scanRegExp): (KJS::Lexer::doneParsing): (KJS::Lexer::makeIdentifier): (KJS::Lexer::makeUString):
  • kjs/lexer.h: (KJS::Lexer::pattern): (KJS::Lexer::flags): (KJS::Lexer::sawError):
  • kjs/nodes.cpp: (KJS::Node::Node): (KJS::FunctionBodyNode::FunctionBodyNode):
  • kjs/nodes.h:
  • kjs/testkjs.cpp: (prettyPrintScript): (kjsmain):
  • kjs/ustring.cpp:
  • kjs/ustring.h:
Location:
trunk/JavaScriptCore
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r27831 r27842  
     12007-11-15  Geoffrey Garen  <[email protected]>
     2
     3        Reviewed by Eric Seidel.
     4
     5        Another round of grammar / parsing cleanup.
     6       
     7        1. Created distinct parser calls for parsing function bodies vs
     8        programs. This will help later with optimizing global variable access.
     9       
     10        2. Turned Parser into a singleton. Cleaned up Lexer's singleton
     11        interface.
     12       
     13        3. Modified Lexer to free a little more memory when done lexing. (Added
     14        FIXMEs for similar issues that I didn't fix.)
     15       
     16        4. Changed Lexer::makeIdentifier and Lexer::makeUString to start
     17        respecting the arguments passed to them. (No behavior change, but this
     18        problem could have caused serious problems for an unsuspecting user of
     19        these functions.)
     20       
     21        5. Removed KJS_DEBUG_MEM because it was bit-rotted.
     22       
     23        6. Removed Parser::prettyPrint because the same work was simpler to do
     24        at the call site.
     25       
     26        7. Some renames:
     27       
     28            "Parser::accept" => "Parser::didFinishParsing"
     29            "Parser::sid" => "Parser::m_sourceID"
     30            "Lexer::doneParsing" => "Lexer::clear"
     31            "sid" => "sourceId"
     32            "lineno" => "lineNo"
     33       
     34        * JavaScriptCore.exp:
     35        * kjs/Parser.cpp:
     36        (KJS::Parser::Parser):
     37        (KJS::Parser::parseProgram):
     38        (KJS::Parser::parseFunctionBody):
     39        (KJS::Parser::parse):
     40        (KJS::Parser::didFinishParsing):
     41        (KJS::parser):
     42        * kjs/Parser.h:
     43        (KJS::Parser::sourceId):
     44        * kjs/function.cpp:
     45        (KJS::GlobalFuncImp::callAsFunction):
     46        * kjs/function_object.cpp:
     47        (FunctionObjectImp::construct):
     48        * kjs/grammar.y:
     49        * kjs/interpreter.cpp:
     50        (KJS::Interpreter::checkSyntax):
     51        (KJS::Interpreter::evaluate):
     52        * kjs/interpreter.h:
     53        * kjs/lexer.cpp:
     54        (kjsyylex):
     55        (KJS::lexer):
     56        (KJS::Lexer::Lexer):
     57        (KJS::Lexer::~Lexer):
     58        (KJS::Lexer::scanRegExp):
     59        (KJS::Lexer::doneParsing):
     60        (KJS::Lexer::makeIdentifier):
     61        (KJS::Lexer::makeUString):
     62        * kjs/lexer.h:
     63        (KJS::Lexer::pattern):
     64        (KJS::Lexer::flags):
     65        (KJS::Lexer::sawError):
     66        * kjs/nodes.cpp:
     67        (KJS::Node::Node):
     68        (KJS::FunctionBodyNode::FunctionBodyNode):
     69        * kjs/nodes.h:
     70        * kjs/testkjs.cpp:
     71        (prettyPrintScript):
     72        (kjsmain):
     73        * kjs/ustring.cpp:
     74        * kjs/ustring.h:
     75
    1762007-11-15  Oliver Hunt  <[email protected]>
    277
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r27746 r27842  
    164164__ZN3KJS4List15expandAndAppendEPNS_7JSValueE
    165165__ZN3KJS4List7markSetEv
     166__ZN3KJS4Node5derefEv
    166167__ZN3KJS6JSCell9getObjectEv
    167168__ZN3KJS6JSCellnwEm
     
    173174__ZN3KJS6JSLock9lockCountEv
    174175__ZN3KJS6Lookup9findEntryEPKNS_9HashTableERKNS_10IdentifierE
    175 __ZN3KJS6Parser11prettyPrintERKNS_7UStringEPiPS1_
     176__ZN3KJS6Parser12parseProgramERKNS_7UStringEiPKNS_5UCharEjPiS7_PS1_
     177__ZN3KJS6parserEv
    176178__ZN3KJS7CStringD1Ev
    177179__ZN3KJS7UString3Rep4nullE
     
    207209__ZN3KJS8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
    208210__ZN3KJS8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
     211__ZN3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
    209212__ZN3KJS8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPPNS_7JSValueE
    210213__ZN3KJS8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
     
    247250__ZNK3KJS19InternalFunctionImp21implementsHasInstanceEv
    248251__ZNK3KJS4List8getSliceEiRS0_
     252__ZNK3KJS4Node8toStringEv
    249253__ZNK3KJS6JSCell17getTruncatedInt32ERi
    250254__ZNK3KJS6JSCell17getTruncatedInt32ERi
     
    271275__ZNK3KJS8JSObject12defaultValueEPNS_9ExecStateENS_6JSTypeE
    272276__ZNK3KJS8JSObject14implementsCallEv
    273 __ZN3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
    274277__ZNK3KJS8JSObject19implementsConstructEv
    275278__ZNK3KJS8JSObject21implementsHasInstanceEv
  • trunk/JavaScriptCore/kjs/Parser.cpp

    r27215 r27842  
    44 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    55 *  Copyright (C) 2001 Peter Kelly ([email protected])
    6  *  Copyright (C) 2003, 2006 Apple Computer, Inc.
     6 *  Copyright (C) 2003, 2006, 2007 Apple Inc.
    77 *
    88 *  This library is free software; you can redistribute it and/or
     
    3131#include <wtf/Vector.h>
    3232
    33 extern int kjsyyparse();
    34 
    3533namespace KJS {
    3634
    37 int Parser::sid = 0;
     35Parser::Parser()
     36    : m_sourceId(0)
     37{
     38}
    3839
    39 static RefPtr<ProgramNode>* progNode;
    40 
    41 PassRefPtr<ProgramNode> Parser::parse(const UString& sourceURL, int startingLineNumber,
     40PassRefPtr<ProgramNode> Parser::parseProgram(const UString& sourceURL, int startingLineNumber,
    4241    const UChar* code, unsigned length,
    4342    int* sourceId, int* errLine, UString* errMsg)
    4443{
     44    parse(sourceURL, startingLineNumber, code, length, sourceId, errLine, errMsg);
     45    return m_progNode.release();
     46}
     47
     48PassRefPtr<FunctionBodyNode> Parser::parseFunctionBody(const UString& sourceURL, int startingLineNumber,
     49    const UChar* code, unsigned length,
     50    int* sourceId, int* errLine, UString* errMsg)
     51{
     52    parse(sourceURL, startingLineNumber, code, length, sourceId, errLine, errMsg);
     53    return m_progNode.release();
     54}
     55
     56void Parser::parse(const UString& sourceURL, int startingLineNumber,
     57    const UChar* code, unsigned length,
     58    int* sourceId, int* errLine, UString* errMsg)
     59{
     60    ASSERT(!m_progNode);
     61
    4562    if (errLine)
    4663        *errLine = -1;
    4764    if (errMsg)
    4865        *errMsg = 0;
    49     if (!progNode)
    50         progNode = new RefPtr<ProgramNode>;
     66       
     67    Lexer& lexer = KJS::lexer();
    5168
    52     Lexer::curr()->setCode(sourceURL, startingLineNumber, code, length);
    53     *progNode = 0;
    54     sid++;
     69    lexer.setCode(sourceURL, startingLineNumber, code, length);
     70    m_sourceId++;
    5571    if (sourceId)
    56         *sourceId = sid;
    57 
    58     // Enable this and the #define YYDEBUG in grammar.y to debug a parse error
    59     //extern int kjsyydebug;
    60     //kjsyydebug=1;
     72        *sourceId = m_sourceId;
    6173
    6274    int parseError = kjsyyparse();
    63     bool lexError = Lexer::curr()->sawError();
    64     Lexer::curr()->doneParsing();
    65     PassRefPtr<ProgramNode> prog = progNode->release();
    66     *progNode = 0;
     75    bool lexError = lexer.sawError();
     76    lexer.clear();
    6777
    6878    Node::clearNewNodes();
    6979
    7080    if (parseError || lexError) {
    71         int eline = Lexer::curr()->lineNo();
    7281        if (errLine)
    73             *errLine = eline;
     82            *errLine = lexer.lineNo();
    7483        if (errMsg)
    7584            *errMsg = "Parse error";
    76         return 0;
     85        m_progNode = 0;
    7786    }
    78 
    79     return prog;
    8087}
    8188
    82 void Parser::accept(PassRefPtr<ProgramNode> prog)
     89void Parser::didFinishParsing(PassRefPtr<ProgramNode> progNode)
    8390{
    84     *progNode = prog;
     91    m_progNode = progNode;
    8592}
    8693
    87 UString Parser::prettyPrint(const UString& code, int* errLine, UString* errMsg)
     94Parser& parser()
    8895{
    89     RefPtr<ProgramNode> progNode = parse(UString(), 0, code.data(), code.size(), 0, errLine, errMsg);
    90     if (!progNode)
    91         return 0;
    92    
    93     return progNode->toString();
     96    ASSERT(JSLock::currentThreadIsHoldingLock());
     97
     98    static Parser staticParser;
     99    return staticParser;
    94100}
    95101
    96 }
     102} // namespace KJS
  • trunk/JavaScriptCore/kjs/Parser.h

    r27215 r27842  
    44 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    55 *  Copyright (C) 2001 Peter Kelly ([email protected])
    6  *  Copyright (C) 2003, 2006 Apple Computer, Inc.
     6 *  Copyright (C) 2003, 2006, 2007 Apple Inc.
    77 *
    88 *  This library is free software; you can redistribute it and/or
     
    2727
    2828#include <wtf/Forward.h>
     29#include <wtf/RefPtr.h>
    2930
    3031namespace KJS {
    3132
    32     class Node;
     33    class FunctionBodyNode;
    3334    class ProgramNode;
    3435    class UString;
     
    3637    struct UChar;
    3738
    38     /**
    39      * @internal
    40      *
    41      * Parses ECMAScript source code and converts into ProgramNode objects, which
    42      * represent the root of a parse tree. This class provides a convenient workaround
    43      * for the problem of the bison parser working in a static context.
    44      */
    45     class Parser {
     39    class Parser : Noncopyable {
    4640    public:
    47         static PassRefPtr<ProgramNode> parse(const UString& sourceURL, int startingLineNumber,
     41        PassRefPtr<ProgramNode> parseProgram(const UString& sourceURL, int startingLineNumber,
    4842            const UChar* code, unsigned length,
    4943            int* sourceId = 0, int* errLine = 0, UString* errMsg = 0);
    5044
    51         static UString prettyPrint(const UString&, int* errLine = 0, UString* errMsg = 0);
     45        PassRefPtr<FunctionBodyNode> parseFunctionBody(const UString& sourceURL, int startingLineNumber,
     46            const UChar* code, unsigned length,
     47            int* sourceId = 0, int* errLine = 0, UString* errMsg = 0);
     48
     49        int sourceId() { return m_sourceId; }
    5250       
    53         static void accept(PassRefPtr<ProgramNode>);
     51        void didFinishParsing(PassRefPtr<ProgramNode>);
    5452
    55         static void saveNewNode(Node*);
     53    private:
     54        friend Parser& parser();
    5655
    57         static int sid;
     56        Parser(); // Use parser() instead.
     57        void parse(const UString& sourceURL, int startingLineNumber,
     58            const UChar* code, unsigned length,
     59            int* sourceId = 0, int* errLine = 0, UString* errMsg = 0);
     60
     61        int m_sourceId;
     62        RefPtr<ProgramNode> m_progNode;
    5863    };
     64   
     65    Parser& parser(); // Returns the singleton JavaScript parser.
    5966
    60 } // namespace
     67} // namespace KJS
    6168
    62 #endif
     69#endif // Parser_h
  • trunk/JavaScriptCore/kjs/function.cpp

    r27746 r27842  
    7878
    7979  Debugger* dbg = exec->dynamicInterpreter()->debugger();
    80   int sid = -1;
    81   int lineno = -1;
     80  int sourceId = -1;
     81  int lineNo = -1;
    8282  if (dbg) {
    83     sid = body->sourceId();
    84     lineno = body->firstLine();
    85 
    86     bool cont = dbg->callEvent(&newExec,sid,lineno,this,args);
     83    sourceId = body->sourceId();
     84    lineNo = body->firstLine();
     85
     86    bool cont = dbg->callEvent(&newExec, sourceId, lineNo, this, args);
    8787    if (!cont) {
    8888      dbg->imp()->abort();
     
    103103
    104104  if (dbg) {
    105     lineno = body->lastLine();
     105    lineNo = body->lastLine();
    106106
    107107    if (comp.complType() == Throw)
    108108        newExec.setException(comp.value());
    109109
    110     int cont = dbg->returnEvent(&newExec,sid,lineno,this);
     110    int cont = dbg->returnEvent(&newExec, sourceId, lineNo, this);
    111111    if (!cont) {
    112112      dbg->imp()->abort();
     
    762762        UString s = x->toString(exec);
    763763       
    764         int sid;
     764        int sourceId;
    765765        int errLine;
    766766        UString errMsg;
    767         RefPtr<ProgramNode> progNode(Parser::parse(UString(), 0, s.data(),s.size(),&sid,&errLine,&errMsg));
     767        RefPtr<ProgramNode> progNode(parser().parseProgram(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg));
    768768
    769769        Debugger* dbg = exec->dynamicInterpreter()->debugger();
    770770        if (dbg) {
    771           bool cont = dbg->sourceParsed(exec, sid, UString(), s, 0, errLine, errMsg);
     771          bool cont = dbg->sourceParsed(exec, sourceId, UString(), s, 0, errLine, errMsg);
    772772          if (!cont)
    773773            return jsUndefined();
     
    776776        // no program node means a syntax occurred
    777777        if (!progNode)
    778           return throwError(exec, SyntaxError, errMsg, errLine, sid, NULL);
     778          return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
    779779
    780780        bool switchGlobal = thisObj && thisObj != exec->dynamicInterpreter()->globalObject();
  • trunk/JavaScriptCore/kjs/function_object.cpp

    r27448 r27842  
    186186
    187187  // parse the source code
    188   int sid;
     188  int sourceId;
    189189  int errLine;
    190190  UString errMsg;
    191   RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, lineNumber, body.data(),body.size(),&sid,&errLine,&errMsg);
     191  RefPtr<FunctionBodyNode> functionBody = parser().parseFunctionBody(sourceURL, lineNumber, body.data(), body.size(), &sourceId, &errLine, &errMsg);
    192192
    193193  // notify debugger that source has been parsed
     
    195195  if (dbg) {
    196196    // send empty sourceURL to indicate constructed code
    197     bool cont = dbg->sourceParsed(exec, sid, UString(), body, lineNumber, errLine, errMsg);
     197    bool cont = dbg->sourceParsed(exec, sourceId, UString(), body, lineNumber, errLine, errMsg);
    198198    if (!cont) {
    199199      dbg->imp()->abort();
     
    203203
    204204  // no program node == syntax error - throw a syntax error
    205   if (!progNode)
     205  if (!functionBody)
    206206    // we can't return a Completion(Throw) here, so just set the exception
    207207    // and return it
    208     return throwError(exec, SyntaxError, errMsg, errLine, sid, sourceURL);
     208    return throwError(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL);
    209209
    210210  ScopeChain scopeChain;
    211211  scopeChain.push(exec->lexicalInterpreter()->globalObject());
    212   FunctionBodyNode *bodyNode = progNode.get();
    213 
    214   FunctionImp* fimp = new FunctionImp(exec, functionName, bodyNode, scopeChain);
     212
     213  FunctionImp* fimp = new FunctionImp(exec, functionName, functionBody.get(), scopeChain);
    215214 
    216215  // parse parameter list. throw syntax error on illegal identifiers
     
    232231              c++, i++;
    233232          if (i == len) {
    234               bodyNode->addParam(Identifier(param));
     233              functionBody->addParam(Identifier(param));
    235234              params++;
    236235              break;
    237236          } else if (*c == ',') {
    238               bodyNode->addParam(Identifier(param));
     237              functionBody->addParam(Identifier(param));
    239238              params++;
    240239              c++, i++;
  • trunk/JavaScriptCore/kjs/grammar.y

    r27831 r27842  
    4343
    4444/* default values for bison */
    45 #define YYDEBUG 0
     45#define YYDEBUG 0 // Set to 1 to debug a parse error.
     46#define kjsyydebug 0 // Set to 1 to debug a parse error.
    4647#if !PLATFORM(DARWIN)
    4748    // avoid triggering warnings in older bison
     
    221222  | STRING                              { $$ = new StringNode($1); }
    222223  | '/' /* regexp */                    {
    223                                             Lexer *l = Lexer::curr();
    224                                             if (!l->scanRegExp()) YYABORT;
    225                                             $$ = new RegExpNode(l->pattern, l->flags);
     224                                            Lexer& l = lexer();
     225                                            if (!l.scanRegExp())
     226                                                YYABORT;
     227                                            $$ = new RegExpNode(l.pattern(), l.flags());
    226228                                        }
    227229  | DIVEQUAL /* regexp with /= */       {
    228                                             Lexer *l = Lexer::curr();
    229                                             if (!l->scanRegExp()) YYABORT;
    230                                             $$ = new RegExpNode("=" + l->pattern, l->flags);
     230                                            Lexer& l = lexer();
     231                                            if (!l.scanRegExp())
     232                                                YYABORT;
     233                                            $$ = new RegExpNode("=" + l.pattern(), l.flags());
    231234                                        }
    232235;
     
    877880
    878881Program:
    879     /* not in spec */                   { Parser::accept(new ProgramNode(new SourceElements)); }
    880     | SourceElements                    { Parser::accept(new ProgramNode($1->release())); }
     882    /* not in spec */                   { parser().didFinishParsing(new ProgramNode(new SourceElements)); }
     883    | SourceElements                    { parser().didFinishParsing(new ProgramNode($1->release())); }
    881884;
    882885
     
    10911094static bool allowAutomaticSemicolon()
    10921095{
    1093     return yychar == '}' || yychar == 0 || Lexer::curr()->prevTerminator();
    1094 }
     1096    return yychar == '}' || yychar == 0 || lexer().prevTerminator();
     1097}
  • trunk/JavaScriptCore/kjs/interpreter.cpp

    r27763 r27842  
    309309    int errLine;
    310310    UString errMsg;
    311     RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg);
     311    RefPtr<ProgramNode> progNode = parser().parseProgram(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg);
    312312    if (!progNode)
    313313        return Completion(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, 0, sourceURL));
     
    329329   
    330330    // parse the source code
    331     int sid;
     331    int sourceId;
    332332    int errLine;
    333333    UString errMsg;
    334     RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, &sid, &errLine, &errMsg);
     334    RefPtr<ProgramNode> progNode = parser().parseProgram(sourceURL, startingLineNumber, code, codeLength, &sourceId, &errLine, &errMsg);
    335335   
    336336    // notify debugger that source has been parsed
    337337    if (m_debugger) {
    338         bool cont = m_debugger->sourceParsed(&m_globalExec, sid, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg);
     338        bool cont = m_debugger->sourceParsed(&m_globalExec, sourceId, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg);
    339339        if (!cont)
    340340            return Completion(Break);
     
    343343    // no program node means a syntax error occurred
    344344    if (!progNode)
    345         return Completion(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, sid, sourceURL));
     345        return Completion(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, sourceId, sourceURL));
    346346   
    347347    m_globalExec.clearException();
     
    605605}
    606606
    607 #ifdef KJS_DEBUG_MEM
    608 #include "lexer.h"
    609 void Interpreter::finalCheck()
    610 {
    611   fprintf(stderr,"Interpreter::finalCheck()\n");
    612   Collector::collect();
    613 
    614   Node::finalCheck();
    615   Collector::finalCheck();
    616   Lexer::globalClear();
    617   UString::globalClear();
    618 }
    619 #endif
    620 
    621607static bool printExceptions = false;
    622608
  • trunk/JavaScriptCore/kjs/interpreter.h

    r27776 r27842  
    292292    virtual void mark();
    293293
    294 #ifdef KJS_DEBUG_MEM
    295     /**
    296      * @internal
    297      */
    298     static void finalCheck();
    299 #endif
    300 
    301294    static bool shouldPrintExceptions();
    302295    static void setShouldPrintExceptions(bool);
  • trunk/JavaScriptCore/kjs/lexer.cpp

    r27695 r27842  
    5252int kjsyylex()
    5353{
    54   return Lexer::curr()->lex();
     54  return lexer().lex();
    5555}
    5656
    5757namespace KJS {
    5858
    59 static Lexer* currLexer = 0;
    60 
    6159static bool isDecimalDigit(int);
     60
     61Lexer& lexer()
     62{
     63    ASSERT(JSLock::currentThreadIsHoldingLock());
     64
     65    // FIXME: We'd like to avoid calling new here, but we don't currently
     66    // support tearing down the Lexer at app quit time, since that would involve
     67    // tearing down its UString data members without holding the JSLock.
     68    static Lexer* staticLexer = new Lexer;
     69    return *staticLexer;
     70}
    6271
    6372Lexer::Lexer()
     
    7685  buffer8 = new char[size8];
    7786  buffer16 = new KJS::UChar[size16];
    78   currLexer = this;
    7987}
    8088
    8189Lexer::~Lexer()
    8290{
    83   doneParsing();
    8491  delete [] buffer8;
    8592  delete [] buffer16;
    8693}
    87 
    88 Lexer *Lexer::curr()
    89 {
    90   if (!currLexer) {
    91     // create singleton instance
    92     currLexer = new Lexer();
    93   }
    94   return currLexer;
    95 }
    96 
    97 #ifdef KJS_DEBUG_MEM
    98 void Lexer::globalClear()
    99 {
    100   delete currLexer;
    101   currLexer = 0L;
    102 }
    103 #endif
    10494
    10595void Lexer::setCode(const UString &sourceURL, int startingLineNumber, const KJS::UChar *c, unsigned int len)
     
    786776KJS::UChar Lexer::convertUnicode(int c1, int c2, int c3, int c4)
    787777{
     778  // FIXME: This conversion is lossy. See http://bugs.webkit.org/show_bug.cgi?id=4920.
    788779  return KJS::UChar((convertHex(c1) << 4) + convertHex(c2),
    789780               (convertHex(c3) << 4) + convertHex(c4));
     
    851842    }
    852843    else { // end of regexp
    853       pattern = UString(buffer16, pos16);
     844      m_pattern = UString(buffer16, pos16);
    854845      pos16 = 0;
    855846      shift(1);
     
    863854    shift(1);
    864855  }
    865   flags = UString(buffer16, pos16);
     856  m_flags = UString(buffer16, pos16);
    866857
    867858  return true;
    868859}
    869860
    870 
    871 void Lexer::doneParsing()
    872 {
    873   for (unsigned i = 0; i < numIdentifiers; i++) {
     861void Lexer::clear()
     862{
     863  for (unsigned i = 0; i < numIdentifiers; i++)
    874864    delete identifiers[i];
    875   }
    876865  fastFree(identifiers);
    877866  identifiers = 0;
     
    879868  identifiersCapacity = 0;
    880869
    881   for (unsigned i = 0; i < numStrings; i++) {
     870  for (unsigned i = 0; i < numStrings; i++)
    882871    delete strings[i];
    883   }
    884872  fastFree(strings);
    885873  strings = 0;
    886874  numStrings = 0;
    887875  stringsCapacity = 0;
     876 
     877  m_pattern = 0;
     878  m_flags = 0;
     879  m_sourceURL = 0;
    888880}
    889881
     
    891883const int growthFactor = 2;
    892884
    893 // FIXME: this completely ignores its parameters, instead using buffer16 and pos16 - wtf?
    894 Identifier *Lexer::makeIdentifier(KJS::UChar*, unsigned int)
     885Identifier* Lexer::makeIdentifier(KJS::UChar* buffer, unsigned int pos)
    895886{
    896887  if (numIdentifiers == identifiersCapacity) {
     
    899890  }
    900891
    901   KJS::Identifier *identifier = new KJS::Identifier(buffer16, pos16);
     892  KJS::Identifier *identifier = new KJS::Identifier(buffer, pos);
    902893  identifiers[numIdentifiers++] = identifier;
    903894  return identifier;
    904895}
    905896 
    906 // FIXME: this completely ignores its parameters, instead using buffer16 and pos16 - wtf?
    907 UString *Lexer::makeUString(KJS::UChar*, unsigned int)
     897UString* Lexer::makeUString(KJS::UChar* buffer, unsigned int pos)
    908898{
    909899  if (numStrings == stringsCapacity) {
     
    912902  }
    913903
    914   UString *string = new UString(buffer16, pos16);
     904  UString *string = new UString(buffer, pos);
    915905  strings[numStrings++] = string;
    916906  return string;
    917907}
    918908
    919 }
     909} // namespace KJS
  • trunk/JavaScriptCore/kjs/lexer.h

    r17862 r27842  
    33 *  This file is part of the KDE libraries
    44 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
     5 *  Copyright (C) 2007 Apple Inc.
    56 *
    67 *  This library is free software; you can redistribute it and/or
     
    2122 */
    2223
    23 #ifndef _KJSLEXER_H_
    24 #define _KJSLEXER_H_
     24#ifndef Lexer_h
     25#define Lexer_h
    2526
    2627#include "ustring.h"
    27 
    2828
    2929namespace KJS {
    3030
    3131  class Identifier;
    32 
    3332  class RegExp;
    3433
    35   class Lexer {
     34  class Lexer : Noncopyable {
    3635  public:
    37     Lexer();
    38     ~Lexer();
    39     static Lexer *curr();
    40 
    4136    void setCode(const UString &sourceURL, int startingLineNumber, const UChar *c, unsigned int len);
    4237    int lex();
     
    7671
    7772    bool scanRegExp();
    78     UString pattern, flags;
     73    const UString& pattern() const { return m_pattern; }
     74    const UString& flags() const { return m_flags; }
     75
     76    static unsigned char convertHex(int);
     77    static unsigned char convertHex(int c1, int c2);
     78    static UChar convertUnicode(int c1, int c2, int c3, int c4);
     79    static bool isIdentStart(int);
     80    static bool isIdentPart(int);
     81    static bool isHexDigit(int);
     82
     83    bool sawError() const { return error; }
     84
     85    void clear();
    7986
    8087  private:
     88    friend Lexer& lexer();
     89    Lexer();
     90    ~Lexer();
     91   
    8192    int yylineno;
    8293    UString m_sourceURL;
    8394    bool done;
    84     char *buffer8;
    85     UChar *buffer16;
     95    char *buffer8; // FIXME: This buffer is never deallocated.
     96    UChar *buffer16; // FIXME: This buffer is never deallocated.
    8697    unsigned int size8, size16;
    8798    unsigned int pos8, pos16;
     
    110121    static unsigned short singleEscape(unsigned short);
    111122    static unsigned short convertOctal(int c1, int c2, int c3);
    112   public:
    113     static unsigned char convertHex(int);
    114     static unsigned char convertHex(int c1, int c2);
    115     static UChar convertUnicode(int c1, int c2, int c3, int c4);
    116     static bool isIdentStart(int);
    117     static bool isIdentPart(int);
    118     static bool isHexDigit(int);
    119 
    120 #ifdef KJS_DEBUG_MEM
    121     /**
    122      * Clear statically allocated resources
    123      */
    124     static void globalClear();
    125 #endif
    126 
    127     bool sawError() const { return error; }
    128     void doneParsing();
    129 
    130   private:
    131123
    132124    void record8(int);
     
    155147    unsigned int numIdentifiers;
    156148    unsigned int identifiersCapacity;
     149   
     150    UString m_pattern;
     151    UString m_flags;
     152  };
     153 
     154  Lexer& lexer(); // Returns the singletone JavaScript lexer.
    157155
    158     // for future extensions
    159     class LexerPrivate;
    160     LexerPrivate *priv;
    161   };
     156} // namespace KJS
    162157
    163 } // namespace
    164 
    165 #endif
     158#endif // Lexer_h
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r27799 r27842  
    133133    ++NodeCounter::count;
    134134#endif
    135   m_line = Lexer::curr()->lineNo();
     135  m_line = lexer().lineNo();
    136136  if (!newNodes)
    137137      newNodes = new HashSet<Node*>;
     
    146146    ++NodeCounter::count;
    147147#endif
    148     m_line = Lexer::curr()->lineNo();
     148    m_line = lexer().lineNo();
    149149    if (!newNodes)
    150150        newNodes = new HashSet<Node*>;
     
    44134413FunctionBodyNode::FunctionBodyNode(SourceElements* children)
    44144414    : BlockNode(children)
    4415     , m_sourceURL(Lexer::curr()->sourceURL())
    4416     , m_sourceId(Parser::sid)
     4415    , m_sourceURL(lexer().sourceURL())
     4416    , m_sourceId(parser().sourceId())
    44174417    , m_initializedDeclarationStacks(false)
    44184418    , m_initializedSymbolTable(false)
  • trunk/JavaScriptCore/kjs/nodes.h

    r27831 r27842  
    5050
    5151    class FuncDeclNode;
     52    class Node;
    5253    class PropertyListNode;
    5354    class SourceStream;
  • trunk/JavaScriptCore/kjs/testkjs.cpp

    r27031 r27842  
    2424#include "config.h"
    2525
     26#include "JSGlobalObject.h"
    2627#include "JSLock.h"
    2728#include "Parser.h"
    2829#include "collector.h"
    29 #include "JSGlobalObject.h"
     30#include "nodes.h"
    3031#include "object.h"
    3132#include "protect.h"
     
    246247  int errLine = 0;
    247248  UString errMsg;
    248   UString s = Parser::prettyPrint(script.data(), &errLine, &errMsg);
    249   if (s.isNull()) {
     249  UString scriptUString(script.data());
     250  RefPtr<ProgramNode> programNode = parser().parseProgram(fileName, 0, scriptUString.data(), scriptUString.size(), 0, &errLine, &errMsg);
     251  if (!programNode) {
    250252    fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
    251253    return false;
    252254  }
    253255 
    254   printf("%s\n", s.UTF8String().c_str());
     256  printf("%s\n", programNode->toString().UTF8String().c_str());
    255257  return true;
    256258}
     
    314316#endif
    315317
    316 #ifdef KJS_DEBUG_MEM
    317   Interpreter::finalCheck();
    318 #endif
    319318  return success ? 0 : 3;
    320319}
  • trunk/JavaScriptCore/kjs/ustring.cpp

    r27810 r27842  
    177177UString::Rep UString::Rep::empty = { 0, 0, 1, 0, 0, &UString::Rep::empty, reinterpret_cast<UChar*>(&almostUChar), 0, 0, 0, 0 };
    178178const int normalStatBufferSize = 4096;
    179 static char *statBuffer = 0;
     179static char *statBuffer = 0; // FIXME: This buffer is never deallocated.
    180180static int statBufferSize = 0;
    181181
     
    887887}
    888888
    889 #ifdef KJS_DEBUG_MEM
    890 void UString::globalClear()
    891 {
    892   delete [] statBuffer;
    893   statBuffer = 0;
    894   statBufferSize = 0;
    895 }
    896 #endif
    897 
    898889UString &UString::operator=(const char *c)
    899890{
  • trunk/JavaScriptCore/kjs/ustring.h

    r27746 r27842  
    383383     */
    384384    static const UString &null();
    385 #ifdef KJS_DEBUG_MEM
    386     /**
    387      * Clear statically allocated resources.
    388      */
    389     static void globalClear();
    390 #endif
    391385
    392386    Rep* rep() const { return m_rep.get(); }
Note: See TracChangeset for help on using the changeset viewer.