18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Library General Public
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Library General Public License for more details.
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Library General Public License
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  along with this library; see the file COPYING.LIB.  If not, write to
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Boston, MA 02110-1301, USA.
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "BytecodeGenerator.h"
26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Completion.h"
27231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "CurrentTime.h"
28545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "ExceptionHelpers.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "InitializeThreading.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSArray.h"
315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "JSFunction.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSLock.h"
33cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "JSString.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SamplingTool.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <math.h>
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdio.h>
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <stdlib.h>
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <string.h>
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !OS(WINDOWS)
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <unistd.h>
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if HAVE(READLINE)
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <readline/history.h>
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <readline/readline.h>
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if HAVE(SYS_TIME_H)
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <sys/time.h>
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if HAVE(SIGNAL_H)
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <signal.h>
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
57d0825bca7fe65beaee391d30da42e937db621564Steve Block#if COMPILER(MSVC) && !OS(WINCE)
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <crtdbg.h>
598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <mmsystem.h>
60d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <windows.h>
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(QT)
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <QCoreApplication>
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <QDateTime>
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace JSC;
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF;
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
71635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void cleanupGlobalData(JSGlobalData*);
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer);
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
74545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL functionPrint(ExecState*);
75545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*);
76545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL functionGC(ExecState*);
77545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*);
78545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL functionRun(ExecState*);
79545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL functionLoad(ExecState*);
80545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState*);
81545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL functionReadline(ExecState*);
82545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic NO_RETURN_WITH_VALUE EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*);
835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(SAMPLING_FLAGS)
85545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
86545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState*);
875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstruct Script {
908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool isFile;
91d0825bca7fe65beaee391d30da42e937db621564Steve Block    char* argument;
92d0825bca7fe65beaee391d30da42e937db621564Steve Block
938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Script(bool isFile, char *argument)
948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        : isFile(isFile)
958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        , argument(argument)
968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian};
998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct Options {
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Options()
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        : interactive(false)
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        , dump(false)
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool interactive;
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool dump;
1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Vector<Script> scripts;
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<UString> arguments;
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const char interactivePrompt[] = "> ";
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const UString interpreterName("Interpreter");
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectclass StopWatch {
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic:
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void start();
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void stop();
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long getElapsedMS(); // call stop() first
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectprivate:
123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    double m_startTime;
124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    double m_stopTime;
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid StopWatch::start()
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_startTime = currentTime();
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid StopWatch::stop()
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_stopTime = currentTime();
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectlong StopWatch::getElapsedMS()
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
139231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return static_cast<long>((m_stopTime - m_startTime) * 1000);
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectclass GlobalObject : public JSGlobalObject {
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic:
1442bde8e466a4451c7319e3a072d118917957d6554Steve Block    GlobalObject(JSGlobalData&, const Vector<UString>& arguments);
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    virtual UString className() const { return "global"; }
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCOMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false);
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectASSERT_CLASS_FITS_IN_CELL(GlobalObject);
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1502bde8e466a4451c7319e3a072d118917957d6554Steve BlockGlobalObject::GlobalObject(JSGlobalData& globalData, const Vector<UString>& arguments)
1512bde8e466a4451c7319e3a072d118917957d6554Steve Block    : JSGlobalObject(globalData)
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "debug"), functionDebug));
15481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "print"), functionPrint));
15581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "quit"), functionQuit));
15681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "gc"), functionGC));
15781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "version"), functionVersion));
15881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "run"), functionRun));
15981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "load"), functionLoad));
16081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "checkSyntax"), functionCheckSyntax));
16181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "readline"), functionReadline));
1625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(SAMPLING_FLAGS)
16481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "setSamplingFlags"), functionSetSamplingFlags));
16581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    putDirectFunction(globalExec(), new (globalExec()) JSFunction(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "clearSamplingFlags"), functionClearSamplingFlags));
1665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObject* array = constructEmptyArray(globalExec());
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < arguments.size(); ++i)
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        array->put(globalExec(), i, jsString(globalExec(), arguments[i]));
1712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    putDirect(globalExec()->globalData(), Identifier(globalExec(), "arguments"), array);
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
174545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    for (unsigned i = 0; i < exec->argumentCount(); ++i) {
177d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (i)
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            putchar(' ');
179d0825bca7fe65beaee391d30da42e937db621564Steve Block
180f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        printf("%s", exec->argument(i).toString(exec).utf8().data());
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
182d0825bca7fe65beaee391d30da42e937db621564Steve Block
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    putchar('\n');
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fflush(stdout);
185545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsUndefined());
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
188545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec)
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
190f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec).utf8().data());
191545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsUndefined());
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
194545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionGC(ExecState* exec)
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
197d0825bca7fe65beaee391d30da42e937db621564Steve Block    exec->heap()->collectAllGarbage();
198545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsUndefined());
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
201545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionVersion(ExecState*)
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need this function for compatibility with the Mozilla JS tests but for now
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we don't actually do any version-specific handling
205545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsUndefined());
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
208545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec)
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    UString fileName = exec->argument(0).toString(exec);
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<char> script;
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!fillBufferWithContentsOfFile(fileName, script))
213545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2152bde8e466a4451c7319e3a072d118917957d6554Steve Block    GlobalObject* globalObject = new (&exec->globalData()) GlobalObject(exec->globalData(), Vector<UString>());
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
217f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    StopWatch stopWatch;
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    stopWatch.start();
219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    stopWatch.stop();
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
222e14391e94c850b8bd03680c23b38978db68687a8John Reck    return JSValue::encode(jsNumber(stopWatch.getElapsedMS()));
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
225545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionLoad(ExecState* exec)
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2275af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    UString fileName = exec->argument(0).toString(exec);
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<char> script;
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!fillBufferWithContentsOfFile(fileName, script))
230545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
2338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Completion result = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (result.complType() == Throw)
235545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        throwError(exec, result.value());
236545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(result.value());
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
239545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState* exec)
2400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    UString fileName = exec->argument(0).toString(exec);
2420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Vector<char> script;
2430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!fillBufferWithContentsOfFile(fileName, script))
244545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
2450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
247f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
248f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    StopWatch stopWatch;
249f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    stopWatch.start();
2500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Completion result = checkSyntax(globalObject->globalExec(), makeSource(script.data(), fileName));
251f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    stopWatch.stop();
252f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (result.complType() == Throw)
254545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        throwError(exec, result.value());
255f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return JSValue::encode(jsNumber(stopWatch.getElapsedMS()));
2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(SAMPLING_FLAGS)
259545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState* exec)
2605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
2615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    for (unsigned i = 0; i < exec->argumentCount(); ++i) {
2625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        unsigned flag = static_cast<unsigned>(exec->argument(i).toNumber(exec));
2635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if ((flag >= 1) && (flag <= 32))
2645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            SamplingFlags::setFlag(flag);
2655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
266545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsNull());
2675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
2685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
269545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState* exec)
2705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
2715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    for (unsigned i = 0; i < exec->argumentCount(); ++i) {
2725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        unsigned flag = static_cast<unsigned>(exec->argument(i).toNumber(exec));
2735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if ((flag >= 1) && (flag <= 32))
2745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            SamplingFlags::clearFlag(flag);
2755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
276545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsNull());
2775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
2785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
2795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
280545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionReadline(ExecState* exec)
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<char, 256> line;
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int c;
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while ((c = getchar()) != EOF) {
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Should we also break on \r?
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (c == '\n')
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        line.append(c);
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    line.append('\0');
291545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsString(exec, line.data()));
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
294545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSC_HOST_CALL functionQuit(ExecState* exec)
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
296d0825bca7fe65beaee391d30da42e937db621564Steve Block    // Technically, destroying the heap in the middle of JS execution is a no-no,
297d0825bca7fe65beaee391d30da42e937db621564Steve Block    // but we want to maintain compatibility with the Mozilla test suite, so
298d0825bca7fe65beaee391d30da42e937db621564Steve Block    // we pretend that execution has terminated to avoid ASSERTs, then tear down the heap.
299d0825bca7fe65beaee391d30da42e937db621564Steve Block    exec->globalData().dynamicGlobalObject = 0;
300d0825bca7fe65beaee391d30da42e937db621564Steve Block
301635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    cleanupGlobalData(&exec->globalData());
302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    exit(EXIT_SUCCESS);
303d0825bca7fe65beaee391d30da42e937db621564Steve Block
304d0825bca7fe65beaee391d30da42e937db621564Steve Block#if COMPILER(MSVC) && OS(WINCE)
305d0825bca7fe65beaee391d30da42e937db621564Steve Block    // Without this, Visual Studio will complain that this method does not return a value.
306545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(jsUndefined());
307d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Use SEH for Release builds only to get rid of the crash report dialog
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// (luckily the same tests fail in Release and Debug builds so far). Need to
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// be in a separate main function because the jscmain function requires object
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// unwinding.
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3150617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#if COMPILER(MSVC) && !defined(_DEBUG) && !OS(WINCE)
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define TRY       __try {
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; }
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define TRY
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define EXCEPT(x)
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint jscmain(int argc, char** argv, JSGlobalData*);
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint main(int argc, char** argv)
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
32781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if OS(WINDOWS)
32881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if !OS(WINCE)
32981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
33081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
33181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
33281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ::SetErrorMode(0);
33381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif
33481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
33581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if defined(_DEBUG)
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    timeBeginPeriod(1);
3458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
3468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(QT)
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QCoreApplication app(argc, argv);
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
351635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Initialize JSC before getting JSGlobalData.
352635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    JSC::initializeThreading();
353635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
354635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // We can't use destructors in the following code because it uses Windows
355635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Structured Exception Handling
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int res = 0;
35728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    JSGlobalData* globalData = JSGlobalData::create(ThreadStackTypeLarge).leakRef();
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TRY
359635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        res = jscmain(argc, argv, globalData);
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    EXCEPT(res = 3)
361635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
362635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    cleanupGlobalData(globalData);
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return res;
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
366635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void cleanupGlobalData(JSGlobalData* globalData)
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
3692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    globalData->clearBuiltinStructures();
370635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    globalData->heap.destroy();
371635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    globalData->deref();
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scripts, bool dump)
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UString script;
3778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UString fileName;
3788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Vector<char> scriptBuffer;
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (dump)
381635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        BytecodeGenerator::setDumpsGeneratedCode(true);
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
383e14391e94c850b8bd03680c23b38978db68687a8John Reck    JSGlobalData& globalData = globalObject->globalData();
384231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(SAMPLING_FLAGS)
3865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SamplingFlags::start();
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool success = true;
3908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (size_t i = 0; i < scripts.size(); i++) {
3918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (scripts[i].isFile) {
3928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            fileName = scripts[i].argument;
3938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!fillBufferWithContentsOfFile(fileName, scriptBuffer))
3948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return false; // fail early so we can catch missing files
3958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            script = scriptBuffer.data();
3968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
3978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            script = scripts[i].argument;
3988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            fileName = "[Command Line]";
3998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
401e14391e94c850b8bd03680c23b38978db68687a8John Reck        globalData.startSampling();
4025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script, fileName));
404635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        success = success && completion.complType() != Throw;
405635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (dump) {
406635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (completion.complType() == Throw)
407f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                printf("Exception: %s\n", completion.value().toString(globalObject->globalExec()).utf8().data());
408635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            else
409f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                printf("End: %s\n", completion.value().toString(globalObject->globalExec()).utf8().data());
410635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
412e14391e94c850b8bd03680c23b38978db68687a8John Reck        globalData.stopSampling();
4135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        globalObject->globalExec()->clearException();
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(SAMPLING_FLAGS)
4175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SamplingFlags::stop();
4185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
419e14391e94c850b8bd03680c23b38978db68687a8John Reck    globalData.dumpSampleData(globalObject->globalExec());
4205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(SAMPLING_COUNTERS)
4215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    AbstractSamplingCounter::dump();
4225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
4235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#if ENABLE(REGEXP_TRACING)
424e14391e94c850b8bd03680c23b38978db68687a8John Reck    globalData.dumpRegExpTrace();
4255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return success;
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#define RUNNING_FROM_XCODE 0
4300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void runInteractive(GlobalObject* globalObject)
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (true) {
4340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if HAVE(READLINE) && !RUNNING_FROM_XCODE
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char* line = readline(interactivePrompt);
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!line)
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (line[0])
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            add_history(line);
440635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line, interpreterName));
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        free(line);
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
4430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        printf("%s", interactivePrompt);
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Vector<char, 256> line;
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int c;
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while ((c = getchar()) != EOF) {
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // FIXME: Should we also break on \r?
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (c == '\n')
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            line.append(c);
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (line.isEmpty())
4530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            break;
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        line.append('\0');
455635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line.data(), interpreterName));
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (completion.complType() == Throw)
458f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            printf("Exception: %s\n", completion.value().toString(globalObject->globalExec()).utf8().data());
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
460f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            printf("%s\n", completion.value().toString(globalObject->globalExec()).utf8().data());
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        globalObject->globalExec()->clearException();
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    printf("\n");
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic NO_RETURN void printUsageStatement(JSGlobalData* globalData, bool help = false)
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n");
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fprintf(stderr, "  -d         Dumps bytecode (debug builds only)\n");
4718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    fprintf(stderr, "  -e         Evaluate argument as script code\n");
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fprintf(stderr, "  -f         Specifies a source file (deprecated)\n");
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fprintf(stderr, "  -h|--help  Prints this help message\n");
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fprintf(stderr, "  -i         Enables interactive mode (default if no files are specified)\n");
4750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if HAVE(SIGNAL_H)
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fprintf(stderr, "  -s         Installs signal handlers that exit on a crash (Unix platforms only)\n");
4770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
4785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    cleanupGlobalData(globalData);
4808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic void parseArguments(int argc, char** argv, Options& options, JSGlobalData* globalData)
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int i = 1;
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (; i < argc; ++i) {
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const char* arg = argv[i];
488d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!strcmp(arg, "-f")) {
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (++i == argc)
4905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                printUsageStatement(globalData);
4918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            options.scripts.append(Script(true, argv[i]));
4928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            continue;
4938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
494d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!strcmp(arg, "-e")) {
4958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (++i == argc)
4965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                printUsageStatement(globalData);
4978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            options.scripts.append(Script(false, argv[i]));
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
500d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!strcmp(arg, "-i")) {
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            options.interactive = true;
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
504d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!strcmp(arg, "-d")) {
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            options.dump = true;
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
508d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!strcmp(arg, "-s")) {
5090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if HAVE(SIGNAL_H)
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            signal(SIGILL, _exit);
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            signal(SIGFPE, _exit);
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            signal(SIGBUS, _exit);
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            signal(SIGSEGV, _exit);
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
517d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!strcmp(arg, "--")) {
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ++i;
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
521d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
522d0825bca7fe65beaee391d30da42e937db621564Steve Block            printUsageStatement(globalData, true);
5238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        options.scripts.append(Script(true, argv[i]));
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
525d0825bca7fe65beaee391d30da42e937db621564Steve Block
5268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (options.scripts.isEmpty())
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        options.interactive = true;
528d0825bca7fe65beaee391d30da42e937db621564Steve Block
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (; i < argc; ++i)
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        options.arguments.append(argv[i]);
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint jscmain(int argc, char** argv, JSGlobalData* globalData)
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Options options;
5385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    parseArguments(argc, argv, options, globalData);
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5402bde8e466a4451c7319e3a072d118917957d6554Steve Block    GlobalObject* globalObject = new (globalData) GlobalObject(*globalData, options.arguments);
5418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool success = runWithScripts(globalObject, options.scripts, options.dump);
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (options.interactive && success)
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        runInteractive(globalObject);
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return success ? 0 : 3;
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer)
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
550f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    FILE* f = fopen(fileName.utf8().data(), "r");
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!f) {
552f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data());
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
556d0825bca7fe65beaee391d30da42e937db621564Steve Block    size_t bufferSize = 0;
557d0825bca7fe65beaee391d30da42e937db621564Steve Block    size_t bufferCapacity = 1024;
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
559d0825bca7fe65beaee391d30da42e937db621564Steve Block    buffer.resize(bufferCapacity);
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (!feof(f) && !ferror(f)) {
562d0825bca7fe65beaee391d30da42e937db621564Steve Block        bufferSize += fread(buffer.data() + bufferSize, 1, bufferCapacity - bufferSize, f);
563d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (bufferSize == bufferCapacity) { // guarantees space for trailing '\0'
564d0825bca7fe65beaee391d30da42e937db621564Steve Block            bufferCapacity *= 2;
565d0825bca7fe65beaee391d30da42e937db621564Steve Block            buffer.resize(bufferCapacity);
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fclose(f);
569d0825bca7fe65beaee391d30da42e937db621564Steve Block    buffer[bufferSize] = '\0';
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
571f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (buffer[0] == '#' && buffer[1] == '!')
572f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        buffer[0] = buffer[1] = '/';
573f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
576