source: webkit/trunk/JavaScriptCore/kjs/testkjs.cpp@ 12908

Last change on this file since 12908 was 12908, checked in by ggaren, 19 years ago

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.
  • Property svn:eol-style set to native
File size: 7.1 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2000 Harri Porten ([email protected])
5 * Copyright (C) 2004 Apple Computer, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include "config.h"
25
26#include "HashTraits.h"
27#include "JSLock.h"
28#include "interpreter.h"
29#include "object.h"
30#include "types.h"
31#include "value.h"
32
33#include <math.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <sys/time.h>
38
39using namespace KJS;
40using namespace KXMLCore;
41
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}
82
83class GlobalImp : public JSObject {
84public:
85 virtual UString className() const { return "global"; }
86};
87
88class TestFunctionImp : public JSObject {
89public:
90 TestFunctionImp(int i, int length);
91 virtual bool implementsCall() const { return true; }
92 virtual JSValue* callAsFunction(ExecState* exec, JSObject* thisObj, const List &args);
93
94 enum { Print, Debug, Quit, GC, Version, Run };
95
96private:
97 int id;
98};
99
100TestFunctionImp::TestFunctionImp(int i, int length) : JSObject(), id(i)
101{
102 putDirect(lengthPropertyName,length,DontDelete|ReadOnly|DontEnum);
103}
104
105JSValue* TestFunctionImp::callAsFunction(ExecState* exec, JSObject*, const List &args)
106{
107 switch (id) {
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)
149{
150 if (argc < 2) {
151 fprintf(stderr, "Usage: testkjs file1 [file2...]\n");
152 return -1;
153 }
154
155 testIsInteger();
156
157 bool success = true;
158 {
159 JSLock lock;
160
161 GlobalImp* global = new GlobalImp();
162
163 // create interpreter
164 Interpreter interp(global);
165 // add debug() function
166 global->put(interp.globalExec(), "debug", new TestFunctionImp(TestFunctionImp::Debug, 1));
167 // add "print" for compatibility with the mozilla js shell
168 global->put(interp.globalExec(), "print", new TestFunctionImp(TestFunctionImp::Print, 1));
169 // add "quit" for compatibility with the mozilla js shell
170 global->put(interp.globalExec(), "quit", new TestFunctionImp(TestFunctionImp::Quit, 0));
171 // add "gc" for compatibility with the mozilla js shell
172 global->put(interp.globalExec(), "gc", new TestFunctionImp(TestFunctionImp::GC, 0));
173 // add "version" for compatibility with the mozilla js shell
174 global->put(interp.globalExec(), "version", new TestFunctionImp(TestFunctionImp::Version, 1));
175 global->put(interp.globalExec(), "run", new TestFunctionImp(TestFunctionImp::Run, 1));
176
177 Interpreter::setShouldPrintExceptions(true);
178
179 for (int i = 1; i < argc; i++) {
180 const char* fileName = argv[i];
181 if (strcmp(fileName, "-f") == 0) // mozilla test driver script uses "-f" prefix for files
182 continue;
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;
196 } // end block, so that interpreter gets deleted
197
198 if (success)
199 fprintf(stderr, "OK.\n");
200
201#ifdef KJS_DEBUG_MEM
202 Interpreter::finalCheck();
203#endif
204 return success ? 0 : 3;
205}
206
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");
242 if (!f) {
243 fprintf(stderr, "Could not open file: %s\n", fileName);
244 return 0;
245 }
246
247 while (!feof(f) && !ferror(f)) {
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);
256 }
257 fclose(f);
258 buffer[buffer_size] = '\0';
259
260 return buffer;
261}
Note: See TracBrowser for help on using the repository browser.