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