Ignore:
Timestamp:
Feb 12, 2006, 7:06:19 PM (19 years ago)
Author:
ggaren
Message:

Reviewed by darin.

Cleaned up testkjs, added new "run" functionality to allow scripting
tests from within JS. ("run" is a part of my new super-accurate
JS iBench.)

No regressions in run-javascriptcore-tests.

  • kjs/testkjs.cpp: (GlobalImp::className): (TestFunctionImp::): (TestFunctionImp::callAsFunction): (main): (run):
File:
1 edited

Legend:

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

    r12317 r12775  
    2323
    2424#include "config.h"
     25
     26#include "JSLock.h"
     27#include "interpreter.h"
     28#include "object.h"
     29#include "types.h"
     30#include "value.h"
     31
     32#include <kxmlcore/HashTraits.h>
    2533#include <stdio.h>
    2634#include <stdlib.h>
    2735#include <string.h>
    2836
    29 #include <kxmlcore/HashTraits.h>
    30 #include "value.h"
    31 #include "object.h"
    32 #include "types.h"
    33 #include "interpreter.h"
    34 #include "JSLock.h"
    3537
    3638using namespace KJS;
    3739using namespace KXMLCore;
     40
     41bool run(const char* fileName, Interpreter *interp);
     42
     43class GlobalImp : public JSObject {
     44public:
     45  virtual UString className() const { return "global"; }
     46};
    3847
    3948class TestFunctionImp : public JSObject {
     
    4352  virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
    4453
    45   enum { Print, Debug, Quit, GC };
     54  enum { Print, Debug, Quit, GC, Version, Run };
    4655
    4756private:
     
    5968  case Print:
    6069  case Debug:
    61     fprintf(stderr,"--> %s\n",args[0]->toString(exec).ascii());
     70    fprintf(stderr,"--> %s\n",args[0]->toString(exec).UTF8String().c_str());
    6271    return jsUndefined();
    6372  case Quit:
     
    6978    Interpreter::collect();
    7079  }
    71     break;
     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();
    7287  default:
    73     break;
     88    assert(0);
    7489  }
    7590
     
    7792}
    7893
    79 class VersionFunctionImp : public JSObject {
    80 public:
    81   VersionFunctionImp() : JSObject() {}
    82   virtual bool implementsCall() const { return true; }
    83   virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
    84 };
    85 
    86 JSValue *VersionFunctionImp::callAsFunction(ExecState * /*exec*/, JSObject * /*thisObj*/, const List &/*args*/)
    87 {
    88   // We need this function for compatibility with the Mozilla JS tests but for now
    89   // we don't actually do any version-specific handling
    90   return jsUndefined();
    91 }
    92 
    93 class GlobalImp : public JSObject {
    94 public:
    95   virtual UString className() const { return "global"; }
    96 };
    97 
    9894int main(int argc, char **argv)
    9995{
    100   // expecting a filename
    10196  if (argc < 2) {
    102     fprintf(stderr, "You have to specify at least one filename\n");
     97    fprintf(stderr, "Usage: testkjs file1 [file2...]\n");
    10398    return -1;
    10499  }
    105100
    106   bool ret = true;
     101  bool success = true;
    107102  {
    108103    JSLock lock;
     
    130125    assert(!IsInteger<GlobalImp>::value);
    131126   
    132     JSObject *global(new GlobalImp());
     127    GlobalImp *global = new GlobalImp();
    133128
    134129    // create interpreter
     
    143138    global->put(interp.globalExec(), "gc", new TestFunctionImp(TestFunctionImp::GC, 0));
    144139    // add "version" for compatibility with the mozilla js shell
    145     global->put(interp.globalExec(), "version", new VersionFunctionImp());
     140    global->put(interp.globalExec(), "version", new TestFunctionImp(TestFunctionImp::Version, 1));
     141    global->put(interp.globalExec(), "run", new TestFunctionImp(TestFunctionImp::Run, 1));
    146142
    147143    for (int i = 1; i < argc; i++) {
    148       int code_len = 0;
    149       int code_alloc = 1024;
    150       char *code = (char*)malloc(code_alloc);
    151 
    152       const char *file = argv[i];
    153       if (strcmp(file, "-f") == 0)
     144      const char *fileName = argv[i];
     145      if (strcmp(fileName, "-f") == 0) // mozilla test driver script uses "-f" prefix for files
    154146        continue;
    155       FILE *f = fopen(file, "r");
    156       if (!f) {
    157         fprintf(stderr, "Error opening %s.\n", file);
    158         return 2;
    159       }
    160 
    161       while (!feof(f) && !ferror(f)) {
    162         size_t len = fread(code+code_len,1,code_alloc-code_len,f);
    163         code_len += len;
    164         if (code_len >= code_alloc) {
    165           code_alloc *= 2;
    166           code = (char*)realloc(code,code_alloc);
    167         }
    168       }
    169       code = (char*)realloc(code,code_len+1);
    170       code[code_len] = '\0';
    171 
    172       // run
    173       Completion comp(interp.evaluate(file, 1, code));
    174 
    175       fclose(f);
    176 
    177       if (comp.complType() == Throw) {
    178         ExecState *exec = interp.globalExec();
    179         JSValue *exVal = comp.value();
    180         char *msg = exVal->toString(exec).ascii();
    181         int lineno = -1;
    182         if (exVal->isObject()) {
    183           JSValue *lineVal = static_cast<JSObject *>(exVal)->get(exec,"line");
    184           if (lineVal->isNumber())
    185             lineno = int(lineVal->toNumber(exec));
    186         }
    187         if (lineno != -1)
    188           fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
    189         else
    190           fprintf(stderr,"Exception: %s\n",msg);
    191         ret = false;
    192       }
    193       else if (comp.complType() == ReturnValue) {
    194         char *msg = comp.value()->toString(interp.globalExec()).ascii();
    195         fprintf(stderr,"Return value: %s\n",msg);
    196       }
    197 
    198       free(code);
     147
     148      success = success && run(fileName, &interp);
    199149    }
    200150  } // end block, so that interpreter gets deleted
    201151
    202   if (ret)
     152  if (success)
    203153    fprintf(stderr, "OK.\n");
    204 
     154 
    205155#ifdef KJS_DEBUG_MEM
    206156  Interpreter::finalCheck();
    207157#endif
    208   return ret ? 0 : 3;
    209 }
     158  return success ? 0 : 3;
     159}
     160
     161bool 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");
     168  if (!f) {
     169    fprintf(stderr, "Error opening %s.\n", fileName);
     170    return 2;
     171  }
     172 
     173  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);
     182  }
     183  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}
Note: See TracChangeset for help on using the changeset viewer.