Changeset 12908 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Feb 20, 2006, 11:43:10 PM (19 years ago)
Author:
ggaren
Message:

Reviewed by Darin, with help from Eric, Maciej.

  • More changes to support super-accurate JS iBench. Doesn't work on Windows. (Doesn't break Windows, either.) I've filed [http://bugzilla. opendarwin.org/show_bug.cgi?id= 7399] about that.
  • kjs/interpreter.cpp: (KJS::Interpreter::evaluate): Print line numbers with exception output
  • kjs/testkjs.cpp: Changed " *" to "* " because Eric says that's the way we roll with .cpp files. (StopWatch::StopWatch): New class. Provides microsecond-accurate timings. (StopWatch::~StopWatch): (StopWatch::start): (StopWatch::stop): (StopWatch::getElapsedMS): (TestFunctionImp::callAsFunction): Added missing return statement. Fixed up "run" to use refactored helper functions. Removed bogus return statement from "quit" case. Made "print" output to stdout instead of stderr because that makes more sense, and PERL handles stdout better. (main): Factored out KXMLCore unit tests. Removed custom exception printing code because the interpreter prints exceptions for you. Added a "delete" call for the GlobalImp we allocate. (testIsInteger): New function, result of refacotring. (createStringWithContentsOfFile): New function, result of refactoring. Renamed "code" to "buffer" to match factored-out-ness.
Location:
trunk/JavaScriptCore/kjs
Files:
2 edited

Legend:

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

    r12317 r12908  
    124124        CString f = sourceURL.UTF8String();
    125125        CString message = comp.value()->toObject(exec)->toString(exec).UTF8String();
     126        int line = comp.value()->toObject(exec)->get(exec, "line")->toUInt32(exec);
    126127#ifdef WIN32
    127                 printf("%s:%s\n", f.c_str(), message.c_str());
     128        printf("%s line %d: %s\n", f.c_str(), line, message.c_str());
    128129#else
    129                 printf("[%d] %s:%s\n", getpid(), f.c_str(), message.c_str());
     130        printf("[%d] %s line %d: %s\n", getpid(), f.c_str(), line, message.c_str());
    130131#endif
    131132    }
  • trunk/JavaScriptCore/kjs/testkjs.cpp

    r12784 r12908  
    2424#include "config.h"
    2525
     26#include "HashTraits.h"
    2627#include "JSLock.h"
    2728#include "interpreter.h"
     
    3031#include "value.h"
    3132
    32 #include <kxmlcore/HashTraits.h>
     33#include <math.h>
    3334#include <stdio.h>
    3435#include <stdlib.h>
    3536#include <string.h>
    36 
     37#include <sys/time.h>
    3738
    3839using namespace KJS;
    3940using namespace KXMLCore;
    4041
    41 bool run(const char* fileName, Interpreter *interp);
     42static void testIsInteger();
     43static char* createStringWithContentsOfFile(const char* fileName);
     44
     45class StopWatch
     46{
     47public:
     48    void start();
     49    void stop();
     50    long getElapsedMS(); // call stop() first
     51   
     52private:
     53    timeval m_startTime;
     54    timeval m_stopTime;
     55};
     56
     57void StopWatch::start()
     58{
     59#if !WIN32
     60    gettimeofday(&m_startTime, 0);
     61#endif
     62}
     63
     64void StopWatch::stop()
     65{
     66#if !WIN32
     67    gettimeofday(&m_stopTime, 0);
     68#endif
     69}
     70
     71long StopWatch::getElapsedMS()
     72{
     73#if !WIN32
     74    timeval elapsedTime;
     75    timersub(&m_stopTime, &m_startTime, &elapsedTime);
     76   
     77    return elapsedTime.tv_sec * 1000 + lroundf(elapsedTime.tv_usec / 1000.0);
     78#else
     79    return 0;
     80#endif
     81}
    4282
    4383class GlobalImp : public JSObject {
     
    5090  TestFunctionImp(int i, int length);
    5191  virtual bool implementsCall() const { return true; }
    52   virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
     92  virtual JSValue* callAsFunction(ExecState* exec, JSObject* thisObj, const List &args);
    5393
    5494  enum { Print, Debug, Quit, GC, Version, Run };
     
    63103}
    64104
    65 JSValue *TestFunctionImp::callAsFunction(ExecState *exec, JSObject * /*thisObj*/, const List &args)
     105JSValue* TestFunctionImp::callAsFunction(ExecState* exec, JSObject*, const List &args)
    66106{
    67107  switch (id) {
    68   case Print:
    69   case Debug:
    70     fprintf(stderr,"--> %s\n",args[0]->toString(exec).UTF8String().c_str());
    71     return jsUndefined();
    72   case Quit:
    73     exit(0);
    74     return jsUndefined();
    75   case GC:
    76   {
    77     JSLock lock;
    78     Interpreter::collect();
    79   }
    80   case Version:
    81     // We need this function for compatibility with the Mozilla JS tests but for now
    82     // we don't actually do any version-specific handling
    83     return jsUndefined();
    84   case Run:
    85     run(args[0]->toString(exec).UTF8String().c_str(), exec->dynamicInterpreter());
    86     return jsUndefined();
    87   default:
    88     assert(0);
    89   }
    90 
    91   return jsUndefined();
    92 }
    93 
    94 int main(int argc, char **argv)
     108    case Print:
     109      printf("--> %s\n", args[0]->toString(exec).UTF8String().c_str());
     110      return jsUndefined();
     111    case Debug:
     112      fprintf(stderr, "--> %s\n", args[0]->toString(exec).UTF8String().c_str());
     113      return jsUndefined();
     114    case GC:
     115    {
     116      JSLock lock;
     117      Interpreter::collect();
     118      return jsUndefined();
     119    }
     120    case Version:
     121      // We need this function for compatibility with the Mozilla JS tests but for now
     122      // we don't actually do any version-specific handling
     123      return jsUndefined();
     124    case Run:
     125    {
     126      StopWatch stopWatch;
     127      char* fileName = strdup(args[0]->toString(exec).UTF8String().c_str());
     128      char* script = createStringWithContentsOfFile(fileName);
     129      if (!script)
     130        return throwError(exec, GeneralError, "Could not open file.");
     131
     132      stopWatch.start();
     133      exec->dynamicInterpreter()->evaluate(fileName, 0, script);
     134      stopWatch.stop();
     135
     136      free(script);
     137      free(fileName);
     138     
     139      return jsNumber(stopWatch.getElapsedMS());
     140    }
     141    case Quit:
     142      exit(0);
     143    default:
     144      abort();
     145  }
     146}
     147
     148int main(int argc, char** argv)
    95149{
    96150  if (argc < 2) {
     
    99153  }
    100154
     155  testIsInteger();
     156
    101157  bool success = true;
    102158  {
    103159    JSLock lock;
    104160   
    105     // Unit tests for KXMLCore::IsInteger. Don't have a better place for them now.
    106     // FIXME: move these once we create a unit test directory for KXMLCore.
    107     assert(IsInteger<bool>::value);
    108     assert(IsInteger<char>::value);
    109     assert(IsInteger<signed char>::value);
    110     assert(IsInteger<unsigned char>::value);
    111     assert(IsInteger<short>::value);
    112     assert(IsInteger<unsigned short>::value);
    113     assert(IsInteger<int>::value);
    114     assert(IsInteger<unsigned int>::value);
    115     assert(IsInteger<long>::value);
    116     assert(IsInteger<unsigned long>::value);
    117     assert(IsInteger<long long>::value);
    118     assert(IsInteger<unsigned long long>::value);
    119 
    120     assert(!IsInteger<char *>::value);
    121     assert(!IsInteger<const char *>::value);
    122     assert(!IsInteger<volatile char *>::value);
    123     assert(!IsInteger<double>::value);
    124     assert(!IsInteger<float>::value);
    125     assert(!IsInteger<GlobalImp>::value);
    126    
    127     GlobalImp *global = new GlobalImp();
     161    GlobalImp* global = new GlobalImp();
    128162
    129163    // create interpreter
     
    141175    global->put(interp.globalExec(), "run", new TestFunctionImp(TestFunctionImp::Run, 1));
    142176
     177    Interpreter::setShouldPrintExceptions(true);
     178   
    143179    for (int i = 1; i < argc; i++) {
    144       const char *fileName = argv[i];
     180      const char* fileName = argv[i];
    145181      if (strcmp(fileName, "-f") == 0) // mozilla test driver script uses "-f" prefix for files
    146182        continue;
    147 
    148       success = success && run(fileName, &interp);
    149     }
     183     
     184      char* script = createStringWithContentsOfFile(fileName);
     185      if (!script) {
     186        success = false;
     187        break; // fail early so we can catch missing files
     188      }
     189
     190      Completion completion = interp.evaluate(fileName, 0, script);
     191      success = success && completion.complType() != Throw;
     192      free(script);
     193    }
     194   
     195    delete global;
    150196  } // end block, so that interpreter gets deleted
    151197
     
    159205}
    160206
    161 bool run(const char* fileName, Interpreter *interp)
    162 {
    163   int code_size = 0;
    164   int code_capacity = 1024;
    165   char *code = (char*)malloc(code_capacity);
    166  
    167   FILE *f = fopen(fileName, "r");
     207static void testIsInteger()
     208{
     209  // Unit tests for KXMLCore::IsInteger. Don't have a better place for them now.
     210  // FIXME: move these once we create a unit test directory for KXMLCore.
     211
     212  assert(IsInteger<bool>::value);
     213  assert(IsInteger<char>::value);
     214  assert(IsInteger<signed char>::value);
     215  assert(IsInteger<unsigned char>::value);
     216  assert(IsInteger<short>::value);
     217  assert(IsInteger<unsigned short>::value);
     218  assert(IsInteger<int>::value);
     219  assert(IsInteger<unsigned int>::value);
     220  assert(IsInteger<long>::value);
     221  assert(IsInteger<unsigned long>::value);
     222  assert(IsInteger<long long>::value);
     223  assert(IsInteger<unsigned long long>::value);
     224
     225  assert(!IsInteger<char*>::value);
     226  assert(!IsInteger<const char* >::value);
     227  assert(!IsInteger<volatile char* >::value);
     228  assert(!IsInteger<double>::value);
     229  assert(!IsInteger<float>::value);
     230  assert(!IsInteger<GlobalImp>::value);
     231}
     232
     233static char* createStringWithContentsOfFile(const char* fileName)
     234{
     235  char* buffer;
     236 
     237  int buffer_size = 0;
     238  int buffer_capacity = 1024;
     239  buffer = (char*)malloc(buffer_capacity);
     240 
     241  FILE* f = fopen(fileName, "r");
    168242  if (!f) {
    169     fprintf(stderr, "Error opening %s.\n", fileName);
    170     return false;
     243    fprintf(stderr, "Could not open file: %s\n", fileName);
     244    return 0;
    171245  }
    172246 
    173247  while (!feof(f) && !ferror(f)) {
    174     code_size += fread(code + code_size, 1, code_capacity - code_size, f);
    175     if (code_size == code_capacity) { // guarantees space for trailing '\0'
    176       code_capacity *= 2;
    177       code = (char*)realloc(code, code_capacity);
    178       assert(code);
    179     }
    180  
    181     assert(code_size < code_capacity);
     248    buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f);
     249    if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
     250      buffer_capacity *= 2;
     251      buffer = (char*)realloc(buffer, buffer_capacity);
     252      assert(buffer);
     253    }
     254   
     255    assert(buffer_size < buffer_capacity);
    182256  }
    183257  fclose(f);
    184   code[code_size] = '\0';
    185 
    186   // run
    187   Completion comp(interp->evaluate(fileName, 1, code));
    188   free(code);
    189 
    190   JSValue *exVal = comp.value();
    191   if (comp.complType() == Throw) {
    192     ExecState *exec = interp->globalExec();
    193     const char *msg = exVal->toString(exec).UTF8String().c_str();
    194     if (exVal->isObject()) {
    195       JSValue *lineVal = static_cast<JSObject *>(exVal)->get(exec, "line");
    196       if (lineVal->isNumber())
    197         fprintf(stderr, "Exception, line %d: %s\n", (int)lineVal->toNumber(exec), msg);
    198       else
    199         fprintf(stderr,"Exception: %s\n",msg);
    200     }
    201    
    202     return false;
    203   } else if (comp.complType() == ReturnValue) {
    204     const char *msg = exVal->toString(interp->globalExec()).UTF8String().c_str();
    205     fprintf(stderr,"Return value: %s\n",msg);
    206   }
    207  
    208   return true;
    209 }
     258  buffer[buffer_size] = '\0';
     259 
     260  return buffer;
     261}
Note: See TracChangeset for help on using the changeset viewer.