bda9a09d0d26b96c3f50a2299d24933ac74f3056
[WebKit-https.git] / Source / JavaScriptCore / jsc.cpp
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2004-2017 Apple Inc. All rights reserved.
4  *  Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com)
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public License
17  *  along with this library; see the file COPYING.LIB.  If not, write to
18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #include "config.h"
24
25 #include "ArrayBuffer.h"
26 #include "ArrayPrototype.h"
27 #include "BuiltinExecutableCreator.h"
28 #include "BuiltinNames.h"
29 #include "ButterflyInlines.h"
30 #include "CodeBlock.h"
31 #include "Completion.h"
32 #include "DOMJITGetterSetter.h"
33 #include "DOMJITPatchpoint.h"
34 #include "DOMJITPatchpointParams.h"
35 #include "Disassembler.h"
36 #include "Exception.h"
37 #include "ExceptionHelpers.h"
38 #include "GetterSetter.h"
39 #include "HeapProfiler.h"
40 #include "HeapSnapshotBuilder.h"
41 #include "HeapStatistics.h"
42 #include "InitializeThreading.h"
43 #include "Interpreter.h"
44 #include "JIT.h"
45 #include "JSArray.h"
46 #include "JSArrayBuffer.h"
47 #include "JSCInlines.h"
48 #include "JSFunction.h"
49 #include "JSInternalPromise.h"
50 #include "JSInternalPromiseDeferred.h"
51 #include "JSLock.h"
52 #include "JSModuleLoader.h"
53 #include "JSNativeStdFunction.h"
54 #include "JSONObject.h"
55 #include "JSProxy.h"
56 #include "JSSourceCode.h"
57 #include "JSString.h"
58 #include "JSTypedArrays.h"
59 #include "JSWebAssemblyCallee.h"
60 #include "LLIntData.h"
61 #include "LLIntThunks.h"
62 #include "ObjectConstructor.h"
63 #include "ParserError.h"
64 #include "ProfilerDatabase.h"
65 #include "ProtoCallFrame.h"
66 #include "ReleaseHeapAccessScope.h"
67 #include "SamplingProfiler.h"
68 #include "ShadowChicken.h"
69 #include "StackVisitor.h"
70 #include "StructureInlines.h"
71 #include "StructureRareDataInlines.h"
72 #include "SuperSampler.h"
73 #include "TestRunnerUtils.h"
74 #include "TypeProfilerLog.h"
75 #include "WasmPlan.h"
76 #include "WasmMemory.h"
77 #include <locale.h>
78 #include <math.h>
79 #include <stdio.h>
80 #include <stdlib.h>
81 #include <string.h>
82 #include <thread>
83 #include <type_traits>
84 #include <wtf/CommaPrinter.h>
85 #include <wtf/CurrentTime.h>
86 #include <wtf/MainThread.h>
87 #include <wtf/NeverDestroyed.h>
88 #include <wtf/StringPrintStream.h>
89 #include <wtf/text/StringBuilder.h>
90
91 #if OS(WINDOWS)
92 #include <direct.h>
93 #else
94 #include <unistd.h>
95 #endif
96
97 #if HAVE(READLINE)
98 // readline/history.h has a Function typedef which conflicts with the WTF::Function template from WTF/Forward.h
99 // We #define it to something else to avoid this conflict.
100 #define Function ReadlineFunction
101 #include <readline/history.h>
102 #include <readline/readline.h>
103 #undef Function
104 #endif
105
106 #if HAVE(SYS_TIME_H)
107 #include <sys/time.h>
108 #endif
109
110 #if HAVE(SIGNAL_H)
111 #include <signal.h>
112 #endif
113
114 #if COMPILER(MSVC)
115 #include <crtdbg.h>
116 #include <mmsystem.h>
117 #include <windows.h>
118 #endif
119
120 #if PLATFORM(IOS) && CPU(ARM_THUMB2)
121 #include <fenv.h>
122 #include <arm/arch.h>
123 #endif
124
125 #if PLATFORM(EFL)
126 #include <Ecore.h>
127 #endif
128
129 #if !defined(PATH_MAX)
130 #define PATH_MAX 4096
131 #endif
132
133 using namespace JSC;
134 using namespace WTF;
135
136 namespace {
137
138 NO_RETURN_WITH_VALUE static void jscExit(int status)
139 {
140     waitForAsynchronousDisassembly();
141     
142 #if ENABLE(DFG_JIT)
143     if (DFG::isCrashing()) {
144         for (;;) {
145 #if OS(WINDOWS)
146             Sleep(1000);
147 #else
148             pause();
149 #endif
150         }
151     }
152 #endif // ENABLE(DFG_JIT)
153     exit(status);
154 }
155
156 class Element;
157 class ElementHandleOwner;
158 class Masuqerader;
159 class Root;
160 class RuntimeArray;
161
162 class Element : public JSNonFinalObject {
163 public:
164     Element(VM& vm, Structure* structure)
165         : Base(vm, structure)
166     {
167     }
168
169     typedef JSNonFinalObject Base;
170
171     Root* root() const { return m_root.get(); }
172     void setRoot(VM& vm, Root* root) { m_root.set(vm, this, root); }
173
174     static Element* create(VM& vm, JSGlobalObject* globalObject, Root* root)
175     {
176         Structure* structure = createStructure(vm, globalObject, jsNull());
177         Element* element = new (NotNull, allocateCell<Element>(vm.heap, sizeof(Element))) Element(vm, structure);
178         element->finishCreation(vm, root);
179         return element;
180     }
181
182     void finishCreation(VM&, Root*);
183
184     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
185     {
186         Element* thisObject = jsCast<Element*>(cell);
187         ASSERT_GC_OBJECT_INHERITS(thisObject, info());
188         Base::visitChildren(thisObject, visitor);
189         visitor.append(thisObject->m_root);
190     }
191
192     static ElementHandleOwner* handleOwner();
193
194     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
195     {
196         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
197     }
198
199     DECLARE_INFO;
200
201 private:
202     WriteBarrier<Root> m_root;
203 };
204
205 class ElementHandleOwner : public WeakHandleOwner {
206 public:
207     bool isReachableFromOpaqueRoots(Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor) override
208     {
209         Element* element = jsCast<Element*>(handle.slot()->asCell());
210         return visitor.containsOpaqueRoot(element->root());
211     }
212 };
213
214 class Masquerader : public JSNonFinalObject {
215 public:
216     Masquerader(VM& vm, Structure* structure)
217         : Base(vm, structure)
218     {
219     }
220
221     typedef JSNonFinalObject Base;
222     static const unsigned StructureFlags = Base::StructureFlags | JSC::MasqueradesAsUndefined;
223
224     static Masquerader* create(VM& vm, JSGlobalObject* globalObject)
225     {
226         globalObject->masqueradesAsUndefinedWatchpoint()->fireAll(vm, "Masquerading object allocated");
227         Structure* structure = createStructure(vm, globalObject, jsNull());
228         Masquerader* result = new (NotNull, allocateCell<Masquerader>(vm.heap, sizeof(Masquerader))) Masquerader(vm, structure);
229         result->finishCreation(vm);
230         return result;
231     }
232
233     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
234     {
235         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
236     }
237
238     DECLARE_INFO;
239 };
240
241 class Root : public JSDestructibleObject {
242 public:
243     Root(VM& vm, Structure* structure)
244         : Base(vm, structure)
245     {
246     }
247
248     Element* element()
249     {
250         return m_element.get();
251     }
252
253     void setElement(Element* element)
254     {
255         Weak<Element> newElement(element, Element::handleOwner());
256         m_element.swap(newElement);
257     }
258
259     static Root* create(VM& vm, JSGlobalObject* globalObject)
260     {
261         Structure* structure = createStructure(vm, globalObject, jsNull());
262         Root* root = new (NotNull, allocateCell<Root>(vm.heap, sizeof(Root))) Root(vm, structure);
263         root->finishCreation(vm);
264         return root;
265     }
266
267     typedef JSDestructibleObject Base;
268
269     DECLARE_INFO;
270
271     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
272     {
273         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
274     }
275
276     static void visitChildren(JSCell* thisObject, SlotVisitor& visitor)
277     {
278         Base::visitChildren(thisObject, visitor);
279         visitor.addOpaqueRoot(thisObject);
280     }
281
282 private:
283     Weak<Element> m_element;
284 };
285
286 class ImpureGetter : public JSNonFinalObject {
287 public:
288     ImpureGetter(VM& vm, Structure* structure)
289         : Base(vm, structure)
290     {
291     }
292
293     DECLARE_INFO;
294     typedef JSNonFinalObject Base;
295     static const unsigned StructureFlags = Base::StructureFlags | JSC::GetOwnPropertySlotIsImpure | JSC::OverridesGetOwnPropertySlot;
296
297     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
298     {
299         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
300     }
301
302     static ImpureGetter* create(VM& vm, Structure* structure, JSObject* delegate)
303     {
304         ImpureGetter* getter = new (NotNull, allocateCell<ImpureGetter>(vm.heap, sizeof(ImpureGetter))) ImpureGetter(vm, structure);
305         getter->finishCreation(vm, delegate);
306         return getter;
307     }
308
309     void finishCreation(VM& vm, JSObject* delegate)
310     {
311         Base::finishCreation(vm);
312         if (delegate)
313             m_delegate.set(vm, this, delegate);
314     }
315
316     static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName name, PropertySlot& slot)
317     {
318         VM& vm = exec->vm();
319         auto scope = DECLARE_THROW_SCOPE(vm);
320         ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);
321         
322         if (thisObject->m_delegate) {
323             if (thisObject->m_delegate->getPropertySlot(exec, name, slot))
324                 return true;
325             RETURN_IF_EXCEPTION(scope, false);
326         }
327
328         return Base::getOwnPropertySlot(object, exec, name, slot);
329     }
330
331     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
332     {
333         Base::visitChildren(cell, visitor);
334         ImpureGetter* thisObject = jsCast<ImpureGetter*>(cell);
335         visitor.append(thisObject->m_delegate);
336     }
337
338     void setDelegate(VM& vm, JSObject* delegate)
339     {
340         m_delegate.set(vm, this, delegate);
341     }
342
343 private:
344     WriteBarrier<JSObject> m_delegate;
345 };
346
347 class CustomGetter : public JSNonFinalObject {
348 public:
349     CustomGetter(VM& vm, Structure* structure)
350         : Base(vm, structure)
351     {
352     }
353
354     DECLARE_INFO;
355     typedef JSNonFinalObject Base;
356     static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;
357
358     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
359     {
360         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
361     }
362
363     static CustomGetter* create(VM& vm, Structure* structure)
364     {
365         CustomGetter* getter = new (NotNull, allocateCell<CustomGetter>(vm.heap, sizeof(CustomGetter))) CustomGetter(vm, structure);
366         getter->finishCreation(vm);
367         return getter;
368     }
369
370     static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
371     {
372         CustomGetter* thisObject = jsCast<CustomGetter*>(object);
373         if (propertyName == PropertyName(Identifier::fromString(exec, "customGetter"))) {
374             slot.setCacheableCustom(thisObject, DontDelete | ReadOnly | DontEnum, thisObject->customGetter);
375             return true;
376         }
377         return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
378     }
379
380 private:
381     static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
382     {
383         VM& vm = exec->vm();
384         auto scope = DECLARE_THROW_SCOPE(vm);
385
386         CustomGetter* thisObject = jsDynamicCast<CustomGetter*>(vm, JSValue::decode(thisValue));
387         if (!thisObject)
388             return throwVMTypeError(exec, scope);
389         bool shouldThrow = thisObject->get(exec, PropertyName(Identifier::fromString(exec, "shouldThrow"))).toBoolean(exec);
390         if (shouldThrow)
391             return throwVMTypeError(exec, scope);
392         return JSValue::encode(jsNumber(100));
393     }
394 };
395
396 class RuntimeArray : public JSArray {
397 public:
398     typedef JSArray Base;
399     static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
400
401     static RuntimeArray* create(ExecState* exec)
402     {
403         VM& vm = exec->vm();
404         JSGlobalObject* globalObject = exec->lexicalGlobalObject();
405         Structure* structure = createStructure(vm, globalObject, createPrototype(vm, globalObject));
406         RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(*exec->heap())) RuntimeArray(exec, structure);
407         runtimeArray->finishCreation(exec);
408         vm.heap.addFinalizer(runtimeArray, destroy);
409         return runtimeArray;
410     }
411
412     ~RuntimeArray() { }
413
414     static void destroy(JSCell* cell)
415     {
416         static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();
417     }
418
419     static const bool needsDestruction = false;
420
421     static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
422     {
423         RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
424         if (propertyName == exec->propertyNames().length) {
425             slot.setCacheableCustom(thisObject, DontDelete | ReadOnly | DontEnum, thisObject->lengthGetter);
426             return true;
427         }
428
429         std::optional<uint32_t> index = parseIndex(propertyName);
430         if (index && index.value() < thisObject->getLength()) {
431             slot.setValue(thisObject, DontDelete | DontEnum, jsNumber(thisObject->m_vector[index.value()]));
432             return true;
433         }
434
435         return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
436     }
437
438     static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)
439     {
440         RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
441         if (index < thisObject->getLength()) {
442             slot.setValue(thisObject, DontDelete | DontEnum, jsNumber(thisObject->m_vector[index]));
443             return true;
444         }
445
446         return JSObject::getOwnPropertySlotByIndex(thisObject, exec, index, slot);
447     }
448
449     static NO_RETURN_DUE_TO_CRASH bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&)
450     {
451         RELEASE_ASSERT_NOT_REACHED();
452     }
453
454     static NO_RETURN_DUE_TO_CRASH bool deleteProperty(JSCell*, ExecState*, PropertyName)
455     {
456         RELEASE_ASSERT_NOT_REACHED();
457     }
458
459     unsigned getLength() const { return m_vector.size(); }
460
461     DECLARE_INFO;
462
463     static ArrayPrototype* createPrototype(VM&, JSGlobalObject* globalObject)
464     {
465         return globalObject->arrayPrototype();
466     }
467
468     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
469     {
470         return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass);
471     }
472
473 protected:
474     void finishCreation(ExecState* exec)
475     {
476         VM& vm = exec->vm();
477         Base::finishCreation(vm);
478         ASSERT(inherits(vm, info()));
479
480         for (size_t i = 0; i < exec->argumentCount(); i++)
481             m_vector.append(exec->argument(i).toInt32(exec));
482     }
483
484 private:
485     RuntimeArray(ExecState* exec, Structure* structure)
486         : JSArray(exec->vm(), structure, 0)
487     {
488     }
489
490     static EncodedJSValue lengthGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
491     {
492         VM& vm = exec->vm();
493         auto scope = DECLARE_THROW_SCOPE(vm);
494
495         RuntimeArray* thisObject = jsDynamicCast<RuntimeArray*>(vm, JSValue::decode(thisValue));
496         if (!thisObject)
497             return throwVMTypeError(exec, scope);
498         return JSValue::encode(jsNumber(thisObject->getLength()));
499     }
500
501     Vector<int> m_vector;
502 };
503
504 class SimpleObject : public JSNonFinalObject {
505 public:
506     SimpleObject(VM& vm, Structure* structure)
507         : Base(vm, structure)
508     {
509     }
510
511     typedef JSNonFinalObject Base;
512     static const bool needsDestruction = false;
513
514     static SimpleObject* create(VM& vm, JSGlobalObject* globalObject)
515     {
516         Structure* structure = createStructure(vm, globalObject, jsNull());
517         SimpleObject* simpleObject = new (NotNull, allocateCell<SimpleObject>(vm.heap, sizeof(SimpleObject))) SimpleObject(vm, structure);
518         simpleObject->finishCreation(vm);
519         return simpleObject;
520     }
521
522     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
523     {
524         SimpleObject* thisObject = jsCast<SimpleObject*>(cell);
525         ASSERT_GC_OBJECT_INHERITS(thisObject, info());
526         Base::visitChildren(thisObject, visitor);
527         visitor.append(thisObject->m_hiddenValue);
528     }
529
530     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
531     {
532         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
533     }
534
535     JSValue hiddenValue()
536     {
537         return m_hiddenValue.get();
538     }
539
540     void setHiddenValue(VM& vm, JSValue value)
541     {
542         ASSERT(value.isCell());
543         m_hiddenValue.set(vm, this, value);
544     }
545
546     DECLARE_INFO;
547
548 private:
549     WriteBarrier<JSC::Unknown> m_hiddenValue;
550 };
551
552 class DOMJITNode : public JSNonFinalObject {
553 public:
554     DOMJITNode(VM& vm, Structure* structure)
555         : Base(vm, structure)
556     {
557     }
558
559     DECLARE_INFO;
560     typedef JSNonFinalObject Base;
561     static const unsigned StructureFlags = Base::StructureFlags;
562
563     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
564     {
565         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
566     }
567
568 #if ENABLE(JIT)
569     static Ref<DOMJIT::Patchpoint> checkDOMJITNode()
570     {
571         Ref<DOMJIT::Patchpoint> patchpoint = DOMJIT::Patchpoint::create();
572         patchpoint->setGenerator([=](CCallHelpers& jit, DOMJIT::PatchpointParams& params) {
573             CCallHelpers::JumpList failureCases;
574             failureCases.append(jit.branch8(
575                 CCallHelpers::NotEqual,
576                 CCallHelpers::Address(params[0].gpr(), JSCell::typeInfoTypeOffset()),
577                 CCallHelpers::TrustedImm32(JSC::JSType(LastJSCObjectType + 1))));
578             return failureCases;
579         });
580         return patchpoint;
581     }
582 #endif
583
584     static DOMJITNode* create(VM& vm, Structure* structure)
585     {
586         DOMJITNode* getter = new (NotNull, allocateCell<DOMJITNode>(vm.heap, sizeof(DOMJITNode))) DOMJITNode(vm, structure);
587         getter->finishCreation(vm);
588         return getter;
589     }
590
591     int32_t value() const
592     {
593         return m_value;
594     }
595
596     static ptrdiff_t offsetOfValue() { return OBJECT_OFFSETOF(DOMJITNode, m_value); }
597
598 private:
599     int32_t m_value { 42 };
600 };
601
602 class DOMJITGetter : public DOMJITNode {
603 public:
604     DOMJITGetter(VM& vm, Structure* structure)
605         : Base(vm, structure)
606     {
607     }
608
609     DECLARE_INFO;
610     typedef DOMJITNode Base;
611     static const unsigned StructureFlags = Base::StructureFlags;
612
613     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
614     {
615         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
616     }
617
618     static DOMJITGetter* create(VM& vm, Structure* structure)
619     {
620         DOMJITGetter* getter = new (NotNull, allocateCell<DOMJITGetter>(vm.heap, sizeof(DOMJITGetter))) DOMJITGetter(vm, structure);
621         getter->finishCreation(vm);
622         return getter;
623     }
624
625     class DOMJITNodeDOMJIT : public DOMJIT::GetterSetter {
626     public:
627         DOMJITNodeDOMJIT()
628             : DOMJIT::GetterSetter(DOMJITGetter::customGetter, nullptr, DOMJITNode::info(), SpecInt32Only)
629         {
630         }
631
632 #if ENABLE(JIT)
633         Ref<DOMJIT::Patchpoint> checkDOM() override
634         {
635             return DOMJITNode::checkDOMJITNode();
636         }
637
638         static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)
639         {
640             NativeCallFrameTracer tracer(&exec->vm(), exec);
641             return JSValue::encode(jsNumber(static_cast<DOMJITGetter*>(pointer)->value()));
642         }
643
644         Ref<DOMJIT::CallDOMGetterPatchpoint> callDOMGetter() override
645         {
646             Ref<DOMJIT::CallDOMGetterPatchpoint> patchpoint = DOMJIT::CallDOMGetterPatchpoint::create();
647             patchpoint->requireGlobalObject = false;
648             patchpoint->setGenerator([=](CCallHelpers& jit, DOMJIT::PatchpointParams& params) {
649                 JSValueRegs results = params[0].jsValueRegs();
650                 GPRReg dom = params[1].gpr();
651                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, dom);
652                 return CCallHelpers::JumpList();
653
654             });
655             return patchpoint;
656         }
657 #endif
658     };
659
660     static DOMJIT::GetterSetter* domJITNodeGetterSetter()
661     {
662         static NeverDestroyed<DOMJITNodeDOMJIT> graph;
663         return &graph.get();
664     }
665
666 private:
667     void finishCreation(VM& vm)
668     {
669         Base::finishCreation(vm);
670         DOMJIT::GetterSetter* domJIT = domJITNodeGetterSetter();
671         CustomGetterSetter* customGetterSetter = CustomGetterSetter::create(vm, domJIT->getter(), domJIT->setter(), domJIT);
672         putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, ReadOnly | CustomAccessor);
673     }
674
675     static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
676     {
677         VM& vm = exec->vm();
678         auto scope = DECLARE_THROW_SCOPE(vm);
679
680         DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, JSValue::decode(thisValue));
681         if (!thisObject)
682             return throwVMTypeError(exec, scope);
683         return JSValue::encode(jsNumber(thisObject->value()));
684     }
685 };
686
687 class DOMJITGetterComplex : public DOMJITNode {
688 public:
689     DOMJITGetterComplex(VM& vm, Structure* structure)
690         : Base(vm, structure)
691     {
692     }
693
694     DECLARE_INFO;
695     typedef DOMJITNode Base;
696     static const unsigned StructureFlags = Base::StructureFlags;
697
698     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
699     {
700         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
701     }
702
703     static DOMJITGetterComplex* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
704     {
705         DOMJITGetterComplex* getter = new (NotNull, allocateCell<DOMJITGetterComplex>(vm.heap, sizeof(DOMJITGetterComplex))) DOMJITGetterComplex(vm, structure);
706         getter->finishCreation(vm, globalObject);
707         return getter;
708     }
709
710     class DOMJITNodeDOMJIT : public DOMJIT::GetterSetter {
711     public:
712         DOMJITNodeDOMJIT()
713             : DOMJIT::GetterSetter(DOMJITGetterComplex::customGetter, nullptr, DOMJITNode::info(), SpecInt32Only)
714         {
715         }
716
717 #if ENABLE(JIT)
718         Ref<DOMJIT::Patchpoint> checkDOM() override
719         {
720             return DOMJITNode::checkDOMJITNode();
721         }
722
723         static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)
724         {
725             VM& vm = exec->vm();
726             NativeCallFrameTracer tracer(&vm, exec);
727             auto scope = DECLARE_THROW_SCOPE(vm);
728             auto* object = static_cast<DOMJITNode*>(pointer);
729             auto* domjitGetterComplex = jsDynamicCast<DOMJITGetterComplex*>(vm, object);
730             if (domjitGetterComplex) {
731                 if (domjitGetterComplex->m_enableException)
732                     return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("DOMJITGetterComplex slow call exception"))));
733             }
734             return JSValue::encode(jsNumber(object->value()));
735         }
736
737         Ref<DOMJIT::CallDOMGetterPatchpoint> callDOMGetter() override
738         {
739             RefPtr<DOMJIT::CallDOMGetterPatchpoint> patchpoint = DOMJIT::CallDOMGetterPatchpoint::create();
740             static_assert(GPRInfo::numberOfRegisters >= 4, "Number of registers should be larger or equal to 4.");
741             patchpoint->numGPScratchRegisters = GPRInfo::numberOfRegisters - 4;
742             patchpoint->numFPScratchRegisters = 3;
743             patchpoint->setGenerator([=](CCallHelpers& jit, DOMJIT::PatchpointParams& params) {
744                 JSValueRegs results = params[0].jsValueRegs();
745                 GPRReg domGPR = params[1].gpr();
746                 for (unsigned i = 0; i < patchpoint->numGPScratchRegisters; ++i)
747                     jit.move(CCallHelpers::TrustedImm32(42), params.gpScratch(i));
748
749                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, domGPR);
750                 return CCallHelpers::JumpList();
751
752             });
753             return *patchpoint.get();
754         }
755 #endif
756     };
757
758     static DOMJIT::GetterSetter* domJITNodeGetterSetter()
759     {
760         static NeverDestroyed<DOMJITNodeDOMJIT> graph;
761         return &graph.get();
762     }
763
764 private:
765     void finishCreation(VM& vm, JSGlobalObject* globalObject)
766     {
767         Base::finishCreation(vm);
768         DOMJIT::GetterSetter* domJIT = domJITNodeGetterSetter();
769         CustomGetterSetter* customGetterSetter = CustomGetterSetter::create(vm, domJIT->getter(), domJIT->setter(), domJIT);
770         putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, ReadOnly | CustomAccessor);
771         putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "enableException"), 0, functionEnableException, NoIntrinsic, 0);
772     }
773
774     static EncodedJSValue JSC_HOST_CALL functionEnableException(ExecState* exec)
775     {
776         VM& vm = exec->vm();
777         auto* object = jsDynamicCast<DOMJITGetterComplex*>(vm, exec->thisValue());
778         if (object)
779             object->m_enableException = true;
780         return JSValue::encode(jsUndefined());
781     }
782
783     static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
784     {
785         VM& vm = exec->vm();
786         auto scope = DECLARE_THROW_SCOPE(vm);
787
788         auto* thisObject = jsDynamicCast<DOMJITNode*>(vm, JSValue::decode(thisValue));
789         if (!thisObject)
790             return throwVMTypeError(exec, scope);
791         if (auto* domjitGetterComplex = jsDynamicCast<DOMJITGetterComplex*>(vm, JSValue::decode(thisValue))) {
792             if (domjitGetterComplex->m_enableException)
793                 return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("DOMJITGetterComplex slow call exception"))));
794         }
795         return JSValue::encode(jsNumber(thisObject->value()));
796     }
797
798     bool m_enableException { false };
799 };
800
801 class DOMJITFunctionObject : public DOMJITNode {
802 public:
803     DOMJITFunctionObject(VM& vm, Structure* structure)
804         : Base(vm, structure)
805     {
806     }
807
808     DECLARE_INFO;
809     typedef DOMJITNode Base;
810     static const unsigned StructureFlags = Base::StructureFlags;
811
812
813     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
814     {
815         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
816     }
817
818     static DOMJITFunctionObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
819     {
820         DOMJITFunctionObject* object = new (NotNull, allocateCell<DOMJITFunctionObject>(vm.heap, sizeof(DOMJITFunctionObject))) DOMJITFunctionObject(vm, structure);
821         object->finishCreation(vm, globalObject);
822         return object;
823     }
824
825     static EncodedJSValue JSC_HOST_CALL safeFunction(ExecState* exec)
826     {
827         VM& vm = exec->vm();
828         auto scope = DECLARE_THROW_SCOPE(vm);
829
830         DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, exec->thisValue());
831         if (!thisObject)
832             return throwVMTypeError(exec, scope);
833         return JSValue::encode(jsNumber(thisObject->value()));
834     }
835
836 #if ENABLE(JIT)
837     static EncodedJSValue JIT_OPERATION unsafeFunction(ExecState* exec, DOMJITNode* node)
838     {
839         NativeCallFrameTracer tracer(&exec->vm(), exec);
840         return JSValue::encode(jsNumber(node->value()));
841     }
842
843     static Ref<DOMJIT::Patchpoint> checkDOMJITNode()
844     {
845         static const double value = 42.0;
846         Ref<DOMJIT::Patchpoint> patchpoint = DOMJIT::Patchpoint::create();
847         patchpoint->numFPScratchRegisters = 1;
848         patchpoint->setGenerator([=](CCallHelpers& jit, DOMJIT::PatchpointParams& params) {
849             CCallHelpers::JumpList failureCases;
850             // May use scratch registers.
851             jit.loadDouble(CCallHelpers::TrustedImmPtr(&value), params.fpScratch(0));
852             failureCases.append(jit.branch8(
853                 CCallHelpers::NotEqual,
854                 CCallHelpers::Address(params[0].gpr(), JSCell::typeInfoTypeOffset()),
855                 CCallHelpers::TrustedImm32(JSC::JSType(LastJSCObjectType + 1))));
856             return failureCases;
857         });
858         return patchpoint;
859     }
860 #endif
861
862 private:
863     void finishCreation(VM&, JSGlobalObject*);
864 };
865
866 #if ENABLE(JIT)
867 static const DOMJIT::Signature DOMJITFunctionObjectSignature((uintptr_t)DOMJITFunctionObject::unsafeFunction, DOMJITFunctionObject::checkDOMJITNode, DOMJITFunctionObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);
868 #endif
869
870 void DOMJITFunctionObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
871 {
872     Base::finishCreation(vm);
873 #if ENABLE(JIT)
874     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "func"), 0, safeFunction, NoIntrinsic, &DOMJITFunctionObjectSignature, ReadOnly);
875 #else
876     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "func"), 0, safeFunction, NoIntrinsic, nullptr, ReadOnly);
877 #endif
878 }
879
880
881 const ClassInfo Element::s_info = { "Element", &Base::s_info, nullptr, CREATE_METHOD_TABLE(Element) };
882 const ClassInfo Masquerader::s_info = { "Masquerader", &Base::s_info, nullptr, CREATE_METHOD_TABLE(Masquerader) };
883 const ClassInfo Root::s_info = { "Root", &Base::s_info, nullptr, CREATE_METHOD_TABLE(Root) };
884 const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, nullptr, CREATE_METHOD_TABLE(ImpureGetter) };
885 const ClassInfo CustomGetter::s_info = { "CustomGetter", &Base::s_info, nullptr, CREATE_METHOD_TABLE(CustomGetter) };
886 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, CREATE_METHOD_TABLE(DOMJITNode) };
887 const ClassInfo DOMJITGetter::s_info = { "DOMJITGetter", &Base::s_info, nullptr, CREATE_METHOD_TABLE(DOMJITGetter) };
888 const ClassInfo DOMJITGetterComplex::s_info = { "DOMJITGetterComplex", &Base::s_info, nullptr, CREATE_METHOD_TABLE(DOMJITGetterComplex) };
889 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
890 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, nullptr, CREATE_METHOD_TABLE(RuntimeArray) };
891 const ClassInfo SimpleObject::s_info = { "SimpleObject", &Base::s_info, nullptr, CREATE_METHOD_TABLE(SimpleObject) };
892 static bool test262AsyncPassed { false };
893 static bool test262AsyncTest { false };
894
895 ElementHandleOwner* Element::handleOwner()
896 {
897     static ElementHandleOwner* owner = 0;
898     if (!owner)
899         owner = new ElementHandleOwner();
900     return owner;
901 }
902
903 void Element::finishCreation(VM& vm, Root* root)
904 {
905     Base::finishCreation(vm);
906     setRoot(vm, root);
907     m_root->setElement(this);
908 }
909
910 }
911
912 static bool fillBufferWithContentsOfFile(const String& fileName, Vector<char>& buffer);
913
914 class CommandLine;
915 class GlobalObject;
916 class Workers;
917
918 template<typename Func>
919 int runJSC(CommandLine, const Func&);
920 static void checkException(GlobalObject*, bool isLastFile, bool hasException, JSValue, const String& uncaughtExceptionName, bool alwaysDumpUncaughtException, bool dump, bool& success);
921
922 class Message : public ThreadSafeRefCounted<Message> {
923 public:
924     Message(ArrayBufferContents&&, int32_t);
925     ~Message();
926     
927     ArrayBufferContents&& releaseContents() { return WTFMove(m_contents); }
928     int32_t index() const { return m_index; }
929
930 private:
931     ArrayBufferContents m_contents;
932     int32_t m_index { 0 };
933 };
934
935 class Worker : public BasicRawSentinelNode<Worker> {
936 public:
937     Worker(Workers&);
938     ~Worker();
939     
940     void enqueue(const AbstractLocker&, RefPtr<Message>);
941     RefPtr<Message> dequeue();
942     
943     static Worker& current();
944
945 private:
946     static ThreadSpecific<Worker*>& currentWorker();
947
948     Workers& m_workers;
949     Deque<RefPtr<Message>> m_messages;
950 };
951
952 class Workers {
953 public:
954     Workers();
955     ~Workers();
956     
957     template<typename Func>
958     void broadcast(const Func&);
959     
960     void report(String);
961     String tryGetReport();
962     String getReport();
963     
964     static Workers& singleton();
965     
966 private:
967     friend class Worker;
968     
969     Lock m_lock;
970     Condition m_condition;
971     SentinelLinkedList<Worker, BasicRawSentinelNode<Worker>> m_workers;
972     Deque<String> m_reports;
973 };
974
975 static EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState*);
976 static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState*);
977 static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState*);
978 static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState*);
979 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(ExecState*);
980 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(ExecState*);
981 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(ExecState*);
982 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITFunctionObject(ExecState*);
983 static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState*);
984 static EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(ExecState*);
985 static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState*);
986
987 static EncodedJSValue JSC_HOST_CALL functionSetElementRoot(ExecState*);
988 static EncodedJSValue JSC_HOST_CALL functionCreateRoot(ExecState*);
989 static EncodedJSValue JSC_HOST_CALL functionCreateElement(ExecState*);
990 static EncodedJSValue JSC_HOST_CALL functionGetElement(ExecState*);
991 static EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(ExecState*);
992 static EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(ExecState*);
993 static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState*);
994 static EncodedJSValue JSC_HOST_CALL functionPrintStdOut(ExecState*);
995 static EncodedJSValue JSC_HOST_CALL functionPrintStdErr(ExecState*);
996 static EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*);
997 static EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState*);
998 static EncodedJSValue JSC_HOST_CALL functionDescribeArray(ExecState*);
999 static EncodedJSValue JSC_HOST_CALL functionSleepSeconds(ExecState*);
1000 static EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState*);
1001 static EncodedJSValue JSC_HOST_CALL functionGCAndSweep(ExecState*);
1002 static EncodedJSValue JSC_HOST_CALL functionFullGC(ExecState*);
1003 static EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState*);
1004 static EncodedJSValue JSC_HOST_CALL functionForceGCSlowPaths(ExecState*);
1005 static EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState*);
1006 static EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState*);
1007 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState*);
1008 #ifndef NDEBUG
1009 static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState*);
1010 #endif
1011 static EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*);
1012 static EncodedJSValue JSC_HOST_CALL functionRun(ExecState*);
1013 static EncodedJSValue JSC_HOST_CALL functionRunString(ExecState*);
1014 static EncodedJSValue JSC_HOST_CALL functionLoad(ExecState*);
1015 static EncodedJSValue JSC_HOST_CALL functionLoadString(ExecState*);
1016 static EncodedJSValue JSC_HOST_CALL functionReadFile(ExecState*);
1017 static EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState*);
1018 static EncodedJSValue JSC_HOST_CALL functionReadline(ExecState*);
1019 static EncodedJSValue JSC_HOST_CALL functionPreciseTime(ExecState*);
1020 static EncodedJSValue JSC_HOST_CALL functionNeverInlineFunction(ExecState*);
1021 static EncodedJSValue JSC_HOST_CALL functionNoDFG(ExecState*);
1022 static EncodedJSValue JSC_HOST_CALL functionNoFTL(ExecState*);
1023 static EncodedJSValue JSC_HOST_CALL functionNoOSRExitFuzzing(ExecState*);
1024 static EncodedJSValue JSC_HOST_CALL functionOptimizeNextInvocation(ExecState*);
1025 static EncodedJSValue JSC_HOST_CALL functionNumberOfDFGCompiles(ExecState*);
1026 static EncodedJSValue JSC_HOST_CALL functionJSCOptions(ExecState*);
1027 static EncodedJSValue JSC_HOST_CALL functionReoptimizationRetryCount(ExecState*);
1028 static EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState*);
1029 static EncodedJSValue JSC_HOST_CALL functionFailNextNewCodeBlock(ExecState*);
1030 static NO_RETURN_WITH_VALUE EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*);
1031 static NO_RETURN_DUE_TO_CRASH EncodedJSValue JSC_HOST_CALL functionAbort(ExecState*);
1032 static EncodedJSValue JSC_HOST_CALL functionFalse1(ExecState*);
1033 static EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*);
1034 static EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*);
1035 static EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*);
1036 static EncodedJSValue JSC_HOST_CALL functionIsInt32(ExecState*);
1037 static EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*);
1038 static EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState*);
1039 static EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState*);
1040 static EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState*);
1041 static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState*);
1042 static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState*);
1043 static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState*);
1044 static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState*);
1045 static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState*);
1046 static EncodedJSValue JSC_HOST_CALL functionBasicBlockExecutionCount(ExecState*);
1047 static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*);
1048 static EncodedJSValue JSC_HOST_CALL functionDrainMicrotasks(ExecState*);
1049 static EncodedJSValue JSC_HOST_CALL functionIs32BitPlatform(ExecState*);
1050 static EncodedJSValue JSC_HOST_CALL functionLoadModule(ExecState*);
1051 static EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(ExecState*);
1052 static EncodedJSValue JSC_HOST_CALL functionPlatformSupportsSamplingProfiler(ExecState*);
1053 static EncodedJSValue JSC_HOST_CALL functionGenerateHeapSnapshot(ExecState*);
1054 static EncodedJSValue JSC_HOST_CALL functionResetSuperSamplerState(ExecState*);
1055 static EncodedJSValue JSC_HOST_CALL functionEnsureArrayStorage(ExecState*);
1056 #if ENABLE(SAMPLING_PROFILER)
1057 static EncodedJSValue JSC_HOST_CALL functionStartSamplingProfiler(ExecState*);
1058 static EncodedJSValue JSC_HOST_CALL functionSamplingProfilerStackTraces(ExecState*);
1059 #endif
1060
1061 static EncodedJSValue JSC_HOST_CALL functionMaxArguments(ExecState*);
1062
1063 #if ENABLE(WEBASSEMBLY)
1064 static EncodedJSValue JSC_HOST_CALL functionTestWasmModuleFunctions(ExecState*);
1065 #endif
1066
1067 #if ENABLE(SAMPLING_FLAGS)
1068 static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
1069 static EncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState*);
1070 #endif
1071
1072 static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState*);
1073 static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState*);
1074 static EncodedJSValue JSC_HOST_CALL functionGetRandomSeed(ExecState*);
1075 static EncodedJSValue JSC_HOST_CALL functionSetRandomSeed(ExecState*);
1076 static EncodedJSValue JSC_HOST_CALL functionIsRope(ExecState*);
1077 static EncodedJSValue JSC_HOST_CALL functionCallerSourceOrigin(ExecState*);
1078 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(ExecState*);
1079 static EncodedJSValue JSC_HOST_CALL functionDollarCreateRealm(ExecState*);
1080 static EncodedJSValue JSC_HOST_CALL functionDollarDetachArrayBuffer(ExecState*);
1081 static EncodedJSValue JSC_HOST_CALL functionDollarEvalScript(ExecState*);
1082 static EncodedJSValue JSC_HOST_CALL functionDollarAgentStart(ExecState*);
1083 static EncodedJSValue JSC_HOST_CALL functionDollarAgentReceiveBroadcast(ExecState*);
1084 static EncodedJSValue JSC_HOST_CALL functionDollarAgentReport(ExecState*);
1085 static EncodedJSValue JSC_HOST_CALL functionDollarAgentSleep(ExecState*);
1086 static EncodedJSValue JSC_HOST_CALL functionDollarAgentBroadcast(ExecState*);
1087 static EncodedJSValue JSC_HOST_CALL functionDollarAgentGetReport(ExecState*);
1088 static EncodedJSValue JSC_HOST_CALL functionDollarAgentLeaving(ExecState*);
1089 static EncodedJSValue JSC_HOST_CALL functionWaitForReport(ExecState*);
1090 static EncodedJSValue JSC_HOST_CALL functionHeapCapacity(ExecState*);
1091
1092 struct Script {
1093     enum class StrictMode {
1094         Strict,
1095         Sloppy
1096     };
1097
1098     enum class ScriptType {
1099         Script,
1100         Module
1101     };
1102
1103     enum class CodeSource {
1104         File,
1105         CommandLine
1106     };
1107
1108     StrictMode strictMode;
1109     CodeSource codeSource;
1110     ScriptType scriptType;
1111     char* argument;
1112
1113     Script(StrictMode strictMode, CodeSource codeSource, ScriptType scriptType, char *argument)
1114         : strictMode(strictMode)
1115         , codeSource(codeSource)
1116         , scriptType(scriptType)
1117         , argument(argument)
1118     {
1119         if (strictMode == StrictMode::Strict)
1120             ASSERT(codeSource == CodeSource::File);
1121     }
1122 };
1123
1124 class CommandLine {
1125 public:
1126     CommandLine(int argc, char** argv)
1127     {
1128         parseArguments(argc, argv);
1129     }
1130
1131     bool m_interactive { false };
1132     bool m_dump { false };
1133     bool m_module { false };
1134     bool m_exitCode { false };
1135     Vector<Script> m_scripts;
1136     Vector<String> m_arguments;
1137     bool m_profile { false };
1138     String m_profilerOutput;
1139     String m_uncaughtExceptionName;
1140     bool m_alwaysDumpUncaughtException { false };
1141     bool m_dumpSamplingProfilerData { false };
1142     bool m_enableRemoteDebugging { false };
1143
1144     void parseArguments(int, char**);
1145 };
1146
1147 static const char interactivePrompt[] = ">>> ";
1148
1149 class StopWatch {
1150 public:
1151     void start();
1152     void stop();
1153     long getElapsedMS(); // call stop() first
1154
1155 private:
1156     double m_startTime;
1157     double m_stopTime;
1158 };
1159
1160 void StopWatch::start()
1161 {
1162     m_startTime = monotonicallyIncreasingTime();
1163 }
1164
1165 void StopWatch::stop()
1166 {
1167     m_stopTime = monotonicallyIncreasingTime();
1168 }
1169
1170 long StopWatch::getElapsedMS()
1171 {
1172     return static_cast<long>((m_stopTime - m_startTime) * 1000);
1173 }
1174
1175 template<typename Vector>
1176 static inline String stringFromUTF(const Vector& utf8)
1177 {
1178     return String::fromUTF8WithLatin1Fallback(utf8.data(), utf8.size());
1179 }
1180
1181 template<typename Vector>
1182 static inline SourceCode jscSource(const Vector& utf8, const SourceOrigin& sourceOrigin, const String& filename)
1183 {
1184     String str = stringFromUTF(utf8);
1185     return makeSource(str, sourceOrigin, filename);
1186 }
1187
1188 class GlobalObject : public JSGlobalObject {
1189 private:
1190     GlobalObject(VM&, Structure*);
1191
1192 public:
1193     typedef JSGlobalObject Base;
1194
1195     static GlobalObject* create(VM& vm, Structure* structure, const Vector<String>& arguments)
1196     {
1197         GlobalObject* object = new (NotNull, allocateCell<GlobalObject>(vm.heap)) GlobalObject(vm, structure);
1198         object->finishCreation(vm, arguments);
1199         return object;
1200     }
1201
1202     static const bool needsDestruction = false;
1203
1204     DECLARE_INFO;
1205     static const GlobalObjectMethodTable s_globalObjectMethodTable;
1206
1207     static Structure* createStructure(VM& vm, JSValue prototype)
1208     {
1209         return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info());
1210     }
1211
1212     static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject*) { return RuntimeFlags::createAllEnabled(); }
1213
1214 protected:
1215     void finishCreation(VM& vm, const Vector<String>& arguments)
1216     {
1217         Base::finishCreation(vm);
1218         
1219         addFunction(vm, "debug", functionDebug, 1);
1220         addFunction(vm, "describe", functionDescribe, 1);
1221         addFunction(vm, "describeArray", functionDescribeArray, 1);
1222         addFunction(vm, "print", functionPrintStdOut, 1);
1223         addFunction(vm, "printErr", functionPrintStdErr, 1);
1224         addFunction(vm, "quit", functionQuit, 0);
1225         addFunction(vm, "abort", functionAbort, 0);
1226         addFunction(vm, "gc", functionGCAndSweep, 0);
1227         addFunction(vm, "fullGC", functionFullGC, 0);
1228         addFunction(vm, "edenGC", functionEdenGC, 0);
1229         addFunction(vm, "forceGCSlowPaths", functionForceGCSlowPaths, 0);
1230         addFunction(vm, "gcHeapSize", functionHeapSize, 0);
1231         addFunction(vm, "addressOf", functionAddressOf, 1);
1232         addFunction(vm, "getGetterSetter", functionGetGetterSetter, 2);
1233 #ifndef NDEBUG
1234         addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
1235 #endif
1236         addFunction(vm, "version", functionVersion, 1);
1237         addFunction(vm, "run", functionRun, 1);
1238         addFunction(vm, "runString", functionRunString, 1);
1239         addFunction(vm, "load", functionLoad, 1);
1240         addFunction(vm, "loadString", functionLoadString, 1);
1241         addFunction(vm, "readFile", functionReadFile, 2);
1242         addFunction(vm, "read", functionReadFile, 2);
1243         addFunction(vm, "checkSyntax", functionCheckSyntax, 1);
1244         addFunction(vm, "sleepSeconds", functionSleepSeconds, 1);
1245         addFunction(vm, "jscStack", functionJSCStack, 1);
1246         addFunction(vm, "readline", functionReadline, 0);
1247         addFunction(vm, "preciseTime", functionPreciseTime, 0);
1248         addFunction(vm, "neverInlineFunction", functionNeverInlineFunction, 1);
1249         addFunction(vm, "noInline", functionNeverInlineFunction, 1);
1250         addFunction(vm, "noDFG", functionNoDFG, 1);
1251         addFunction(vm, "noFTL", functionNoFTL, 1);
1252         addFunction(vm, "noOSRExitFuzzing", functionNoOSRExitFuzzing, 1);
1253         addFunction(vm, "numberOfDFGCompiles", functionNumberOfDFGCompiles, 1);
1254         addFunction(vm, "jscOptions", functionJSCOptions, 0);
1255         addFunction(vm, "optimizeNextInvocation", functionOptimizeNextInvocation, 1);
1256         addFunction(vm, "reoptimizationRetryCount", functionReoptimizationRetryCount, 1);
1257         addFunction(vm, "transferArrayBuffer", functionTransferArrayBuffer, 1);
1258         addFunction(vm, "failNextNewCodeBlock", functionFailNextNewCodeBlock, 1);
1259 #if ENABLE(SAMPLING_FLAGS)
1260         addFunction(vm, "setSamplingFlags", functionSetSamplingFlags, 1);
1261         addFunction(vm, "clearSamplingFlags", functionClearSamplingFlags, 1);
1262 #endif
1263         addFunction(vm, "shadowChickenFunctionsOnStack", functionShadowChickenFunctionsOnStack, 0);
1264         addFunction(vm, "setGlobalConstRedeclarationShouldNotThrow", functionSetGlobalConstRedeclarationShouldNotThrow, 0);
1265         addConstructableFunction(vm, "Root", functionCreateRoot, 0);
1266         addConstructableFunction(vm, "Element", functionCreateElement, 1);
1267         addFunction(vm, "getElement", functionGetElement, 1);
1268         addFunction(vm, "setElementRoot", functionSetElementRoot, 2);
1269         
1270         addConstructableFunction(vm, "SimpleObject", functionCreateSimpleObject, 0);
1271         addFunction(vm, "getHiddenValue", functionGetHiddenValue, 1);
1272         addFunction(vm, "setHiddenValue", functionSetHiddenValue, 2);
1273         
1274         putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "DFGTrue"), 0, functionFalse1, DFGTrueIntrinsic, DontEnum);
1275         putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "OSRExit"), 0, functionUndefined1, OSRExitIntrinsic, DontEnum);
1276         putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "isFinalTier"), 0, functionFalse2, IsFinalTierIntrinsic, DontEnum);
1277         putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "predictInt32"), 0, functionUndefined2, SetInt32HeapPredictionIntrinsic, DontEnum);
1278         putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "isInt32"), 0, functionIsInt32, CheckInt32Intrinsic, DontEnum);
1279         putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "fiatInt52"), 0, functionIdentity, FiatInt52Intrinsic, DontEnum);
1280         
1281         addFunction(vm, "effectful42", functionEffectful42, 0);
1282         addFunction(vm, "makeMasquerader", functionMakeMasquerader, 0);
1283         addFunction(vm, "hasCustomProperties", functionHasCustomProperties, 0);
1284
1285         addFunction(vm, "createProxy", functionCreateProxy, 1);
1286         addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);
1287
1288         addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
1289         addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0);
1290         addFunction(vm, "createDOMJITNodeObject", functionCreateDOMJITNodeObject, 0);
1291         addFunction(vm, "createDOMJITGetterObject", functionCreateDOMJITGetterObject, 0);
1292         addFunction(vm, "createDOMJITGetterComplexObject", functionCreateDOMJITGetterComplexObject, 0);
1293         addFunction(vm, "createDOMJITFunctionObject", functionCreateDOMJITFunctionObject, 0);
1294         addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);
1295         addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0);
1296         addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
1297
1298         addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 0);
1299         addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);
1300         addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);
1301
1302         addFunction(vm, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges , 0);
1303         addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
1304         addFunction(vm, "basicBlockExecutionCount", functionBasicBlockExecutionCount, 2);
1305
1306         addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);
1307
1308         addFunction(vm, "drainMicrotasks", functionDrainMicrotasks, 0);
1309
1310         addFunction(vm, "getRandomSeed", functionGetRandomSeed, 0);
1311         addFunction(vm, "setRandomSeed", functionSetRandomSeed, 1);
1312         addFunction(vm, "isRope", functionIsRope, 1);
1313         addFunction(vm, "callerSourceOrigin", functionCallerSourceOrigin, 0);
1314
1315         addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);
1316
1317         addFunction(vm, "is32BitPlatform", functionIs32BitPlatform, 0);
1318
1319         addFunction(vm, "loadModule", functionLoadModule, 1);
1320         addFunction(vm, "checkModuleSyntax", functionCheckModuleSyntax, 1);
1321
1322         addFunction(vm, "platformSupportsSamplingProfiler", functionPlatformSupportsSamplingProfiler, 0);
1323         addFunction(vm, "generateHeapSnapshot", functionGenerateHeapSnapshot, 0);
1324         addFunction(vm, "resetSuperSamplerState", functionResetSuperSamplerState, 0);
1325         addFunction(vm, "ensureArrayStorage", functionEnsureArrayStorage, 0);
1326 #if ENABLE(SAMPLING_PROFILER)
1327         addFunction(vm, "startSamplingProfiler", functionStartSamplingProfiler, 0);
1328         addFunction(vm, "samplingProfilerStackTraces", functionSamplingProfilerStackTraces, 0);
1329 #endif
1330
1331         addFunction(vm, "maxArguments", functionMaxArguments, 0);
1332
1333 #if ENABLE(WEBASSEMBLY)
1334         addFunction(vm, "testWasmModuleFunctions", functionTestWasmModuleFunctions, 0);
1335 #endif
1336
1337         if (!arguments.isEmpty()) {
1338             JSArray* array = constructEmptyArray(globalExec(), 0);
1339             for (size_t i = 0; i < arguments.size(); ++i)
1340                 array->putDirectIndex(globalExec(), i, jsString(globalExec(), arguments[i]));
1341             putDirect(vm, Identifier::fromString(globalExec(), "arguments"), array);
1342         }
1343
1344         putDirect(vm, Identifier::fromString(globalExec(), "console"), jsUndefined());
1345         
1346         Structure* plainObjectStructure = JSFinalObject::createStructure(vm, this, objectPrototype(), 0);
1347         
1348         JSObject* dollar = JSFinalObject::create(vm, plainObjectStructure);
1349         putDirect(vm, Identifier::fromString(globalExec(), "$"), dollar);
1350         
1351         addFunction(vm, dollar, "createRealm", functionDollarCreateRealm, 0);
1352         addFunction(vm, dollar, "detachArrayBuffer", functionDollarDetachArrayBuffer, 1);
1353         addFunction(vm, dollar, "evalScript", functionDollarEvalScript, 1);
1354         
1355         dollar->putDirect(vm, Identifier::fromString(globalExec(), "global"), this);
1356         
1357         JSObject* agent = JSFinalObject::create(vm, plainObjectStructure);
1358         dollar->putDirect(vm, Identifier::fromString(globalExec(), "agent"), agent);
1359         
1360         // The test262 INTERPRETING.md document says that some of these functions are just in the main
1361         // thread and some are in the other threads. We just put them in all threads.
1362         addFunction(vm, agent, "start", functionDollarAgentStart, 1);
1363         addFunction(vm, agent, "receiveBroadcast", functionDollarAgentReceiveBroadcast, 1);
1364         addFunction(vm, agent, "report", functionDollarAgentReport, 1);
1365         addFunction(vm, agent, "sleep", functionDollarAgentSleep, 1);
1366         addFunction(vm, agent, "broadcast", functionDollarAgentBroadcast, 1);
1367         addFunction(vm, agent, "getReport", functionDollarAgentGetReport, 0);
1368         addFunction(vm, agent, "leaving", functionDollarAgentLeaving, 0);
1369         
1370         addFunction(vm, "waitForReport", functionWaitForReport, 0);
1371
1372         addFunction(vm, "heapCapacity", functionHeapCapacity, 0);
1373     }
1374     
1375     void addFunction(VM& vm, JSObject* object, const char* name, NativeFunction function, unsigned arguments)
1376     {
1377         Identifier identifier = Identifier::fromString(&vm, name);
1378         object->putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function));
1379     }
1380
1381     void addFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
1382     {
1383         addFunction(vm, this, name, function, arguments);
1384     }
1385     
1386     void addConstructableFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
1387     {
1388         Identifier identifier = Identifier::fromString(&vm, name);
1389         putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function, NoIntrinsic, function));
1390     }
1391
1392     static JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, ExecState*, JSModuleLoader*, JSString*, const SourceOrigin&);
1393     static JSInternalPromise* moduleLoaderResolve(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue);
1394     static JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue);
1395 };
1396
1397 const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, nullptr, CREATE_METHOD_TABLE(GlobalObject) };
1398 const GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = {
1399     &supportsRichSourceInfo,
1400     &shouldInterruptScript,
1401     &javaScriptRuntimeFlags,
1402     nullptr,
1403     &shouldInterruptScriptBeforeTimeout,
1404     &moduleLoaderImportModule,
1405     &moduleLoaderResolve,
1406     &moduleLoaderFetch,
1407     nullptr,
1408     nullptr,
1409     nullptr
1410 };
1411
1412 GlobalObject::GlobalObject(VM& vm, Structure* structure)
1413     : JSGlobalObject(vm, structure, &s_globalObjectMethodTable)
1414 {
1415 }
1416
1417 static UChar pathSeparator()
1418 {
1419 #if OS(WINDOWS)
1420     return '\\';
1421 #else
1422     return '/';
1423 #endif
1424 }
1425
1426 struct DirectoryName {
1427     // In unix, it is "/". In Windows, it becomes a drive letter like "C:\"
1428     String rootName;
1429
1430     // If the directory name is "/home/WebKit", this becomes "home/WebKit". If the directory name is "/", this becomes "".
1431     String queryName;
1432 };
1433
1434 struct ModuleName {
1435     ModuleName(const String& moduleName);
1436
1437     bool startsWithRoot() const
1438     {
1439         return !queries.isEmpty() && queries[0].isEmpty();
1440     }
1441
1442     Vector<String> queries;
1443 };
1444
1445 ModuleName::ModuleName(const String& moduleName)
1446 {
1447     // A module name given from code is represented as the UNIX style path. Like, `./A/B.js`.
1448     moduleName.split('/', true, queries);
1449 }
1450
1451 static std::optional<DirectoryName> extractDirectoryName(const String& absolutePathToFile)
1452 {
1453     size_t firstSeparatorPosition = absolutePathToFile.find(pathSeparator());
1454     if (firstSeparatorPosition == notFound)
1455         return std::nullopt;
1456     DirectoryName directoryName;
1457     directoryName.rootName = absolutePathToFile.substring(0, firstSeparatorPosition + 1); // Include the separator.
1458     size_t lastSeparatorPosition = absolutePathToFile.reverseFind(pathSeparator());
1459     ASSERT_WITH_MESSAGE(lastSeparatorPosition != notFound, "If the separator is not found, this function already returns when performing the forward search.");
1460     if (firstSeparatorPosition == lastSeparatorPosition)
1461         directoryName.queryName = StringImpl::empty();
1462     else {
1463         size_t queryStartPosition = firstSeparatorPosition + 1;
1464         size_t queryLength = lastSeparatorPosition - queryStartPosition; // Not include the last separator.
1465         directoryName.queryName = absolutePathToFile.substring(queryStartPosition, queryLength);
1466     }
1467     return directoryName;
1468 }
1469
1470 static std::optional<DirectoryName> currentWorkingDirectory()
1471 {
1472 #if OS(WINDOWS)
1473     // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364934.aspx
1474     // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#maxpath
1475     // The _MAX_PATH in Windows is 260. If the path of the current working directory is longer than that, _getcwd truncates the result.
1476     // And other I/O functions taking a path name also truncate it. To avoid this situation,
1477     //
1478     // (1). When opening the file in Windows for modules, we always use the abosolute path and add "\\?\" prefix to the path name.
1479     // (2). When retrieving the current working directory, use GetCurrentDirectory instead of _getcwd.
1480     //
1481     // In the path utility functions inside the JSC shell, we does not handle the UNC and UNCW including the network host name.
1482     DWORD bufferLength = ::GetCurrentDirectoryW(0, nullptr);
1483     if (!bufferLength)
1484         return std::nullopt;
1485     // In Windows, wchar_t is the UTF-16LE.
1486     // https://msdn.microsoft.com/en-us/library/dd374081.aspx
1487     // https://msdn.microsoft.com/en-us/library/windows/desktop/ff381407.aspx
1488     auto buffer = std::make_unique<wchar_t[]>(bufferLength);
1489     DWORD lengthNotIncludingNull = ::GetCurrentDirectoryW(bufferLength, buffer.get());
1490     static_assert(sizeof(wchar_t) == sizeof(UChar), "In Windows, both are UTF-16LE");
1491     String directoryString = String(reinterpret_cast<UChar*>(buffer.get()));
1492     // We don't support network path like \\host\share\<path name>.
1493     if (directoryString.startsWith("\\\\"))
1494         return std::nullopt;
1495 #else
1496     auto buffer = std::make_unique<char[]>(PATH_MAX);
1497     if (!getcwd(buffer.get(), PATH_MAX))
1498         return std::nullopt;
1499     String directoryString = String::fromUTF8(buffer.get());
1500 #endif
1501     if (directoryString.isEmpty())
1502         return std::nullopt;
1503
1504     if (directoryString[directoryString.length() - 1] == pathSeparator())
1505         return extractDirectoryName(directoryString);
1506     // Append the seperator to represents the file name. extractDirectoryName only accepts the absolute file name.
1507     return extractDirectoryName(makeString(directoryString, pathSeparator()));
1508 }
1509
1510 static String resolvePath(const DirectoryName& directoryName, const ModuleName& moduleName)
1511 {
1512     Vector<String> directoryPieces;
1513     directoryName.queryName.split(pathSeparator(), false, directoryPieces);
1514
1515     // Only first '/' is recognized as the path from the root.
1516     if (moduleName.startsWithRoot())
1517         directoryPieces.clear();
1518
1519     for (const auto& query : moduleName.queries) {
1520         if (query == String(ASCIILiteral(".."))) {
1521             if (!directoryPieces.isEmpty())
1522                 directoryPieces.removeLast();
1523         } else if (!query.isEmpty() && query != String(ASCIILiteral(".")))
1524             directoryPieces.append(query);
1525     }
1526
1527     StringBuilder builder;
1528     builder.append(directoryName.rootName);
1529     for (size_t i = 0; i < directoryPieces.size(); ++i) {
1530         builder.append(directoryPieces[i]);
1531         if (i + 1 != directoryPieces.size())
1532             builder.append(pathSeparator());
1533     }
1534     return builder.toString();
1535 }
1536
1537 static String absolutePath(const String& fileName)
1538 {
1539     auto directoryName = currentWorkingDirectory();
1540     if (!directoryName)
1541         return fileName;
1542     return resolvePath(directoryName.value(), ModuleName(fileName.impl()));
1543 }
1544
1545 JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* globalObject, ExecState* exec, JSModuleLoader*, JSString* moduleNameValue, const SourceOrigin& sourceOrigin)
1546 {
1547     VM& vm = globalObject->vm();
1548     auto scope = DECLARE_CATCH_SCOPE(vm);
1549
1550     auto rejectPromise = [&] (JSValue error) {
1551         return JSInternalPromiseDeferred::create(exec, globalObject)->reject(exec, error);
1552     };
1553
1554     auto referrer = sourceOrigin.string();
1555     auto moduleName = moduleNameValue->value(exec);
1556     if (UNLIKELY(scope.exception())) {
1557         JSValue exception = scope.exception();
1558         scope.clearException();
1559         return rejectPromise(exception);
1560     }
1561
1562     auto directoryName = extractDirectoryName(referrer.impl());
1563     if (!directoryName)
1564         return rejectPromise(createError(exec, makeString("Could not resolve the referrer name '", String(referrer.impl()), "'.")));
1565
1566     return JSC::importModule(exec, Identifier::fromString(&vm, resolvePath(directoryName.value(), ModuleName(moduleName))), jsUndefined());
1567 }
1568
1569 JSInternalPromise* GlobalObject::moduleLoaderResolve(JSGlobalObject* globalObject, ExecState* exec, JSModuleLoader*, JSValue keyValue, JSValue referrerValue, JSValue)
1570 {
1571     VM& vm = globalObject->vm();
1572     auto scope = DECLARE_CATCH_SCOPE(vm);
1573
1574     JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::create(exec, globalObject);
1575     const Identifier key = keyValue.toPropertyKey(exec);
1576     if (UNLIKELY(scope.exception())) {
1577         JSValue exception = scope.exception();
1578         scope.clearException();
1579         return deferred->reject(exec, exception);
1580     }
1581
1582     if (key.isSymbol())
1583         return deferred->resolve(exec, keyValue);
1584
1585     if (referrerValue.isUndefined()) {
1586         auto directoryName = currentWorkingDirectory();
1587         if (!directoryName)
1588             return deferred->reject(exec, createError(exec, ASCIILiteral("Could not resolve the current working directory.")));
1589         return deferred->resolve(exec, jsString(exec, resolvePath(directoryName.value(), ModuleName(key.impl()))));
1590     }
1591
1592     const Identifier referrer = referrerValue.toPropertyKey(exec);
1593     if (UNLIKELY(scope.exception())) {
1594         JSValue exception = scope.exception();
1595         scope.clearException();
1596         return deferred->reject(exec, exception);
1597     }
1598
1599     if (referrer.isSymbol()) {
1600         auto directoryName = currentWorkingDirectory();
1601         if (!directoryName)
1602             return deferred->reject(exec, createError(exec, ASCIILiteral("Could not resolve the current working directory.")));
1603         return deferred->resolve(exec, jsString(exec, resolvePath(directoryName.value(), ModuleName(key.impl()))));
1604     }
1605
1606     // If the referrer exists, we assume that the referrer is the correct absolute path.
1607     auto directoryName = extractDirectoryName(referrer.impl());
1608     if (!directoryName)
1609         return deferred->reject(exec, createError(exec, makeString("Could not resolve the referrer name '", String(referrer.impl()), "'.")));
1610     return deferred->resolve(exec, jsString(exec, resolvePath(directoryName.value(), ModuleName(key.impl()))));
1611 }
1612
1613 static void convertShebangToJSComment(Vector<char>& buffer)
1614 {
1615     if (buffer.size() >= 2) {
1616         if (buffer[0] == '#' && buffer[1] == '!')
1617             buffer[0] = buffer[1] = '/';
1618     }
1619 }
1620
1621 static bool fillBufferWithContentsOfFile(FILE* file, Vector<char>& buffer)
1622 {
1623     // We might have injected "use strict"; at the top.
1624     size_t initialSize = buffer.size();
1625     fseek(file, 0, SEEK_END);
1626     size_t bufferCapacity = ftell(file);
1627     fseek(file, 0, SEEK_SET);
1628     buffer.resize(bufferCapacity + initialSize);
1629     size_t readSize = fread(buffer.data() + initialSize, 1, buffer.size(), file);
1630     return readSize == buffer.size() - initialSize;
1631 }
1632
1633 static bool fillBufferWithContentsOfFile(const String& fileName, Vector<char>& buffer)
1634 {
1635     FILE* f = fopen(fileName.utf8().data(), "rb");
1636     if (!f) {
1637         fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data());
1638         return false;
1639     }
1640
1641     bool result = fillBufferWithContentsOfFile(f, buffer);
1642     fclose(f);
1643
1644     return result;
1645 }
1646
1647 static bool fetchScriptFromLocalFileSystem(const String& fileName, Vector<char>& buffer)
1648 {
1649     if (!fillBufferWithContentsOfFile(fileName, buffer))
1650         return false;
1651     convertShebangToJSComment(buffer);
1652     return true;
1653 }
1654
1655 static bool fetchModuleFromLocalFileSystem(const String& fileName, Vector<char>& buffer)
1656 {
1657     // We assume that fileName is always an absolute path.
1658 #if OS(WINDOWS)
1659     // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#maxpath
1660     // Use long UNC to pass the long path name to the Windows APIs.
1661     String longUNCPathName = WTF::makeString("\\\\?\\", fileName);
1662     static_assert(sizeof(wchar_t) == sizeof(UChar), "In Windows, both are UTF-16LE");
1663     auto utf16Vector = longUNCPathName.charactersWithNullTermination();
1664     FILE* f = _wfopen(reinterpret_cast<wchar_t*>(utf16Vector.data()), L"rb");
1665 #else
1666     FILE* f = fopen(fileName.utf8().data(), "r");
1667 #endif
1668     if (!f) {
1669         fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data());
1670         return false;
1671     }
1672
1673     bool result = fillBufferWithContentsOfFile(f, buffer);
1674     if (result)
1675         convertShebangToJSComment(buffer);
1676     fclose(f);
1677
1678     return result;
1679 }
1680
1681 JSInternalPromise* GlobalObject::moduleLoaderFetch(JSGlobalObject* globalObject, ExecState* exec, JSModuleLoader*, JSValue key, JSValue)
1682 {
1683     VM& vm = globalObject->vm();
1684     auto scope = DECLARE_CATCH_SCOPE(vm);
1685     JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::create(exec, globalObject);
1686     String moduleKey = key.toWTFString(exec);
1687     if (UNLIKELY(scope.exception())) {
1688         JSValue exception = scope.exception();
1689         scope.clearException();
1690         return deferred->reject(exec, exception);
1691     }
1692
1693     // Here, now we consider moduleKey as the fileName.
1694     Vector<char> utf8;
1695     if (!fetchModuleFromLocalFileSystem(moduleKey, utf8))
1696         return deferred->reject(exec, createError(exec, makeString("Could not open file '", moduleKey, "'.")));
1697
1698     return deferred->resolve(exec, JSSourceCode::create(exec->vm(), makeSource(stringFromUTF(utf8), SourceOrigin { moduleKey }, moduleKey, TextPosition(), SourceProviderSourceType::Module)));
1699 }
1700
1701
1702 static EncodedJSValue printInternal(ExecState* exec, FILE* out)
1703 {
1704     VM& vm = exec->vm();
1705     auto scope = DECLARE_THROW_SCOPE(vm);
1706
1707     if (test262AsyncTest) {
1708         JSValue value = exec->argument(0);
1709         if (value.isString() && WTF::equal(asString(value)->value(exec).impl(), "Test262:AsyncTestComplete"))
1710             test262AsyncPassed = true;
1711         return JSValue::encode(jsUndefined());
1712     }
1713
1714     for (unsigned i = 0; i < exec->argumentCount(); ++i) {
1715         if (i)
1716             if (EOF == fputc(' ', out))
1717                 goto fail;
1718
1719         auto viewWithString = exec->uncheckedArgument(i).toString(exec)->viewWithUnderlyingString(*exec);
1720         RETURN_IF_EXCEPTION(scope, encodedJSValue());
1721         if (fprintf(out, "%s", viewWithString.view.utf8().data()) < 0)
1722             goto fail;
1723     }
1724
1725     fputc('\n', out);
1726 fail:
1727     fflush(out);
1728     return JSValue::encode(jsUndefined());
1729 }
1730
1731 EncodedJSValue JSC_HOST_CALL functionPrintStdOut(ExecState* exec) { return printInternal(exec, stdout); }
1732 EncodedJSValue JSC_HOST_CALL functionPrintStdErr(ExecState* exec) { return printInternal(exec, stderr); }
1733
1734 #ifndef NDEBUG
1735 EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec)
1736 {
1737     VMEntryFrame* topVMEntryFrame = exec->vm().topVMEntryFrame;
1738     ExecState* callerFrame = exec->callerFrame(topVMEntryFrame);
1739     if (callerFrame)
1740         exec->vm().interpreter->dumpCallFrame(callerFrame);
1741     return JSValue::encode(jsUndefined());
1742 }
1743 #endif
1744
1745 EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec)
1746 {
1747     VM& vm = exec->vm();
1748     auto scope = DECLARE_THROW_SCOPE(vm);
1749     auto viewWithString = exec->argument(0).toString(exec)->viewWithUnderlyingString(*exec);
1750     RETURN_IF_EXCEPTION(scope, encodedJSValue());
1751     fprintf(stderr, "--> %s\n", viewWithString.view.utf8().data());
1752     return JSValue::encode(jsUndefined());
1753 }
1754
1755 EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState* exec)
1756 {
1757     if (exec->argumentCount() < 1)
1758         return JSValue::encode(jsUndefined());
1759     return JSValue::encode(jsString(exec, toString(exec->argument(0))));
1760 }
1761
1762 EncodedJSValue JSC_HOST_CALL functionDescribeArray(ExecState* exec)
1763 {
1764     if (exec->argumentCount() < 1)
1765         return JSValue::encode(jsUndefined());
1766     VM& vm = exec->vm();
1767     JSObject* object = jsDynamicCast<JSObject*>(vm, exec->argument(0));
1768     if (!object)
1769         return JSValue::encode(jsNontrivialString(exec, ASCIILiteral("<not object>")));
1770     return JSValue::encode(jsNontrivialString(exec, toString("<Butterfly: ", RawPointer(object->butterfly()), "; public length: ", object->getArrayLength(), "; vector length: ", object->getVectorLength(), ">")));
1771 }
1772
1773 EncodedJSValue JSC_HOST_CALL functionSleepSeconds(ExecState* exec)
1774 {
1775     VM& vm = exec->vm();
1776     auto scope = DECLARE_THROW_SCOPE(vm);
1777
1778     if (exec->argumentCount() >= 1) {
1779         Seconds seconds = Seconds(exec->argument(0).toNumber(exec));
1780         RETURN_IF_EXCEPTION(scope, encodedJSValue());
1781         sleep(seconds);
1782     }
1783     
1784     return JSValue::encode(jsUndefined());
1785 }
1786
1787 class FunctionJSCStackFunctor {
1788 public:
1789     FunctionJSCStackFunctor(StringBuilder& trace)
1790         : m_trace(trace)
1791     {
1792     }
1793
1794     StackVisitor::Status operator()(StackVisitor& visitor) const
1795     {
1796         m_trace.append(String::format("    %zu   %s\n", visitor->index(), visitor->toString().utf8().data()));
1797         return StackVisitor::Continue;
1798     }
1799
1800 private:
1801     StringBuilder& m_trace;
1802 };
1803
1804 EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState* exec)
1805 {
1806     StringBuilder trace;
1807     trace.appendLiteral("--> Stack trace:\n");
1808
1809     FunctionJSCStackFunctor functor(trace);
1810     exec->iterate(functor);
1811     fprintf(stderr, "%s", trace.toString().utf8().data());
1812     return JSValue::encode(jsUndefined());
1813 }
1814
1815 EncodedJSValue JSC_HOST_CALL functionCreateRoot(ExecState* exec)
1816 {
1817     JSLockHolder lock(exec);
1818     return JSValue::encode(Root::create(exec->vm(), exec->lexicalGlobalObject()));
1819 }
1820
1821 EncodedJSValue JSC_HOST_CALL functionCreateElement(ExecState* exec)
1822 {
1823     VM& vm = exec->vm();
1824     JSLockHolder lock(vm);
1825     auto scope = DECLARE_THROW_SCOPE(vm);
1826
1827     Root* root = jsDynamicCast<Root*>(vm, exec->argument(0));
1828     if (!root)
1829         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Cannot create Element without a Root."))));
1830     return JSValue::encode(Element::create(vm, exec->lexicalGlobalObject(), root));
1831 }
1832
1833 EncodedJSValue JSC_HOST_CALL functionGetElement(ExecState* exec)
1834 {
1835     JSLockHolder lock(exec);
1836     VM& vm = exec->vm();
1837     Root* root = jsDynamicCast<Root*>(vm, exec->argument(0));
1838     if (!root)
1839         return JSValue::encode(jsUndefined());
1840     Element* result = root->element();
1841     return JSValue::encode(result ? result : jsUndefined());
1842 }
1843
1844 EncodedJSValue JSC_HOST_CALL functionSetElementRoot(ExecState* exec)
1845 {
1846     JSLockHolder lock(exec);
1847     VM& vm = exec->vm();
1848     Element* element = jsDynamicCast<Element*>(vm, exec->argument(0));
1849     Root* root = jsDynamicCast<Root*>(vm, exec->argument(1));
1850     if (element && root)
1851         element->setRoot(exec->vm(), root);
1852     return JSValue::encode(jsUndefined());
1853 }
1854
1855 EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(ExecState* exec)
1856 {
1857     JSLockHolder lock(exec);
1858     return JSValue::encode(SimpleObject::create(exec->vm(), exec->lexicalGlobalObject()));
1859 }
1860
1861 EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(ExecState* exec)
1862 {
1863     VM& vm = exec->vm();
1864     JSLockHolder lock(vm);
1865     auto scope = DECLARE_THROW_SCOPE(vm);
1866
1867     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, exec->argument(0));
1868     if (UNLIKELY(!simpleObject)) {
1869         throwTypeError(exec, scope, ASCIILiteral("Invalid use of getHiddenValue test function"));
1870         return encodedJSValue();
1871     }
1872     return JSValue::encode(simpleObject->hiddenValue());
1873 }
1874
1875 EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState* exec)
1876 {
1877     VM& vm = exec->vm();
1878     JSLockHolder lock(vm);
1879     auto scope = DECLARE_THROW_SCOPE(vm);
1880
1881     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, exec->argument(0));
1882     if (UNLIKELY(!simpleObject)) {
1883         throwTypeError(exec, scope, ASCIILiteral("Invalid use of setHiddenValue test function"));
1884         return encodedJSValue();
1885     }
1886     JSValue value = exec->argument(1);
1887     simpleObject->setHiddenValue(exec->vm(), value);
1888     return JSValue::encode(jsUndefined());
1889 }
1890
1891 EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState* exec)
1892 {
1893     JSLockHolder lock(exec);
1894     JSValue target = exec->argument(0);
1895     if (!target.isObject())
1896         return JSValue::encode(jsUndefined());
1897     JSObject* jsTarget = asObject(target.asCell());
1898     Structure* structure = JSProxy::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsTarget->getPrototypeDirect(), ImpureProxyType);
1899     JSProxy* proxy = JSProxy::create(exec->vm(), structure, jsTarget);
1900     return JSValue::encode(proxy);
1901 }
1902
1903 EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState* exec)
1904 {
1905     JSLockHolder lock(exec);
1906     RuntimeArray* array = RuntimeArray::create(exec);
1907     return JSValue::encode(array);
1908 }
1909
1910 EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState* exec)
1911 {
1912     JSLockHolder lock(exec);
1913     JSValue target = exec->argument(0);
1914     JSObject* delegate = nullptr;
1915     if (target.isObject())
1916         delegate = asObject(target.asCell());
1917     Structure* structure = ImpureGetter::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsNull());
1918     ImpureGetter* result = ImpureGetter::create(exec->vm(), structure, delegate);
1919     return JSValue::encode(result);
1920 }
1921
1922 EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState* exec)
1923 {
1924     JSLockHolder lock(exec);
1925     Structure* structure = CustomGetter::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsNull());
1926     CustomGetter* result = CustomGetter::create(exec->vm(), structure);
1927     return JSValue::encode(result);
1928 }
1929
1930 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(ExecState* exec)
1931 {
1932     JSLockHolder lock(exec);
1933     Structure* structure = DOMJITNode::createStructure(exec->vm(), exec->lexicalGlobalObject(), DOMJITGetter::create(exec->vm(), DOMJITGetter::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsNull())));
1934     DOMJITNode* result = DOMJITNode::create(exec->vm(), structure);
1935     return JSValue::encode(result);
1936 }
1937
1938 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(ExecState* exec)
1939 {
1940     JSLockHolder lock(exec);
1941     Structure* structure = DOMJITGetter::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsNull());
1942     DOMJITGetter* result = DOMJITGetter::create(exec->vm(), structure);
1943     return JSValue::encode(result);
1944 }
1945
1946 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(ExecState* exec)
1947 {
1948     JSLockHolder lock(exec);
1949     Structure* structure = DOMJITGetterComplex::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsNull());
1950     DOMJITGetterComplex* result = DOMJITGetterComplex::create(exec->vm(), exec->lexicalGlobalObject(), structure);
1951     return JSValue::encode(result);
1952 }
1953
1954 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITFunctionObject(ExecState* exec)
1955 {
1956     JSLockHolder lock(exec);
1957     Structure* structure = DOMJITFunctionObject::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsNull());
1958     DOMJITFunctionObject* result = DOMJITFunctionObject::create(exec->vm(), exec->lexicalGlobalObject(), structure);
1959     return JSValue::encode(result);
1960 }
1961
1962 EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState* exec)
1963 {
1964     VM& vm = exec->vm();
1965     JSLockHolder lock(vm);
1966     auto scope = DECLARE_THROW_SCOPE(vm);
1967
1968     JSValue base = exec->argument(0);
1969     if (!base.isObject())
1970         return JSValue::encode(jsUndefined());
1971     JSValue delegate = exec->argument(1);
1972     if (!delegate.isObject())
1973         return JSValue::encode(jsUndefined());
1974     ImpureGetter* impureGetter = jsDynamicCast<ImpureGetter*>(vm, asObject(base.asCell()));
1975     if (UNLIKELY(!impureGetter)) {
1976         throwTypeError(exec, scope, ASCIILiteral("argument is not an ImpureGetter"));
1977         return encodedJSValue();
1978     }
1979     impureGetter->setDelegate(vm, asObject(delegate.asCell()));
1980     return JSValue::encode(jsUndefined());
1981 }
1982
1983 EncodedJSValue JSC_HOST_CALL functionGCAndSweep(ExecState* exec)
1984 {
1985     JSLockHolder lock(exec);
1986     exec->heap()->collectAllGarbage();
1987     return JSValue::encode(jsNumber(exec->heap()->sizeAfterLastFullCollection()));
1988 }
1989
1990 EncodedJSValue JSC_HOST_CALL functionFullGC(ExecState* exec)
1991 {
1992     JSLockHolder lock(exec);
1993     exec->heap()->collectSync(CollectionScope::Full);
1994     return JSValue::encode(jsNumber(exec->heap()->sizeAfterLastFullCollection()));
1995 }
1996
1997 EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState* exec)
1998 {
1999     JSLockHolder lock(exec);
2000     exec->heap()->collectSync(CollectionScope::Eden);
2001     return JSValue::encode(jsNumber(exec->heap()->sizeAfterLastEdenCollection()));
2002 }
2003
2004 EncodedJSValue JSC_HOST_CALL functionForceGCSlowPaths(ExecState*)
2005 {
2006     // It's best for this to be the first thing called in the 
2007     // JS program so the option is set to true before we JIT.
2008     Options::forceGCSlowPaths() = true;
2009     return JSValue::encode(jsUndefined());
2010 }
2011
2012 EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState* exec)
2013 {
2014     JSLockHolder lock(exec);
2015     return JSValue::encode(jsNumber(exec->heap()->size()));
2016 }
2017
2018 // This function is not generally very helpful in 64-bit code as the tag and payload
2019 // share a register. But in 32-bit JITed code the tag may not be checked if an
2020 // optimization removes type checking requirements, such as in ===.
2021 EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState* exec)
2022 {
2023     JSValue value = exec->argument(0);
2024     if (!value.isCell())
2025         return JSValue::encode(jsUndefined());
2026     // Need to cast to uint64_t so bitwise_cast will play along.
2027     uint64_t asNumber = reinterpret_cast<uint64_t>(value.asCell());
2028     EncodedJSValue returnValue = JSValue::encode(jsNumber(bitwise_cast<double>(asNumber)));
2029     return returnValue;
2030 }
2031
2032 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState* exec)
2033 {
2034     JSValue value = exec->argument(0);
2035     if (!value.isObject())
2036         return JSValue::encode(jsUndefined());
2037
2038     JSValue property = exec->argument(1);
2039     if (!property.isString())
2040         return JSValue::encode(jsUndefined());
2041
2042     PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry);
2043     value.getPropertySlot(exec, asString(property)->toIdentifier(exec), slot);
2044
2045     JSValue result;
2046     if (slot.isCacheableGetter())
2047         result = slot.getterSetter();
2048     else
2049         result = jsNull();
2050
2051     return JSValue::encode(result);
2052 }
2053
2054 EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*)
2055 {
2056     // We need this function for compatibility with the Mozilla JS tests but for now
2057     // we don't actually do any version-specific handling
2058     return JSValue::encode(jsUndefined());
2059 }
2060
2061 EncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec)
2062 {
2063     VM& vm = exec->vm();
2064     auto scope = DECLARE_THROW_SCOPE(vm);
2065
2066     String fileName = exec->argument(0).toWTFString(exec);
2067     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2068     Vector<char> script;
2069     if (!fetchScriptFromLocalFileSystem(fileName, script))
2070         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Could not open file."))));
2071
2072     GlobalObject* globalObject = GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>());
2073
2074     JSArray* array = constructEmptyArray(globalObject->globalExec(), 0);
2075     for (unsigned i = 1; i < exec->argumentCount(); ++i)
2076         array->putDirectIndex(globalObject->globalExec(), i - 1, exec->uncheckedArgument(i));
2077     globalObject->putDirect(
2078         vm, Identifier::fromString(globalObject->globalExec(), "arguments"), array);
2079
2080     NakedPtr<Exception> exception;
2081     StopWatch stopWatch;
2082     stopWatch.start();
2083     evaluate(globalObject->globalExec(), jscSource(script, SourceOrigin { absolutePath(fileName) }, fileName), JSValue(), exception);
2084     stopWatch.stop();
2085
2086     if (exception) {
2087         throwException(globalObject->globalExec(), scope, exception);
2088         return JSValue::encode(jsUndefined());
2089     }
2090     
2091     return JSValue::encode(jsNumber(stopWatch.getElapsedMS()));
2092 }
2093
2094 EncodedJSValue JSC_HOST_CALL functionRunString(ExecState* exec)
2095 {
2096     VM& vm = exec->vm();
2097     auto scope = DECLARE_THROW_SCOPE(vm);
2098
2099     String source = exec->argument(0).toWTFString(exec);
2100     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2101
2102     GlobalObject* globalObject = GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>());
2103
2104     JSArray* array = constructEmptyArray(globalObject->globalExec(), 0);
2105     for (unsigned i = 1; i < exec->argumentCount(); ++i)
2106         array->putDirectIndex(globalObject->globalExec(), i - 1, exec->uncheckedArgument(i));
2107     globalObject->putDirect(
2108         vm, Identifier::fromString(globalObject->globalExec(), "arguments"), array);
2109
2110     NakedPtr<Exception> exception;
2111     evaluate(globalObject->globalExec(), makeSource(source, exec->callerSourceOrigin()), JSValue(), exception);
2112
2113     if (exception) {
2114         scope.throwException(globalObject->globalExec(), exception);
2115         return JSValue::encode(jsUndefined());
2116     }
2117     
2118     return JSValue::encode(globalObject);
2119 }
2120
2121 EncodedJSValue JSC_HOST_CALL functionLoad(ExecState* exec)
2122 {
2123     VM& vm = exec->vm();
2124     auto scope = DECLARE_THROW_SCOPE(vm);
2125
2126     String fileName = exec->argument(0).toWTFString(exec);
2127     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2128     Vector<char> script;
2129     if (!fetchScriptFromLocalFileSystem(fileName, script))
2130         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Could not open file."))));
2131
2132     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
2133     
2134     NakedPtr<Exception> evaluationException;
2135     JSValue result = evaluate(globalObject->globalExec(), jscSource(script, SourceOrigin { absolutePath(fileName) }, fileName), JSValue(), evaluationException);
2136     if (evaluationException)
2137         throwException(exec, scope, evaluationException);
2138     return JSValue::encode(result);
2139 }
2140
2141 EncodedJSValue JSC_HOST_CALL functionLoadString(ExecState* exec)
2142 {
2143     VM& vm = exec->vm();
2144     auto scope = DECLARE_THROW_SCOPE(vm);
2145
2146     String sourceCode = exec->argument(0).toWTFString(exec);
2147     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2148     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
2149
2150     NakedPtr<Exception> evaluationException;
2151     JSValue result = evaluate(globalObject->globalExec(), makeSource(sourceCode, exec->callerSourceOrigin()), JSValue(), evaluationException);
2152     if (evaluationException)
2153         throwException(exec, scope, evaluationException);
2154     return JSValue::encode(result);
2155 }
2156
2157 EncodedJSValue JSC_HOST_CALL functionReadFile(ExecState* exec)
2158 {
2159     VM& vm = exec->vm();
2160     auto scope = DECLARE_THROW_SCOPE(vm);
2161
2162     String fileName = exec->argument(0).toWTFString(exec);
2163     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2164
2165     bool isBinary = false;
2166     if (exec->argumentCount() > 1) {
2167         String type = exec->argument(1).toWTFString(exec);
2168         RETURN_IF_EXCEPTION(scope, encodedJSValue());
2169         if (type != "binary")
2170             return throwVMError(exec, scope, "Expected 'binary' as second argument.");
2171         isBinary = true;
2172     }
2173
2174     Vector<char> content;
2175     if (!fillBufferWithContentsOfFile(fileName, content))
2176         return throwVMError(exec, scope, "Could not open file.");
2177
2178     if (!isBinary)
2179         return JSValue::encode(jsString(exec, stringFromUTF(content)));
2180
2181     Structure* structure = exec->lexicalGlobalObject()->typedArrayStructure(TypeUint8);
2182     auto length = content.size();
2183     JSObject* result = createUint8TypedArray(exec, structure, ArrayBuffer::createFromBytes(content.releaseBuffer().leakPtr(), length, [] (void* p) { fastFree(p); }), 0, length);
2184     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2185
2186     return JSValue::encode(result);
2187 }
2188
2189 EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState* exec)
2190 {
2191     VM& vm = exec->vm();
2192     auto scope = DECLARE_THROW_SCOPE(vm);
2193
2194     String fileName = exec->argument(0).toWTFString(exec);
2195     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2196     Vector<char> script;
2197     if (!fetchScriptFromLocalFileSystem(fileName, script))
2198         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Could not open file."))));
2199
2200     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
2201
2202     StopWatch stopWatch;
2203     stopWatch.start();
2204
2205     JSValue syntaxException;
2206     bool validSyntax = checkSyntax(globalObject->globalExec(), jscSource(script, SourceOrigin { absolutePath(fileName) }, fileName), &syntaxException);
2207     stopWatch.stop();
2208
2209     if (!validSyntax)
2210         throwException(exec, scope, syntaxException);
2211     return JSValue::encode(jsNumber(stopWatch.getElapsedMS()));
2212 }
2213
2214 #if ENABLE(SAMPLING_FLAGS)
2215 EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState* exec)
2216 {
2217     for (unsigned i = 0; i < exec->argumentCount(); ++i) {
2218         unsigned flag = static_cast<unsigned>(exec->uncheckedArgument(i).toNumber(exec));
2219         if ((flag >= 1) && (flag <= 32))
2220             SamplingFlags::setFlag(flag);
2221     }
2222     return JSValue::encode(jsNull());
2223 }
2224
2225 EncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState* exec)
2226 {
2227     for (unsigned i = 0; i < exec->argumentCount(); ++i) {
2228         unsigned flag = static_cast<unsigned>(exec->uncheckedArgument(i).toNumber(exec));
2229         if ((flag >= 1) && (flag <= 32))
2230             SamplingFlags::clearFlag(flag);
2231     }
2232     return JSValue::encode(jsNull());
2233 }
2234 #endif
2235
2236 EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState* exec)
2237 {
2238     return JSValue::encode(exec->vm().shadowChicken().functionsOnStack(exec));
2239 }
2240
2241 EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState* exec)
2242 {
2243     exec->vm().setGlobalConstRedeclarationShouldThrow(false);
2244     return JSValue::encode(jsUndefined());
2245 }
2246
2247 EncodedJSValue JSC_HOST_CALL functionGetRandomSeed(ExecState* exec)
2248 {
2249     return JSValue::encode(jsNumber(exec->lexicalGlobalObject()->weakRandom().seed()));
2250 }
2251
2252 EncodedJSValue JSC_HOST_CALL functionSetRandomSeed(ExecState* exec)
2253 {
2254     VM& vm = exec->vm();
2255     auto scope = DECLARE_THROW_SCOPE(vm);
2256
2257     unsigned seed = exec->argument(0).toUInt32(exec);
2258     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2259     exec->lexicalGlobalObject()->weakRandom().setSeed(seed);
2260     return JSValue::encode(jsUndefined());
2261 }
2262
2263 EncodedJSValue JSC_HOST_CALL functionIsRope(ExecState* exec)
2264 {
2265     JSValue argument = exec->argument(0);
2266     if (!argument.isString())
2267         return JSValue::encode(jsBoolean(false));
2268     const StringImpl* impl = asString(argument)->tryGetValueImpl();
2269     return JSValue::encode(jsBoolean(!impl));
2270 }
2271
2272 EncodedJSValue JSC_HOST_CALL functionCallerSourceOrigin(ExecState* state)
2273 {
2274     SourceOrigin sourceOrigin = state->callerSourceOrigin();
2275     if (sourceOrigin.isNull())
2276         return JSValue::encode(jsNull());
2277     return JSValue::encode(jsString(state, sourceOrigin.string()));
2278 }
2279
2280 EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(ExecState* exec)
2281 {
2282     JSValue value = exec->argument(0);
2283     RELEASE_ASSERT(value.isObject());
2284     JSGlobalObject* globalObject = jsCast<JSObject*>(value)->globalObject();
2285     RELEASE_ASSERT(globalObject);
2286     return JSValue::encode(globalObject);
2287 }
2288
2289 EncodedJSValue JSC_HOST_CALL functionReadline(ExecState* exec)
2290 {
2291     Vector<char, 256> line;
2292     int c;
2293     while ((c = getchar()) != EOF) {
2294         // FIXME: Should we also break on \r? 
2295         if (c == '\n')
2296             break;
2297         line.append(c);
2298     }
2299     line.append('\0');
2300     return JSValue::encode(jsString(exec, line.data()));
2301 }
2302
2303 EncodedJSValue JSC_HOST_CALL functionPreciseTime(ExecState*)
2304 {
2305     return JSValue::encode(jsNumber(currentTime()));
2306 }
2307
2308 EncodedJSValue JSC_HOST_CALL functionNeverInlineFunction(ExecState* exec)
2309 {
2310     return JSValue::encode(setNeverInline(exec));
2311 }
2312
2313 EncodedJSValue JSC_HOST_CALL functionNoDFG(ExecState* exec)
2314 {
2315     return JSValue::encode(setNeverOptimize(exec));
2316 }
2317
2318 EncodedJSValue JSC_HOST_CALL functionNoFTL(ExecState* exec)
2319 {
2320     VM& vm = exec->vm();
2321     if (JSFunction* function = jsDynamicCast<JSFunction*>(vm, exec->argument(0))) {
2322         FunctionExecutable* executable = function->jsExecutable();
2323         executable->setNeverFTLOptimize(true);
2324     }
2325
2326     return JSValue::encode(jsUndefined());
2327 }
2328
2329 EncodedJSValue JSC_HOST_CALL functionNoOSRExitFuzzing(ExecState* exec)
2330 {
2331     return JSValue::encode(setCannotUseOSRExitFuzzing(exec));
2332 }
2333
2334 EncodedJSValue JSC_HOST_CALL functionOptimizeNextInvocation(ExecState* exec)
2335 {
2336     return JSValue::encode(optimizeNextInvocation(exec));
2337 }
2338
2339 EncodedJSValue JSC_HOST_CALL functionNumberOfDFGCompiles(ExecState* exec)
2340 {
2341     return JSValue::encode(numberOfDFGCompiles(exec));
2342 }
2343
2344 Message::Message(ArrayBufferContents&& contents, int32_t index)
2345     : m_contents(WTFMove(contents))
2346     , m_index(index)
2347 {
2348 }
2349
2350 Message::~Message()
2351 {
2352 }
2353
2354 Worker::Worker(Workers& workers)
2355     : m_workers(workers)
2356 {
2357     auto locker = holdLock(m_workers.m_lock);
2358     m_workers.m_workers.append(this);
2359     
2360     *currentWorker() = this;
2361 }
2362
2363 Worker::~Worker()
2364 {
2365     auto locker = holdLock(m_workers.m_lock);
2366     RELEASE_ASSERT(isOnList());
2367     remove();
2368 }
2369
2370 void Worker::enqueue(const AbstractLocker&, RefPtr<Message> message)
2371 {
2372     m_messages.append(message);
2373 }
2374
2375 RefPtr<Message> Worker::dequeue()
2376 {
2377     auto locker = holdLock(m_workers.m_lock);
2378     while (m_messages.isEmpty())
2379         m_workers.m_condition.wait(m_workers.m_lock);
2380     return m_messages.takeFirst();
2381 }
2382
2383 Worker& Worker::current()
2384 {
2385     return **currentWorker();
2386 }
2387
2388 ThreadSpecific<Worker*>& Worker::currentWorker()
2389 {
2390     static ThreadSpecific<Worker*>* result;
2391     static std::once_flag flag;
2392     std::call_once(
2393         flag,
2394         [] () {
2395             result = new ThreadSpecific<Worker*>();
2396         });
2397     return *result;
2398 }
2399
2400 Workers::Workers()
2401 {
2402 }
2403
2404 Workers::~Workers()
2405 {
2406     UNREACHABLE_FOR_PLATFORM();
2407 }
2408
2409 template<typename Func>
2410 void Workers::broadcast(const Func& func)
2411 {
2412     auto locker = holdLock(m_lock);
2413     for (Worker* worker = m_workers.begin(); worker != m_workers.end(); worker = worker->next()) {
2414         if (worker != &Worker::current())
2415             func(locker, *worker);
2416     }
2417     m_condition.notifyAll();
2418 }
2419
2420 void Workers::report(String string)
2421 {
2422     auto locker = holdLock(m_lock);
2423     m_reports.append(string.isolatedCopy());
2424     m_condition.notifyAll();
2425 }
2426
2427 String Workers::tryGetReport()
2428 {
2429     auto locker = holdLock(m_lock);
2430     if (m_reports.isEmpty())
2431         return String();
2432     return m_reports.takeFirst();
2433 }
2434
2435 String Workers::getReport()
2436 {
2437     auto locker = holdLock(m_lock);
2438     while (m_reports.isEmpty())
2439         m_condition.wait(m_lock);
2440     return m_reports.takeFirst();
2441 }
2442
2443 Workers& Workers::singleton()
2444 {
2445     static Workers* result;
2446     static std::once_flag flag;
2447     std::call_once(
2448         flag,
2449         [] {
2450             result = new Workers();
2451         });
2452     return *result;
2453 }
2454
2455 EncodedJSValue JSC_HOST_CALL functionDollarCreateRealm(ExecState* exec)
2456 {
2457     VM& vm = exec->vm();
2458     GlobalObject* result = GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>());
2459     return JSValue::encode(result->getDirect(vm, Identifier::fromString(exec, "$")));
2460 }
2461
2462 EncodedJSValue JSC_HOST_CALL functionDollarDetachArrayBuffer(ExecState* exec)
2463 {
2464     return functionTransferArrayBuffer(exec);
2465 }
2466
2467 EncodedJSValue JSC_HOST_CALL functionDollarEvalScript(ExecState* exec)
2468 {
2469     VM& vm = exec->vm();
2470     auto scope = DECLARE_THROW_SCOPE(vm);
2471
2472     String sourceCode = exec->argument(0).toWTFString(exec);
2473     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2474     
2475     GlobalObject* globalObject = jsDynamicCast<GlobalObject*>(vm,
2476         exec->thisValue().get(exec, Identifier::fromString(exec, "global")));
2477     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2478     if (!globalObject)
2479         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Expected global to point to a global object"))));
2480     
2481     NakedPtr<Exception> evaluationException;
2482     JSValue result = evaluate(globalObject->globalExec(), makeSource(sourceCode, exec->callerSourceOrigin()), JSValue(), evaluationException);
2483     if (evaluationException)
2484         throwException(exec, scope, evaluationException);
2485     return JSValue::encode(result);
2486 }
2487
2488 EncodedJSValue JSC_HOST_CALL functionDollarAgentStart(ExecState* exec)
2489 {
2490     VM& vm = exec->vm();
2491     auto scope = DECLARE_THROW_SCOPE(vm);
2492
2493     String sourceCode = exec->argument(0).toWTFString(exec).isolatedCopy();
2494     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2495     
2496     Lock didStartLock;
2497     Condition didStartCondition;
2498     bool didStart = false;
2499     
2500     ThreadIdentifier thread = createThread(
2501         "JSC Agent",
2502         [sourceCode, &didStartLock, &didStartCondition, &didStart] () {
2503             CommandLine commandLine(0, nullptr);
2504             commandLine.m_interactive = false;
2505             runJSC(
2506                 commandLine,
2507                 [&] (VM&, GlobalObject* globalObject) {
2508                     // Notify the thread that started us that we have registered a worker.
2509                     {
2510                         auto locker = holdLock(didStartLock);
2511                         didStart = true;
2512                         didStartCondition.notifyOne();
2513                     }
2514                     
2515                     NakedPtr<Exception> evaluationException;
2516                     bool success = true;
2517                     JSValue result;
2518                     result = evaluate(globalObject->globalExec(), makeSource(sourceCode, SourceOrigin(ASCIILiteral("worker"))), JSValue(), evaluationException);
2519                     if (evaluationException)
2520                         result = evaluationException->value();
2521                     checkException(globalObject, true, evaluationException, result, String(), false, false, success);
2522                     if (!success)
2523                         exit(1);
2524                     return success;
2525                 });
2526         });
2527     detachThread(thread);
2528     
2529     {
2530         auto locker = holdLock(didStartLock);
2531         while (!didStart)
2532             didStartCondition.wait(didStartLock);
2533     }
2534     
2535     return JSValue::encode(jsUndefined());
2536 }
2537
2538 EncodedJSValue JSC_HOST_CALL functionDollarAgentReceiveBroadcast(ExecState* exec)
2539 {
2540     VM& vm = exec->vm();
2541     auto scope = DECLARE_THROW_SCOPE(vm);
2542
2543     JSValue callback = exec->argument(0);
2544     CallData callData;
2545     CallType callType = getCallData(callback, callData);
2546     if (callType == CallType::None)
2547         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Expected callback"))));
2548     
2549     RefPtr<Message> message;
2550     {
2551         ReleaseHeapAccessScope releaseAccess(vm.heap);
2552         message = Worker::current().dequeue();
2553     }
2554     
2555     RefPtr<ArrayBuffer> nativeBuffer = ArrayBuffer::create(message->releaseContents());
2556     JSArrayBuffer* jsBuffer = JSArrayBuffer::create(vm, exec->lexicalGlobalObject()->arrayBufferStructure(nativeBuffer->sharingMode()), nativeBuffer);
2557     
2558     MarkedArgumentBuffer args;
2559     args.append(jsBuffer);
2560     args.append(jsNumber(message->index()));
2561     return JSValue::encode(call(exec, callback, callType, callData, jsNull(), args));
2562 }
2563
2564 EncodedJSValue JSC_HOST_CALL functionDollarAgentReport(ExecState* exec)
2565 {
2566     VM& vm = exec->vm();
2567     auto scope = DECLARE_THROW_SCOPE(vm);
2568
2569     String report = exec->argument(0).toWTFString(exec);
2570     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2571     
2572     Workers::singleton().report(report);
2573     
2574     return JSValue::encode(jsUndefined());
2575 }
2576
2577 EncodedJSValue JSC_HOST_CALL functionDollarAgentSleep(ExecState* exec)
2578 {
2579     VM& vm = exec->vm();
2580     auto scope = DECLARE_THROW_SCOPE(vm);
2581
2582     if (exec->argumentCount() >= 1) {
2583         Seconds seconds = Seconds::fromMilliseconds(exec->argument(0).toNumber(exec));
2584         RETURN_IF_EXCEPTION(scope, encodedJSValue());
2585         sleep(seconds);
2586     }
2587     return JSValue::encode(jsUndefined());
2588 }
2589
2590 EncodedJSValue JSC_HOST_CALL functionDollarAgentBroadcast(ExecState* exec)
2591 {
2592     VM& vm = exec->vm();
2593     auto scope = DECLARE_THROW_SCOPE(vm);
2594
2595     JSArrayBuffer* jsBuffer = jsDynamicCast<JSArrayBuffer*>(vm, exec->argument(0));
2596     if (!jsBuffer || !jsBuffer->isShared())
2597         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Expected SharedArrayBuffer"))));
2598     
2599     int32_t index = exec->argument(1).toInt32(exec);
2600     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2601     
2602     Workers::singleton().broadcast(
2603         [&] (const AbstractLocker& locker, Worker& worker) {
2604             ArrayBuffer* nativeBuffer = jsBuffer->impl();
2605             ArrayBufferContents contents;
2606             nativeBuffer->transferTo(vm, contents); // "transferTo" means "share" if the buffer is shared.
2607             RefPtr<Message> message = adoptRef(new Message(WTFMove(contents), index));
2608             worker.enqueue(locker, message);
2609         });
2610     
2611     return JSValue::encode(jsUndefined());
2612 }
2613
2614 EncodedJSValue JSC_HOST_CALL functionDollarAgentGetReport(ExecState* exec)
2615 {
2616     VM& vm = exec->vm();
2617
2618     String string = Workers::singleton().tryGetReport();
2619     if (!string)
2620         return JSValue::encode(jsNull());
2621     
2622     return JSValue::encode(jsString(&vm, string));
2623 }
2624
2625 EncodedJSValue JSC_HOST_CALL functionDollarAgentLeaving(ExecState*)
2626 {
2627     return JSValue::encode(jsUndefined());
2628 }
2629
2630 EncodedJSValue JSC_HOST_CALL functionWaitForReport(ExecState* exec)
2631 {
2632     VM& vm = exec->vm();
2633
2634     String string;
2635     {
2636         ReleaseHeapAccessScope releaseAccess(vm.heap);
2637         string = Workers::singleton().getReport();
2638     }
2639     if (!string)
2640         return JSValue::encode(jsNull());
2641     
2642     return JSValue::encode(jsString(&vm, string));
2643 }
2644
2645 EncodedJSValue JSC_HOST_CALL functionHeapCapacity(ExecState* exec)
2646 {
2647     VM& vm = exec->vm();
2648     return JSValue::encode(jsNumber(vm.heap.capacity()));
2649 }
2650
2651 template<typename ValueType>
2652 typename std::enable_if<!std::is_fundamental<ValueType>::value>::type addOption(VM&, JSObject*, Identifier, ValueType) { }
2653
2654 template<typename ValueType>
2655 typename std::enable_if<std::is_fundamental<ValueType>::value>::type addOption(VM& vm, JSObject* optionsObject, Identifier identifier, ValueType value)
2656 {
2657     optionsObject->putDirect(vm, identifier, JSValue(value));
2658 }
2659
2660 EncodedJSValue JSC_HOST_CALL functionJSCOptions(ExecState* exec)
2661 {
2662     JSObject* optionsObject = constructEmptyObject(exec);
2663 #define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
2664     addOption(exec->vm(), optionsObject, Identifier::fromString(exec, #name_), Options::name_());
2665     JSC_OPTIONS(FOR_EACH_OPTION)
2666 #undef FOR_EACH_OPTION
2667     return JSValue::encode(optionsObject);
2668 }
2669
2670 EncodedJSValue JSC_HOST_CALL functionReoptimizationRetryCount(ExecState* exec)
2671 {
2672     if (exec->argumentCount() < 1)
2673         return JSValue::encode(jsUndefined());
2674     
2675     CodeBlock* block = getSomeBaselineCodeBlockForFunction(exec->argument(0));
2676     if (!block)
2677         return JSValue::encode(jsNumber(0));
2678     
2679     return JSValue::encode(jsNumber(block->reoptimizationRetryCounter()));
2680 }
2681
2682 EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState* exec)
2683 {
2684     VM& vm = exec->vm();
2685     auto scope = DECLARE_THROW_SCOPE(vm);
2686
2687     if (exec->argumentCount() < 1)
2688         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Not enough arguments"))));
2689     
2690     JSArrayBuffer* buffer = jsDynamicCast<JSArrayBuffer*>(vm, exec->argument(0));
2691     if (!buffer)
2692         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Expected an array buffer"))));
2693     
2694     ArrayBufferContents dummyContents;
2695     buffer->impl()->transferTo(vm, dummyContents);
2696     
2697     return JSValue::encode(jsUndefined());
2698 }
2699
2700 EncodedJSValue JSC_HOST_CALL functionFailNextNewCodeBlock(ExecState* exec)
2701 {
2702     exec->vm().setFailNextNewCodeBlock();
2703     return JSValue::encode(jsUndefined());
2704 }
2705
2706 EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*)
2707 {
2708     jscExit(EXIT_SUCCESS);
2709
2710 #if COMPILER(MSVC)
2711     // Without this, Visual Studio will complain that this method does not return a value.
2712     return JSValue::encode(jsUndefined());
2713 #endif
2714 }
2715
2716 EncodedJSValue JSC_HOST_CALL functionAbort(ExecState*)
2717 {
2718     CRASH();
2719 }
2720
2721 EncodedJSValue JSC_HOST_CALL functionFalse1(ExecState*) { return JSValue::encode(jsBoolean(false)); }
2722 EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*) { return JSValue::encode(jsBoolean(false)); }
2723
2724 EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*) { return JSValue::encode(jsUndefined()); }
2725 EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*) { return JSValue::encode(jsUndefined()); }
2726 EncodedJSValue JSC_HOST_CALL functionIsInt32(ExecState* exec)
2727 {
2728     for (size_t i = 0; i < exec->argumentCount(); ++i) {
2729         if (!exec->argument(i).isInt32())
2730             return JSValue::encode(jsBoolean(false));
2731     }
2732     return JSValue::encode(jsBoolean(true));
2733 }
2734
2735 EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState* exec) { return JSValue::encode(exec->argument(0)); }
2736
2737 EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*)
2738 {
2739     return JSValue::encode(jsNumber(42));
2740 }
2741
2742 EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState* exec)
2743 {
2744     return JSValue::encode(Masquerader::create(exec->vm(), exec->lexicalGlobalObject()));
2745 }
2746
2747 EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState* exec)
2748 {
2749     JSValue value = exec->argument(0);
2750     if (value.isObject())
2751         return JSValue::encode(jsBoolean(asObject(value)->hasCustomProperties()));
2752     return JSValue::encode(jsBoolean(false));
2753 }
2754
2755 EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState* exec)
2756 {
2757     exec->vm().dumpTypeProfilerData();
2758     return JSValue::encode(jsUndefined());
2759 }
2760
2761 EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState* exec)
2762 {
2763     VM& vm = exec->vm();
2764     RELEASE_ASSERT(exec->vm().typeProfiler());
2765     vm.typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionFindTypeForExpression"));
2766
2767     JSValue functionValue = exec->argument(0);
2768     RELEASE_ASSERT(functionValue.isFunction());
2769     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2770
2771     RELEASE_ASSERT(exec->argument(1).isString());
2772     String substring = asString(exec->argument(1))->value(exec);
2773     String sourceCodeText = executable->source().view().toString();
2774     unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
2775     
2776     String jsonString = exec->vm().typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), exec->vm());
2777     return JSValue::encode(JSONParse(exec, jsonString));
2778 }
2779
2780 EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState* exec)
2781 {
2782     VM& vm = exec->vm();
2783     RELEASE_ASSERT(exec->vm().typeProfiler());
2784     vm.typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionReturnTypeFor"));
2785
2786     JSValue functionValue = exec->argument(0);
2787     RELEASE_ASSERT(functionValue.isFunction());
2788     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2789
2790     unsigned offset = executable->typeProfilingStartOffset();
2791     String jsonString = exec->vm().typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), exec->vm());
2792     return JSValue::encode(JSONParse(exec, jsonString));
2793 }
2794
2795 EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState* exec)
2796 {
2797     RELEASE_ASSERT(exec->vm().controlFlowProfiler());
2798     exec->vm().controlFlowProfiler()->dumpData();
2799     return JSValue::encode(jsUndefined());
2800 }
2801
2802 EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState* exec)
2803 {
2804     VM& vm = exec->vm();
2805     RELEASE_ASSERT(vm.controlFlowProfiler());
2806
2807     JSValue functionValue = exec->argument(0);
2808     RELEASE_ASSERT(functionValue.isFunction());
2809     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2810
2811     RELEASE_ASSERT(exec->argument(1).isString());
2812     String substring = asString(exec->argument(1))->value(exec);
2813     String sourceCodeText = executable->source().view().toString();
2814     RELEASE_ASSERT(sourceCodeText.contains(substring));
2815     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2816     
2817     bool hasExecuted = vm.controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset, executable->sourceID(), vm);
2818     return JSValue::encode(jsBoolean(hasExecuted));
2819 }
2820
2821 EncodedJSValue JSC_HOST_CALL functionBasicBlockExecutionCount(ExecState* exec)
2822 {
2823     VM& vm = exec->vm();
2824     RELEASE_ASSERT(vm.controlFlowProfiler());
2825
2826     JSValue functionValue = exec->argument(0);
2827     RELEASE_ASSERT(functionValue.isFunction());
2828     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2829
2830     RELEASE_ASSERT(exec->argument(1).isString());
2831     String substring = asString(exec->argument(1))->value(exec);
2832     String sourceCodeText = executable->source().view().toString();
2833     RELEASE_ASSERT(sourceCodeText.contains(substring));
2834     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2835     
2836     size_t executionCount = vm.controlFlowProfiler()->basicBlockExecutionCountAtTextOffset(offset, executable->sourceID(), exec->vm());
2837     return JSValue::encode(JSValue(executionCount));
2838 }
2839
2840 EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*)
2841 {
2842     Options::useExceptionFuzz() = true;
2843     return JSValue::encode(jsUndefined());
2844 }
2845
2846 EncodedJSValue JSC_HOST_CALL functionDrainMicrotasks(ExecState* exec)
2847 {
2848     exec->vm().drainMicrotasks();
2849     return JSValue::encode(jsUndefined());
2850 }
2851
2852 EncodedJSValue JSC_HOST_CALL functionIs32BitPlatform(ExecState*)
2853 {
2854 #if USE(JSVALUE64)
2855     return JSValue::encode(JSValue(JSC::JSValue::JSFalse));
2856 #else
2857     return JSValue::encode(JSValue(JSC::JSValue::JSTrue));
2858 #endif
2859 }
2860
2861 EncodedJSValue JSC_HOST_CALL functionLoadModule(ExecState* exec)
2862 {
2863     VM& vm = exec->vm();
2864     auto scope = DECLARE_THROW_SCOPE(vm);
2865
2866     String fileName = exec->argument(0).toWTFString(exec);
2867     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2868     Vector<char> script;
2869     if (!fetchScriptFromLocalFileSystem(fileName, script))
2870         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Could not open file."))));
2871
2872     JSInternalPromise* promise = loadAndEvaluateModule(exec, fileName);
2873     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2874
2875     JSValue error;
2876     JSFunction* errorHandler = JSNativeStdFunction::create(vm, exec->lexicalGlobalObject(), 1, String(), [&](ExecState* exec) {
2877         error = exec->argument(0);
2878         return JSValue::encode(jsUndefined());
2879     });
2880
2881     promise->then(exec, nullptr, errorHandler);
2882     vm.drainMicrotasks();
2883     if (error)
2884         return JSValue::encode(throwException(exec, scope, error));
2885     return JSValue::encode(jsUndefined());
2886 }
2887
2888 EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState* exec)
2889 {
2890     VM& vm = exec->vm();
2891     auto scope = DECLARE_THROW_SCOPE(vm);
2892
2893     if (exec->argumentCount() < 1 || !exec->argument(0).isString())
2894         return JSValue::encode(jsUndefined());
2895
2896     String functionText = asString(exec->argument(0))->value(exec);
2897     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2898
2899     const SourceCode& source = makeSource(functionText, { });
2900     JSFunction* func = JSFunction::createBuiltinFunction(vm, createBuiltinExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, source), exec->lexicalGlobalObject());
2901
2902     return JSValue::encode(func);
2903 }
2904
2905 EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(ExecState* exec)
2906 {
2907     VM& vm = exec->vm();
2908     return JSValue::encode(GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>()));
2909 }
2910
2911 EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(ExecState* exec)
2912 {
2913     VM& vm = exec->vm();
2914     auto scope = DECLARE_THROW_SCOPE(vm);
2915
2916     String source = exec->argument(0).toWTFString(exec);
2917     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2918
2919     StopWatch stopWatch;
2920     stopWatch.start();
2921
2922     ParserError error;
2923     bool validSyntax = checkModuleSyntax(exec, makeSource(source, { }, String(), TextPosition(), SourceProviderSourceType::Module), error);
2924     stopWatch.stop();
2925
2926     if (!validSyntax)
2927         throwException(exec, scope, jsNontrivialString(exec, toString("SyntaxError: ", error.message(), ":", error.line())));
2928     return JSValue::encode(jsNumber(stopWatch.getElapsedMS()));
2929 }
2930
2931 EncodedJSValue JSC_HOST_CALL functionPlatformSupportsSamplingProfiler(ExecState*)
2932 {
2933 #if ENABLE(SAMPLING_PROFILER)
2934     return JSValue::encode(JSValue(JSC::JSValue::JSTrue));
2935 #else
2936     return JSValue::encode(JSValue(JSC::JSValue::JSFalse));
2937 #endif
2938 }
2939
2940 EncodedJSValue JSC_HOST_CALL functionGenerateHeapSnapshot(ExecState* exec)
2941 {
2942     VM& vm = exec->vm();
2943     JSLockHolder lock(vm);
2944     auto scope = DECLARE_THROW_SCOPE(vm);
2945
2946     HeapSnapshotBuilder snapshotBuilder(exec->vm().ensureHeapProfiler());
2947     snapshotBuilder.buildSnapshot();
2948
2949     String jsonString = snapshotBuilder.json();
2950     EncodedJSValue result = JSValue::encode(JSONParse(exec, jsonString));
2951     RELEASE_ASSERT(!scope.exception());
2952     return result;
2953 }
2954
2955 EncodedJSValue JSC_HOST_CALL functionResetSuperSamplerState(ExecState*)
2956 {
2957     resetSuperSamplerState();
2958     return JSValue::encode(jsUndefined());
2959 }
2960
2961 EncodedJSValue JSC_HOST_CALL functionEnsureArrayStorage(ExecState* exec)
2962 {
2963     VM& vm = exec->vm();
2964     for (unsigned i = 0; i < exec->argumentCount(); ++i) {
2965         if (JSObject* object = jsDynamicCast<JSObject*>(vm, exec->argument(0)))
2966             object->ensureArrayStorage(exec->vm());
2967     }
2968     return JSValue::encode(jsUndefined());
2969 }
2970
2971 #if ENABLE(SAMPLING_PROFILER)
2972 EncodedJSValue JSC_HOST_CALL functionStartSamplingProfiler(ExecState* exec)
2973 {
2974     SamplingProfiler& samplingProfiler = exec->vm().ensureSamplingProfiler(WTF::Stopwatch::create());
2975     samplingProfiler.noticeCurrentThreadAsJSCExecutionThread();
2976     samplingProfiler.start();
2977     return JSValue::encode(jsUndefined());
2978 }
2979
2980 EncodedJSValue JSC_HOST_CALL functionSamplingProfilerStackTraces(ExecState* exec)
2981 {
2982     VM& vm = exec->vm();
2983     auto scope = DECLARE_THROW_SCOPE(vm);
2984
2985     if (!vm.samplingProfiler())
2986         return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Sampling profiler was never started"))));
2987
2988     String jsonString = vm.samplingProfiler()->stackTracesAsJSON();
2989     EncodedJSValue result = JSValue::encode(JSONParse(exec, jsonString));
2990     RELEASE_ASSERT(!scope.exception());
2991     return result;
2992 }
2993 #endif // ENABLE(SAMPLING_PROFILER)
2994
2995 EncodedJSValue JSC_HOST_CALL functionMaxArguments(ExecState*)
2996 {
2997     return JSValue::encode(jsNumber(JSC::maxArguments));
2998 }
2999
3000 #if ENABLE(WEBASSEMBLY)
3001
3002 static CString valueWithTypeOfWasmValue(ExecState* exec, VM& vm, JSValue value, JSValue wasmValue)
3003 {
3004     JSString* type = asString(wasmValue.get(exec, makeIdentifier(vm, "type")));
3005
3006     const String& typeString = type->value(exec);
3007     if (typeString == "i64" || typeString == "i32")
3008         return toCString(typeString, " ", RawPointer(bitwise_cast<void*>(value)));
3009     if (typeString == "f32")
3010         return toCString(typeString, " hex: ", RawPointer(bitwise_cast<void*>(value)), ", float: ", bitwise_cast<float>(static_cast<uint32_t>(JSValue::encode(value))));
3011     return toCString(typeString, " hex: ", RawPointer(bitwise_cast<void*>(value)), ", double: ", bitwise_cast<double>(value));
3012 }
3013
3014 static JSValue box(ExecState* exec, VM& vm, JSValue wasmValue)
3015 {
3016
3017     JSString* type = asString(wasmValue.get(exec, makeIdentifier(vm, "type")));
3018     JSValue value = wasmValue.get(exec, makeIdentifier(vm, "value"));
3019
3020     auto unboxString = [&] (const char* hexFormat, const char* decFormat, auto& result) {
3021         if (!value.isString())
3022             return false;
3023
3024         const char* str = toCString(asString(value)->value(exec)).data();
3025         int scanResult;
3026         int length = std::strlen(str);
3027         if ((length > 2 && (str[0] == '0' && str[1] == 'x'))
3028             || (length > 3 && (str[0] == '-' && str[1] == '0' && str[2] == 'x')))
3029 #if COMPILER(CLANG)
3030 #pragma clang diagnostic push
3031 #pragma clang diagnostic ignored "-Wformat-nonliteral"
3032 #endif
3033             scanResult = sscanf(str, hexFormat, &result);
3034         else
3035             scanResult = sscanf(str, decFormat, &result);
3036 #if COMPILER(CLANG)
3037 #pragma clang diagnostic pop
3038 #endif
3039         RELEASE_ASSERT(scanResult != EOF);
3040         return true;
3041     };
3042
3043     const String& typeString = type->value(exec);
3044     if (typeString == "i64") {
3045         int64_t result;
3046         if (!unboxString("%llx", "%lld", result))
3047             CRASH();
3048         return JSValue::decode(result);
3049     }
3050
3051     if (typeString == "i32") {
3052         int32_t result;
3053         if (!unboxString("%x", "%d", result))
3054             result = value.asInt32();
3055         return JSValue::decode(static_cast<uint32_t>(result));
3056     }
3057
3058     if (typeString == "f32") {
3059         float result;
3060         if (!unboxString("%a", "%f", result))
3061             result = value.toFloat(exec);
3062         return JSValue::decode(bitwise_cast<uint32_t>(result));
3063     }
3064
3065     RELEASE_ASSERT(typeString == "f64");
3066     double result;
3067     if (!unboxString("%la", "%lf", result))
3068         result = value.asNumber();
3069     return JSValue::decode(bitwise_cast<uint64_t>(result));
3070 }
3071
3072 static JSValue callWasmFunction(VM* vm, JSGlobalObject* globalObject, JSWebAssemblyCallee* wasmCallee, Vector<JSValue>& boxedArgs)
3073 {
3074     JSValue firstArgument;
3075     int argCount = 1;
3076     JSValue* remainingArgs = nullptr;
3077     if (boxedArgs.size()) {
3078         remainingArgs = boxedArgs.data();
3079         firstArgument = *remainingArgs;
3080         remainingArgs++;
3081         argCount = boxedArgs.size();
3082     }
3083
3084     ProtoCallFrame protoCallFrame;
3085     protoCallFrame.init(nullptr, globalObject->globalExec()->jsCallee(), firstArgument, argCount, remainingArgs);
3086
3087     return JSValue::decode(vmEntryToWasm(wasmCallee->entrypoint(), vm, &protoCallFrame));
3088 }
3089
3090 // testWasmModule(JSArrayBufferView source, number functionCount, ...[[WasmValue, [WasmValue]]]) where the ith copy of [[result, [args]]] is a list
3091 // of arguments to be passed to the ith wasm function as well as the expected result. WasmValue is an object with "type" and "value" properties.
3092 static EncodedJSValue JSC_HOST_CALL functionTestWasmModuleFunctions(ExecState* exec)
3093 {
3094     VM& vm = exec->vm();
3095     auto scope = DECLARE_THROW_SCOPE(vm);
3096
3097     if (!Options::useWebAssembly())
3098         return throwVMTypeError(exec, scope, ASCIILiteral("testWasmModule should only be called if the useWebAssembly option is set"));
3099
3100     JSArrayBufferView* source = jsCast<JSArrayBufferView*>(exec->argument(0));
3101     uint32_t functionCount = exec->argument(1).toUInt32(exec);
3102
3103     if (exec->argumentCount() != functionCount + 2)
3104         CRASH();
3105
3106     Wasm::Plan plan(&vm, static_cast<uint8_t*>(source->vector()), source->length());
3107     plan.run();
3108     if (plan.failed()) {
3109         dataLogLn("failed to parse module: ", plan.errorMessage());
3110         CRASH();
3111     }
3112
3113     if (plan.internalFunctionCount() != functionCount)
3114         CRASH();
3115
3116     MarkedArgumentBuffer callees;
3117     MarkedArgumentBuffer keepAlive;
3118     {
3119         unsigned lastIndex = UINT_MAX;
3120         plan.initializeCallees(exec->lexicalGlobalObject(),
3121             [&] (unsigned calleeIndex, JSWebAssemblyCallee* jsEntrypointCallee, JSWebAssemblyCallee* wasmEntrypointCallee) {
3122                 RELEASE_ASSERT(!calleeIndex || (calleeIndex - 1 == lastIndex));
3123                 callees.append(jsEntrypointCallee);
3124                 keepAlive.append(wasmEntrypointCallee);
3125                 lastIndex = calleeIndex;
3126             });
3127     }
3128     std::unique_ptr<Wasm::ModuleInformation> moduleInformation = plan.takeModuleInformation();
3129     RELEASE_ASSERT(!moduleInformation->memory);
3130
3131     for (uint32_t i = 0; i < functionCount; ++i) {
3132         JSArray* testCases = jsCast<JSArray*>(exec->argument(i + 2));
3133         for (unsigned testIndex = 0; testIndex < testCases->length(); ++testIndex) {
3134             JSArray* test = jsCast<JSArray*>(testCases->getIndexQuickly(testIndex));
3135             JSObject* result = jsCast<JSObject*>(test->getIndexQuickly(0));
3136             JSArray* arguments = jsCast<JSArray*>(test->getIndexQuickly(1));
3137
3138             Vector<JSValue> boxedArgs;
3139             for (unsigned argIndex = 0; argIndex < arguments->length(); ++argIndex)
3140                 boxedArgs.append(box(exec, vm, arguments->getIndexQuickly(argIndex)));
3141
3142             JSValue callResult;
3143             {
3144                 auto scope = DECLARE_THROW_SCOPE(vm);
3145                 callResult = callWasmFunction(&vm, exec->lexicalGlobalObject(), jsCast<JSWebAssemblyCallee*>(callees.at(i)), boxedArgs);
3146                 RETURN_IF_EXCEPTION(scope, { });
3147             }
3148             JSValue expected = box(exec, vm, result);
3149             if (callResult != expected) {
3150                 dataLog("Arguments: ");
3151                 CommaPrinter comma(", ");
3152                 for (unsigned argIndex = 0; argIndex < arguments->length(); ++argIndex)
3153                     dataLog(comma, valueWithTypeOfWasmValue(exec, vm, boxedArgs[argIndex], arguments->getIndexQuickly(argIndex)));
3154                 dataLogLn();
3155
3156                 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, toCString(" (callResult == ", valueWithTypeOfWasmValue(exec, vm, callResult, result), ", expected == ", valueWithTypeOfWasmValue(exec, vm, expected, result), ")").data());
3157                 CRASH();
3158             }
3159         }
3160     }
3161
3162     return encodedJSUndefined();
3163 }
3164
3165 #endif // ENABLE(WEBASSEBLY)
3166
3167 // Use SEH for Release builds only to get rid of the crash report dialog
3168 // (luckily the same tests fail in Release and Debug builds so far). Need to
3169 // be in a separate main function because the jscmain function requires object
3170 // unwinding.
3171
3172 #if COMPILER(MSVC) && !defined(_DEBUG)
3173 #define TRY       __try {
3174 #define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; }
3175 #else
3176 #define TRY
3177 #define EXCEPT(x)
3178 #endif
3179
3180 int jscmain(int argc, char** argv);
3181
3182 static double s_desiredTimeout;
3183 static double s_timeoutMultiplier = 1.0;
3184
3185 static NO_RETURN_DUE_TO_CRASH void timeoutThreadMain(void*)
3186 {
3187     Seconds timeoutDuration(s_desiredTimeout * s_timeoutMultiplier);
3188     sleep(timeoutDuration);
3189     dataLog("Timed out after ", timeoutDuration, " seconds!\n");
3190     CRASH();
3191 }
3192
3193 static void startTimeoutThreadIfNeeded()
3194 {
3195     if (char* timeoutString = getenv("JSCTEST_timeout")) {
3196         if (sscanf(timeoutString, "%lf", &s_desiredTimeout) != 1) {
3197             dataLog("WARNING: timeout string is malformed, got ", timeoutString,
3198                 " but expected a number. Not using a timeout.\n");
3199         } else
3200             createThread(timeoutThreadMain, 0, "jsc Timeout Thread");
3201     }
3202 }
3203
3204 int main(int argc, char** argv)
3205 {
3206 #if PLATFORM(IOS) && CPU(ARM_THUMB2)
3207     // Enabled IEEE754 denormal support.
3208     fenv_t env;
3209     fegetenv( &env );
3210     env.__fpscr &= ~0x01000000u;
3211     fesetenv( &env );
3212 #endif
3213
3214 #if OS(WINDOWS)
3215     // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
3216     // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
3217     // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
3218     ::SetErrorMode(0);
3219
3220 #if defined(_DEBUG)
3221     _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
3222     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
3223     _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
3224     _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
3225     _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
3226     _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
3227 #endif
3228
3229     timeBeginPeriod(1);
3230 #endif
3231
3232 #if PLATFORM(EFL)
3233     ecore_init();
3234 #endif
3235
3236 #if PLATFORM(GTK)
3237     if (!setlocale(LC_ALL, ""))
3238         WTFLogAlways("Locale not supported by C library.\n\tUsing the fallback 'C' locale.");
3239 #endif
3240
3241     // Need to initialize WTF threading before we start any threads. Cannot initialize JSC
3242     // threading yet, since that would do somethings that we'd like to defer until after we
3243     // have a chance to parse options.
3244     WTF::initializeThreading();
3245
3246 #if PLATFORM(IOS)
3247     Options::crashIfCantAllocateJITMemory() = true;
3248 #endif
3249
3250     // We can't use destructors in the following code because it uses Windows
3251     // Structured Exception Handling
3252     int res = 0;
3253     TRY
3254         res = jscmain(argc, argv);
3255     EXCEPT(res = 3)
3256     finalizeStatsAtEndOfTesting();
3257
3258 #if PLATFORM(EFL)
3259     ecore_shutdown();
3260 #endif
3261
3262     jscExit(res);
3263 }
3264
3265 static void dumpException(GlobalObject* globalObject, JSValue exception)
3266 {
3267     VM& vm = globalObject->vm();
3268     auto scope = DECLARE_CATCH_SCOPE(vm);
3269
3270 #define CHECK_EXCEPTION() do { \
3271         if (scope.exception()) { \
3272             scope.clearException(); \
3273             return; \
3274         } \
3275     } while (false)
3276
3277     printf("Exception: %s\n", exception.toWTFString(globalObject->globalExec()).utf8().data());
3278
3279     Identifier nameID = Identifier::fromString(globalObject->globalExec(), "name");
3280     Identifier fileNameID = Identifier::fromString(globalObject->globalExec(), "sourceURL");
3281     Identifier lineNumberID = Identifier::fromString(globalObject->globalExec(), "line");
3282     Identifier stackID = Identifier::fromString(globalObject->globalExec(), "stack");
3283     
3284     JSValue nameValue = exception.get(globalObject->globalExec(), nameID);
3285     CHECK_EXCEPTION();
3286     JSValue fileNameValue = exception.get(globalObject->globalExec(), fileNameID);
3287     CHECK_EXCEPTION();
3288     JSValue lineNumberValue = exception.get(globalObject->globalExec(), lineNumberID);
3289     CHECK_EXCEPTION();
3290     JSValue stackValue = exception.get(globalObject->globalExec(), stackID);
3291     CHECK_EXCEPTION();
3292     
3293     if (nameValue.toWTFString(globalObject->globalExec()) == "SyntaxError"
3294         && (!fileNameValue.isUndefinedOrNull() || !lineNumberValue.isUndefinedOrNull())) {
3295         printf(
3296             "at %s:%s\n",
3297             fileNameValue.toWTFString(globalObject->globalExec()).utf8().data(),
3298             lineNumberValue.toWTFString(globalObject->globalExec()).utf8().data());
3299     }
3300     
3301     if (!stackValue.isUndefinedOrNull())
3302         printf("%s\n", stackValue.toWTFString(globalObject->globalExec()).utf8().data());
3303
3304 #undef CHECK_EXCEPTION
3305 }
3306
3307 static bool checkUncaughtException(VM& vm, GlobalObject* globalObject, JSValue exception, const String& expectedExceptionName, bool alwaysDumpException)
3308 {
3309     auto scope = DECLARE_CATCH_SCOPE(vm);
3310     scope.clearException();
3311     if (!exception) {
3312         printf("Expected uncaught exception with name '%s' but none was thrown\n", expectedExceptionName.utf8().data());
3313         return false;
3314     }
3315
3316     ExecState* exec = globalObject->globalExec();
3317     JSValue exceptionClass = globalObject->get(exec, Identifier::fromString(exec, expectedExceptionName));
3318     if (!exceptionClass.isObject() || scope.exception()) {
3319         printf("Expected uncaught exception with name '%s' but given exception class is not defined\n", expectedExceptionName.utf8().data());
3320         return false;
3321     }
3322
3323     bool isInstanceOfExpectedException = jsCast<JSObject*>(exceptionClass)->hasInstance(exec, exception);
3324     if (scope.exception()) {
3325         printf("Expected uncaught exception with name '%s' but given exception class fails performing hasInstance\n", expectedExceptionName.utf8().data());
3326         return false;
3327     }
3328     if (isInstanceOfExpectedException) {
3329         if (alwaysDumpException)
3330             dumpException(globalObject, exception);
3331         return true;
3332     }
3333
3334     printf("Expected uncaught exception with name '%s' but exception value is not instance of this exception class\n", expectedExceptionName.utf8().data());
3335     dumpException(globalObject, exception);
3336     return false;
3337 }
3338
3339 static void checkException(GlobalObject* globalObject, bool isLastFile, bool hasException, JSValue value, const String& uncaughtExceptionName, bool alwaysDumpUncaughtException, bool dump, bool& success)
3340 {
3341     VM& vm = globalObject->vm();
3342     if (!uncaughtExceptionName || !isLastFile) {
3343         success = success && !hasException;
3344         if (dump && !hasException)
3345             printf("End: %s\n", value.toWTFString(globalObject->globalExec()).utf8().data());
3346         if (hasException)
3347             dumpException(globalObject, value);
3348     } else
3349         success = success && checkUncaughtException(vm, globalObject, (hasException) ? value : JSValue(), uncaughtExceptionName, alwaysDumpUncaughtException);
3350 }
3351
3352 static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scripts, const String& uncaughtExceptionName, bool alwaysDumpUncaughtException, bool dump, bool module)
3353 {
3354     String fileName;
3355     Vector<char> scriptBuffer;
3356
3357     if (dump)
3358         JSC::Options::dumpGeneratedBytecodes() = true;
3359
3360     VM& vm = globalObject->vm();
3361     auto scope = DECLARE_CATCH_SCOPE(vm);
3362     bool success = true;
3363
3364 #if ENABLE(SAMPLING_FLAGS)
3365     SamplingFlags::start();
3366 #endif
3367
3368     for (size_t i = 0; i < scripts.size(); i++) {
3369         JSInternalPromise* promise = nullptr;
3370         bool isModule = module || scripts[i].scriptType == Script::ScriptType::Module;
3371         if (scripts[i].codeSource == Script::CodeSource::File) {
3372             fileName = scripts[i].argument;
3373             if (scripts[i].strictMode == Script::StrictMode::Strict)
3374                 scriptBuffer.append("\"use strict\";\n", strlen("\"use strict\";\n"));
3375
3376             if (isModule)
3377                 promise = loadAndEvaluateModule(globalObject->globalExec(), fileName);
3378             else {
3379                 if (!fetchScriptFromLocalFileSystem(fileName, scriptBuffer))
3380                     return false; // fail early so we can catch missing files
3381             }
3382         } else {
3383             size_t commandLineLength = strlen(scripts[i].argument);
3384             scriptBuffer.resize(commandLineLength);
3385             std::copy(scripts[i].argument, scripts[i].argument + commandLineLength, scriptBuffer.begin());
3386             fileName = ASCIILiteral("[Command Line]");
3387         }
3388
3389         bool isLastFile = i == scripts.size() - 1;
3390         if (isModule) {
3391             if (!promise)
3392                 promise = loadAndEvaluateModule(globalObject->globalExec(), makeSource(stringFromUTF(scriptBuffer), SourceOrigin { absolutePath(fileName) }, fileName, TextPosition(), SourceProviderSourceType::Module));
3393             scope.clearException();
3394
3395             JSFunction* fulfillHandler = JSNativeStdFunction::create(vm, globalObject, 1, String(), [&, isLastFile](ExecState* exec) {
3396                 checkException(globalObject, isLastFile, false, exec->argument(0), uncaughtExceptionName, alwaysDumpUncaughtException, dump, success);
3397                 return JSValue::encode(jsUndefined());
3398             });
3399
3400             JSFunction* rejectHandler = JSNativeStdFunction::create(vm, globalObject, 1, String(), [&, isLastFile](ExecState* exec) {
3401                 checkException(globalObject, isLastFile, true, exec->argument(0), uncaughtExceptionName, alwaysDumpUncaughtException, dump, success);
3402                 return JSValue::encode(jsUndefined());
3403             });
3404
3405             promise->then(globalObject->globalExec(), fulfillHandler, rejectHandler);
3406             vm.drainMicrotasks();
3407         } else {
3408             NakedPtr<Exception> evaluationException;
3409             JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(scriptBuffer, SourceOrigin { absolutePath(fileName) }, fileName), JSValue(), evaluationException);
3410             ASSERT(!scope.exception());
3411             if (evaluationException)
3412                 returnValue = evaluationException->value();
3413             checkException(globalObject, isLastFile, evaluationException, returnValue, uncaughtExceptionName, alwaysDumpUncaughtException, dump, success);
3414         }
3415
3416         scriptBuffer.clear();
3417         scope.clearException();
3418     }
3419
3420 #if ENABLE(REGEXP_TRACING)
3421     vm.dumpRegExpTrace();
3422 #endif
3423     return success;
3424 }
3425
3426 #define RUNNING_FROM_XCODE 0
3427
3428 static void runInteractive(GlobalObject* globalObject)
3429 {
3430     VM& vm = globalObject->vm();
3431     auto scope = DECLARE_CATCH_SCOPE(vm);
3432
3433     std::optional<DirectoryName> directoryName = currentWorkingDirectory();
3434     if (!directoryName)
3435         return;
3436     SourceOrigin sourceOrigin(resolvePath(directoryName.value(), ModuleName("interpreter")));
3437     
3438     bool shouldQuit = false;
3439     while (!shouldQuit) {
3440 #if HAVE(READLINE) && !RUNNING_FROM_XCODE
3441         ParserError error;
3442         String source;
3443         do {
3444             error = ParserError();
3445             char* line = readline(source.isEmpty() ? interactivePrompt : "... ");
3446             shouldQuit = !line;
3447             if (!line)
3448                 break;
3449             source = source + line;
3450             source = source + '\n';
3451             checkSyntax(globalObject->vm(), makeSource(source, sourceOrigin), error);
3452             if (!line[0]) {
3453                 free(line);
3454                 break;
3455             }
3456             add_history(line);
3457             free(line);
3458         } while (error.syntaxErrorType() == ParserError::SyntaxErrorRecoverable);
3459         
3460         if (error.isValid()) {
3461             printf("%s:%d\n", error.message().utf8().data(), error.line());
3462             continue;
3463         }
3464         
3465         
3466         NakedPtr<Exception> evaluationException;
3467         JSValue returnValue = evaluate(globalObject->globalExec(), makeSource(source, sourceOrigin), JSValue(), evaluationException);
3468 #else
3469         printf("%s", interactivePrompt);
3470         Vector<char, 256> line;
3471         int c;
3472         while ((c = getchar()) != EOF) {
3473             // FIXME: Should we also break on \r? 
3474             if (c == '\n')
3475                 break;
3476             line.append(c);
3477         }
3478         if (line.isEmpty())
3479             break;
3480
3481         NakedPtr<Exception> evaluationException;
3482         JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(line, sourceOrigin, sourceOrigin.string()), JSValue(), evaluationException);
3483 #endif
3484         if (evaluationException)
3485             printf("Exception: %s\n", evaluationException->value().toWTFString(globalObject->globalExec()).utf8().data());
3486         else
3487             printf("%s\n", returnValue.toWTFString(globalObject->globalExec()).utf8().data());
3488
3489         scope.clearException();
3490         globalObject->vm().drainMicrotasks();
3491     }
3492     printf("\n");
3493 }
3494
3495 static NO_RETURN void printUsageStatement(bool help = false)
3496 {
3497     fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n");
3498     fprintf(stderr, "  -d         Dumps bytecode (debug builds only)\n");
3499     fprintf(stderr, "  -e         Evaluate argument as script code\n");
3500     fprintf(stderr, "  -f         Specifies a source file (deprecated)\n");
3501     fprintf(stderr, "  -h|--help  Prints this help message\n");
3502     fprintf(stderr, "  -i         Enables interactive mode (default if no files are specified)\n");
3503     fprintf(stderr, "  -m         Execute as a module\n");
3504 #if HAVE(SIGNAL_H)
3505     fprintf(stderr, "  -s         Installs signal handlers that exit on a crash (Unix platforms only)\n");
3506 #endif
3507     fprintf(stderr, "  -p <file>  Outputs profiling data to a file\n");
3508     fprintf(stderr, "  -x         Output exit code before terminating\n");
3509     fprintf(stderr, "\n");
3510     fprintf(stderr, "  --sample                   Collects and outputs sampling profiler data\n");
3511     fprintf(stderr, "  --test262-async            Check that some script calls the print function with the string 'Test262:AsyncTestComplete'\n");
3512     fprintf(stderr, "  --strict-file=<file>       Parse the given file as if it were in strict mode (this option may be passed more than once)\n");
3513     fprintf(stderr, "  --module-file=<file>       Parse and evaluate the given file as module (this option may be passed more than once)\n");
3514     fprintf(stderr, "  --exception=<name>         Check the last script exits with an uncaught exception with the specified name\n");
3515     fprintf(stderr, "  --dumpException            Dump uncaught exception text\n");
3516     fprintf(stderr, "  --options                  Dumps all JSC VM options and exits\n");
3517     fprintf(stderr, "  --dumpOptions              Dumps all non-default JSC VM options before continuing\n");
3518     fprintf(stderr, "  --<jsc VM option>=<value>  Sets the specified JSC VM option\n");
3519     fprintf(stderr, "\n");
3520
3521     jscExit(help ? EXIT_SUCCESS : EXIT_FAILURE);
3522 }
3523
3524 void CommandLine::parseArguments(int argc, char** argv)
3525 {
3526     Options::initialize();
3527     
3528     int i = 1;
3529     JSC::Options::DumpLevel dumpOptionsLevel = JSC::Options::DumpLevel::None;
3530     bool needToExit = false;
3531
3532     bool hasBadJSCOptions = false;
3533     for (; i < argc; ++i) {
3534         const char* arg = argv[i];
3535         if (!strcmp(arg, "-f")) {
3536             if (++i == argc)
3537                 printUsageStatement();
3538             m_scripts.append(Script(Script::StrictMode::Sloppy, Script::CodeSource::File, Script::ScriptType::Script, argv[i]));
3539             continue;
3540         }
3541         if (!strcmp(arg, "-e")) {
3542             if (++i == argc)
3543                 printUsageStatement();
3544             m_scripts.append(Script(Script::StrictMode::Sloppy, Script::CodeSource::CommandLine, Script::ScriptType::Script, argv[i]));
3545             continue;
3546         }
3547         if (!strcmp(arg, "-i")) {
3548             m_interactive = true;
3549             continue;
3550         }
3551         if (!strcmp(arg, "-d")) {
3552             m_dump = true;
3553             continue;
3554         }
3555         if (!strcmp(arg, "-p")) {
3556             if (++i == argc)
3557                 printUsageStatement();
3558             m_profile = true;
3559             m_profilerOutput = argv[i];
3560             continue;
3561         }
3562         if (!strcmp(arg, "-m")) {
3563             m_module = true;
3564             continue;
3565         }
3566         if (!strcmp(arg, "-s")) {
3567 #if HAVE(SIGNAL_H)
3568             signal(SIGILL, _exit);
3569             signal(SIGFPE, _exit);
3570             signal(SIGBUS, _exit);
3571             signal(SIGSEGV, _exit);
3572 #endif
3573             continue;
3574         }
3575         if (!strcmp(arg, "-x")) {
3576             m_exitCode = true;
3577             continue;
3578         }
3579         if (!strcmp(arg, "--")) {
3580             ++i;
3581             break;
3582         }
3583         if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
3584             printUsageStatement(true);
3585
3586         if (!strcmp(arg, "--options")) {
3587             dumpOptionsLevel = JSC::Options::DumpLevel::Verbose;
3588             needToExit = true;
3589             continue;
3590         }
3591         if (!strcmp(arg, "--dumpOptions")) {
3592             dumpOptionsLevel = JSC::Options::DumpLevel::Overridden;
3593             continue;
3594         }
3595         if (!strcmp(arg, "--sample")) {
3596             JSC::Options::useSamplingProfiler() = true;
3597             JSC::Options::collectSamplingProfilerDataForJSCShell() = true;
3598             m_dumpSamplingProfilerData = true;
3599             continue;
3600         }
3601
3602         static const char* timeoutMultiplierOptStr = "--timeoutMultiplier=";
3603         static const unsigned timeoutMultiplierOptStrLength = strlen(timeoutMultiplierOptStr);
3604         if (!strncmp(arg, timeoutMultiplierOptStr, timeoutMultiplierOptStrLength)) {
3605             const char* valueStr = &arg[timeoutMultiplierOptStrLength];
3606             if (sscanf(valueStr, "%lf", &s_timeoutMultiplier) != 1)
3607                 dataLog("WARNING: --timeoutMultiplier=", valueStr, " is invalid. Expects a numeric ratio.\n");
3608             continue;
3609         }
3610
3611         if (!strcmp(arg, "--test262-async")) {
3612             test262AsyncTest = true;
3613             continue;
3614         }
3615
3616         if (!strcmp(arg, "--remote-debug")) {
3617             m_enableRemoteDebugging = true;
3618             continue;
3619         }
3620
3621         static const unsigned strictFileStrLength = strlen("--strict-file=");
3622         if (!strncmp(arg, "--strict-file=", strictFileStrLength)) {
3623             m_scripts.append(Script(Script::StrictMode::Strict, Script::CodeSource::File, Script::ScriptType::Script, argv[i] + strictFileStrLength));
3624             continue;
3625         }
3626
3627         static const unsigned moduleFileStrLength = strlen("--module-file=");
3628         if (!strncmp(arg, "--module-file=", moduleFileStrLength)) {
3629             m_scripts.append(Script(Script::StrictMode::Sloppy, Script::CodeSource::File, Script::ScriptType::Module, argv[i] + moduleFileStrLength));
3630             continue;
3631         }
3632
3633         if (!strcmp(arg, "--dumpException")) {
3634             m_alwaysDumpUncaughtException = true;
3635             continue;
3636         }
3637
3638         static const unsigned exceptionStrLength = strlen("--exception=");
3639         if (!strncmp(arg, "--exception=", exceptionStrLength)) {
3640             m_uncaughtExceptionName = String(arg + exceptionStrLength);
3641             continue;
3642         }
3643
3644         // See if the -- option is a JSC VM option.
3645         if (strstr(arg, "--") == arg) {
3646             if (!JSC::Options::setOption(&arg[2])) {
3647                 hasBadJSCOptions = true;
3648                 dataLog("ERROR: invalid option: ", arg, "\n");
3649             }
3650             continue;
3651         }
3652
3653         // This arg is not recognized by the VM nor by jsc. Pass it on to the
3654         // script.
3655         m_scripts.append(Script(Script::StrictMode::Sloppy, Script::CodeSource::File, Script::ScriptType::Script, argv[i]));
3656     }
3657
3658     if (hasBadJSCOptions && JSC::Options::validateOptions())
3659         CRASH();
3660
3661     if (m_scripts.isEmpty())
3662         m_interactive = true;
3663
3664     for (; i < argc; ++i)
3665         m_arguments.append(argv[i]);
3666
3667     if (dumpOptionsLevel != JSC::Options::DumpLevel::None) {
3668         const char* optionsTitle = (dumpOptionsLevel == JSC::Options::DumpLevel::Overridden)
3669             ? "Modified JSC runtime options:"
3670             : "All JSC runtime options:";
3671         JSC::Options::dumpAllOptions(stderr, dumpOptionsLevel, optionsTitle);
3672     }
3673     JSC::Options::ensureOptionsAreCoherent();
3674     if (needToExit)
3675         jscExit(EXIT_SUCCESS);
3676 }
3677
3678 template<typename Func>
3679 int runJSC(CommandLine options, const Func& func)
3680 {
3681     Worker worker(Workers::singleton());
3682     
3683     VM& vm = VM::create(LargeHeap).leakRef();
3684     JSLockHolder locker(&vm);
3685
3686     int result;
3687     if (options.m_profile && !vm.m_perBytecodeProfiler)
3688         vm.m_perBytecodeProfiler = std::make_unique<Profiler::Database>(vm);
3689
3690     GlobalObject* globalObject = GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), options.m_arguments);
3691     globalObject->setRemoteDebuggingEnabled(options.m_enableRemoteDebugging);
3692     bool success = func(vm, globalObject);
3693     if (options.m_interactive && success)
3694         runInteractive(globalObject);
3695
3696     vm.drainMicrotasks();
3697     result = success && (test262AsyncTest == test262AsyncPassed) ? 0 : 3;
3698
3699     if (options.m_exitCode)
3700         printf("jsc exiting %d\n", result);
3701
3702     if (options.m_profile) {
3703         if (!vm.m_perBytecodeProfiler->save(options.m_profilerOutput.utf8().data()))
3704             fprintf(stderr, "could not save profiler output.\n");
3705     }
3706
3707 #if ENABLE(JIT)
3708     if (Options::useExceptionFuzz())
3709         printf("JSC EXCEPTION FUZZ: encountered %u checks.\n", numberOfExceptionFuzzChecks());
3710     bool fireAtEnabled =
3711     Options::fireExecutableAllocationFuzzAt() || Options::fireExecutableAllocationFuzzAtOrAfter();
3712     if (Options::useExecutableAllocationFuzz() && (!fireAtEnabled || Options::verboseExecutableAllocationFuzz()))
3713         printf("JSC EXECUTABLE ALLOCATION FUZZ: encountered %u checks.\n", numberOfExecutableAllocationFuzzChecks());
3714     if (Options::useOSRExitFuzz()) {
3715         printf("JSC OSR EXIT FUZZ: encountered %u static checks.\n", numberOfStaticOSRExitFuzzChecks());
3716         printf("JSC OSR EXIT FUZZ: encountered %u dynamic checks.\n", numberOfOSRExitFuzzChecks());
3717     }
3718
3719     auto compileTimeStats = JIT::compileTimeStats();
3720     Vector<CString> compileTimeKeys;
3721     for (auto& entry : compileTimeStats)
3722         compileTimeKeys.append(entry.key);
3723     std::sort(compileTimeKeys.begin(), compileTimeKeys.end());
3724     for (CString key : compileTimeKeys)
3725         printf("%40s: %.3lf ms\n", key.data(), compileTimeStats.get(key));
3726 #endif
3727
3728     if (Options::gcAtEnd()) {
3729         // We need to hold the API lock to do a GC.
3730         JSLockHolder locker(&vm);
3731         vm.heap.collectAllGarbage();
3732     }
3733
3734     if (options.m_dumpSamplingProfilerData) {
3735 #if ENABLE(SAMPLING_PROFILER)
3736         JSLockHolder locker(&vm);
3737         vm.samplingProfiler()->reportTopFunctions();
3738         vm.samplingProfiler()->reportTopBytecodes();
3739 #else
3740         dataLog("Sampling profiler is not enabled on this platform\n");
3741 #endif
3742     }
3743
3744     return result;
3745 }
3746
3747 int jscmain(int argc, char** argv)
3748 {
3749     // Need to override and enable restricted options before we start parsing options below.
3750     Options::enableRestrictedOptions(true);
3751
3752     // Note that the options parsing can affect VM creation, and thus
3753     // comes first.
3754     CommandLine options(argc, argv);
3755
3756     // Initialize JSC before getting VM.
3757     WTF::initializeMainThread();
3758     JSC::initializeThreading();
3759     startTimeoutThreadIfNeeded();
3760
3761     int result;
3762     result = runJSC(
3763         options,
3764         [&] (VM&, GlobalObject* globalObject) {
3765             return runWithScripts(globalObject, options.m_scripts, options.m_uncaughtExceptionName, options.m_alwaysDumpUncaughtException, options.m_dump, options.m_module);
3766         });
3767
3768     printSuperSamplerState();
3769
3770     return result;
3771 }
3772
3773 #if OS(WINDOWS)
3774 extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[])
3775 {
3776     return main(argc, const_cast<char**>(argv));
3777 }
3778 #endif