Ignore:
Timestamp:
Feb 24, 2008, 9:29:20 PM (17 years ago)
Author:
[email protected]
Message:

Reviewed by Mark Rowe.

http://bugs.webkit.org/show_bug.cgi?id=17528
Give testkjs a bath

  • JavaScriptCore.exp:
  • JavaScriptCore.xcodeproj/project.pbxproj: Make the testkjs.cpp use 4 space indentation.
  • kjs/testkjs.cpp: (StopWatch::getElapsedMS): (GlobalObject::className): (GlobalObject::GlobalObject): Rename GlobalImp to GlobalObject and setup the global functions in the GlobalObject's constructor. Also, use static functions for the implementation so we can use the standard PrototypeFunction class and remove TestFunctionImp. (functionPrint): Move print() functionality here. (functionDebug): Move debug() functionality here. (functionGC): Move gc() functionality here. (functionVersion): Move version() functionality here. (functionRun): Move run() functionality here. (functionLoad): Move load() functionality here. (functionQuit): Move quit() functionality here. (prettyPrintScript): Fix indentation. (runWithScripts): Since all the functionality of createGlobalObject is now in the GlobalObject constructor, just call new here. (parseArguments): Fix indentation. (kjsmain): Ditto (fillBufferWithContentsOfFile): Ditto.
File:
1 edited

Legend:

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

    r30553 r30555  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    32 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
    4  *  Copyright (C) 2004-2007 Apple Inc.
     3 *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
    54 *  Copyright (C) 2006 Bjoern Graf ([email protected])
    65 *
     
    2928#include "array_object.h"
    3029#include "collector.h"
     30#include "function.h"
    3131#include "interpreter.h"
    3232#include "nodes.h"
     
    5757static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer);
    5858
    59 class StopWatch
    60 {
     59static JSValue* functionPrint(ExecState*, JSObject*, const List&);
     60static JSValue* functionDebug(ExecState*, JSObject*, const List&);
     61static JSValue* functionGC(ExecState*, JSObject*, const List&);
     62static JSValue* functionVersion(ExecState*, JSObject*, const List&);
     63static JSValue* functionRun(ExecState*, JSObject*, const List&);
     64static JSValue* functionLoad(ExecState*, JSObject*, const List&);
     65static JSValue* functionQuit(ExecState*, JSObject*, const List&);
     66
     67class StopWatch {
    6168public:
    6269    void start();
    6370    void stop();
    6471    long getElapsedMS(); // call stop() first
    65    
     72
    6673private:
    6774#if PLATFORM(QT)
     
    109116    timeval elapsedTime;
    110117    timersub(&m_stopTime, &m_startTime, &elapsedTime);
    111    
     118
    112119    return elapsedTime.tv_sec * 1000 + lroundf(elapsedTime.tv_usec / 1000.0f);
    113120#endif
    114121}
    115122
    116 class GlobalImp : public JSGlobalObject {
     123class GlobalObject : public JSGlobalObject {
    117124public:
    118   virtual UString className() const { return "global"; }
     125    GlobalObject(Vector<UString>& arguments);
     126    virtual UString className() const { return "global"; }
    119127};
    120 COMPILE_ASSERT(!IsInteger<GlobalImp>::value, WTF_IsInteger_GlobalImp_false);
    121 
    122 class TestFunctionImp : public JSObject {
    123 public:
    124   enum TestFunctionType { Print, Debug, Quit, GC, Version, Run, Load };
    125 
    126   TestFunctionImp(TestFunctionType i, int length);
    127   virtual bool implementsCall() const { return true; }
    128   virtual JSValue* callAsFunction(ExecState* exec, JSObject* thisObj, const List &args);
    129 
    130 private:
    131   TestFunctionType m_type;
    132 };
    133 
    134 TestFunctionImp::TestFunctionImp(TestFunctionType i, int length)
    135   : JSObject()
    136   , m_type(i)
    137 {
    138   putDirect(Identifier("length"), length, DontDelete | ReadOnly | DontEnum);
    139 }
    140 
    141 JSValue* TestFunctionImp::callAsFunction(ExecState* exec, JSObject*, const List &args)
    142 {
    143   switch (m_type) {
    144     case Print:
    145       printf("%s\n", args[0]->toString(exec).UTF8String().c_str());
    146       return jsUndefined();
    147     case Debug:
    148       fprintf(stderr, "--> %s\n", args[0]->toString(exec).UTF8String().c_str());
    149       return jsUndefined();
    150     case GC:
    151     {
    152       JSLock lock;
    153       Collector::collect();
    154       return jsUndefined();
    155     }
    156     case Version:
    157       // We need this function for compatibility with the Mozilla JS tests but for now
    158       // we don't actually do any version-specific handling
    159       return jsUndefined();
    160     case Run:
    161     {
    162       StopWatch stopWatch;
    163       UString fileName = args[0]->toString(exec);
    164       Vector<char> script;
    165       if (!fillBufferWithContentsOfFile(fileName, script))
     128COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false);
     129
     130GlobalObject::GlobalObject(Vector<UString>& arguments)
     131{
     132    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, "debug", functionDebug));
     133    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, "print", functionPrint));
     134    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 0, "quit", functionQuit));
     135    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 0, "gc", functionGC));
     136    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, "version", functionVersion));
     137    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, "run", functionRun));
     138    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, "load", functionLoad));
     139
     140    JSObject* array = arrayConstructor()->construct(globalExec(), globalExec()->emptyList());
     141    for (size_t i = 0; i < arguments.size(); ++i)
     142        array->put(globalExec(), i, jsString(arguments[i]));
     143    putDirect("arguments", array);
     144
     145    Interpreter::setShouldPrintExceptions(true);
     146}
     147
     148JSValue* functionPrint(ExecState* exec, JSObject*, const List& args)
     149{
     150    printf("%s\n", args[0]->toString(exec).UTF8String().c_str());
     151    return jsUndefined();
     152}
     153
     154JSValue* functionDebug(ExecState* exec, JSObject*, const List& args)
     155{
     156    fprintf(stderr, "--> %s\n", args[0]->toString(exec).UTF8String().c_str());
     157    return jsUndefined();
     158}
     159
     160JSValue* functionGC(ExecState*, JSObject*, const List&)
     161{
     162    JSLock lock;
     163    Collector::collect();
     164    return jsUndefined();
     165}
     166
     167JSValue* functionVersion(ExecState*, JSObject*, const List&)
     168{
     169    // We need this function for compatibility with the Mozilla JS tests but for now
     170    // we don't actually do any version-specific handling
     171    return jsUndefined();
     172}
     173
     174JSValue* functionRun(ExecState* exec, JSObject*, const List& args)
     175{
     176    StopWatch stopWatch;
     177    UString fileName = args[0]->toString(exec);
     178    Vector<char> script;
     179    if (!fillBufferWithContentsOfFile(fileName, script))
    166180        return throwError(exec, GeneralError, "Could not open file.");
    167181
    168       stopWatch.start();
    169       Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), fileName, 0, script.data());
    170       stopWatch.stop();
    171      
    172       return jsNumber(stopWatch.getElapsedMS());
    173     }
    174     case Load:
    175     {
    176       UString fileName = args[0]->toString(exec);
    177       Vector<char> script;
    178       if (!fillBufferWithContentsOfFile(fileName, script))
     182    stopWatch.start();
     183    Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), fileName, 0, script.data());
     184    stopWatch.stop();
     185
     186    return jsNumber(stopWatch.getElapsedMS());
     187}
     188
     189JSValue* functionLoad(ExecState* exec, JSObject*, const List& args)
     190{
     191    UString fileName = args[0]->toString(exec);
     192    Vector<char> script;
     193    if (!fillBufferWithContentsOfFile(fileName, script))
    179194        return throwError(exec, GeneralError, "Could not open file.");
    180195
    181       Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), fileName, 0, script.data());
    182 
    183       return jsUndefined();
    184     }
    185     case Quit:
    186       exit(0);
    187     default:
    188       abort();
    189   }
    190   return 0;
     196    Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), fileName, 0, script.data());
     197
     198    return jsUndefined();
     199}
     200
     201JSValue* functionQuit(ExecState*, JSObject*, const List&)
     202{
     203    exit(0);
     204    return jsUndefined();
    191205}
    192206
     
    224238}
    225239
    226 static GlobalImp* createGlobalObject(Vector<UString>& arguments)
    227 {
    228   GlobalImp* global = new GlobalImp;
    229 
    230   // add debug() function
    231   global->put(global->globalExec(), "debug", new TestFunctionImp(TestFunctionImp::Debug, 1));
    232   // add "print" for compatibility with the mozilla js shell
    233   global->put(global->globalExec(), "print", new TestFunctionImp(TestFunctionImp::Print, 1));
    234   // add "quit" for compatibility with the mozilla js shell
    235   global->put(global->globalExec(), "quit", new TestFunctionImp(TestFunctionImp::Quit, 0));
    236   // add "gc" for compatibility with the mozilla js shell
    237   global->put(global->globalExec(), "gc", new TestFunctionImp(TestFunctionImp::GC, 0));
    238   // add "version" for compatibility with the mozilla js shell
    239   global->put(global->globalExec(), "version", new TestFunctionImp(TestFunctionImp::Version, 1));
    240   global->put(global->globalExec(), "run", new TestFunctionImp(TestFunctionImp::Run, 1));
    241   global->put(global->globalExec(), "load", new TestFunctionImp(TestFunctionImp::Load, 1));
    242 
    243   JSObject* array = global->arrayConstructor()->construct(global->globalExec(), global->globalExec()->emptyList());
    244   for (size_t i = 0; i < arguments.size(); ++i)
    245     array->put(global->globalExec(), i, jsString(arguments[i]));
    246   global->put(global->globalExec(), "arguments", array);
    247 
    248   Interpreter::setShouldPrintExceptions(true);
    249   return global;
    250 }
    251 
    252240static bool prettyPrintScript(const UString& fileName, const Vector<char>& script)
    253241{
    254   int errLine = 0;
    255   UString errMsg;
    256   UString scriptUString(script.data());
    257   RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(fileName, 0, scriptUString.data(), scriptUString.size(), 0, &errLine, &errMsg);
    258   if (!programNode) {
    259     fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
    260     return false;
    261   }
    262  
    263   printf("%s\n", programNode->toString().UTF8String().c_str());
    264   return true;
     242    int errLine = 0;
     243    UString errMsg;
     244    UString scriptUString(script.data());
     245    RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(fileName, 0, scriptUString.data(), scriptUString.size(), 0, &errLine, &errMsg);
     246    if (!programNode) {
     247        fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
     248        return false;
     249    }
     250
     251    printf("%s\n", programNode->toString().UTF8String().c_str());
     252    return true;
    265253}
    266254
    267255static bool runWithScripts(const Vector<UString>& fileNames, Vector<UString>& arguments, bool prettyPrint)
    268256{
    269   GlobalImp* globalObject = createGlobalObject(arguments);
    270   Vector<char> script;
    271  
    272   bool success = true;
    273  
    274   for (size_t i = 0; i < fileNames.size(); i++) {
    275     UString fileName = fileNames[i];
    276    
    277     if (!fillBufferWithContentsOfFile(fileName, script))
    278       return false; // fail early so we can catch missing files
    279    
    280     if (prettyPrint)
    281       prettyPrintScript(fileName, script);
    282     else {
    283       Completion completion = Interpreter::evaluate(globalObject->globalExec(), fileName, 0, script.data());
    284       success = success && completion.complType() != Throw;
    285     }
    286   }
    287   return success;
     257    GlobalObject* globalObject = new GlobalObject(arguments);
     258    Vector<char> script;
     259
     260    bool success = true;
     261
     262    for (size_t i = 0; i < fileNames.size(); i++) {
     263        UString fileName = fileNames[i];
     264
     265        if (!fillBufferWithContentsOfFile(fileName, script))
     266            return false; // fail early so we can catch missing files
     267
     268        if (prettyPrint)
     269            prettyPrintScript(fileName, script);
     270        else {
     271            Completion completion = Interpreter::evaluate(globalObject->globalExec(), fileName, 0, script.data());
     272            success = success && completion.complType() != Throw;
     273        }
     274    }
     275    return success;
    288276}
    289277
     
    296284static void parseArguments(int argc, char** argv, Vector<UString>& fileNames, Vector<UString>& arguments, bool& prettyPrint)
    297285{
    298   if (argc < 3)
    299     printUsageStatement();
    300 
    301   int i = 1;
    302   for (; i < argc; ++i) {
    303     const char* arg = argv[i];
    304     if (strcmp(arg, "-f") == 0) {
    305       if (++i == argc)
     286    if (argc < 3)
    306287        printUsageStatement();
    307       fileNames.append(argv[i]);
    308       continue;
    309     }
    310     if (strcmp(arg, "-p") == 0) {
    311       prettyPrint = true;
    312       continue;
    313     }
    314     if (strcmp(arg, "--") == 0) {
    315       ++i;
    316       break;
    317     }
    318     break;
    319   }
    320 
    321   for (; i < argc; ++i)
    322     arguments.append(argv[i]);
     288
     289    int i = 1;
     290    for (; i < argc; ++i) {
     291        const char* arg = argv[i];
     292        if (strcmp(arg, "-f") == 0) {
     293            if (++i == argc)
     294                printUsageStatement();
     295            fileNames.append(argv[i]);
     296            continue;
     297        }
     298        if (strcmp(arg, "-p") == 0) {
     299            prettyPrint = true;
     300            continue;
     301        }
     302        if (strcmp(arg, "--") == 0) {
     303            ++i;
     304            break;
     305        }
     306        break;
     307    }
     308
     309    for (; i < argc; ++i)
     310        arguments.append(argv[i]);
    323311}
    324312
    325313int kjsmain(int argc, char** argv)
    326314{
    327   JSLock lock;
    328  
    329   bool prettyPrint = false;
    330   Vector<UString> fileNames;
    331   Vector<UString> arguments;
    332   parseArguments(argc, argv, fileNames, arguments, prettyPrint);
    333  
    334   bool success = runWithScripts(fileNames, arguments, prettyPrint);
     315    JSLock lock;
     316
     317    bool prettyPrint = false;
     318    Vector<UString> fileNames;
     319    Vector<UString> arguments;
     320    parseArguments(argc, argv, fileNames, arguments, prettyPrint);
     321
     322    bool success = runWithScripts(fileNames, arguments, prettyPrint);
    335323
    336324#ifndef NDEBUG
    337   Collector::collect();
    338 #endif
    339 
    340   return success ? 0 : 3;
     325    Collector::collect();
     326#endif
     327
     328    return success ? 0 : 3;
    341329}
    342330
    343331static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer)
    344332{
    345   FILE* f = fopen(fileName.UTF8String().c_str(), "r");
    346   if (!f) {
    347     fprintf(stderr, "Could not open file: %s\n", fileName.UTF8String().c_str());
    348     return false;
    349   }
    350  
    351   size_t buffer_size = 0;
    352   size_t buffer_capacity = 1024;
    353  
    354   buffer.resize(buffer_capacity);
    355  
    356   while (!feof(f) && !ferror(f)) {
    357     buffer_size += fread(buffer.data() + buffer_size, 1, buffer_capacity - buffer_size, f);
    358     if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
    359       buffer_capacity *= 2;
    360       buffer.resize(buffer_capacity);
    361     }
    362   }
    363   fclose(f);
    364   buffer[buffer_size] = '\0';
    365  
    366   return true;
    367 }
     333    FILE* f = fopen(fileName.UTF8String().c_str(), "r");
     334    if (!f) {
     335        fprintf(stderr, "Could not open file: %s\n", fileName.UTF8String().c_str());
     336        return false;
     337    }
     338
     339    size_t buffer_size = 0;
     340    size_t buffer_capacity = 1024;
     341
     342    buffer.resize(buffer_capacity);
     343
     344    while (!feof(f) && !ferror(f)) {
     345        buffer_size += fread(buffer.data() + buffer_size, 1, buffer_capacity - buffer_size, f);
     346        if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
     347            buffer_capacity *= 2;
     348            buffer.resize(buffer_capacity);
     349        }
     350    }
     351    fclose(f);
     352    buffer[buffer_size] = '\0';
     353
     354    return true;
     355}
Note: See TracChangeset for help on using the changeset viewer.