source: webkit/trunk/JavaScriptCore/kjs/Shell.cpp@ 36726

Last change on this file since 36726 was 36726, checked in by Darin Adler, 17 years ago

JavaScriptCore:

2008-09-20 Darin Adler <Darin Adler>

Reviewed by Maciej Stachowiak.

This also includes some optimizations that make the change an overall
small speedup. Without those it was a bit of a slowdown.

  • API/JSCallbackConstructor.cpp: (JSC::JSCallbackConstructor::JSCallbackConstructor): Take a structure.
  • API/JSCallbackConstructor.h: Ditto.
  • API/JSCallbackFunction.cpp: (JSC::JSCallbackFunction::JSCallbackFunction): Pass a structure.
  • API/JSCallbackObject.h: Take a structure.
  • API/JSCallbackObjectFunctions.h: (JSC::JSCallbackObject::JSCallbackObject): Ditto.
  • API/JSClassRef.cpp: (OpaqueJSClass::prototype): Pass in a structure. Call setPrototype if there's a custom prototype involved.
  • API/JSObjectRef.cpp: (JSObjectMake): Ditto. (JSObjectMakeConstructor): Pass in a structure.
  • VM/Machine.cpp: (JSC::jsLess): Added a special case for when both arguments are strings. This avoids converting both strings to with UString::toDouble. (JSC::jsLessEq): Ditto. (JSC::Machine::privateExecute): Pass in a structure. (JSC::Machine::cti_op_construct_JSConstruct): Ditto. (JSC::Machine::cti_op_new_regexp): Ditto. (JSC::Machine::cti_op_is_string): Ditto.
  • VM/Machine.h: Made isJSString public so it can be used in the CTI.
  • kjs/Arguments.cpp: (JSC::Arguments::Arguments): Pass in a structure.
  • kjs/JSCell.h: Mark constructor explicit.
  • kjs/JSGlobalObject.cpp: (JSC::markIfNeeded): Added an overload for marking structures. (JSC::JSGlobalObject::reset): Eliminate code to set data members to zero. We now do that in the constructor, and we no longer use this anywhere except in the constructor. Added code to create structures. Pass structures rather than prototypes when creating objects. (JSC::JSGlobalObject::mark): Mark the structures.
  • kjs/JSGlobalObject.h: Removed unneeded class declarations. Added initializers for raw pointers in JSGlobalObjectData so everything starts with a 0. Added structure data and accessor functions.
  • kjs/JSImmediate.cpp: (JSC::JSImmediate::nonInlineNaN): Added.
  • kjs/JSImmediate.h: (JSC::JSImmediate::toDouble): Rewrote to avoid PIC branches.
  • kjs/JSNumberCell.cpp: (JSC::jsNumberCell): Made non-inline to avoid PIC branches in functions that call this one. (JSC::jsNaN): Ditto.
  • kjs/JSNumberCell.h: Ditto.
  • kjs/JSObject.h: Removed constructor that takes a prototype. All callers now pass structures.
  • kjs/ArrayConstructor.cpp: (JSC::ArrayConstructor::ArrayConstructor): (JSC::constructArrayWithSizeQuirk):
  • kjs/ArrayConstructor.h:
  • kjs/ArrayPrototype.cpp: (JSC::ArrayPrototype::ArrayPrototype):
  • kjs/ArrayPrototype.h:
  • kjs/BooleanConstructor.cpp: (JSC::BooleanConstructor::BooleanConstructor): (JSC::constructBoolean): (JSC::constructBooleanFromImmediateBoolean):
  • kjs/BooleanConstructor.h:
  • kjs/BooleanObject.cpp: (JSC::BooleanObject::BooleanObject):
  • kjs/BooleanObject.h:
  • kjs/BooleanPrototype.cpp: (JSC::BooleanPrototype::BooleanPrototype):
  • kjs/BooleanPrototype.h:
  • kjs/DateConstructor.cpp: (JSC::DateConstructor::DateConstructor): (JSC::constructDate):
  • kjs/DateConstructor.h:
  • kjs/DateInstance.cpp: (JSC::DateInstance::DateInstance):
  • kjs/DateInstance.h:
  • kjs/DatePrototype.cpp: (JSC::DatePrototype::DatePrototype):
  • kjs/DatePrototype.h:
  • kjs/ErrorConstructor.cpp: (JSC::ErrorConstructor::ErrorConstructor): (JSC::constructError):
  • kjs/ErrorConstructor.h:
  • kjs/ErrorInstance.cpp: (JSC::ErrorInstance::ErrorInstance):
  • kjs/ErrorInstance.h:
  • kjs/ErrorPrototype.cpp: (JSC::ErrorPrototype::ErrorPrototype):
  • kjs/ErrorPrototype.h:
  • kjs/FunctionConstructor.cpp: (JSC::FunctionConstructor::FunctionConstructor):
  • kjs/FunctionConstructor.h:
  • kjs/FunctionPrototype.cpp: (JSC::FunctionPrototype::FunctionPrototype): (JSC::FunctionPrototype::addFunctionProperties):
  • kjs/FunctionPrototype.h:
  • kjs/GlobalEvalFunction.cpp: (JSC::GlobalEvalFunction::GlobalEvalFunction):
  • kjs/GlobalEvalFunction.h:
  • kjs/InternalFunction.cpp: (JSC::InternalFunction::InternalFunction):
  • kjs/InternalFunction.h: (JSC::InternalFunction::InternalFunction):
  • kjs/JSArray.cpp: (JSC::JSArray::JSArray): (JSC::constructEmptyArray): (JSC::constructArray):
  • kjs/JSArray.h:
  • kjs/JSFunction.cpp: (JSC::JSFunction::JSFunction): (JSC::JSFunction::construct):
  • kjs/JSObject.cpp: (JSC::constructEmptyObject):
  • kjs/JSString.cpp: (JSC::StringObject::create):
  • kjs/JSWrapperObject.h:
  • kjs/MathObject.cpp: (JSC::MathObject::MathObject):
  • kjs/MathObject.h:
  • kjs/NativeErrorConstructor.cpp: (JSC::NativeErrorConstructor::NativeErrorConstructor): (JSC::NativeErrorConstructor::construct):
  • kjs/NativeErrorConstructor.h:
  • kjs/NativeErrorPrototype.cpp: (JSC::NativeErrorPrototype::NativeErrorPrototype):
  • kjs/NativeErrorPrototype.h:
  • kjs/NumberConstructor.cpp: (JSC::NumberConstructor::NumberConstructor): (JSC::constructWithNumberConstructor):
  • kjs/NumberConstructor.h:
  • kjs/NumberObject.cpp: (JSC::NumberObject::NumberObject): (JSC::constructNumber): (JSC::constructNumberFromImmediateNumber):
  • kjs/NumberObject.h:
  • kjs/NumberPrototype.cpp: (JSC::NumberPrototype::NumberPrototype):
  • kjs/NumberPrototype.h:
  • kjs/ObjectConstructor.cpp: (JSC::ObjectConstructor::ObjectConstructor): (JSC::constructObject):
  • kjs/ObjectConstructor.h:
  • kjs/ObjectPrototype.cpp: (JSC::ObjectPrototype::ObjectPrototype):
  • kjs/ObjectPrototype.h:
  • kjs/PrototypeFunction.cpp: (JSC::PrototypeFunction::PrototypeFunction):
  • kjs/PrototypeFunction.h:
  • kjs/RegExpConstructor.cpp: (JSC::RegExpConstructor::RegExpConstructor): (JSC::RegExpMatchesArray::RegExpMatchesArray): (JSC::constructRegExp):
  • kjs/RegExpConstructor.h:
  • kjs/RegExpObject.cpp: (JSC::RegExpObject::RegExpObject):
  • kjs/RegExpObject.h:
  • kjs/RegExpPrototype.cpp: (JSC::RegExpPrototype::RegExpPrototype):
  • kjs/RegExpPrototype.h:
  • kjs/Shell.cpp: (GlobalObject::GlobalObject):
  • kjs/StringConstructor.cpp: (JSC::StringConstructor::StringConstructor): (JSC::constructWithStringConstructor):
  • kjs/StringConstructor.h:
  • kjs/StringObject.cpp: (JSC::StringObject::StringObject):
  • kjs/StringObject.h:
  • kjs/StringObjectThatMasqueradesAsUndefined.h: (JSC::StringObjectThatMasqueradesAsUndefined::StringObjectThatMasqueradesAsUndefined):
  • kjs/StringPrototype.cpp: (JSC::StringPrototype::StringPrototype):
  • kjs/StringPrototype.h: Take and pass structures.

WebCore:

2008-09-20 Darin Adler <Darin Adler>

Reviewed by Maciej Stachowiak.

  • bindings/js/JSCSSStyleDeclarationCustom.cpp: (WebCore::JSCSSStyleDeclaration::nameGetter): Pass in a structure ID. Note that this makes a new structure every time -- we could optimize this slightly be caching and reusing a single one.
  • bridge/runtime_method.cpp: (JSC::RuntimeMethod::RuntimeMethod): Create a unique structure using getDOMStructure.
  • bridge/runtime_method.h: (JSC::RuntimeMethod::createPrototype): Added createPrototype so getDOMStructure will work.
  • bindings/js/JSDOMWindowShell.cpp: (WebCore::JSDOMWindowShell::JSDOMWindowShell): Initialize m_window to 0; needed in case garbage collection happens while creating the JSDOMWindow.
  • Property svn:eol-style set to native
File size: 16.2 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4 * Copyright (C) 2006 Bjoern Graf ([email protected])
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include "config.h"
24
25#include "ObjectPrototype.h"
26#include "ObjectConstructor.h"
27
28#include "CodeGenerator.h"
29#include "InitializeThreading.h"
30#include "JSArray.h"
31#include "JSFunction.h"
32#include "JSGlobalObject.h"
33#include "JSLock.h"
34#include "JSObject.h"
35#include "Parser.h"
36#include "PrototypeFunction.h"
37#include "SamplingTool.h"
38#include "collector.h"
39#include "completion.h"
40#include "interpreter.h"
41#include "nodes.h"
42#include "protect.h"
43#include <math.h>
44#include <stdio.h>
45#include <string.h>
46#include <wtf/Assertions.h>
47#include <wtf/HashTraits.h>
48
49#if !PLATFORM(WIN_OS)
50#include <unistd.h>
51#endif
52
53#if HAVE(READLINE)
54#include <readline/history.h>
55#include <readline/readline.h>
56#endif
57
58#if HAVE(SYS_TIME_H)
59#include <sys/time.h>
60#endif
61
62#if PLATFORM(UNIX)
63#include <signal.h>
64#endif
65
66#if COMPILER(MSVC)
67#include <crtdbg.h>
68#include <windows.h>
69#endif
70
71#if PLATFORM(QT)
72#include <QDateTime>
73#endif
74
75using namespace JSC;
76using namespace WTF;
77
78static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer);
79
80static JSValue* functionPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
81static JSValue* functionDebug(ExecState*, JSObject*, JSValue*, const ArgList&);
82static JSValue* functionGC(ExecState*, JSObject*, JSValue*, const ArgList&);
83static JSValue* functionVersion(ExecState*, JSObject*, JSValue*, const ArgList&);
84static JSValue* functionRun(ExecState*, JSObject*, JSValue*, const ArgList&);
85static JSValue* functionLoad(ExecState*, JSObject*, JSValue*, const ArgList&);
86static JSValue* functionReadline(ExecState*, JSObject*, JSValue*, const ArgList&);
87static JSValue* functionQuit(ExecState*, JSObject*, JSValue*, const ArgList&);
88
89struct Options {
90 Options()
91 : interactive(false)
92 , prettyPrint(false)
93 , dump(false)
94 {
95 }
96
97 bool interactive;
98 bool prettyPrint;
99 bool dump;
100 Vector<UString> fileNames;
101 Vector<UString> arguments;
102};
103
104static const char interactivePrompt[] = "> ";
105static const UString interpreterName("Interpreter");
106
107class StopWatch {
108public:
109 void start();
110 void stop();
111 long getElapsedMS(); // call stop() first
112
113private:
114#if PLATFORM(QT)
115 uint m_startTime;
116 uint m_stopTime;
117#elif PLATFORM(WIN_OS)
118 DWORD m_startTime;
119 DWORD m_stopTime;
120#else
121 // Windows does not have timeval, disabling this class for now (bug 7399)
122 timeval m_startTime;
123 timeval m_stopTime;
124#endif
125};
126
127void StopWatch::start()
128{
129#if PLATFORM(QT)
130 QDateTime t = QDateTime::currentDateTime();
131 m_startTime = t.toTime_t() * 1000 + t.time().msec();
132#elif PLATFORM(WIN_OS)
133 m_startTime = timeGetTime();
134#else
135 gettimeofday(&m_startTime, 0);
136#endif
137}
138
139void StopWatch::stop()
140{
141#if PLATFORM(QT)
142 QDateTime t = QDateTime::currentDateTime();
143 m_stopTime = t.toTime_t() * 1000 + t.time().msec();
144#elif PLATFORM(WIN_OS)
145 m_stopTime = timeGetTime();
146#else
147 gettimeofday(&m_stopTime, 0);
148#endif
149}
150
151long StopWatch::getElapsedMS()
152{
153#if PLATFORM(WIN_OS) || PLATFORM(QT)
154 return m_stopTime - m_startTime;
155#else
156 timeval elapsedTime;
157 timersub(&m_stopTime, &m_startTime, &elapsedTime);
158
159 return elapsedTime.tv_sec * 1000 + lroundf(elapsedTime.tv_usec / 1000.0f);
160#endif
161}
162
163class GlobalObject : public JSGlobalObject {
164public:
165 GlobalObject(JSGlobalData*, const Vector<UString>& arguments);
166 virtual UString className() const { return "global"; }
167};
168COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false);
169ASSERT_CLASS_FITS_IN_CELL(GlobalObject);
170
171GlobalObject::GlobalObject(JSGlobalData* globalData, const Vector<UString>& arguments)
172 : JSGlobalObject(globalData)
173{
174 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "debug"), functionDebug));
175 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "print"), functionPrint));
176 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "quit"), functionQuit));
177 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "gc"), functionGC));
178 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "version"), functionVersion));
179 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "run"), functionRun));
180 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "load"), functionLoad));
181 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "readline"), functionReadline));
182
183 JSObject* array = constructEmptyArray(globalExec());
184 for (size_t i = 0; i < arguments.size(); ++i)
185 array->put(globalExec(), i, jsString(globalExec(), arguments[i]));
186 putDirect(Identifier(globalExec(), "arguments"), array);
187
188 Interpreter::setShouldPrintExceptions(true);
189}
190
191JSValue* functionPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
192{
193 for (unsigned i = 0; i < args.size(); ++i) {
194 if (i != 0)
195 putchar(' ');
196
197 printf("%s", args.at(exec, i)->toString(exec).UTF8String().c_str());
198 }
199
200 putchar('\n');
201 fflush(stdout);
202 return jsUndefined();
203}
204
205JSValue* functionDebug(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
206{
207 fprintf(stderr, "--> %s\n", args.at(exec, 0)->toString(exec).UTF8String().c_str());
208 return jsUndefined();
209}
210
211JSValue* functionGC(ExecState* exec, JSObject*, JSValue*, const ArgList&)
212{
213 JSLock lock(false);
214 exec->heap()->collect();
215 return jsUndefined();
216}
217
218JSValue* functionVersion(ExecState*, JSObject*, JSValue*, const ArgList&)
219{
220 // We need this function for compatibility with the Mozilla JS tests but for now
221 // we don't actually do any version-specific handling
222 return jsUndefined();
223}
224
225JSValue* functionRun(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
226{
227 StopWatch stopWatch;
228 UString fileName = args.at(exec, 0)->toString(exec);
229 Vector<char> script;
230 if (!fillBufferWithContentsOfFile(fileName, script))
231 return throwError(exec, GeneralError, "Could not open file.");
232
233 JSGlobalObject* globalObject = exec->dynamicGlobalObject();
234
235 stopWatch.start();
236 Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
237 stopWatch.stop();
238
239 return jsNumber(globalObject->globalExec(), stopWatch.getElapsedMS());
240}
241
242JSValue* functionLoad(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
243{
244 UString fileName = args.at(exec, 0)->toString(exec);
245 Vector<char> script;
246 if (!fillBufferWithContentsOfFile(fileName, script))
247 return throwError(exec, GeneralError, "Could not open file.");
248
249 JSGlobalObject* globalObject = exec->dynamicGlobalObject();
250 Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
251
252 return jsUndefined();
253}
254
255JSValue* functionReadline(ExecState* exec, JSObject*, JSValue*, const ArgList&)
256{
257 Vector<char, 256> line;
258 int c;
259 while ((c = getchar()) != EOF) {
260 // FIXME: Should we also break on \r?
261 if (c == '\n')
262 break;
263 line.append(c);
264 }
265 line.append('\0');
266 return jsString(exec, line.data());
267}
268
269JSValue* functionQuit(ExecState*, JSObject*, JSValue*, const ArgList&)
270{
271 exit(0);
272#if !COMPILER(MSVC)
273 // MSVC knows that exit(0) never returns, so it flags this return statement as unreachable.
274 return jsUndefined();
275#endif
276}
277
278// Use SEH for Release builds only to get rid of the crash report dialog
279// (luckily the same tests fail in Release and Debug builds so far). Need to
280// be in a separate main function because the jscmain function requires object
281// unwinding.
282
283#if COMPILER(MSVC) && !defined(_DEBUG)
284#define TRY __try {
285#define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; }
286#else
287#define TRY
288#define EXCEPT(x)
289#endif
290
291int jscmain(int argc, char** argv, JSGlobalData*);
292
293int main(int argc, char** argv)
294{
295#if defined(_DEBUG) && PLATFORM(WIN_OS)
296 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
297 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
298 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
299 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
300 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
301 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
302#endif
303
304 int res = 0;
305 TRY
306 JSGlobalData* globalData = JSGlobalData::create().releaseRef();
307 res = jscmain(argc, argv, globalData);
308 delete globalData;
309 EXCEPT(res = 3)
310 return res;
311}
312
313static bool prettyPrintScript(ExecState* exec, const UString& fileName, const Vector<char>& script)
314{
315 int errLine = 0;
316 UString errMsg;
317 UString scriptUString(script.data());
318 RefPtr<ProgramNode> programNode = exec->parser()->parse<ProgramNode>(exec, fileName, 1, UStringSourceProvider::create(scriptUString), 0, &errLine, &errMsg);
319 if (!programNode) {
320 fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
321 return false;
322 }
323
324 printf("%s\n", programNode->toString().UTF8String().c_str());
325 return true;
326}
327
328static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fileNames, bool prettyPrint, bool dump)
329{
330 Vector<char> script;
331
332 if (dump)
333 CodeGenerator::setDumpsGeneratedCode(true);
334
335#if ENABLE(SAMPLING_TOOL)
336 Machine* machine = globalObject->globalData()->machine;
337 machine->m_sampler = new SamplingTool();
338 machine->m_sampler->start();
339#endif
340
341 bool success = true;
342 for (size_t i = 0; i < fileNames.size(); i++) {
343 UString fileName = fileNames[i];
344
345 if (!fillBufferWithContentsOfFile(fileName, script))
346 return false; // fail early so we can catch missing files
347
348 if (prettyPrint)
349 prettyPrintScript(globalObject->globalExec(), fileName, script);
350 else {
351 Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
352 success = success && completion.complType() != Throw;
353 if (dump) {
354 if (completion.complType() == Throw)
355 printf("Exception: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
356 else
357 printf("End: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
358 }
359
360 globalObject->globalExec()->clearException();
361 }
362 }
363
364#if ENABLE(SAMPLING_TOOL)
365 machine->m_sampler->stop();
366 machine->m_sampler->dump(globalObject->globalExec());
367 delete machine->m_sampler;
368#endif
369 return success;
370}
371
372static void runInteractive(GlobalObject* globalObject)
373{
374 while (true) {
375#if HAVE(READLINE)
376 char* line = readline(interactivePrompt);
377 if (!line)
378 break;
379 if (line[0])
380 add_history(line);
381 Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), interpreterName, 1, line);
382 free(line);
383#else
384 puts(interactivePrompt);
385 Vector<char, 256> line;
386 int c;
387 while ((c = getchar()) != EOF) {
388 // FIXME: Should we also break on \r?
389 if (c == '\n')
390 break;
391 line.append(c);
392 }
393 line.append('\0');
394 Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), interpreterName, 1, line.data());
395#endif
396 if (completion.complType() == Throw)
397 printf("Exception: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
398 else
399 printf("%s\n", completion.value()->toString(globalObject->globalExec()).UTF8String().c_str());
400
401 globalObject->globalExec()->clearException();
402 }
403 printf("\n");
404}
405
406static void printUsageStatement()
407{
408 fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n");
409 fprintf(stderr, " -d Dumps bytecode (debug builds only)\n");
410 fprintf(stderr, " -f Specifies a source file (deprecated)\n");
411 fprintf(stderr, " -h|--help Prints this help message\n");
412 fprintf(stderr, " -i Enables interactive mode (default if no files are specified)\n");
413 fprintf(stderr, " -p Prints formatted source code\n");
414 fprintf(stderr, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n");
415 exit(-1);
416}
417
418static void parseArguments(int argc, char** argv, Options& options)
419{
420 int i = 1;
421 for (; i < argc; ++i) {
422 const char* arg = argv[i];
423 if (strcmp(arg, "-f") == 0) {
424 if (++i == argc)
425 printUsageStatement();
426 options.fileNames.append(argv[i]);
427 continue;
428 }
429 if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
430 printUsageStatement();
431 }
432 if (strcmp(arg, "-i") == 0) {
433 options.interactive = true;
434 continue;
435 }
436 if (strcmp(arg, "-p") == 0) {
437 options.prettyPrint = true;
438 continue;
439 }
440 if (strcmp(arg, "-d") == 0) {
441 options.dump = true;
442 continue;
443 }
444 if (strcmp(arg, "-s") == 0) {
445#if PLATFORM(UNIX)
446 signal(SIGILL, _exit);
447 signal(SIGFPE, _exit);
448 signal(SIGBUS, _exit);
449 signal(SIGSEGV, _exit);
450#endif
451 continue;
452 }
453 if (strcmp(arg, "--") == 0) {
454 ++i;
455 break;
456 }
457 options.fileNames.append(argv[i]);
458 }
459
460 if (options.fileNames.isEmpty())
461 options.interactive = true;
462
463 for (; i < argc; ++i)
464 options.arguments.append(argv[i]);
465}
466
467int jscmain(int argc, char** argv, JSGlobalData* globalData)
468{
469 JSC::initializeThreading();
470
471 JSLock lock(false);
472
473 Options options;
474 parseArguments(argc, argv, options);
475
476 GlobalObject* globalObject = new (globalData) GlobalObject(globalData, options.arguments);
477 bool success = runWithScripts(globalObject, options.fileNames, options.prettyPrint, options.dump);
478 if (options.interactive && success)
479 runInteractive(globalObject);
480
481 return success ? 0 : 3;
482}
483
484static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer)
485{
486 FILE* f = fopen(fileName.UTF8String().c_str(), "r");
487 if (!f) {
488 fprintf(stderr, "Could not open file: %s\n", fileName.UTF8String().c_str());
489 return false;
490 }
491
492 size_t buffer_size = 0;
493 size_t buffer_capacity = 1024;
494
495 buffer.resize(buffer_capacity);
496
497 while (!feof(f) && !ferror(f)) {
498 buffer_size += fread(buffer.data() + buffer_size, 1, buffer_capacity - buffer_size, f);
499 if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
500 buffer_capacity *= 2;
501 buffer.resize(buffer_capacity);
502 }
503 }
504 fclose(f);
505 buffer[buffer_size] = '\0';
506
507 return true;
508}
Note: See TracBrowser for help on using the repository browser.