source: webkit/trunk/Source/JavaScriptCore/jsc.cpp@ 97532

Last change on this file since 97532 was 97532, checked in by [email protected], 14 years ago

Rename virtual put to putVirtual
https://bugs.webkit.org/show_bug.cgi?id=69851

Reviewed by Darin Adler.

.:

Renamed virtual versions of put to putVirtual in prepration for
adding the static put to the MethodTable in ClassInfo since the
compiler gets mad if the virtual and static versions have the same
name.

  • Source/autotools/symbols.filter:

Source/JavaScriptCore:

Renamed virtual versions of put to putVirtual in prepration for
adding the static put to the MethodTable in ClassInfo since the
compiler gets mad if the virtual and static versions have the same
name.

  • API/JSCallbackObject.h:
  • API/JSCallbackObjectFunctions.h:

(JSC::::putVirtual):

  • API/JSObjectRef.cpp:

(JSObjectSetProperty):
(JSObjectSetPropertyAtIndex):

(JSC::DebuggerActivation::putVirtual):
(JSC::DebuggerActivation::put):

  • debugger/DebuggerActivation.h:
  • dfg/DFGOperations.cpp:

(JSC::DFG::putByVal):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::execute):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • jsc.cpp:

(GlobalObject::finishCreation):

  • runtime/Arguments.cpp:

(JSC::Arguments::putVirtual):

  • runtime/Arguments.h:
  • runtime/ArrayPrototype.cpp:

(JSC::putProperty):
(JSC::arrayProtoFuncConcat):
(JSC::arrayProtoFuncPush):
(JSC::arrayProtoFuncReverse):
(JSC::arrayProtoFuncShift):
(JSC::arrayProtoFuncSlice):
(JSC::arrayProtoFuncSort):
(JSC::arrayProtoFuncSplice):
(JSC::arrayProtoFuncUnShift):
(JSC::arrayProtoFuncFilter):
(JSC::arrayProtoFuncMap):

  • runtime/JSActivation.cpp:

(JSC::JSActivation::putVirtual):

  • runtime/JSActivation.h:
  • runtime/JSArray.cpp:

(JSC::JSArray::putVirtual):
(JSC::JSArray::putSlowCase):
(JSC::JSArray::push):
(JSC::JSArray::shiftCount):
(JSC::JSArray::unshiftCount):

  • runtime/JSArray.h:
  • runtime/JSByteArray.cpp:

(JSC::JSByteArray::putVirtual):

  • runtime/JSByteArray.h:
  • runtime/JSCell.cpp:

(JSC::JSCell::putVirtual):
(JSC::JSCell::put):

  • runtime/JSCell.h:
  • runtime/JSFunction.cpp:

(JSC::JSFunction::putVirtual):

  • runtime/JSFunction.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::putVirtual):
(JSC::JSGlobalObject::putWithAttributes):

  • runtime/JSGlobalObject.h:
  • runtime/JSNotAnObject.cpp:

(JSC::JSNotAnObject::putVirtual):

  • runtime/JSNotAnObject.h:
  • runtime/JSONObject.cpp:

(JSC::Walker::walk):

  • runtime/JSObject.cpp:

(JSC::JSObject::putVirtual):
(JSC::JSObject::put):
(JSC::JSObject::defineOwnProperty):

  • runtime/JSObject.h:

(JSC::JSValue::put):

  • runtime/JSStaticScopeObject.cpp:

(JSC::JSStaticScopeObject::putVirtual):

  • runtime/JSStaticScopeObject.h:
  • runtime/Lookup.h:

(JSC::lookupPut):

  • runtime/ObjectPrototype.cpp:

(JSC::ObjectPrototype::putVirtual):

  • runtime/ObjectPrototype.h:
  • runtime/RegExpConstructor.cpp:

(JSC::RegExpMatchesArray::fillArrayInstance):
(JSC::RegExpConstructor::putVirtual):

  • runtime/RegExpConstructor.h:
  • runtime/RegExpMatchesArray.h:

(JSC::RegExpMatchesArray::putVirtual):

  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::putVirtual):

  • runtime/RegExpObject.h:
  • runtime/StringObject.cpp:

(JSC::StringObject::putVirtual):

  • runtime/StringObject.h:
  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncSplit):

Source/JavaScriptGlue:

Renamed virtual versions of put to putVirtual in prepration for
adding the static put to the MethodTable in ClassInfo since the
compiler gets mad if the virtual and static versions have the same
name.

  • JSValueWrapper.cpp:

(JSValueWrapper::JSObjectSetProperty):

  • UserObjectImp.cpp:

(UserObjectImp::putVirtual):

  • UserObjectImp.h:

Source/WebCore:

No new tests.

Renamed virtual versions of put to putVirtual in prepration for
adding the static put to the MethodTable in ClassInfo since the
compiler gets mad if the virtual and static versions have the same
name.

  • WebCore.exp.in:
  • bindings/js/JSDOMWindowCustom.cpp:

(WebCore::JSDOMWindow::putVirtual):

  • bindings/js/JSDOMWindowShell.cpp:

(WebCore::JSDOMWindowShell::putVirtual):

  • bindings/js/JSDOMWindowShell.h:
  • bindings/js/JSLocationCustom.cpp:

(WebCore::JSLocation::putDelegate):

  • bindings/js/JSPluginElementFunctions.cpp:

(WebCore::runtimeObjectCustomPut):

  • bindings/js/SerializedScriptValue.cpp:

(WebCore::CloneDeserializer::putProperty):

  • bindings/objc/WebScriptObject.mm:

(-[WebScriptObject setValue:forKey:]):
(-[WebScriptObject setWebScriptValueAtIndex:value:]):

  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateHeader):
(GenerateImplementation):

  • bindings/scripts/test/JS/JSTestObj.cpp:

(WebCore::JSTestObj::putVirtual):

  • bindings/scripts/test/JS/JSTestObj.h:
  • bridge/NP_jsobject.cpp:

(_NPN_SetProperty):

  • bridge/jni/jni_jsobject.mm:

(JavaJSObject::setMember):
(JavaJSObject::setSlot):

  • bridge/objc/objc_runtime.h:
  • bridge/objc/objc_runtime.mm:

(JSC::Bindings::ObjcFallbackObjectImp::putVirtual):

  • bridge/qt/qt_instance.cpp:

(JSC::Bindings::QtInstance::put):

  • bridge/qt/qt_runtime.cpp:

(JSC::Bindings::convertQVariantToValue):

  • bridge/runtime_array.cpp:

(JSC::RuntimeArray::putVirtual):

  • bridge/runtime_array.h:
  • bridge/runtime_object.cpp:

(JSC::Bindings::RuntimeObject::putVirtual):

  • bridge/runtime_object.h:
  • bridge/testqtbindings.cpp:

(main):

Source/WebKit/efl:

Renamed virtual versions of put to putVirtual in prepration for
adding the static put to the MethodTable in ClassInfo since the
compiler gets mad if the virtual and static versions have the same
name.

  • ewk/ewk_view.cpp:

(ewk_view_js_object_add):

Source/WebKit/mac:

Renamed virtual versions of put to putVirtual in prepration for
adding the static put to the MethodTable in ClassInfo since the
compiler gets mad if the virtual and static versions have the same
name.

  • Plugins/Hosted/NetscapePluginInstanceProxy.mm:

(WebKit::NetscapePluginInstanceProxy::setProperty):

Source/WebKit/qt:

Renamed virtual versions of put to putVirtual in prepration for
adding the static put to the MethodTable in ClassInfo since the
compiler gets mad if the virtual and static versions have the same
name.

  • Api/qwebframe.cpp:

(QWebFrame::addToJavaScriptWindowObject):

Source/WebKit2:

Renamed virtual versions of put to putVirtual in prepration for
adding the static put to the MethodTable in ClassInfo since the
compiler gets mad if the virtual and static versions have the same
name.

  • WebProcess/Plugins/Netscape/JSNPObject.cpp:

(WebKit::JSNPObject::putVirtual):
(WebKit::JSNPObject::put):

  • WebProcess/Plugins/Netscape/JSNPObject.h:
  • WebProcess/Plugins/Netscape/NPJSObject.cpp:

(WebKit::NPJSObject::setProperty):

  • Property svn:eol-style set to native
File size: 19.5 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 "BytecodeGenerator.h"
26#include "Completion.h"
27#include "CurrentTime.h"
28#include "ExceptionHelpers.h"
29#include "InitializeThreading.h"
30#include "JSArray.h"
31#include "JSFunction.h"
32#include "JSLock.h"
33#include "JSString.h"
34#include "SamplingTool.h"
35#include <math.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39
40#if !OS(WINDOWS)
41#include <unistd.h>
42#endif
43
44#if HAVE(READLINE)
45#include <readline/history.h>
46#include <readline/readline.h>
47#endif
48
49#if HAVE(SYS_TIME_H)
50#include <sys/time.h>
51#endif
52
53#if HAVE(SIGNAL_H)
54#include <signal.h>
55#endif
56
57#if COMPILER(MSVC) && !OS(WINCE)
58#include <crtdbg.h>
59#include <mmsystem.h>
60#include <windows.h>
61#endif
62
63#if PLATFORM(QT)
64#include <QCoreApplication>
65#include <QDateTime>
66#endif
67
68using namespace JSC;
69using namespace WTF;
70
71static void cleanupGlobalData(JSGlobalData*);
72static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer);
73
74static EncodedJSValue JSC_HOST_CALL functionPrint(ExecState*);
75static EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*);
76static EncodedJSValue JSC_HOST_CALL functionGC(ExecState*);
77#ifndef NDEBUG
78static EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState*);
79#endif
80static EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*);
81static EncodedJSValue JSC_HOST_CALL functionRun(ExecState*);
82static EncodedJSValue JSC_HOST_CALL functionLoad(ExecState*);
83static EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState*);
84static EncodedJSValue JSC_HOST_CALL functionReadline(ExecState*);
85static EncodedJSValue JSC_HOST_CALL functionPreciseTime(ExecState*);
86static NO_RETURN_WITH_VALUE EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*);
87
88#if ENABLE(SAMPLING_FLAGS)
89static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
90static EncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState*);
91#endif
92
93struct Script {
94 bool isFile;
95 char* argument;
96
97 Script(bool isFile, char *argument)
98 : isFile(isFile)
99 , argument(argument)
100 {
101 }
102};
103
104struct Options {
105 Options()
106 : interactive(false)
107 , dump(false)
108 {
109 }
110
111 bool interactive;
112 bool dump;
113 Vector<Script> scripts;
114 Vector<UString> arguments;
115};
116
117static const char interactivePrompt[] = "> ";
118
119class StopWatch {
120public:
121 void start();
122 void stop();
123 long getElapsedMS(); // call stop() first
124
125private:
126 double m_startTime;
127 double m_stopTime;
128};
129
130void StopWatch::start()
131{
132 m_startTime = currentTime();
133}
134
135void StopWatch::stop()
136{
137 m_stopTime = currentTime();
138}
139
140long StopWatch::getElapsedMS()
141{
142 return static_cast<long>((m_stopTime - m_startTime) * 1000);
143}
144
145class GlobalObject : public JSGlobalObject {
146private:
147 GlobalObject(JSGlobalData&, Structure*);
148
149public:
150 typedef JSGlobalObject Base;
151
152 static GlobalObject* create(JSGlobalData& globalData, Structure* structure, const Vector<UString>& arguments)
153 {
154 GlobalObject* object = new (allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure);
155 object->finishCreation(globalData, arguments);
156 return object;
157 }
158 virtual UString className() const { return "global"; }
159
160protected:
161 void finishCreation(JSGlobalData& globalData, const Vector<UString>& arguments)
162 {
163 Base::finishCreation(globalData);
164
165 addFunction(globalData, "debug", functionDebug, 1);
166 addFunction(globalData, "print", functionPrint, 1);
167 addFunction(globalData, "quit", functionQuit, 0);
168 addFunction(globalData, "gc", functionGC, 0);
169#ifndef NDEBUG
170 addFunction(globalData, "releaseExecutableMemory", functionReleaseExecutableMemory, 0);
171#endif
172 addFunction(globalData, "version", functionVersion, 1);
173 addFunction(globalData, "run", functionRun, 1);
174 addFunction(globalData, "load", functionLoad, 1);
175 addFunction(globalData, "checkSyntax", functionCheckSyntax, 1);
176 addFunction(globalData, "readline", functionReadline, 0);
177 addFunction(globalData, "preciseTime", functionPreciseTime, 0);
178#if ENABLE(SAMPLING_FLAGS)
179 addFunction(globalData, "setSamplingFlags", functionSetSamplingFlags, 1);
180 addFunction(globalData, "clearSamplingFlags", functionClearSamplingFlags, 1);
181#endif
182
183 JSObject* array = constructEmptyArray(globalExec());
184 for (size_t i = 0; i < arguments.size(); ++i)
185 array->putVirtual(globalExec(), i, jsString(globalExec(), arguments[i]));
186 putDirect(globalData, Identifier(globalExec(), "arguments"), array);
187 }
188
189 void addFunction(JSGlobalData& globalData, const char* name, NativeFunction function, unsigned arguments)
190 {
191 Identifier identifier(globalExec(), name);
192 putDirect(globalData, identifier, JSFunction::create(globalExec(), this, arguments, identifier, function));
193 }
194};
195COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false);
196ASSERT_CLASS_FITS_IN_CELL(GlobalObject);
197
198GlobalObject::GlobalObject(JSGlobalData& globalData, Structure* structure)
199 : JSGlobalObject(globalData, structure)
200{
201}
202
203EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
204{
205 for (unsigned i = 0; i < exec->argumentCount(); ++i) {
206 if (i)
207 putchar(' ');
208
209 printf("%s", exec->argument(i).toString(exec).utf8().data());
210 }
211
212 putchar('\n');
213 fflush(stdout);
214 return JSValue::encode(jsUndefined());
215}
216
217EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec)
218{
219 fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec).utf8().data());
220 return JSValue::encode(jsUndefined());
221}
222
223EncodedJSValue JSC_HOST_CALL functionGC(ExecState* exec)
224{
225 JSLock lock(SilenceAssertionsOnly);
226 exec->heap()->collectAllGarbage();
227 return JSValue::encode(jsUndefined());
228}
229
230#ifndef NDEBUG
231EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState* exec)
232{
233 JSLock lock(SilenceAssertionsOnly);
234 exec->globalData().releaseExecutableMemory();
235 return JSValue::encode(jsUndefined());
236}
237#endif
238
239EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*)
240{
241 // We need this function for compatibility with the Mozilla JS tests but for now
242 // we don't actually do any version-specific handling
243 return JSValue::encode(jsUndefined());
244}
245
246EncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec)
247{
248 UString fileName = exec->argument(0).toString(exec);
249 Vector<char> script;
250 if (!fillBufferWithContentsOfFile(fileName, script))
251 return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
252
253 GlobalObject* globalObject = GlobalObject::create(exec->globalData(), GlobalObject::createStructure(exec->globalData(), jsNull()), Vector<UString>());
254
255 StopWatch stopWatch;
256 stopWatch.start();
257 evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
258 stopWatch.stop();
259
260 return JSValue::encode(jsNumber(stopWatch.getElapsedMS()));
261}
262
263EncodedJSValue JSC_HOST_CALL functionLoad(ExecState* exec)
264{
265 UString fileName = exec->argument(0).toString(exec);
266 Vector<char> script;
267 if (!fillBufferWithContentsOfFile(fileName, script))
268 return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
269
270 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
271
272 JSValue evaluationException;
273 JSValue result = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName), JSValue(), &evaluationException);
274 if (evaluationException)
275 throwError(exec, evaluationException);
276 return JSValue::encode(result);
277}
278
279EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState* exec)
280{
281 UString fileName = exec->argument(0).toString(exec);
282 Vector<char> script;
283 if (!fillBufferWithContentsOfFile(fileName, script))
284 return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
285
286 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
287
288 StopWatch stopWatch;
289 stopWatch.start();
290
291 JSValue syntaxException;
292 bool validSyntax = checkSyntax(globalObject->globalExec(), makeSource(script.data(), fileName), &syntaxException);
293 stopWatch.stop();
294
295 if (!validSyntax)
296 throwError(exec, syntaxException);
297 return JSValue::encode(jsNumber(stopWatch.getElapsedMS()));
298}
299
300#if ENABLE(SAMPLING_FLAGS)
301EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState* exec)
302{
303 for (unsigned i = 0; i < exec->argumentCount(); ++i) {
304 unsigned flag = static_cast<unsigned>(exec->argument(i).toNumber(exec));
305 if ((flag >= 1) && (flag <= 32))
306 SamplingFlags::setFlag(flag);
307 }
308 return JSValue::encode(jsNull());
309}
310
311EncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState* exec)
312{
313 for (unsigned i = 0; i < exec->argumentCount(); ++i) {
314 unsigned flag = static_cast<unsigned>(exec->argument(i).toNumber(exec));
315 if ((flag >= 1) && (flag <= 32))
316 SamplingFlags::clearFlag(flag);
317 }
318 return JSValue::encode(jsNull());
319}
320#endif
321
322EncodedJSValue JSC_HOST_CALL functionReadline(ExecState* exec)
323{
324 Vector<char, 256> line;
325 int c;
326 while ((c = getchar()) != EOF) {
327 // FIXME: Should we also break on \r?
328 if (c == '\n')
329 break;
330 line.append(c);
331 }
332 line.append('\0');
333 return JSValue::encode(jsString(exec, line.data()));
334}
335
336EncodedJSValue JSC_HOST_CALL functionPreciseTime(ExecState*)
337{
338 return JSValue::encode(jsNumber(currentTime()));
339}
340
341EncodedJSValue JSC_HOST_CALL functionQuit(ExecState* exec)
342{
343 // Technically, destroying the heap in the middle of JS execution is a no-no,
344 // but we want to maintain compatibility with the Mozilla test suite, so
345 // we pretend that execution has terminated to avoid ASSERTs, then tear down the heap.
346 exec->globalData().dynamicGlobalObject = 0;
347
348 cleanupGlobalData(&exec->globalData());
349 exit(EXIT_SUCCESS);
350
351#if COMPILER(MSVC) && OS(WINCE)
352 // Without this, Visual Studio will complain that this method does not return a value.
353 return JSValue::encode(jsUndefined());
354#endif
355}
356
357// Use SEH for Release builds only to get rid of the crash report dialog
358// (luckily the same tests fail in Release and Debug builds so far). Need to
359// be in a separate main function because the jscmain function requires object
360// unwinding.
361
362#if COMPILER(MSVC) && !COMPILER(INTEL) && !defined(_DEBUG) && !OS(WINCE)
363#define TRY __try {
364#define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; }
365#else
366#define TRY
367#define EXCEPT(x)
368#endif
369
370int jscmain(int argc, char** argv, JSGlobalData*);
371
372int main(int argc, char** argv)
373{
374#if OS(WINDOWS)
375#if !OS(WINCE)
376 // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
377 // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
378 // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
379 ::SetErrorMode(0);
380#endif
381
382#if defined(_DEBUG)
383 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
384 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
385 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
386 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
387 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
388 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
389#endif
390
391 timeBeginPeriod(1);
392#endif
393
394#if PLATFORM(QT)
395 QCoreApplication app(argc, argv);
396#endif
397
398 // Initialize JSC before getting JSGlobalData.
399 JSC::initializeThreading();
400
401 // We can't use destructors in the following code because it uses Windows
402 // Structured Exception Handling
403 int res = 0;
404 JSGlobalData* globalData = JSGlobalData::create(ThreadStackTypeLarge, LargeHeap).leakRef();
405 TRY
406 res = jscmain(argc, argv, globalData);
407 EXCEPT(res = 3)
408
409 cleanupGlobalData(globalData);
410 return res;
411}
412
413static void cleanupGlobalData(JSGlobalData* globalData)
414{
415 JSLock lock(SilenceAssertionsOnly);
416 globalData->clearBuiltinStructures();
417 globalData->heap.destroy();
418 globalData->deref();
419}
420
421static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scripts, bool dump)
422{
423 UString script;
424 UString fileName;
425 Vector<char> scriptBuffer;
426
427 if (dump)
428 BytecodeGenerator::setDumpsGeneratedCode(true);
429
430 JSGlobalData& globalData = globalObject->globalData();
431
432#if ENABLE(SAMPLING_FLAGS)
433 SamplingFlags::start();
434#endif
435
436 bool success = true;
437 for (size_t i = 0; i < scripts.size(); i++) {
438 if (scripts[i].isFile) {
439 fileName = scripts[i].argument;
440 if (!fillBufferWithContentsOfFile(fileName, scriptBuffer))
441 return false; // fail early so we can catch missing files
442 script = scriptBuffer.data();
443 } else {
444 script = scripts[i].argument;
445 fileName = "[Command Line]";
446 }
447
448 globalData.startSampling();
449
450 JSValue evaluationException;
451 JSValue returnValue = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script, fileName), JSValue(), &evaluationException);
452 success = success && !evaluationException;
453 if (dump) {
454 if (evaluationException)
455 printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec()).utf8().data());
456 else
457 printf("End: %s\n", returnValue.toString(globalObject->globalExec()).utf8().data());
458 }
459
460 globalData.stopSampling();
461 globalObject->globalExec()->clearException();
462 }
463
464#if ENABLE(SAMPLING_FLAGS)
465 SamplingFlags::stop();
466#endif
467 globalData.dumpSampleData(globalObject->globalExec());
468#if ENABLE(SAMPLING_COUNTERS)
469 AbstractSamplingCounter::dump();
470#endif
471#if ENABLE(REGEXP_TRACING)
472 globalData.dumpRegExpTrace();
473#endif
474 return success;
475}
476
477#define RUNNING_FROM_XCODE 0
478
479static void runInteractive(GlobalObject* globalObject)
480{
481 UString interpreterName("Interpreter");
482
483 while (true) {
484#if HAVE(READLINE) && !RUNNING_FROM_XCODE
485 char* line = readline(interactivePrompt);
486 if (!line)
487 break;
488 if (line[0])
489 add_history(line);
490 JSValue evaluationException;
491 JSValue returnValue = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line, interpreterName), JSValue(), &evaluationException);
492 free(line);
493#else
494 printf("%s", interactivePrompt);
495 Vector<char, 256> line;
496 int c;
497 while ((c = getchar()) != EOF) {
498 // FIXME: Should we also break on \r?
499 if (c == '\n')
500 break;
501 line.append(c);
502 }
503 if (line.isEmpty())
504 break;
505 line.append('\0');
506
507 JSValue evaluationException;
508 JSValue returnValue = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line.data(), interpreterName), JSValue(), &evaluationException);
509#endif
510 if (evaluationException)
511 printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec()).utf8().data());
512 else
513 printf("%s\n", returnValue.toString(globalObject->globalExec()).utf8().data());
514
515 globalObject->globalExec()->clearException();
516 }
517 printf("\n");
518}
519
520static NO_RETURN void printUsageStatement(JSGlobalData* globalData, bool help = false)
521{
522 fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n");
523 fprintf(stderr, " -d Dumps bytecode (debug builds only)\n");
524 fprintf(stderr, " -e Evaluate argument as script code\n");
525 fprintf(stderr, " -f Specifies a source file (deprecated)\n");
526 fprintf(stderr, " -h|--help Prints this help message\n");
527 fprintf(stderr, " -i Enables interactive mode (default if no files are specified)\n");
528#if HAVE(SIGNAL_H)
529 fprintf(stderr, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n");
530#endif
531
532 cleanupGlobalData(globalData);
533 exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
534}
535
536static void parseArguments(int argc, char** argv, Options& options, JSGlobalData* globalData)
537{
538 int i = 1;
539 for (; i < argc; ++i) {
540 const char* arg = argv[i];
541 if (!strcmp(arg, "-f")) {
542 if (++i == argc)
543 printUsageStatement(globalData);
544 options.scripts.append(Script(true, argv[i]));
545 continue;
546 }
547 if (!strcmp(arg, "-e")) {
548 if (++i == argc)
549 printUsageStatement(globalData);
550 options.scripts.append(Script(false, argv[i]));
551 continue;
552 }
553 if (!strcmp(arg, "-i")) {
554 options.interactive = true;
555 continue;
556 }
557 if (!strcmp(arg, "-d")) {
558 options.dump = true;
559 continue;
560 }
561 if (!strcmp(arg, "-s")) {
562#if HAVE(SIGNAL_H)
563 signal(SIGILL, _exit);
564 signal(SIGFPE, _exit);
565 signal(SIGBUS, _exit);
566 signal(SIGSEGV, _exit);
567#endif
568 continue;
569 }
570 if (!strcmp(arg, "--")) {
571 ++i;
572 break;
573 }
574 if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
575 printUsageStatement(globalData, true);
576 options.scripts.append(Script(true, argv[i]));
577 }
578
579 if (options.scripts.isEmpty())
580 options.interactive = true;
581
582 for (; i < argc; ++i)
583 options.arguments.append(argv[i]);
584}
585
586int jscmain(int argc, char** argv, JSGlobalData* globalData)
587{
588 JSLock lock(SilenceAssertionsOnly);
589
590 Options options;
591 parseArguments(argc, argv, options, globalData);
592
593 GlobalObject* globalObject = GlobalObject::create(*globalData, GlobalObject::createStructure(*globalData, jsNull()), options.arguments);
594 bool success = runWithScripts(globalObject, options.scripts, options.dump);
595 if (options.interactive && success)
596 runInteractive(globalObject);
597
598 return success ? 0 : 3;
599}
600
601static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer)
602{
603 FILE* f = fopen(fileName.utf8().data(), "r");
604 if (!f) {
605 fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data());
606 return false;
607 }
608
609 size_t bufferSize = 0;
610 size_t bufferCapacity = 1024;
611
612 buffer.resize(bufferCapacity);
613
614 while (!feof(f) && !ferror(f)) {
615 bufferSize += fread(buffer.data() + bufferSize, 1, bufferCapacity - bufferSize, f);
616 if (bufferSize == bufferCapacity) { // guarantees space for trailing '\0'
617 bufferCapacity *= 2;
618 buffer.resize(bufferCapacity);
619 }
620 }
621 fclose(f);
622 buffer[bufferSize] = '\0';
623
624 if (buffer[0] == '#' && buffer[1] == '!')
625 buffer[0] = buffer[1] = '/';
626
627 return true;
628}
Note: See TracBrowser for help on using the repository browser.