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