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

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

JavaScriptCore:

2008-10-18 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

Use JSValuePtr everywhere instead of JSValue*. In the future, we'll be
changing JSValuePtr to be a class, and then eventually renaming it
to JSValue once that's done.

  • JavaScriptCore.exp: Update entry points, since some now take JSValue* instead of const JSValue*.
  • API/APICast.h:
  • API/JSCallbackConstructor.h:
  • API/JSCallbackFunction.cpp:
  • API/JSCallbackFunction.h:
  • API/JSCallbackObject.h:
  • API/JSCallbackObjectFunctions.h:
  • API/JSContextRef.cpp:
  • API/JSObjectRef.cpp:
  • API/JSValueRef.cpp:
  • VM/CTI.cpp:
  • VM/CTI.h:
  • VM/CodeBlock.cpp:
  • VM/CodeBlock.h:
  • VM/CodeGenerator.cpp:
  • VM/CodeGenerator.h:
  • VM/ExceptionHelpers.cpp:
  • VM/ExceptionHelpers.h:
  • VM/JSPropertyNameIterator.cpp:
  • VM/JSPropertyNameIterator.h:
  • VM/Machine.cpp:
  • VM/Machine.h:
  • VM/Register.h:
  • kjs/ArgList.cpp:
  • kjs/ArgList.h:
  • kjs/Arguments.cpp:
  • kjs/Arguments.h:
  • kjs/ArrayConstructor.cpp:
  • kjs/ArrayPrototype.cpp:
  • kjs/BooleanConstructor.cpp:
  • kjs/BooleanConstructor.h:
  • kjs/BooleanObject.h:
  • kjs/BooleanPrototype.cpp:
  • kjs/CallData.cpp:
  • kjs/CallData.h:
  • kjs/ConstructData.cpp:
  • kjs/ConstructData.h:
  • kjs/DateConstructor.cpp:
  • kjs/DateInstance.h:
  • kjs/DatePrototype.cpp:
  • kjs/DebuggerCallFrame.cpp:
  • kjs/DebuggerCallFrame.h:
  • kjs/ErrorConstructor.cpp:
  • kjs/ErrorPrototype.cpp:
  • kjs/ExecState.cpp:
  • kjs/ExecState.h:
  • kjs/FunctionConstructor.cpp:
  • kjs/FunctionPrototype.cpp:
  • kjs/GetterSetter.cpp:
  • kjs/GetterSetter.h:
  • kjs/InternalFunction.h:
  • kjs/JSActivation.cpp:
  • kjs/JSActivation.h:
  • kjs/JSArray.cpp:
  • kjs/JSArray.h:
  • kjs/JSCell.cpp:
  • kjs/JSCell.h:
  • kjs/JSFunction.cpp:
  • kjs/JSFunction.h:
  • kjs/JSGlobalData.h:
  • kjs/JSGlobalObject.cpp:
  • kjs/JSGlobalObject.h:
  • kjs/JSGlobalObjectFunctions.cpp:
  • kjs/JSGlobalObjectFunctions.h:
  • kjs/JSImmediate.cpp:
  • kjs/JSImmediate.h:
  • kjs/JSNotAnObject.cpp:
  • kjs/JSNotAnObject.h:
  • kjs/JSNumberCell.cpp:
  • kjs/JSNumberCell.h:
  • kjs/JSObject.cpp:
  • kjs/JSObject.h:
  • kjs/JSStaticScopeObject.cpp:
  • kjs/JSStaticScopeObject.h:
  • kjs/JSString.cpp:
  • kjs/JSString.h:
  • kjs/JSValue.h:
  • kjs/JSVariableObject.h:
  • kjs/JSWrapperObject.h:
  • kjs/MathObject.cpp:
  • kjs/NativeErrorConstructor.cpp:
  • kjs/NumberConstructor.cpp:
  • kjs/NumberConstructor.h:
  • kjs/NumberObject.cpp:
  • kjs/NumberObject.h:
  • kjs/NumberPrototype.cpp:
  • kjs/ObjectConstructor.cpp:
  • kjs/ObjectPrototype.cpp:
  • kjs/ObjectPrototype.h:
  • kjs/PropertyMap.h:
  • kjs/PropertySlot.cpp:
  • kjs/PropertySlot.h:
  • kjs/RegExpConstructor.cpp:
  • kjs/RegExpConstructor.h:
  • kjs/RegExpMatchesArray.h:
  • kjs/RegExpObject.cpp:
  • kjs/RegExpObject.h:
  • kjs/RegExpPrototype.cpp:
  • kjs/Shell.cpp:
  • kjs/StringConstructor.cpp:
  • kjs/StringObject.cpp:
  • kjs/StringObject.h:
  • kjs/StringObjectThatMasqueradesAsUndefined.h:
  • kjs/StringPrototype.cpp:
  • kjs/StructureID.cpp:
  • kjs/StructureID.h:
  • kjs/collector.cpp:
  • kjs/collector.h:
  • kjs/completion.h:
  • kjs/grammar.y:
  • kjs/interpreter.cpp:
  • kjs/interpreter.h:
  • kjs/lookup.cpp:
  • kjs/lookup.h:
  • kjs/nodes.h:
  • kjs/operations.cpp:
  • kjs/operations.h:
  • kjs/protect.h:
  • profiler/ProfileGenerator.cpp: Replace JSValue* with JSValuePtr.

JavaScriptGlue:

2008-10-18 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

Use JSValuePtr everywhere instead of JSValue*. In the future, we'll be
changing JSValuePtr to be a class, and then eventually renaming it
to JSValue once that's done.

  • JSObject.cpp:
  • JSValueWrapper.cpp:
  • UserObjectImp.cpp:
  • UserObjectImp.h: Replace JSValue* with JSValuePtr.

WebCore:

2008-10-18 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

Use JSValuePtr everywhere instead of JSValue*. In the future, we'll be
changing JSValuePtr to be a class, and then eventually renaming it
to JSValue once that's done.

  • bindings/js/JSAttrCustom.cpp:
  • bindings/js/JSCSSRuleCustom.cpp:
  • bindings/js/JSCSSStyleDeclarationCustom.cpp:
  • bindings/js/JSCSSValueCustom.cpp:
  • bindings/js/JSCanvasPixelArrayCustom.h:
  • bindings/js/JSCanvasRenderingContext2DCustom.cpp:
  • bindings/js/JSClipboardCustom.cpp:
  • bindings/js/JSConsoleCustom.cpp:
  • bindings/js/JSCustomSQLStatementCallback.cpp:
  • bindings/js/JSCustomSQLStatementErrorCallback.cpp:
  • bindings/js/JSCustomSQLTransactionCallback.cpp:
  • bindings/js/JSCustomSQLTransactionErrorCallback.cpp:
  • bindings/js/JSCustomVoidCallback.cpp:
  • bindings/js/JSCustomVoidCallback.h:
  • bindings/js/JSCustomXPathNSResolver.cpp:
  • bindings/js/JSDOMApplicationCacheCustom.cpp:
  • bindings/js/JSDOMBinding.cpp:
  • bindings/js/JSDOMBinding.h:
  • bindings/js/JSDOMWindowBase.cpp:
  • bindings/js/JSDOMWindowBase.h:
  • bindings/js/JSDOMWindowCustom.cpp:
  • bindings/js/JSDOMWindowCustom.h:
  • bindings/js/JSDOMWindowShell.cpp:
  • bindings/js/JSDOMWindowShell.h:
  • bindings/js/JSDatabaseCustom.cpp:
  • bindings/js/JSDocumentCustom.cpp:
  • bindings/js/JSElementCustom.cpp:
  • bindings/js/JSEventCustom.cpp:
  • bindings/js/JSEventListener.cpp:
  • bindings/js/JSEventTarget.cpp:
  • bindings/js/JSEventTargetBase.h:
  • bindings/js/JSEventTargetNodeCustom.cpp:
  • bindings/js/JSHTMLAllCollection.h:
  • bindings/js/JSHTMLAppletElementCustom.cpp:
  • bindings/js/JSHTMLCollectionCustom.cpp:
  • bindings/js/JSHTMLDocumentCustom.cpp:
  • bindings/js/JSHTMLEmbedElementCustom.cpp:
  • bindings/js/JSHTMLFormElementCustom.cpp:
  • bindings/js/JSHTMLFrameElementCustom.cpp:
  • bindings/js/JSHTMLFrameSetElementCustom.cpp:
  • bindings/js/JSHTMLIFrameElementCustom.cpp:
  • bindings/js/JSHTMLInputElementCustom.cpp:
  • bindings/js/JSHTMLObjectElementCustom.cpp:
  • bindings/js/JSHTMLOptionsCollectionCustom.cpp:
  • bindings/js/JSHTMLSelectElementCustom.cpp:
  • bindings/js/JSHTMLSelectElementCustom.h:
  • bindings/js/JSHistoryCustom.cpp:
  • bindings/js/JSImageDataCustom.cpp:
  • bindings/js/JSInspectedObjectWrapper.cpp:
  • bindings/js/JSInspectedObjectWrapper.h:
  • bindings/js/JSInspectorCallbackWrapper.cpp:
  • bindings/js/JSInspectorCallbackWrapper.h:
  • bindings/js/JSJavaScriptCallFrameCustom.cpp:
  • bindings/js/JSLocationCustom.cpp:
  • bindings/js/JSMessagePortCustom.cpp:
  • bindings/js/JSMimeTypeArrayCustom.cpp:
  • bindings/js/JSNamedNodeMapCustom.cpp:
  • bindings/js/JSNamedNodesCollection.cpp:
  • bindings/js/JSNamedNodesCollection.h:
  • bindings/js/JSNavigatorCustom.cpp:
  • bindings/js/JSNodeCustom.cpp:
  • bindings/js/JSNodeFilterCondition.cpp:
  • bindings/js/JSNodeFilterCustom.cpp:
  • bindings/js/JSNodeIteratorCustom.cpp:
  • bindings/js/JSNodeListCustom.cpp:
  • bindings/js/JSPluginArrayCustom.cpp:
  • bindings/js/JSPluginCustom.cpp:
  • bindings/js/JSPluginElementFunctions.cpp:
  • bindings/js/JSPluginElementFunctions.h:
  • bindings/js/JSQuarantinedObjectWrapper.cpp:
  • bindings/js/JSQuarantinedObjectWrapper.h:
  • bindings/js/JSRGBColor.cpp:
  • bindings/js/JSRGBColor.h:
  • bindings/js/JSSQLResultSetRowListCustom.cpp:
  • bindings/js/JSSQLTransactionCustom.cpp:
  • bindings/js/JSSVGElementInstanceCustom.cpp:
  • bindings/js/JSSVGLengthCustom.cpp:
  • bindings/js/JSSVGMatrixCustom.cpp:
  • bindings/js/JSSVGPathSegCustom.cpp:
  • bindings/js/JSSVGPathSegListCustom.cpp:
  • bindings/js/JSSVGPointListCustom.cpp:
  • bindings/js/JSSVGTransformListCustom.cpp:
  • bindings/js/JSStorageCustom.cpp:
  • bindings/js/JSStyleSheetCustom.cpp:
  • bindings/js/JSStyleSheetListCustom.cpp:
  • bindings/js/JSTextCustom.cpp:
  • bindings/js/JSTreeWalkerCustom.cpp:
  • bindings/js/JSXMLHttpRequestCustom.cpp:
  • bindings/js/JSXMLHttpRequestUploadCustom.cpp:
  • bindings/js/JSXSLTProcessorCustom.cpp:
  • bindings/js/ScheduledAction.cpp:
  • bindings/js/ScheduledAction.h:
  • bindings/js/ScriptController.cpp:
  • bindings/js/ScriptController.h:
  • bindings/objc/WebScriptObject.mm:
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/NP_jsobject.cpp:
  • bridge/c/c_instance.cpp:
  • bridge/c/c_instance.h:
  • bridge/c/c_runtime.cpp:
  • bridge/c/c_runtime.h:
  • bridge/c/c_utility.cpp:
  • bridge/jni/jni_instance.cpp:
  • bridge/jni/jni_instance.h:
  • bridge/jni/jni_jsobject.mm:
  • bridge/jni/jni_objc.mm:
  • bridge/jni/jni_runtime.cpp:
  • bridge/jni/jni_runtime.h:
  • bridge/jni/jni_utility.cpp:
  • bridge/objc/objc_class.mm:
  • bridge/objc/objc_instance.h:
  • bridge/objc/objc_instance.mm:
  • bridge/objc/objc_runtime.h:
  • bridge/objc/objc_runtime.mm:
  • bridge/objc/objc_utility.h:
  • bridge/objc/objc_utility.mm:
  • bridge/runtime.h:
  • bridge/runtime_array.cpp:
  • bridge/runtime_array.h:
  • bridge/runtime_method.cpp:
  • bridge/runtime_method.h:
  • bridge/runtime_object.cpp:
  • bridge/runtime_object.h:
  • inspector/JavaScriptCallFrame.cpp:
  • inspector/JavaScriptCallFrame.h:
  • inspector/JavaScriptProfile.cpp:
  • inspector/JavaScriptProfileNode.cpp:
  • loader/FrameLoader.cpp:
  • loader/FrameLoader.h:
  • page/Console.cpp:
  • page/Console.h:
  • plugins/MimeTypeArray.h:
  • plugins/Plugin.h:
  • plugins/PluginArray.h:
  • xml/XMLHttpRequest.cpp: Replace JSValue* with JSValuePtr.
  • Property svn:eol-style set to native
File size: 16.0 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 "CodeGenerator.h"
26#include "InitializeThreading.h"
27#include "JSArray.h"
28#include "JSLock.h"
29#include "PrototypeFunction.h"
30#include "SamplingTool.h"
31#include "completion.h"
32#include "interpreter.h"
33#include <math.h>
34#include <stdio.h>
35#include <string.h>
36
37#if !PLATFORM(WIN_OS)
38#include <unistd.h>
39#endif
40
41#if HAVE(READLINE)
42#include <readline/history.h>
43#include <readline/readline.h>
44#endif
45
46#if HAVE(SYS_TIME_H)
47#include <sys/time.h>
48#endif
49
50#if PLATFORM(UNIX)
51#include <signal.h>
52#endif
53
54#if COMPILER(MSVC)
55#include <crtdbg.h>
56#include <windows.h>
57#endif
58
59#if PLATFORM(QT)
60#include <QCoreApplication>
61#include <QDateTime>
62#endif
63
64using namespace JSC;
65using namespace WTF;
66
67static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer);
68
69static JSValuePtr functionPrint(ExecState*, JSObject*, JSValuePtr, const ArgList&);
70static JSValuePtr functionDebug(ExecState*, JSObject*, JSValuePtr, const ArgList&);
71static JSValuePtr functionGC(ExecState*, JSObject*, JSValuePtr, const ArgList&);
72static JSValuePtr functionVersion(ExecState*, JSObject*, JSValuePtr, const ArgList&);
73static JSValuePtr functionRun(ExecState*, JSObject*, JSValuePtr, const ArgList&);
74static JSValuePtr functionLoad(ExecState*, JSObject*, JSValuePtr, const ArgList&);
75static JSValuePtr functionReadline(ExecState*, JSObject*, JSValuePtr, const ArgList&);
76static JSValuePtr functionQuit(ExecState*, JSObject*, JSValuePtr, const ArgList&);
77
78struct Options {
79 Options()
80 : interactive(false)
81 , prettyPrint(false)
82 , dump(false)
83 {
84 }
85
86 bool interactive;
87 bool prettyPrint;
88 bool dump;
89 Vector<UString> fileNames;
90 Vector<UString> arguments;
91};
92
93static const char interactivePrompt[] = "> ";
94static const UString interpreterName("Interpreter");
95
96class StopWatch {
97public:
98 void start();
99 void stop();
100 long getElapsedMS(); // call stop() first
101
102private:
103#if PLATFORM(QT)
104 uint m_startTime;
105 uint m_stopTime;
106#elif PLATFORM(WIN_OS)
107 DWORD m_startTime;
108 DWORD m_stopTime;
109#else
110 // Windows does not have timeval, disabling this class for now (bug 7399)
111 timeval m_startTime;
112 timeval m_stopTime;
113#endif
114};
115
116void StopWatch::start()
117{
118#if PLATFORM(QT)
119 QDateTime t = QDateTime::currentDateTime();
120 m_startTime = t.toTime_t() * 1000 + t.time().msec();
121#elif PLATFORM(WIN_OS)
122 m_startTime = timeGetTime();
123#else
124 gettimeofday(&m_startTime, 0);
125#endif
126}
127
128void StopWatch::stop()
129{
130#if PLATFORM(QT)
131 QDateTime t = QDateTime::currentDateTime();
132 m_stopTime = t.toTime_t() * 1000 + t.time().msec();
133#elif PLATFORM(WIN_OS)
134 m_stopTime = timeGetTime();
135#else
136 gettimeofday(&m_stopTime, 0);
137#endif
138}
139
140long StopWatch::getElapsedMS()
141{
142#if PLATFORM(WIN_OS) || PLATFORM(QT)
143 return m_stopTime - m_startTime;
144#else
145 timeval elapsedTime;
146 timersub(&m_stopTime, &m_startTime, &elapsedTime);
147
148 return elapsedTime.tv_sec * 1000 + lroundf(elapsedTime.tv_usec / 1000.0f);
149#endif
150}
151
152class GlobalObject : public JSGlobalObject {
153public:
154 GlobalObject(JSGlobalData*, const Vector<UString>& arguments);
155 virtual UString className() const { return "global"; }
156};
157COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false);
158ASSERT_CLASS_FITS_IN_CELL(GlobalObject);
159
160GlobalObject::GlobalObject(JSGlobalData* globalData, const Vector<UString>& arguments)
161 : JSGlobalObject(globalData)
162{
163 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "debug"), functionDebug));
164 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "print"), functionPrint));
165 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "quit"), functionQuit));
166 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "gc"), functionGC));
167 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "version"), functionVersion));
168 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "run"), functionRun));
169 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "load"), functionLoad));
170 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "readline"), functionReadline));
171
172 JSObject* array = constructEmptyArray(globalExec());
173 for (size_t i = 0; i < arguments.size(); ++i)
174 array->put(globalExec(), i, jsString(globalExec(), arguments[i]));
175 putDirect(Identifier(globalExec(), "arguments"), array);
176
177 Interpreter::setShouldPrintExceptions(true);
178}
179
180JSValuePtr functionPrint(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
181{
182 for (unsigned i = 0; i < args.size(); ++i) {
183 if (i != 0)
184 putchar(' ');
185
186 printf("%s", args.at(exec, i)->toString(exec).UTF8String().c_str());
187 }
188
189 putchar('\n');
190 fflush(stdout);
191 return jsUndefined();
192}
193
194JSValuePtr functionDebug(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
195{
196 fprintf(stderr, "--> %s\n", args.at(exec, 0)->toString(exec).UTF8String().c_str());
197 return jsUndefined();
198}
199
200JSValuePtr functionGC(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
201{
202 JSLock lock(false);
203 exec->heap()->collect();
204 return jsUndefined();
205}
206
207JSValuePtr functionVersion(ExecState*, JSObject*, JSValuePtr, const ArgList&)
208{
209 // We need this function for compatibility with the Mozilla JS tests but for now
210 // we don't actually do any version-specific handling
211 return jsUndefined();
212}
213
214JSValuePtr functionRun(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
215{
216 StopWatch stopWatch;
217 UString fileName = args.at(exec, 0)->toString(exec);
218 Vector<char> script;
219 if (!fillBufferWithContentsOfFile(fileName, script))
220 return throwError(exec, GeneralError, "Could not open file.");
221
222 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
223
224 stopWatch.start();
225 Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
226 stopWatch.stop();
227
228 return jsNumber(globalObject->globalExec(), stopWatch.getElapsedMS());
229}
230
231JSValuePtr functionLoad(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
232{
233 UString fileName = args.at(exec, 0)->toString(exec);
234 Vector<char> script;
235 if (!fillBufferWithContentsOfFile(fileName, script))
236 return throwError(exec, GeneralError, "Could not open file.");
237
238 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
239 Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
240
241 return jsUndefined();
242}
243
244JSValuePtr functionReadline(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
245{
246 Vector<char, 256> line;
247 int c;
248 while ((c = getchar()) != EOF) {
249 // FIXME: Should we also break on \r?
250 if (c == '\n')
251 break;
252 line.append(c);
253 }
254 line.append('\0');
255 return jsString(exec, line.data());
256}
257
258JSValuePtr functionQuit(ExecState*, JSObject*, JSValuePtr, const ArgList&)
259{
260 exit(0);
261#if !COMPILER(MSVC)
262 // MSVC knows that exit(0) never returns, so it flags this return statement as unreachable.
263 return jsUndefined();
264#endif
265}
266
267// Use SEH for Release builds only to get rid of the crash report dialog
268// (luckily the same tests fail in Release and Debug builds so far). Need to
269// be in a separate main function because the jscmain function requires object
270// unwinding.
271
272#if COMPILER(MSVC) && !defined(_DEBUG)
273#define TRY __try {
274#define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; }
275#else
276#define TRY
277#define EXCEPT(x)
278#endif
279
280int jscmain(int argc, char** argv, JSGlobalData*);
281
282int main(int argc, char** argv)
283{
284#if defined(_DEBUG) && PLATFORM(WIN_OS)
285 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
286 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
287 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
288 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
289 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
290 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
291#endif
292
293#if PLATFORM(QT)
294 QCoreApplication app(argc, argv);
295#endif
296
297 int res = 0;
298 TRY
299 res = jscmain(argc, argv, JSGlobalData::create().releaseRef());
300 EXCEPT(res = 3)
301 return res;
302}
303
304static bool prettyPrintScript(ExecState* exec, const UString& fileName, const Vector<char>& script)
305{
306 int errLine = 0;
307 UString errMsg;
308 RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), makeSource(script.data(), fileName), &errLine, &errMsg);
309 if (!programNode) {
310 fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
311 return false;
312 }
313
314 printf("%s\n", programNode->toString().UTF8String().c_str());
315 return true;
316}
317
318static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fileNames, bool prettyPrint, bool dump)
319{
320 Vector<char> script;
321
322 if (dump)
323 CodeGenerator::setDumpsGeneratedCode(true);
324
325#if ENABLE(SAMPLING_TOOL)
326 Machine* machine = globalObject->globalData()->machine;
327 machine->m_sampler = new SamplingTool();
328 machine->m_sampler->start();
329#endif
330
331 bool success = true;
332 for (size_t i = 0; i < fileNames.size(); i++) {
333 UString fileName = fileNames[i];
334
335 if (!fillBufferWithContentsOfFile(fileName, script))
336 return false; // fail early so we can catch missing files
337
338 if (prettyPrint)
339 prettyPrintScript(globalObject->globalExec(), fileName, script);
340 else {
341 Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
342 success = success && completion.complType() != Throw;
343 if (dump) {
344 if (completion.complType() == Throw)
345 printf("Exception: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
346 else
347 printf("End: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
348 }
349
350 globalObject->globalExec()->clearException();
351 }
352 }
353
354#if ENABLE(SAMPLING_TOOL)
355 machine->m_sampler->stop();
356 machine->m_sampler->dump(globalObject->globalExec());
357 delete machine->m_sampler;
358#endif
359 return success;
360}
361
362static void runInteractive(GlobalObject* globalObject)
363{
364 while (true) {
365#if HAVE(READLINE)
366 char* line = readline(interactivePrompt);
367 if (!line)
368 break;
369 if (line[0])
370 add_history(line);
371 Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line, interpreterName));
372 free(line);
373#else
374 puts(interactivePrompt);
375 Vector<char, 256> line;
376 int c;
377 while ((c = getchar()) != EOF) {
378 // FIXME: Should we also break on \r?
379 if (c == '\n')
380 break;
381 line.append(c);
382 }
383 line.append('\0');
384 Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line.data(), interpreterName));
385#endif
386 if (completion.complType() == Throw)
387 printf("Exception: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
388 else
389 printf("%s\n", completion.value()->toString(globalObject->globalExec()).UTF8String().c_str());
390
391 globalObject->globalExec()->clearException();
392 }
393 printf("\n");
394}
395
396static void printUsageStatement()
397{
398 fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n");
399 fprintf(stderr, " -d Dumps bytecode (debug builds only)\n");
400 fprintf(stderr, " -f Specifies a source file (deprecated)\n");
401 fprintf(stderr, " -h|--help Prints this help message\n");
402 fprintf(stderr, " -i Enables interactive mode (default if no files are specified)\n");
403 fprintf(stderr, " -p Prints formatted source code\n");
404 fprintf(stderr, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n");
405 exit(-1);
406}
407
408static void parseArguments(int argc, char** argv, Options& options)
409{
410 int i = 1;
411 for (; i < argc; ++i) {
412 const char* arg = argv[i];
413 if (strcmp(arg, "-f") == 0) {
414 if (++i == argc)
415 printUsageStatement();
416 options.fileNames.append(argv[i]);
417 continue;
418 }
419 if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
420 printUsageStatement();
421 }
422 if (strcmp(arg, "-i") == 0) {
423 options.interactive = true;
424 continue;
425 }
426 if (strcmp(arg, "-p") == 0) {
427 options.prettyPrint = true;
428 continue;
429 }
430 if (strcmp(arg, "-d") == 0) {
431 options.dump = true;
432 continue;
433 }
434 if (strcmp(arg, "-s") == 0) {
435#if PLATFORM(UNIX)
436 signal(SIGILL, _exit);
437 signal(SIGFPE, _exit);
438 signal(SIGBUS, _exit);
439 signal(SIGSEGV, _exit);
440#endif
441 continue;
442 }
443 if (strcmp(arg, "--") == 0) {
444 ++i;
445 break;
446 }
447 options.fileNames.append(argv[i]);
448 }
449
450 if (options.fileNames.isEmpty())
451 options.interactive = true;
452
453 for (; i < argc; ++i)
454 options.arguments.append(argv[i]);
455}
456
457int jscmain(int argc, char** argv, JSGlobalData* globalData)
458{
459 JSC::initializeThreading();
460
461 JSLock lock(false);
462
463 Options options;
464 parseArguments(argc, argv, options);
465
466 GlobalObject* globalObject = new (globalData) GlobalObject(globalData, options.arguments);
467 bool success = runWithScripts(globalObject, options.fileNames, options.prettyPrint, options.dump);
468 if (options.interactive && success)
469 runInteractive(globalObject);
470
471 return success ? 0 : 3;
472}
473
474static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer)
475{
476 FILE* f = fopen(fileName.UTF8String().c_str(), "r");
477 if (!f) {
478 fprintf(stderr, "Could not open file: %s\n", fileName.UTF8String().c_str());
479 return false;
480 }
481
482 size_t buffer_size = 0;
483 size_t buffer_capacity = 1024;
484
485 buffer.resize(buffer_capacity);
486
487 while (!feof(f) && !ferror(f)) {
488 buffer_size += fread(buffer.data() + buffer_size, 1, buffer_capacity - buffer_size, f);
489 if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
490 buffer_capacity *= 2;
491 buffer.resize(buffer_capacity);
492 }
493 }
494 fclose(f);
495 buffer[buffer_size] = '\0';
496
497 return true;
498}
Note: See TracBrowser for help on using the repository browser.