2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2012, 2013 Apple Inc. All rights reserved.
4 * Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com)
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.
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.
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.
25 #include "ArrayPrototype.h"
26 #include "ButterflyInlines.h"
27 #include "BytecodeGenerator.h"
28 #include "CodeBlock.h"
29 #include "Completion.h"
30 #include "CopiedSpaceInlines.h"
31 #include "ExceptionHelpers.h"
32 #include "HeapStatistics.h"
33 #include "InitializeThreading.h"
34 #include "Interpreter.h"
36 #include "JSArrayBuffer.h"
37 #include "JSCInlines.h"
38 #include "JSFunction.h"
42 #include "ProfilerDatabase.h"
43 #include "SamplingTool.h"
44 #include "StackVisitor.h"
45 #include "StructureInlines.h"
46 #include "StructureRareDataInlines.h"
47 #include "TestRunnerUtils.h"
53 #include <wtf/CurrentTime.h>
54 #include <wtf/MainThread.h>
55 #include <wtf/StringPrintStream.h>
56 #include <wtf/text/StringBuilder.h>
63 // readline/history.h has a Function typedef which conflicts with the WTF::Function template from WTF/Forward.h
64 // We #define it to something else to avoid this conflict.
65 #define Function ReadlineFunction
66 #include <readline/history.h>
67 #include <readline/readline.h>
79 #if COMPILER(MSVC) && !OS(WINCE)
85 #if PLATFORM(IOS) && CPU(ARM_THUMB2)
98 extern const struct HashTable globalObjectTable;
103 NO_RETURN_WITH_VALUE static void jscExit(int status)
106 if (DFG::isCrashing()) {
115 #endif // ENABLE(DFG_JIT)
120 class ElementHandleOwner;
125 class Element : public JSNonFinalObject {
127 Element(VM& vm, Structure* structure, Root* root)
128 : Base(vm, structure)
133 typedef JSNonFinalObject Base;
134 static const bool needsDestruction = false;
136 Root* root() const { return m_root; }
137 void setRoot(Root* root) { m_root = root; }
139 static Element* create(VM& vm, JSGlobalObject* globalObject, Root* root)
141 Structure* structure = createStructure(vm, globalObject, jsNull());
142 Element* element = new (NotNull, allocateCell<Element>(vm.heap, sizeof(Element))) Element(vm, structure, root);
143 element->finishCreation(vm);
147 void finishCreation(VM&);
149 static ElementHandleOwner* handleOwner();
151 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
153 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
162 class ElementHandleOwner : public WeakHandleOwner {
164 virtual bool isReachableFromOpaqueRoots(Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
166 Element* element = jsCast<Element*>(handle.slot()->asCell());
167 return visitor.containsOpaqueRoot(element->root());
171 class Masquerader : public JSNonFinalObject {
173 Masquerader(VM& vm, Structure* structure)
174 : Base(vm, structure)
178 typedef JSNonFinalObject Base;
180 static Masquerader* create(VM& vm, JSGlobalObject* globalObject)
182 globalObject->masqueradesAsUndefinedWatchpoint()->fireAll();
183 Structure* structure = createStructure(vm, globalObject, jsNull());
184 Masquerader* result = new (NotNull, allocateCell<Masquerader>(vm.heap, sizeof(Masquerader))) Masquerader(vm, structure);
185 result->finishCreation(vm);
189 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
191 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
197 static const unsigned StructureFlags = JSC::MasqueradesAsUndefined | Base::StructureFlags;
200 class Root : public JSDestructibleObject {
202 Root(VM& vm, Structure* structure)
203 : Base(vm, structure)
209 return m_element.get();
212 void setElement(Element* element)
214 Weak<Element> newElement(element, Element::handleOwner());
215 m_element.swap(newElement);
218 static Root* create(VM& vm, JSGlobalObject* globalObject)
220 Structure* structure = createStructure(vm, globalObject, jsNull());
221 Root* root = new (NotNull, allocateCell<Root>(vm.heap, sizeof(Root))) Root(vm, structure);
222 root->finishCreation(vm);
226 typedef JSDestructibleObject Base;
229 static const bool needsDestruction = true;
231 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
233 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
236 static void visitChildren(JSCell* thisObject, SlotVisitor& visitor)
238 Base::visitChildren(thisObject, visitor);
239 visitor.addOpaqueRoot(thisObject);
243 Weak<Element> m_element;
246 class ImpureGetter : public JSNonFinalObject {
248 ImpureGetter(VM& vm, Structure* structure)
249 : Base(vm, structure)
254 typedef JSNonFinalObject Base;
256 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
258 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
261 static ImpureGetter* create(VM& vm, Structure* structure, JSObject* delegate)
263 ImpureGetter* getter = new (NotNull, allocateCell<ImpureGetter>(vm.heap, sizeof(ImpureGetter))) ImpureGetter(vm, structure);
264 getter->finishCreation(vm, delegate);
268 void finishCreation(VM& vm, JSObject* delegate)
270 Base::finishCreation(vm);
272 m_delegate.set(vm, this, delegate);
275 static const unsigned StructureFlags = JSC::HasImpureGetOwnPropertySlot | JSC::OverridesGetOwnPropertySlot | JSC::OverridesVisitChildren | Base::StructureFlags;
277 static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName name, PropertySlot& slot)
279 ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);
281 if (thisObject->m_delegate && thisObject->m_delegate->getPropertySlot(exec, name, slot))
284 return Base::getOwnPropertySlot(object, exec, name, slot);
287 static void visitChildren(JSCell* cell, SlotVisitor& visitor)
289 Base::visitChildren(cell, visitor);
290 ImpureGetter* thisObject = jsCast<ImpureGetter*>(cell);
291 visitor.append(&thisObject->m_delegate);
294 void setDelegate(VM& vm, JSObject* delegate)
296 m_delegate.set(vm, this, delegate);
300 WriteBarrier<JSObject> m_delegate;
303 class RuntimeArray : public JSArray {
305 typedef JSArray Base;
307 static RuntimeArray* create(ExecState* exec)
310 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
311 Structure* structure = createStructure(vm, globalObject, createPrototype(vm, globalObject));
312 RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(*exec->heap())) RuntimeArray(exec, structure);
313 runtimeArray->finishCreation(exec);
314 vm.heap.addFinalizer(runtimeArray, destroy);
320 static void destroy(JSCell* cell)
322 static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();
325 static const bool needsDestruction = false;
327 static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
329 RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
330 if (propertyName == exec->propertyNames().length) {
331 slot.setCacheableCustom(thisObject, DontDelete | ReadOnly | DontEnum, thisObject->lengthGetter);
335 unsigned index = propertyName.asIndex();
336 if (index < thisObject->getLength()) {
337 ASSERT(index != PropertyName::NotAnIndex);
338 slot.setValue(thisObject, DontDelete | DontEnum, jsNumber(thisObject->m_vector[index]));
342 return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
345 static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)
347 RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
348 if (index < thisObject->getLength()) {
349 slot.setValue(thisObject, DontDelete | DontEnum, jsNumber(thisObject->m_vector[index]));
353 return JSObject::getOwnPropertySlotByIndex(thisObject, exec, index, slot);
356 static NO_RETURN_DUE_TO_CRASH void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&)
358 RELEASE_ASSERT_NOT_REACHED();
361 static NO_RETURN_DUE_TO_CRASH bool deleteProperty(JSCell*, ExecState*, PropertyName)
363 RELEASE_ASSERT_NOT_REACHED();
364 #if !COMPILER(CLANG) && !COMPILER(MSVC)
369 unsigned getLength() const { return m_vector.size(); }
373 static ArrayPrototype* createPrototype(VM&, JSGlobalObject* globalObject)
375 return globalObject->arrayPrototype();
378 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
380 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayClass);
384 void finishCreation(ExecState* exec)
386 Base::finishCreation(exec->vm());
387 ASSERT(inherits(info()));
389 for (size_t i = 0; i < exec->argumentCount(); i++)
390 m_vector.append(exec->argument(i).toInt32(exec));
393 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSArray::StructureFlags;
396 RuntimeArray(ExecState* exec, Structure* structure)
397 : JSArray(exec->vm(), structure, 0)
401 static EncodedJSValue lengthGetter(ExecState* exec, JSObject*, EncodedJSValue thisValue, PropertyName)
403 RuntimeArray* thisObject = jsDynamicCast<RuntimeArray*>(JSValue::decode(thisValue));
405 return throwVMTypeError(exec);
406 return JSValue::encode(jsNumber(thisObject->getLength()));
409 Vector<int> m_vector;
412 const ClassInfo Element::s_info = { "Element", &Base::s_info, 0, CREATE_METHOD_TABLE(Element) };
413 const ClassInfo Masquerader::s_info = { "Masquerader", &Base::s_info, 0, CREATE_METHOD_TABLE(Masquerader) };
414 const ClassInfo Root::s_info = { "Root", &Base::s_info, 0, CREATE_METHOD_TABLE(Root) };
415 const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, 0, CREATE_METHOD_TABLE(ImpureGetter) };
416 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, 0, CREATE_METHOD_TABLE(RuntimeArray) };
418 ElementHandleOwner* Element::handleOwner()
420 static ElementHandleOwner* owner = 0;
422 owner = new ElementHandleOwner();
426 void Element::finishCreation(VM& vm)
428 Base::finishCreation(vm);
429 m_root->setElement(this);
434 static bool fillBufferWithContentsOfFile(const String& fileName, Vector<char>& buffer);
436 static EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState*);
437 static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState*);
438 static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState*);
439 static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState*);
441 static EncodedJSValue JSC_HOST_CALL functionSetElementRoot(ExecState*);
442 static EncodedJSValue JSC_HOST_CALL functionCreateRoot(ExecState*);
443 static EncodedJSValue JSC_HOST_CALL functionCreateElement(ExecState*);
444 static EncodedJSValue JSC_HOST_CALL functionGetElement(ExecState*);
445 static EncodedJSValue JSC_HOST_CALL functionPrint(ExecState*);
446 static EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*);
447 static EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState*);
448 static EncodedJSValue JSC_HOST_CALL functionDescribeArray(ExecState*);
449 static EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState*);
450 static EncodedJSValue JSC_HOST_CALL functionGCAndSweep(ExecState*);
451 static EncodedJSValue JSC_HOST_CALL functionFullGC(ExecState*);
452 static EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState*);
453 static EncodedJSValue JSC_HOST_CALL functionDeleteAllCompiledCode(ExecState*);
455 static EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState*);
456 static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState*);
458 static EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*);
459 static EncodedJSValue JSC_HOST_CALL functionRun(ExecState*);
460 static EncodedJSValue JSC_HOST_CALL functionLoad(ExecState*);
461 static EncodedJSValue JSC_HOST_CALL functionReadFile(ExecState*);
462 static EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState*);
463 static EncodedJSValue JSC_HOST_CALL functionReadline(ExecState*);
464 static EncodedJSValue JSC_HOST_CALL functionPreciseTime(ExecState*);
465 static EncodedJSValue JSC_HOST_CALL functionNeverInlineFunction(ExecState*);
466 static EncodedJSValue JSC_HOST_CALL functionOptimizeNextInvocation(ExecState*);
467 static EncodedJSValue JSC_HOST_CALL functionNumberOfDFGCompiles(ExecState*);
468 static EncodedJSValue JSC_HOST_CALL functionReoptimizationRetryCount(ExecState*);
469 static EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState*);
470 static NO_RETURN_WITH_VALUE EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*);
471 static EncodedJSValue JSC_HOST_CALL functionFalse1(ExecState*);
472 static EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*);
473 static EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*);
474 static EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*);
475 static EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*);
476 static EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState*);
477 static EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState*);
478 static EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState*);
479 static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables (ExecState*);
481 #if ENABLE(SAMPLING_FLAGS)
482 static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
483 static EncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState*);
490 Script(bool isFile, char *argument)
499 CommandLine(int argc, char** argv)
500 : m_interactive(false)
505 parseArguments(argc, argv);
511 Vector<Script> m_scripts;
512 Vector<String> m_arguments;
514 String m_profilerOutput;
516 void parseArguments(int, char**);
519 static const char interactivePrompt[] = ">>> ";
525 long getElapsedMS(); // call stop() first
532 void StopWatch::start()
534 m_startTime = monotonicallyIncreasingTime();
537 void StopWatch::stop()
539 m_stopTime = monotonicallyIncreasingTime();
542 long StopWatch::getElapsedMS()
544 return static_cast<long>((m_stopTime - m_startTime) * 1000);
547 class GlobalObject : public JSGlobalObject {
549 GlobalObject(VM&, Structure*);
552 typedef JSGlobalObject Base;
554 static GlobalObject* create(VM& vm, Structure* structure, const Vector<String>& arguments)
556 GlobalObject* object = new (NotNull, allocateCell<GlobalObject>(vm.heap)) GlobalObject(vm, structure);
557 object->finishCreation(vm, arguments);
558 vm.heap.addFinalizer(object, destroy);
562 static const bool needsDestruction = false;
565 static const GlobalObjectMethodTable s_globalObjectMethodTable;
567 static Structure* createStructure(VM& vm, JSValue prototype)
569 return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info());
572 static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return true; }
575 void finishCreation(VM& vm, const Vector<String>& arguments)
577 Base::finishCreation(vm);
579 addFunction(vm, "debug", functionDebug, 1);
580 addFunction(vm, "describe", functionDescribe, 1);
581 addFunction(vm, "describeArray", functionDescribeArray, 1);
582 addFunction(vm, "print", functionPrint, 1);
583 addFunction(vm, "quit", functionQuit, 0);
584 addFunction(vm, "gc", functionGCAndSweep, 0);
585 addFunction(vm, "fullGC", functionFullGC, 0);
586 addFunction(vm, "edenGC", functionEdenGC, 0);
587 addFunction(vm, "deleteAllCompiledCode", functionDeleteAllCompiledCode, 0);
589 addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
590 addFunction(vm, "releaseExecutableMemory", functionReleaseExecutableMemory, 0);
592 addFunction(vm, "version", functionVersion, 1);
593 addFunction(vm, "run", functionRun, 1);
594 addFunction(vm, "load", functionLoad, 1);
595 addFunction(vm, "readFile", functionReadFile, 1);
596 addFunction(vm, "checkSyntax", functionCheckSyntax, 1);
597 addFunction(vm, "jscStack", functionJSCStack, 1);
598 addFunction(vm, "readline", functionReadline, 0);
599 addFunction(vm, "preciseTime", functionPreciseTime, 0);
600 addFunction(vm, "neverInlineFunction", functionNeverInlineFunction, 1);
601 addFunction(vm, "noInline", functionNeverInlineFunction, 1);
602 addFunction(vm, "numberOfDFGCompiles", functionNumberOfDFGCompiles, 1);
603 addFunction(vm, "optimizeNextInvocation", functionOptimizeNextInvocation, 1);
604 addFunction(vm, "reoptimizationRetryCount", functionReoptimizationRetryCount, 1);
605 addFunction(vm, "transferArrayBuffer", functionTransferArrayBuffer, 1);
606 #if ENABLE(SAMPLING_FLAGS)
607 addFunction(vm, "setSamplingFlags", functionSetSamplingFlags, 1);
608 addFunction(vm, "clearSamplingFlags", functionClearSamplingFlags, 1);
610 addConstructableFunction(vm, "Root", functionCreateRoot, 0);
611 addConstructableFunction(vm, "Element", functionCreateElement, 1);
612 addFunction(vm, "getElement", functionGetElement, 1);
613 addFunction(vm, "setElementRoot", functionSetElementRoot, 2);
615 putDirectNativeFunction(vm, this, Identifier(&vm, "DFGTrue"), 0, functionFalse1, DFGTrueIntrinsic, DontEnum | JSC::Function);
616 putDirectNativeFunction(vm, this, Identifier(&vm, "OSRExit"), 0, functionUndefined1, OSRExitIntrinsic, DontEnum | JSC::Function);
617 putDirectNativeFunction(vm, this, Identifier(&vm, "isFinalTier"), 0, functionFalse2, IsFinalTierIntrinsic, DontEnum | JSC::Function);
618 putDirectNativeFunction(vm, this, Identifier(&vm, "predictInt32"), 0, functionUndefined2, SetInt32HeapPredictionIntrinsic, DontEnum | JSC::Function);
619 putDirectNativeFunction(vm, this, Identifier(&vm, "fiatInt52"), 0, functionIdentity, FiatInt52Intrinsic, DontEnum | JSC::Function);
621 addFunction(vm, "effectful42", functionEffectful42, 0);
622 addFunction(vm, "makeMasquerader", functionMakeMasquerader, 0);
623 addFunction(vm, "hasCustomProperties", functionHasCustomProperties, 0);
625 addFunction(vm, "createProxy", functionCreateProxy, 1);
626 addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);
628 addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
629 addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
630 addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 4);
632 JSArray* array = constructEmptyArray(globalExec(), 0);
633 for (size_t i = 0; i < arguments.size(); ++i)
634 array->putDirectIndex(globalExec(), i, jsString(globalExec(), arguments[i]));
635 putDirect(vm, Identifier(globalExec(), "arguments"), array);
637 putDirect(vm, Identifier(globalExec(), "console"), jsUndefined());
640 void addFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
642 Identifier identifier(&vm, name);
643 putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function));
646 void addConstructableFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
648 Identifier identifier(&vm, name);
649 putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function, NoIntrinsic, function));
653 const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, &globalObjectTable, CREATE_METHOD_TABLE(GlobalObject) };
654 const GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = { &allowsAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptExperimentsEnabled, 0, &shouldInterruptScriptBeforeTimeout };
657 GlobalObject::GlobalObject(VM& vm, Structure* structure)
658 : JSGlobalObject(vm, structure, &s_globalObjectMethodTable)
662 static inline String stringFromUTF(const char* utf8)
664 // Find the the first non-ascii character, or nul.
665 const char* pos = utf8;
668 size_t asciiLength = pos - utf8;
670 // Fast case - string is all ascii.
672 return String(utf8, asciiLength);
674 // Slow case - contains non-ascii characters, use fromUTF8WithLatin1Fallback.
676 ASSERT(strlen(utf8) == asciiLength + strlen(pos));
677 return String::fromUTF8WithLatin1Fallback(utf8, asciiLength + strlen(pos));
680 static inline SourceCode jscSource(const char* utf8, const String& filename)
682 String str = stringFromUTF(utf8);
683 return makeSource(str, filename);
686 EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
688 for (unsigned i = 0; i < exec->argumentCount(); ++i) {
692 printf("%s", exec->uncheckedArgument(i).toString(exec)->value(exec).utf8().data());
697 return JSValue::encode(jsUndefined());
701 EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec)
703 if (!exec->callerFrame()->isVMEntrySentinel())
704 exec->vm().interpreter->dumpCallFrame(exec->callerFrame());
705 return JSValue::encode(jsUndefined());
709 EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec)
711 fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec)->value(exec).utf8().data());
712 return JSValue::encode(jsUndefined());
715 EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState* exec)
717 if (exec->argumentCount() < 1)
718 return JSValue::encode(jsUndefined());
719 return JSValue::encode(jsString(exec, toString(exec->argument(0))));
722 EncodedJSValue JSC_HOST_CALL functionDescribeArray(ExecState* exec)
724 if (exec->argumentCount() < 1)
725 return JSValue::encode(jsUndefined());
726 JSObject* object = jsDynamicCast<JSObject*>(exec->argument(0));
728 return JSValue::encode(jsString(exec, "<not object>"));
729 return JSValue::encode(jsString(exec, toString("<Public length: ", object->getArrayLength(), "; vector length: ", object->getVectorLength(), ">")));
732 class FunctionJSCStackFunctor {
734 FunctionJSCStackFunctor(StringBuilder& trace)
739 StackVisitor::Status operator()(StackVisitor& visitor)
741 m_trace.append(String::format(" %zu %s\n", visitor->index(), visitor->toString().utf8().data()));
742 return StackVisitor::Continue;
746 StringBuilder& m_trace;
749 EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState* exec)
752 trace.appendLiteral("--> Stack trace:\n");
754 FunctionJSCStackFunctor functor(trace);
755 exec->iterate(functor);
756 fprintf(stderr, "%s", trace.toString().utf8().data());
757 return JSValue::encode(jsUndefined());
760 EncodedJSValue JSC_HOST_CALL functionCreateRoot(ExecState* exec)
762 JSLockHolder lock(exec);
763 return JSValue::encode(Root::create(exec->vm(), exec->lexicalGlobalObject()));
766 EncodedJSValue JSC_HOST_CALL functionCreateElement(ExecState* exec)
768 JSLockHolder lock(exec);
769 JSValue arg = exec->argument(0);
770 return JSValue::encode(Element::create(exec->vm(), exec->lexicalGlobalObject(), arg.isNull() ? nullptr : jsCast<Root*>(exec->argument(0))));
773 EncodedJSValue JSC_HOST_CALL functionGetElement(ExecState* exec)
775 JSLockHolder lock(exec);
776 Element* result = jsCast<Root*>(exec->argument(0).asCell())->element();
777 return JSValue::encode(result ? result : jsUndefined());
780 EncodedJSValue JSC_HOST_CALL functionSetElementRoot(ExecState* exec)
782 JSLockHolder lock(exec);
783 Element* element = jsCast<Element*>(exec->argument(0));
784 Root* root = jsCast<Root*>(exec->argument(1));
785 element->setRoot(root);
786 return JSValue::encode(jsUndefined());
789 EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState* exec)
791 JSLockHolder lock(exec);
792 JSValue target = exec->argument(0);
793 if (!target.isObject())
794 return JSValue::encode(jsUndefined());
795 JSObject* jsTarget = asObject(target.asCell());
796 Structure* structure = JSProxy::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsTarget->prototype());
797 JSProxy* proxy = JSProxy::create(exec->vm(), structure, jsTarget);
798 return JSValue::encode(proxy);
801 EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState* exec)
803 JSLockHolder lock(exec);
804 RuntimeArray* array = RuntimeArray::create(exec);
805 return JSValue::encode(array);
808 EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState* exec)
810 JSLockHolder lock(exec);
811 JSValue target = exec->argument(0);
812 JSObject* delegate = nullptr;
813 if (target.isObject())
814 delegate = asObject(target.asCell());
815 Structure* structure = ImpureGetter::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsNull());
816 ImpureGetter* result = ImpureGetter::create(exec->vm(), structure, delegate);
817 return JSValue::encode(result);
820 EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState* exec)
822 JSLockHolder lock(exec);
823 JSValue base = exec->argument(0);
824 if (!base.isObject())
825 return JSValue::encode(jsUndefined());
826 JSValue delegate = exec->argument(1);
827 if (!delegate.isObject())
828 return JSValue::encode(jsUndefined());
829 ImpureGetter* impureGetter = jsCast<ImpureGetter*>(asObject(base.asCell()));
830 impureGetter->setDelegate(exec->vm(), asObject(delegate.asCell()));
831 return JSValue::encode(jsUndefined());
834 EncodedJSValue JSC_HOST_CALL functionGCAndSweep(ExecState* exec)
836 JSLockHolder lock(exec);
837 exec->heap()->collectAllGarbage();
838 return JSValue::encode(jsUndefined());
841 EncodedJSValue JSC_HOST_CALL functionFullGC(ExecState* exec)
843 JSLockHolder lock(exec);
844 exec->heap()->collect(FullCollection);
845 return JSValue::encode(jsUndefined());
848 EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState* exec)
850 JSLockHolder lock(exec);
851 exec->heap()->collect(EdenCollection);
852 return JSValue::encode(jsUndefined());
855 EncodedJSValue JSC_HOST_CALL functionDeleteAllCompiledCode(ExecState* exec)
857 JSLockHolder lock(exec);
858 exec->heap()->deleteAllCompiledCode();
859 return JSValue::encode(jsUndefined());
863 EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState* exec)
865 JSLockHolder lock(exec);
866 exec->vm().releaseExecutableMemory();
867 return JSValue::encode(jsUndefined());
871 EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*)
873 // We need this function for compatibility with the Mozilla JS tests but for now
874 // we don't actually do any version-specific handling
875 return JSValue::encode(jsUndefined());
878 EncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec)
880 String fileName = exec->argument(0).toString(exec)->value(exec);
882 if (!fillBufferWithContentsOfFile(fileName, script))
883 return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
885 GlobalObject* globalObject = GlobalObject::create(exec->vm(), GlobalObject::createStructure(exec->vm(), jsNull()), Vector<String>());
887 JSArray* array = constructEmptyArray(globalObject->globalExec(), 0);
888 for (unsigned i = 1; i < exec->argumentCount(); ++i)
889 array->putDirectIndex(globalObject->globalExec(), i - 1, exec->uncheckedArgument(i));
890 globalObject->putDirect(
891 exec->vm(), Identifier(globalObject->globalExec(), "arguments"), array);
896 evaluate(globalObject->globalExec(), jscSource(script.data(), fileName), JSValue(), &exception);
900 exec->vm().throwException(globalObject->globalExec(), exception);
901 return JSValue::encode(jsUndefined());
904 return JSValue::encode(jsNumber(stopWatch.getElapsedMS()));
907 EncodedJSValue JSC_HOST_CALL functionLoad(ExecState* exec)
909 String fileName = exec->argument(0).toString(exec)->value(exec);
911 if (!fillBufferWithContentsOfFile(fileName, script))
912 return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
914 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
916 JSValue evaluationException;
917 JSValue result = evaluate(globalObject->globalExec(), jscSource(script.data(), fileName), JSValue(), &evaluationException);
918 if (evaluationException)
919 exec->vm().throwException(exec, evaluationException);
920 return JSValue::encode(result);
923 EncodedJSValue JSC_HOST_CALL functionReadFile(ExecState* exec)
925 String fileName = exec->argument(0).toString(exec)->value(exec);
927 if (!fillBufferWithContentsOfFile(fileName, script))
928 return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
930 return JSValue::encode(jsString(exec, stringFromUTF(script.data())));
933 EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState* exec)
935 String fileName = exec->argument(0).toString(exec)->value(exec);
937 if (!fillBufferWithContentsOfFile(fileName, script))
938 return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
940 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
945 JSValue syntaxException;
946 bool validSyntax = checkSyntax(globalObject->globalExec(), jscSource(script.data(), fileName), &syntaxException);
950 exec->vm().throwException(exec, syntaxException);
951 return JSValue::encode(jsNumber(stopWatch.getElapsedMS()));
954 #if ENABLE(SAMPLING_FLAGS)
955 EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState* exec)
957 for (unsigned i = 0; i < exec->argumentCount(); ++i) {
958 unsigned flag = static_cast<unsigned>(exec->uncheckedArgument(i).toNumber(exec));
959 if ((flag >= 1) && (flag <= 32))
960 SamplingFlags::setFlag(flag);
962 return JSValue::encode(jsNull());
965 EncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState* exec)
967 for (unsigned i = 0; i < exec->argumentCount(); ++i) {
968 unsigned flag = static_cast<unsigned>(exec->uncheckedArgument(i).toNumber(exec));
969 if ((flag >= 1) && (flag <= 32))
970 SamplingFlags::clearFlag(flag);
972 return JSValue::encode(jsNull());
976 EncodedJSValue JSC_HOST_CALL functionReadline(ExecState* exec)
978 Vector<char, 256> line;
980 while ((c = getchar()) != EOF) {
981 // FIXME: Should we also break on \r?
987 return JSValue::encode(jsString(exec, line.data()));
990 EncodedJSValue JSC_HOST_CALL functionPreciseTime(ExecState*)
992 return JSValue::encode(jsNumber(currentTime()));
995 EncodedJSValue JSC_HOST_CALL functionNeverInlineFunction(ExecState* exec)
997 return JSValue::encode(setNeverInline(exec));
1000 EncodedJSValue JSC_HOST_CALL functionOptimizeNextInvocation(ExecState* exec)
1002 return JSValue::encode(optimizeNextInvocation(exec));
1005 EncodedJSValue JSC_HOST_CALL functionNumberOfDFGCompiles(ExecState* exec)
1007 return JSValue::encode(numberOfDFGCompiles(exec));
1010 EncodedJSValue JSC_HOST_CALL functionReoptimizationRetryCount(ExecState* exec)
1012 if (exec->argumentCount() < 1)
1013 return JSValue::encode(jsUndefined());
1015 CodeBlock* block = getSomeBaselineCodeBlockForFunction(exec->argument(0));
1017 return JSValue::encode(jsNumber(0));
1019 return JSValue::encode(jsNumber(block->reoptimizationRetryCounter()));
1022 EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState* exec)
1024 if (exec->argumentCount() < 1)
1025 return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Not enough arguments")));
1027 JSArrayBuffer* buffer = jsDynamicCast<JSArrayBuffer*>(exec->argument(0));
1029 return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Expected an array buffer")));
1031 ArrayBufferContents dummyContents;
1032 buffer->impl()->transfer(dummyContents);
1034 return JSValue::encode(jsUndefined());
1037 EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*)
1039 jscExit(EXIT_SUCCESS);
1042 // Without this, Visual Studio will complain that this method does not return a value.
1043 return JSValue::encode(jsUndefined());
1047 EncodedJSValue JSC_HOST_CALL functionFalse1(ExecState*) { return JSValue::encode(jsBoolean(false)); }
1048 EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*) { return JSValue::encode(jsBoolean(false)); }
1050 EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*) { return JSValue::encode(jsUndefined()); }
1051 EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*) { return JSValue::encode(jsUndefined()); }
1053 EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState* exec) { return JSValue::encode(exec->argument(0)); }
1055 EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*)
1057 return JSValue::encode(jsNumber(42));
1060 EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState* exec)
1062 return JSValue::encode(Masquerader::create(exec->vm(), exec->lexicalGlobalObject()));
1065 EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState* exec)
1067 JSValue value = exec->argument(0);
1068 if (value.isObject())
1069 return JSValue::encode(jsBoolean(asObject(value)->hasCustomProperties()));
1070 return JSValue::encode(jsBoolean(false));
1073 EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState* exec)
1075 exec->vm().dumpHighFidelityProfilingTypes();
1076 return JSValue::encode(jsUndefined());
1079 // Use SEH for Release builds only to get rid of the crash report dialog
1080 // (luckily the same tests fail in Release and Debug builds so far). Need to
1081 // be in a separate main function because the jscmain function requires object
1084 #if COMPILER(MSVC) && !defined(_DEBUG) && !OS(WINCE)
1086 #define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; }
1092 int jscmain(int argc, char** argv);
1094 static double s_desiredTimeout;
1096 static NO_RETURN_DUE_TO_CRASH void timeoutThreadMain(void*)
1098 auto timeout = std::chrono::microseconds(static_cast<std::chrono::microseconds::rep>(s_desiredTimeout * 1000000));
1099 std::this_thread::sleep_for(timeout);
1101 dataLog("Timed out after ", s_desiredTimeout, " seconds!\n");
1105 int main(int argc, char** argv)
1107 #if PLATFORM(IOS) && CPU(ARM_THUMB2)
1108 // Enabled IEEE754 denormal support.
1111 env.__fpscr &= ~0x01000000u;
1117 // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
1118 // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
1119 // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
1123 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
1124 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
1125 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
1126 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
1127 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
1128 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
1139 // Initialize JSC before getting VM.
1140 #if ENABLE(SAMPLING_REGIONS)
1141 WTF::initializeMainThread();
1143 JSC::initializeThreading();
1146 if (char* timeoutString = getenv("JSC_timeout")) {
1147 if (sscanf(timeoutString, "%lf", &s_desiredTimeout) != 1) {
1149 "WARNING: timeout string is malformed, got ", timeoutString,
1150 " but expected a number. Not using a timeout.\n");
1152 createThread(timeoutThreadMain, 0, "jsc Timeout Thread");
1157 Options::crashIfCantAllocateJITMemory() = true;
1160 // We can't use destructors in the following code because it uses Windows
1161 // Structured Exception Handling
1164 res = jscmain(argc, argv);
1166 if (Options::logHeapStatisticsAtExit())
1167 HeapStatistics::reportSuccess();
1176 static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scripts, bool dump)
1180 Vector<char> scriptBuffer;
1183 JSC::Options::dumpGeneratedBytecodes() = true;
1185 VM& vm = globalObject->vm();
1187 #if ENABLE(SAMPLING_FLAGS)
1188 SamplingFlags::start();
1191 bool success = true;
1192 for (size_t i = 0; i < scripts.size(); i++) {
1193 if (scripts[i].isFile) {
1194 fileName = scripts[i].argument;
1195 if (!fillBufferWithContentsOfFile(fileName, scriptBuffer))
1196 return false; // fail early so we can catch missing files
1197 script = scriptBuffer.data();
1199 script = scripts[i].argument;
1200 fileName = "[Command Line]";
1205 JSValue evaluationException;
1206 JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(script, fileName), JSValue(), &evaluationException);
1207 success = success && !evaluationException;
1208 if (dump && !evaluationException)
1209 printf("End: %s\n", returnValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
1210 if (evaluationException) {
1211 printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
1212 Identifier stackID(globalObject->globalExec(), "stack");
1213 JSValue stackValue = evaluationException.get(globalObject->globalExec(), stackID);
1214 if (!stackValue.isUndefinedOrNull())
1215 printf("%s\n", stackValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
1219 globalObject->globalExec()->clearException();
1222 #if ENABLE(SAMPLING_FLAGS)
1223 SamplingFlags::stop();
1225 #if ENABLE(SAMPLING_REGIONS)
1226 SamplingRegion::dump();
1228 vm.dumpSampleData(globalObject->globalExec());
1229 #if ENABLE(SAMPLING_COUNTERS)
1230 AbstractSamplingCounter::dump();
1232 #if ENABLE(REGEXP_TRACING)
1233 vm.dumpRegExpTrace();
1238 #define RUNNING_FROM_XCODE 0
1240 static void runInteractive(GlobalObject* globalObject)
1242 String interpreterName("Interpreter");
1244 bool shouldQuit = false;
1245 while (!shouldQuit) {
1246 #if HAVE(READLINE) && !RUNNING_FROM_XCODE
1250 error = ParserError();
1251 char* line = readline(source.isEmpty() ? interactivePrompt : "... ");
1255 source = source + line;
1256 source = source + '\n';
1257 checkSyntax(globalObject->vm(), makeSource(source, interpreterName), error);
1261 } while (error.m_syntaxErrorType == ParserError::SyntaxErrorRecoverable);
1263 if (error.m_type != ParserError::ErrorNone) {
1264 printf("%s:%d\n", error.m_message.utf8().data(), error.m_line);
1269 JSValue evaluationException;
1270 JSValue returnValue = evaluate(globalObject->globalExec(), makeSource(source, interpreterName), JSValue(), &evaluationException);
1272 printf("%s", interactivePrompt);
1273 Vector<char, 256> line;
1275 while ((c = getchar()) != EOF) {
1276 // FIXME: Should we also break on \r?
1285 JSValue evaluationException;
1286 JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(line.data(), interpreterName), JSValue(), &evaluationException);
1288 if (evaluationException)
1289 printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
1291 printf("%s\n", returnValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
1293 globalObject->globalExec()->clearException();
1298 static NO_RETURN void printUsageStatement(bool help = false)
1300 fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n");
1301 fprintf(stderr, " -d Dumps bytecode (debug builds only)\n");
1302 fprintf(stderr, " -e Evaluate argument as script code\n");
1303 fprintf(stderr, " -f Specifies a source file (deprecated)\n");
1304 fprintf(stderr, " -h|--help Prints this help message\n");
1305 fprintf(stderr, " -i Enables interactive mode (default if no files are specified)\n");
1307 fprintf(stderr, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n");
1309 fprintf(stderr, " -p <file> Outputs profiling data to a file\n");
1310 fprintf(stderr, " -x Output exit code before terminating\n");
1311 fprintf(stderr, "\n");
1312 fprintf(stderr, " --options Dumps all JSC VM options and exits\n");
1313 fprintf(stderr, " --dumpOptions Dumps all JSC VM options before continuing\n");
1314 fprintf(stderr, " --<jsc VM option>=<value> Sets the specified JSC VM option\n");
1315 fprintf(stderr, "\n");
1317 jscExit(help ? EXIT_SUCCESS : EXIT_FAILURE);
1320 void CommandLine::parseArguments(int argc, char** argv)
1323 bool needToDumpOptions = false;
1324 bool needToExit = false;
1326 for (; i < argc; ++i) {
1327 const char* arg = argv[i];
1328 if (!strcmp(arg, "-f")) {
1330 printUsageStatement();
1331 m_scripts.append(Script(true, argv[i]));
1334 if (!strcmp(arg, "-e")) {
1336 printUsageStatement();
1337 m_scripts.append(Script(false, argv[i]));
1340 if (!strcmp(arg, "-i")) {
1341 m_interactive = true;
1344 if (!strcmp(arg, "-d")) {
1348 if (!strcmp(arg, "-p")) {
1350 printUsageStatement();
1352 m_profilerOutput = argv[i];
1355 if (!strcmp(arg, "-s")) {
1357 signal(SIGILL, _exit);
1358 signal(SIGFPE, _exit);
1359 signal(SIGBUS, _exit);
1360 signal(SIGSEGV, _exit);
1364 if (!strcmp(arg, "-x")) {
1368 if (!strcmp(arg, "--")) {
1372 if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
1373 printUsageStatement(true);
1375 if (!strcmp(arg, "--options")) {
1376 needToDumpOptions = true;
1380 if (!strcmp(arg, "--dumpOptions")) {
1381 needToDumpOptions = true;
1385 // See if the -- option is a JSC VM option.
1386 // NOTE: At this point, we know that the arg starts with "--". Skip it.
1387 if (JSC::Options::setOption(&arg[2])) {
1388 // The arg was recognized as a VM option and has been parsed.
1389 continue; // Just continue with the next arg.
1392 // This arg is not recognized by the VM nor by jsc. Pass it on to the
1394 m_scripts.append(Script(true, argv[i]));
1397 if (m_scripts.isEmpty())
1398 m_interactive = true;
1400 for (; i < argc; ++i)
1401 m_arguments.append(argv[i]);
1403 if (needToDumpOptions)
1404 JSC::Options::dumpAllOptions(stderr);
1406 jscExit(EXIT_SUCCESS);
1409 int jscmain(int argc, char** argv)
1411 // Note that the options parsing can affect VM creation, and thus
1413 CommandLine options(argc, argv);
1414 VM* vm = VM::create(LargeHeap).leakRef();
1417 JSLockHolder locker(vm);
1419 if (options.m_profile && !vm->m_perBytecodeProfiler)
1420 vm->m_perBytecodeProfiler = adoptPtr(new Profiler::Database(*vm));
1422 GlobalObject* globalObject = GlobalObject::create(*vm, GlobalObject::createStructure(*vm, jsNull()), options.m_arguments);
1423 bool success = runWithScripts(globalObject, options.m_scripts, options.m_dump);
1424 if (options.m_interactive && success)
1425 runInteractive(globalObject);
1427 result = success ? 0 : 3;
1429 if (options.m_exitCode)
1430 printf("jsc exiting %d\n", result);
1432 if (options.m_profile) {
1433 if (!vm->m_perBytecodeProfiler->save(options.m_profilerOutput.utf8().data()))
1434 fprintf(stderr, "could not save profiler output.\n");
1438 if (Options::enableExceptionFuzz())
1439 printf("JSC EXCEPTION FUZZ: encountered %u checks.\n", numberOfExceptionFuzzChecks());
1446 static bool fillBufferWithContentsOfFile(const String& fileName, Vector<char>& buffer)
1448 FILE* f = fopen(fileName.utf8().data(), "r");
1450 fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data());
1454 size_t bufferSize = 0;
1455 size_t bufferCapacity = 1024;
1457 buffer.resize(bufferCapacity);
1459 while (!feof(f) && !ferror(f)) {
1460 bufferSize += fread(buffer.data() + bufferSize, 1, bufferCapacity - bufferSize, f);
1461 if (bufferSize == bufferCapacity) { // guarantees space for trailing '\0'
1462 bufferCapacity *= 2;
1463 buffer.resize(bufferCapacity);
1467 buffer[bufferSize] = '\0';
1469 if (buffer[0] == '#' && buffer[1] == '!')
1470 buffer[0] = buffer[1] = '/';