Make JITType an enum class
[WebKit-https.git] / Source / JavaScriptCore / tools / JSDollarVM.cpp
1 /*
2  * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "JSDollarVM.h"
28
29 #include "BuiltinExecutableCreator.h"
30 #include "CodeBlock.h"
31 #include "DOMAttributeGetterSetter.h"
32 #include "DOMJITGetterSetter.h"
33 #include "FrameTracers.h"
34 #include "FunctionCodeBlock.h"
35 #include "GetterSetter.h"
36 #include "JSArray.h"
37 #include "JSArrayBuffer.h"
38 #include "JSCInlines.h"
39 #include "JSFunction.h"
40 #include "JSONObject.h"
41 #include "JSProxy.h"
42 #include "JSString.h"
43 #include "ShadowChicken.h"
44 #include "Snippet.h"
45 #include "SnippetParams.h"
46 #include "TypeProfiler.h"
47 #include "TypeProfilerLog.h"
48 #include "VMInspector.h"
49 #include <wtf/Atomics.h>
50 #include <wtf/DataLog.h>
51 #include <wtf/ProcessID.h>
52 #include <wtf/StringPrintStream.h>
53
54 #if ENABLE(WEBASSEMBLY)
55 #include "JSWebAssemblyHelpers.h"
56 #include "WasmStreamingParser.h"
57 #endif
58
59 using namespace JSC;
60
61 namespace {
62
63 class JSDollarVMCallFrame : public JSDestructibleObject {
64     using Base = JSDestructibleObject;
65 public:
66     JSDollarVMCallFrame(VM& vm, Structure* structure)
67         : Base(vm, structure)
68     { }
69
70     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
71     {
72         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
73     }
74
75     static JSDollarVMCallFrame* create(ExecState* exec, unsigned requestedFrameIndex)
76     {
77         VM& vm = exec->vm();
78         JSGlobalObject* globalObject = exec->lexicalGlobalObject();
79         Structure* structure = createStructure(vm, globalObject, jsNull());
80         JSDollarVMCallFrame* frame = new (NotNull, allocateCell<JSDollarVMCallFrame>(vm.heap, sizeof(JSDollarVMCallFrame))) JSDollarVMCallFrame(vm, structure);
81         frame->finishCreation(vm, exec, requestedFrameIndex);
82         return frame;
83     }
84
85     void finishCreation(VM& vm, CallFrame* frame, unsigned requestedFrameIndex)
86     {
87         Base::finishCreation(vm);
88
89         auto addProperty = [&] (VM& vm, const char* name, JSValue value) {
90             JSDollarVMCallFrame::addProperty(vm, name, value);
91         };
92
93         unsigned frameIndex = 0;
94         bool isValid = false;
95         frame->iterate([&] (StackVisitor& visitor) {
96
97             if (frameIndex++ != requestedFrameIndex)
98                 return StackVisitor::Continue;
99
100             addProperty(vm, "name", jsString(&vm, visitor->functionName()));
101
102             if (visitor->callee().isCell())
103                 addProperty(vm, "callee", visitor->callee().asCell());
104
105             CodeBlock* codeBlock = visitor->codeBlock();
106             if (codeBlock) {
107                 addProperty(vm, "codeBlock", codeBlock);
108                 addProperty(vm, "unlinkedCodeBlock", codeBlock->unlinkedCodeBlock());
109                 addProperty(vm, "executable", codeBlock->ownerExecutable());
110             }
111             isValid = true;
112
113             return StackVisitor::Done;
114         });
115
116         addProperty(vm, "valid", jsBoolean(isValid));
117     }
118
119     DECLARE_INFO;
120
121 private:
122     void addProperty(VM& vm, const char* name, JSValue value)
123     {
124         Identifier identifier = Identifier::fromString(&vm, name);
125         putDirect(vm, identifier, value);
126     }
127 };
128
129 const ClassInfo JSDollarVMCallFrame::s_info = { "CallFrame", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDollarVMCallFrame) };
130
131 class ElementHandleOwner;
132 class Root;
133
134 class Element : public JSNonFinalObject {
135 public:
136     Element(VM& vm, Structure* structure)
137         : Base(vm, structure)
138     {
139     }
140
141     typedef JSNonFinalObject Base;
142
143     Root* root() const { return m_root.get(); }
144     void setRoot(VM& vm, Root* root) { m_root.set(vm, this, root); }
145
146     static Element* create(VM& vm, JSGlobalObject* globalObject, Root* root)
147     {
148         Structure* structure = createStructure(vm, globalObject, jsNull());
149         Element* element = new (NotNull, allocateCell<Element>(vm.heap, sizeof(Element))) Element(vm, structure);
150         element->finishCreation(vm, root);
151         return element;
152     }
153
154     void finishCreation(VM&, Root*);
155
156     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
157     {
158         Element* thisObject = jsCast<Element*>(cell);
159         ASSERT_GC_OBJECT_INHERITS(thisObject, info());
160         Base::visitChildren(thisObject, visitor);
161         visitor.append(thisObject->m_root);
162     }
163
164     static ElementHandleOwner* handleOwner();
165
166     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
167     {
168         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
169     }
170
171     DECLARE_INFO;
172
173 private:
174     WriteBarrier<Root> m_root;
175 };
176
177 class ElementHandleOwner : public WeakHandleOwner {
178 public:
179     bool isReachableFromOpaqueRoots(Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason) override
180     {
181         if (UNLIKELY(reason))
182             *reason = "JSC::Element is opaque root";
183         Element* element = jsCast<Element*>(handle.slot()->asCell());
184         return visitor.containsOpaqueRoot(element->root());
185     }
186 };
187
188 class Root : public JSDestructibleObject {
189 public:
190     Root(VM& vm, Structure* structure)
191         : Base(vm, structure)
192     {
193     }
194
195     Element* element()
196     {
197         return m_element.get();
198     }
199
200     void setElement(Element* element)
201     {
202         Weak<Element> newElement(element, Element::handleOwner());
203         m_element.swap(newElement);
204     }
205
206     static Root* create(VM& vm, JSGlobalObject* globalObject)
207     {
208         Structure* structure = createStructure(vm, globalObject, jsNull());
209         Root* root = new (NotNull, allocateCell<Root>(vm.heap, sizeof(Root))) Root(vm, structure);
210         root->finishCreation(vm);
211         return root;
212     }
213
214     typedef JSDestructibleObject Base;
215
216     DECLARE_INFO;
217
218     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
219     {
220         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
221     }
222
223     static void visitChildren(JSCell* thisObject, SlotVisitor& visitor)
224     {
225         Base::visitChildren(thisObject, visitor);
226         visitor.addOpaqueRoot(thisObject);
227     }
228
229 private:
230     Weak<Element> m_element;
231 };
232
233 class SimpleObject : public JSNonFinalObject {
234 public:
235     SimpleObject(VM& vm, Structure* structure)
236         : Base(vm, structure)
237     {
238     }
239
240     typedef JSNonFinalObject Base;
241     static const bool needsDestruction = false;
242
243     static SimpleObject* create(VM& vm, JSGlobalObject* globalObject)
244     {
245         Structure* structure = createStructure(vm, globalObject, jsNull());
246         SimpleObject* simpleObject = new (NotNull, allocateCell<SimpleObject>(vm.heap, sizeof(SimpleObject))) SimpleObject(vm, structure);
247         simpleObject->finishCreation(vm);
248         return simpleObject;
249     }
250
251     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
252     {
253         SimpleObject* thisObject = jsCast<SimpleObject*>(cell);
254         ASSERT_GC_OBJECT_INHERITS(thisObject, info());
255         Base::visitChildren(thisObject, visitor);
256         visitor.append(thisObject->m_hiddenValue);
257     }
258
259     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
260     {
261         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
262     }
263
264     JSValue hiddenValue()
265     {
266         return m_hiddenValue.get();
267     }
268
269     void setHiddenValue(VM& vm, JSValue value)
270     {
271         ASSERT(value.isCell());
272         m_hiddenValue.set(vm, this, value);
273     }
274
275     DECLARE_INFO;
276
277 private:
278     WriteBarrier<JSC::Unknown> m_hiddenValue;
279 };
280
281 class ImpureGetter : public JSNonFinalObject {
282 public:
283     ImpureGetter(VM& vm, Structure* structure)
284         : Base(vm, structure)
285     {
286     }
287
288     DECLARE_INFO;
289     typedef JSNonFinalObject Base;
290     static const unsigned StructureFlags = Base::StructureFlags | JSC::GetOwnPropertySlotIsImpure | JSC::OverridesGetOwnPropertySlot;
291
292     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
293     {
294         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
295     }
296
297     static ImpureGetter* create(VM& vm, Structure* structure, JSObject* delegate)
298     {
299         ImpureGetter* getter = new (NotNull, allocateCell<ImpureGetter>(vm.heap, sizeof(ImpureGetter))) ImpureGetter(vm, structure);
300         getter->finishCreation(vm, delegate);
301         return getter;
302     }
303
304     void finishCreation(VM& vm, JSObject* delegate)
305     {
306         Base::finishCreation(vm);
307         if (delegate)
308             m_delegate.set(vm, this, delegate);
309     }
310
311     static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName name, PropertySlot& slot)
312     {
313         VM& vm = exec->vm();
314         auto scope = DECLARE_THROW_SCOPE(vm);
315         ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);
316         
317         if (thisObject->m_delegate) {
318             if (thisObject->m_delegate->getPropertySlot(exec, name, slot))
319                 return true;
320             RETURN_IF_EXCEPTION(scope, false);
321         }
322
323         return Base::getOwnPropertySlot(object, exec, name, slot);
324     }
325
326     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
327     {
328         Base::visitChildren(cell, visitor);
329         ImpureGetter* thisObject = jsCast<ImpureGetter*>(cell);
330         visitor.append(thisObject->m_delegate);
331     }
332
333     void setDelegate(VM& vm, JSObject* delegate)
334     {
335         m_delegate.set(vm, this, delegate);
336     }
337
338 private:
339     WriteBarrier<JSObject> m_delegate;
340 };
341
342 class CustomGetter : public JSNonFinalObject {
343 public:
344     CustomGetter(VM& vm, Structure* structure)
345         : Base(vm, structure)
346     {
347     }
348
349     DECLARE_INFO;
350     typedef JSNonFinalObject Base;
351     static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;
352
353     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
354     {
355         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
356     }
357
358     static CustomGetter* create(VM& vm, Structure* structure)
359     {
360         CustomGetter* getter = new (NotNull, allocateCell<CustomGetter>(vm.heap, sizeof(CustomGetter))) CustomGetter(vm, structure);
361         getter->finishCreation(vm);
362         return getter;
363     }
364
365     static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
366     {
367         CustomGetter* thisObject = jsCast<CustomGetter*>(object);
368         if (propertyName == PropertyName(Identifier::fromString(exec, "customGetter"))) {
369             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, thisObject->customGetter);
370             return true;
371         }
372         
373         if (propertyName == PropertyName(Identifier::fromString(exec, "customGetterAccessor"))) {
374             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor, thisObject->customGetterAcessor);
375             return true;
376         }
377         
378         return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
379     }
380
381 private:
382     static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
383     {
384         VM& vm = exec->vm();
385         auto scope = DECLARE_THROW_SCOPE(vm);
386
387         CustomGetter* thisObject = jsDynamicCast<CustomGetter*>(vm, JSValue::decode(thisValue));
388         if (!thisObject)
389             return throwVMTypeError(exec, scope);
390         bool shouldThrow = thisObject->get(exec, PropertyName(Identifier::fromString(exec, "shouldThrow"))).toBoolean(exec);
391         RETURN_IF_EXCEPTION(scope, encodedJSValue());
392         if (shouldThrow)
393             return throwVMTypeError(exec, scope);
394         return JSValue::encode(jsNumber(100));
395     }
396     
397     static EncodedJSValue customGetterAcessor(ExecState* exec, EncodedJSValue thisValue, PropertyName)
398     {
399         VM& vm = exec->vm();
400         auto scope = DECLARE_THROW_SCOPE(vm);
401         
402         JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
403         if (!thisObject)
404             return throwVMTypeError(exec, scope);
405         bool shouldThrow = thisObject->get(exec, PropertyName(Identifier::fromString(exec, "shouldThrow"))).toBoolean(exec);
406         RETURN_IF_EXCEPTION(scope, encodedJSValue());
407         if (shouldThrow)
408             return throwVMTypeError(exec, scope);
409         return JSValue::encode(jsNumber(100));
410     }
411 };
412
413 class RuntimeArray : public JSArray {
414 public:
415     typedef JSArray Base;
416     static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
417
418     static RuntimeArray* create(ExecState* exec)
419     {
420         VM& vm = exec->vm();
421         JSGlobalObject* globalObject = exec->lexicalGlobalObject();
422         Structure* structure = createStructure(vm, globalObject, createPrototype(vm, globalObject));
423         RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(vm.heap)) RuntimeArray(exec, structure);
424         runtimeArray->finishCreation(exec);
425         vm.heap.addFinalizer(runtimeArray, destroy);
426         return runtimeArray;
427     }
428
429     ~RuntimeArray() { }
430
431     static void destroy(JSCell* cell)
432     {
433         static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();
434     }
435
436     static const bool needsDestruction = false;
437
438     static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
439     {
440         VM& vm = exec->vm();
441         RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
442         if (propertyName == vm.propertyNames->length) {
443             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, thisObject->lengthGetter);
444             return true;
445         }
446
447         Optional<uint32_t> index = parseIndex(propertyName);
448         if (index && index.value() < thisObject->getLength()) {
449             slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index.value()]));
450             return true;
451         }
452
453         return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
454     }
455
456     static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)
457     {
458         RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
459         if (index < thisObject->getLength()) {
460             slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index]));
461             return true;
462         }
463
464         return JSObject::getOwnPropertySlotByIndex(thisObject, exec, index, slot);
465     }
466
467     static NO_RETURN_DUE_TO_CRASH bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&)
468     {
469         RELEASE_ASSERT_NOT_REACHED();
470     }
471
472     static NO_RETURN_DUE_TO_CRASH bool deleteProperty(JSCell*, ExecState*, PropertyName)
473     {
474         RELEASE_ASSERT_NOT_REACHED();
475     }
476
477     unsigned getLength() const { return m_vector.size(); }
478
479     DECLARE_INFO;
480
481     static ArrayPrototype* createPrototype(VM&, JSGlobalObject* globalObject)
482     {
483         return globalObject->arrayPrototype();
484     }
485
486     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
487     {
488         return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass);
489     }
490
491 protected:
492     void finishCreation(ExecState* exec)
493     {
494         VM& vm = exec->vm();
495         Base::finishCreation(vm);
496         ASSERT(inherits(vm, info()));
497
498         for (size_t i = 0; i < exec->argumentCount(); i++)
499             m_vector.append(exec->argument(i).toInt32(exec));
500     }
501
502 private:
503     RuntimeArray(ExecState* exec, Structure* structure)
504         : JSArray(exec->vm(), structure, 0)
505     {
506     }
507
508     static EncodedJSValue lengthGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
509     {
510         VM& vm = exec->vm();
511         auto scope = DECLARE_THROW_SCOPE(vm);
512
513         RuntimeArray* thisObject = jsDynamicCast<RuntimeArray*>(vm, JSValue::decode(thisValue));
514         if (!thisObject)
515             return throwVMTypeError(exec, scope);
516         return JSValue::encode(jsNumber(thisObject->getLength()));
517     }
518
519     Vector<int> m_vector;
520 };
521
522 class DOMJITNode : public JSNonFinalObject {
523 public:
524     DOMJITNode(VM& vm, Structure* structure)
525         : Base(vm, structure)
526     {
527     }
528
529     DECLARE_INFO;
530     typedef JSNonFinalObject Base;
531     static const unsigned StructureFlags = Base::StructureFlags;
532
533     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
534     {
535         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
536     }
537
538 #if ENABLE(JIT)
539     static Ref<Snippet> checkSubClassSnippet()
540     {
541         Ref<Snippet> snippet = Snippet::create();
542         snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {
543             CCallHelpers::JumpList failureCases;
544             failureCases.append(jit.branchIfNotType(params[0].gpr(), JSC::JSType(LastJSCObjectType + 1)));
545             return failureCases;
546         });
547         return snippet;
548     }
549 #endif
550
551     static DOMJITNode* create(VM& vm, Structure* structure)
552     {
553         DOMJITNode* getter = new (NotNull, allocateCell<DOMJITNode>(vm.heap, sizeof(DOMJITNode))) DOMJITNode(vm, structure);
554         getter->finishCreation(vm);
555         return getter;
556     }
557
558     int32_t value() const
559     {
560         return m_value;
561     }
562
563     static ptrdiff_t offsetOfValue() { return OBJECT_OFFSETOF(DOMJITNode, m_value); }
564
565 private:
566     int32_t m_value { 42 };
567 };
568
569 class DOMJITGetter : public DOMJITNode {
570 public:
571     DOMJITGetter(VM& vm, Structure* structure)
572         : Base(vm, structure)
573     {
574     }
575
576     DECLARE_INFO;
577     typedef DOMJITNode Base;
578     static const unsigned StructureFlags = Base::StructureFlags;
579
580     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
581     {
582         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
583     }
584
585     static DOMJITGetter* create(VM& vm, Structure* structure)
586     {
587         DOMJITGetter* getter = new (NotNull, allocateCell<DOMJITGetter>(vm.heap, sizeof(DOMJITGetter))) DOMJITGetter(vm, structure);
588         getter->finishCreation(vm);
589         return getter;
590     }
591
592     class DOMJITAttribute : public DOMJIT::GetterSetter {
593     public:
594         constexpr DOMJITAttribute()
595             : DOMJIT::GetterSetter(
596                 DOMJITGetter::customGetter,
597 #if ENABLE(JIT)
598                 &callDOMGetter,
599 #else
600                 nullptr,
601 #endif
602                 SpecInt32Only)
603         {
604         }
605
606 #if ENABLE(JIT)
607         static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)
608         {
609             VM& vm = exec->vm();
610             NativeCallFrameTracer tracer(&vm, exec);
611             return JSValue::encode(jsNumber(static_cast<DOMJITGetter*>(pointer)->value()));
612         }
613
614         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
615         {
616             Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
617             snippet->requireGlobalObject = false;
618             snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {
619                 JSValueRegs results = params[0].jsValueRegs();
620                 GPRReg dom = params[1].gpr();
621                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, dom);
622                 return CCallHelpers::JumpList();
623
624             });
625             return snippet;
626         }
627 #endif
628     };
629
630 private:
631     void finishCreation(VM&);
632
633     static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
634     {
635         VM& vm = exec->vm();
636         DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, JSValue::decode(thisValue));
637         ASSERT(thisObject);
638         return JSValue::encode(jsNumber(thisObject->value()));
639     }
640 };
641
642 static const DOMJITGetter::DOMJITAttribute DOMJITGetterDOMJIT;
643
644 void DOMJITGetter::finishCreation(VM& vm)
645 {
646     Base::finishCreation(vm);
647     const DOMJIT::GetterSetter* domJIT = &DOMJITGetterDOMJIT;
648     auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITNode::info(), domJIT });
649     putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
650 }
651
652 class DOMJITGetterComplex : public DOMJITNode {
653 public:
654     DOMJITGetterComplex(VM& vm, Structure* structure)
655         : Base(vm, structure)
656     {
657     }
658
659     DECLARE_INFO;
660     typedef DOMJITNode Base;
661     static const unsigned StructureFlags = Base::StructureFlags;
662
663     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
664     {
665         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
666     }
667
668     static DOMJITGetterComplex* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
669     {
670         DOMJITGetterComplex* getter = new (NotNull, allocateCell<DOMJITGetterComplex>(vm.heap, sizeof(DOMJITGetterComplex))) DOMJITGetterComplex(vm, structure);
671         getter->finishCreation(vm, globalObject);
672         return getter;
673     }
674
675     class DOMJITAttribute : public DOMJIT::GetterSetter {
676     public:
677         constexpr DOMJITAttribute()
678             : DOMJIT::GetterSetter(
679                 DOMJITGetterComplex::customGetter,
680 #if ENABLE(JIT)
681                 &callDOMGetter,
682 #else
683                 nullptr,
684 #endif
685                 SpecInt32Only)
686         {
687         }
688
689 #if ENABLE(JIT)
690         static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)
691         {
692             VM& vm = exec->vm();
693             NativeCallFrameTracer tracer(&vm, exec);
694             auto scope = DECLARE_THROW_SCOPE(vm);
695             auto* object = static_cast<DOMJITNode*>(pointer);
696             auto* domjitGetterComplex = jsDynamicCast<DOMJITGetterComplex*>(vm, object);
697             if (domjitGetterComplex) {
698                 if (domjitGetterComplex->m_enableException)
699                     return JSValue::encode(throwException(exec, scope, createError(exec, "DOMJITGetterComplex slow call exception"_s)));
700             }
701             return JSValue::encode(jsNumber(object->value()));
702         }
703
704         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
705         {
706             Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
707             static_assert(GPRInfo::numberOfRegisters >= 4, "Number of registers should be larger or equal to 4.");
708             unsigned numGPScratchRegisters = GPRInfo::numberOfRegisters - 4;
709             snippet->numGPScratchRegisters = numGPScratchRegisters;
710             snippet->numFPScratchRegisters = 3;
711             snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {
712                 JSValueRegs results = params[0].jsValueRegs();
713                 GPRReg domGPR = params[1].gpr();
714                 for (unsigned i = 0; i < numGPScratchRegisters; ++i)
715                     jit.move(CCallHelpers::TrustedImm32(42), params.gpScratch(i));
716
717                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, domGPR);
718                 return CCallHelpers::JumpList();
719             });
720             return snippet;
721         }
722 #endif
723     };
724
725 private:
726     void finishCreation(VM&, JSGlobalObject*);
727
728     static EncodedJSValue JSC_HOST_CALL functionEnableException(ExecState* exec)
729     {
730         VM& vm = exec->vm();
731         auto* object = jsDynamicCast<DOMJITGetterComplex*>(vm, exec->thisValue());
732         if (object)
733             object->m_enableException = true;
734         return JSValue::encode(jsUndefined());
735     }
736
737     static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
738     {
739         VM& vm = exec->vm();
740         auto scope = DECLARE_THROW_SCOPE(vm);
741
742         auto* thisObject = jsDynamicCast<DOMJITGetterComplex*>(vm, JSValue::decode(thisValue));
743         ASSERT(thisObject);
744         if (thisObject->m_enableException)
745             return JSValue::encode(throwException(exec, scope, createError(exec, "DOMJITGetterComplex slow call exception"_s)));
746         return JSValue::encode(jsNumber(thisObject->value()));
747     }
748
749     bool m_enableException { false };
750 };
751
752 static const DOMJITGetterComplex::DOMJITAttribute DOMJITGetterComplexDOMJIT;
753
754 void DOMJITGetterComplex::finishCreation(VM& vm, JSGlobalObject* globalObject)
755 {
756     Base::finishCreation(vm);
757     const DOMJIT::GetterSetter* domJIT = &DOMJITGetterComplexDOMJIT;
758     auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITGetterComplex::info(), domJIT });
759     putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
760     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "enableException"), 0, functionEnableException, NoIntrinsic, 0);
761 }
762
763 class DOMJITFunctionObject : public DOMJITNode {
764 public:
765     DOMJITFunctionObject(VM& vm, Structure* structure)
766         : Base(vm, structure)
767     {
768     }
769
770     DECLARE_INFO;
771     typedef DOMJITNode Base;
772     static const unsigned StructureFlags = Base::StructureFlags;
773
774
775     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
776     {
777         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
778     }
779
780     static DOMJITFunctionObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
781     {
782         DOMJITFunctionObject* object = new (NotNull, allocateCell<DOMJITFunctionObject>(vm.heap, sizeof(DOMJITFunctionObject))) DOMJITFunctionObject(vm, structure);
783         object->finishCreation(vm, globalObject);
784         return object;
785     }
786
787     static EncodedJSValue JSC_HOST_CALL safeFunction(ExecState* exec)
788     {
789         VM& vm = exec->vm();
790         auto scope = DECLARE_THROW_SCOPE(vm);
791
792         DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, exec->thisValue());
793         if (!thisObject)
794             return throwVMTypeError(exec, scope);
795         return JSValue::encode(jsNumber(thisObject->value()));
796     }
797
798     static EncodedJSValue JIT_OPERATION unsafeFunction(ExecState* exec, DOMJITNode* node)
799     {
800         VM& vm = exec->vm();
801         NativeCallFrameTracer tracer(&vm, exec);
802         return JSValue::encode(jsNumber(node->value()));
803     }
804
805 #if ENABLE(JIT)
806     static Ref<Snippet> checkSubClassSnippet()
807     {
808         Ref<Snippet> snippet = Snippet::create();
809         snippet->numFPScratchRegisters = 1;
810         snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {
811             static const double value = 42.0;
812             CCallHelpers::JumpList failureCases;
813             // May use scratch registers.
814             jit.loadDouble(CCallHelpers::TrustedImmPtr(&value), params.fpScratch(0));
815             failureCases.append(jit.branchIfNotType(params[0].gpr(), JSC::JSType(LastJSCObjectType + 1)));
816             return failureCases;
817         });
818         return snippet;
819     }
820 #endif
821
822 private:
823     void finishCreation(VM&, JSGlobalObject*);
824 };
825
826 static const DOMJIT::Signature DOMJITFunctionObjectSignature((uintptr_t)DOMJITFunctionObject::unsafeFunction, DOMJITFunctionObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);
827
828 void DOMJITFunctionObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
829 {
830     Base::finishCreation(vm);
831     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "func"), 0, safeFunction, NoIntrinsic, &DOMJITFunctionObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));
832 }
833
834 class DOMJITCheckSubClassObject : public DOMJITNode {
835 public:
836     DOMJITCheckSubClassObject(VM& vm, Structure* structure)
837         : Base(vm, structure)
838     {
839     }
840
841     DECLARE_INFO;
842     typedef DOMJITNode Base;
843     static const unsigned StructureFlags = Base::StructureFlags;
844
845
846     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
847     {
848         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
849     }
850
851     static DOMJITCheckSubClassObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
852     {
853         DOMJITCheckSubClassObject* object = new (NotNull, allocateCell<DOMJITCheckSubClassObject>(vm.heap, sizeof(DOMJITCheckSubClassObject))) DOMJITCheckSubClassObject(vm, structure);
854         object->finishCreation(vm, globalObject);
855         return object;
856     }
857
858     static EncodedJSValue JSC_HOST_CALL safeFunction(ExecState* exec)
859     {
860         VM& vm = exec->vm();
861         auto scope = DECLARE_THROW_SCOPE(vm);
862
863         auto* thisObject = jsDynamicCast<DOMJITCheckSubClassObject*>(vm, exec->thisValue());
864         if (!thisObject)
865             return throwVMTypeError(exec, scope);
866         return JSValue::encode(jsNumber(thisObject->value()));
867     }
868
869     static EncodedJSValue JIT_OPERATION unsafeFunction(ExecState* exec, DOMJITNode* node)
870     {
871         VM& vm = exec->vm();
872         NativeCallFrameTracer tracer(&vm, exec);
873         return JSValue::encode(jsNumber(node->value()));
874     }
875
876 private:
877     void finishCreation(VM&, JSGlobalObject*);
878 };
879
880 static const DOMJIT::Signature DOMJITCheckSubClassObjectSignature((uintptr_t)DOMJITCheckSubClassObject::unsafeFunction, DOMJITCheckSubClassObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);
881
882 void DOMJITCheckSubClassObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
883 {
884     Base::finishCreation(vm);
885     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "func"), 0, safeFunction, NoIntrinsic, &DOMJITCheckSubClassObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));
886 }
887
888 class DOMJITGetterBaseJSObject : public DOMJITNode {
889 public:
890     DOMJITGetterBaseJSObject(VM& vm, Structure* structure)
891         : Base(vm, structure)
892     {
893     }
894
895     DECLARE_INFO;
896     using Base = DOMJITNode;
897     static const unsigned StructureFlags = Base::StructureFlags;
898
899     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
900     {
901         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
902     }
903
904     static DOMJITGetterBaseJSObject* create(VM& vm, Structure* structure)
905     {
906         DOMJITGetterBaseJSObject* getter = new (NotNull, allocateCell<DOMJITGetterBaseJSObject>(vm.heap, sizeof(DOMJITGetterBaseJSObject))) DOMJITGetterBaseJSObject(vm, structure);
907         getter->finishCreation(vm);
908         return getter;
909     }
910
911     class DOMJITAttribute : public DOMJIT::GetterSetter {
912     public:
913         constexpr DOMJITAttribute()
914             : DOMJIT::GetterSetter(
915                 DOMJITGetterBaseJSObject::customGetter,
916 #if ENABLE(JIT)
917                 &callDOMGetter,
918 #else
919                 nullptr,
920 #endif
921                 SpecBytecodeTop)
922         {
923         }
924
925 #if ENABLE(JIT)
926         static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)
927         {
928             VM& vm = exec->vm();
929             NativeCallFrameTracer tracer(&vm, exec);
930             JSObject* object = static_cast<JSObject*>(pointer);
931             return JSValue::encode(object->getPrototypeDirect(vm));
932         }
933
934         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
935         {
936             Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
937             snippet->requireGlobalObject = false;
938             snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {
939                 JSValueRegs results = params[0].jsValueRegs();
940                 GPRReg dom = params[1].gpr();
941                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, dom);
942                 return CCallHelpers::JumpList();
943
944             });
945             return snippet;
946         }
947 #endif
948     };
949
950 private:
951     void finishCreation(VM&);
952
953     static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
954     {
955         VM& vm = exec->vm();
956         JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
957         RELEASE_ASSERT(thisObject);
958         return JSValue::encode(thisObject->getPrototypeDirect(vm));
959     }
960 };
961
962 static const DOMJITGetterBaseJSObject::DOMJITAttribute DOMJITGetterBaseJSObjectDOMJIT;
963
964 void DOMJITGetterBaseJSObject::finishCreation(VM& vm)
965 {
966     Base::finishCreation(vm);
967     const DOMJIT::GetterSetter* domJIT = &DOMJITGetterBaseJSObjectDOMJIT;
968     auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { JSObject::info(), domJIT });
969     putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
970 }
971
972 class Message : public ThreadSafeRefCounted<Message> {
973 public:
974     Message(ArrayBufferContents&&, int32_t);
975     ~Message();
976
977     ArrayBufferContents&& releaseContents() { return WTFMove(m_contents); }
978     int32_t index() const { return m_index; }
979
980 private:
981     ArrayBufferContents m_contents;
982     int32_t m_index { 0 };
983 };
984
985 class JSTestCustomGetterSetter : public JSNonFinalObject {
986 public:
987     using Base = JSNonFinalObject;
988     static const unsigned StructureFlags = Base::StructureFlags;
989
990     JSTestCustomGetterSetter(VM& vm, Structure* structure)
991         : Base(vm, structure)
992     { }
993
994     static JSTestCustomGetterSetter* create(VM& vm, JSGlobalObject*, Structure* structure)
995     {
996         JSTestCustomGetterSetter* result = new (NotNull, allocateCell<JSTestCustomGetterSetter>(vm.heap, sizeof(JSTestCustomGetterSetter))) JSTestCustomGetterSetter(vm, structure);
997         result->finishCreation(vm);
998         return result;
999     }
1000
1001     void finishCreation(VM&);
1002
1003     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
1004     {
1005         return Structure::create(vm, globalObject, globalObject->objectPrototype(), TypeInfo(ObjectType, StructureFlags), info());
1006     }
1007
1008     DECLARE_INFO;
1009 };
1010
1011
1012 static EncodedJSValue customGetAccessor(ExecState*, EncodedJSValue thisValue, PropertyName)
1013 {
1014     // Passed |this|
1015     return thisValue;
1016 }
1017
1018 static EncodedJSValue customGetValue(ExecState* exec, EncodedJSValue slotValue, PropertyName)
1019 {
1020     RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>(exec->vm()));
1021     // Passed property holder.
1022     return slotValue;
1023 }
1024
1025 static bool customSetAccessor(ExecState* exec, EncodedJSValue thisObject, EncodedJSValue encodedValue)
1026 {
1027     VM& vm = exec->vm();
1028
1029     JSValue value = JSValue::decode(encodedValue);
1030     RELEASE_ASSERT(value.isObject());
1031     JSObject* object = asObject(value);
1032     PutPropertySlot slot(object);
1033     object->put(object, exec, Identifier::fromString(&vm, "result"), JSValue::decode(thisObject), slot);
1034
1035     return true;
1036 }
1037
1038 static bool customSetValue(ExecState* exec, EncodedJSValue slotValue, EncodedJSValue encodedValue)
1039 {
1040     VM& vm = exec->vm();
1041
1042     RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>(exec->vm()));
1043
1044     JSValue value = JSValue::decode(encodedValue);
1045     RELEASE_ASSERT(value.isObject());
1046     JSObject* object = asObject(value);
1047     PutPropertySlot slot(object);
1048     object->put(object, exec, Identifier::fromString(&vm, "result"), JSValue::decode(slotValue), slot);
1049
1050     return true;
1051 }
1052
1053 void JSTestCustomGetterSetter::finishCreation(VM& vm)
1054 {
1055     Base::finishCreation(vm);
1056
1057     putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customValue"),
1058         CustomGetterSetter::create(vm, customGetValue, customSetValue), 0);
1059     putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customAccessor"),
1060         CustomGetterSetter::create(vm, customGetAccessor, customSetAccessor), static_cast<unsigned>(PropertyAttribute::CustomAccessor));
1061 }
1062
1063 const ClassInfo Element::s_info = { "Element", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Element) };
1064 const ClassInfo Root::s_info = { "Root", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Root) };
1065 const ClassInfo SimpleObject::s_info = { "SimpleObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(SimpleObject) };
1066 const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ImpureGetter) };
1067 const ClassInfo CustomGetter::s_info = { "CustomGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(CustomGetter) };
1068 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RuntimeArray) };
1069 #if ENABLE(JIT)
1070 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, &DOMJITNode::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITNode) };
1071 #else
1072 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITNode) };
1073 #endif
1074 const ClassInfo DOMJITGetter::s_info = { "DOMJITGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetter) };
1075 const ClassInfo DOMJITGetterComplex::s_info = { "DOMJITGetterComplex", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterComplex) };
1076 const ClassInfo DOMJITGetterBaseJSObject::s_info = { "DOMJITGetterBaseJSObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterBaseJSObject) };
1077 #if ENABLE(JIT)
1078 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, &DOMJITFunctionObject::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
1079 #else
1080 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
1081 #endif
1082 const ClassInfo DOMJITCheckSubClassObject::s_info = { "DOMJITCheckSubClassObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITCheckSubClassObject) };
1083 const ClassInfo JSTestCustomGetterSetter::s_info = { "JSTestCustomGetterSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestCustomGetterSetter) };
1084
1085 ElementHandleOwner* Element::handleOwner()
1086 {
1087     static ElementHandleOwner* owner = 0;
1088     if (!owner)
1089         owner = new ElementHandleOwner();
1090     return owner;
1091 }
1092
1093 void Element::finishCreation(VM& vm, Root* root)
1094 {
1095     Base::finishCreation(vm);
1096     setRoot(vm, root);
1097     m_root->setElement(this);
1098 }
1099
1100 #if ENABLE(WEBASSEMBLY)
1101
1102 static EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserAddBytes(ExecState*);
1103 static EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserFinalize(ExecState*);
1104
1105 class WasmStreamingParser : public JSDestructibleObject {
1106 public:
1107     WasmStreamingParser(VM& vm, Structure* structure)
1108         : Base(vm, structure)
1109         , m_info(Wasm::ModuleInformation::create())
1110         , m_streamingParser(m_info.get())
1111     {
1112     }
1113
1114     using Base = JSDestructibleObject;
1115
1116     static WasmStreamingParser* create(VM& vm, JSGlobalObject* globalObject)
1117     {
1118         Structure* structure = createStructure(vm, globalObject, jsNull());
1119         WasmStreamingParser* result = new (NotNull, allocateCell<WasmStreamingParser>(vm.heap, sizeof(WasmStreamingParser))) WasmStreamingParser(vm, structure);
1120         result->finishCreation(vm);
1121         return result;
1122     }
1123
1124     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1125     {
1126         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
1127     }
1128
1129     Wasm::StreamingParser& streamingParser() { return m_streamingParser; }
1130
1131     void finishCreation(VM& vm)
1132     {
1133         Base::finishCreation(vm);
1134
1135         JSGlobalObject* globalObject = this->globalObject(vm);
1136         putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "addBytes"), 0, functionWasmStreamingParserAddBytes, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
1137         putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "finalize"), 0, functionWasmStreamingParserFinalize, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
1138     }
1139
1140     DECLARE_INFO;
1141
1142     Ref<Wasm::ModuleInformation> m_info;
1143     Wasm::StreamingParser m_streamingParser;
1144 };
1145
1146 const ClassInfo WasmStreamingParser::s_info = { "WasmStreamingParser", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WasmStreamingParser) };
1147
1148 EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserAddBytes(ExecState* exec)
1149 {
1150     VM& vm = exec->vm();
1151     auto scope = DECLARE_THROW_SCOPE(exec->vm());
1152     auto* thisObject = jsDynamicCast<WasmStreamingParser*>(vm, exec->thisValue());
1153     if (!thisObject)
1154         RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(false)));
1155
1156     auto data = getWasmBufferFromValue(exec, exec->argument(0));
1157     RETURN_IF_EXCEPTION(scope, encodedJSValue());
1158     RELEASE_AND_RETURN(scope, JSValue::encode(jsNumber(static_cast<int32_t>(thisObject->streamingParser().addBytes(bitwise_cast<const uint8_t*>(data.first), data.second)))));
1159 }
1160
1161 EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserFinalize(ExecState* exec)
1162 {
1163     VM& vm = exec->vm();
1164     auto* thisObject = jsDynamicCast<WasmStreamingParser*>(vm, exec->thisValue());
1165     if (!thisObject)
1166         return JSValue::encode(jsBoolean(false));
1167     return JSValue::encode(jsNumber(static_cast<int32_t>(thisObject->streamingParser().finalize())));
1168 }
1169
1170 #endif
1171
1172 } // namespace
1173
1174 namespace JSC {
1175
1176 const ClassInfo JSDollarVM::s_info = { "DollarVM", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDollarVM) };
1177
1178 // Triggers a crash immediately.
1179 // Usage: $vm.crash()
1180 static NO_RETURN_DUE_TO_CRASH EncodedJSValue JSC_HOST_CALL functionCrash(ExecState*)
1181 {
1182     CRASH();
1183 }
1184
1185 // Executes a breakpoint instruction if the first argument is truthy or is unset.
1186 // Usage: $vm.breakpoint(<condition>)
1187 static EncodedJSValue JSC_HOST_CALL functionBreakpoint(ExecState* exec)
1188 {
1189     // Nothing should throw here but we might as well double check...
1190     VM& vm = exec->vm();
1191     auto scope = DECLARE_CATCH_SCOPE(vm);
1192     UNUSED_PARAM(scope);
1193     if (!exec->argumentCount() || exec->argument(0).toBoolean(exec))
1194         WTFBreakpointTrap();
1195
1196     return encodedJSUndefined();
1197 }
1198
1199 // Returns true if the current frame is a DFG frame.
1200 // Usage: isDFG = $vm.dfgTrue()
1201 static EncodedJSValue JSC_HOST_CALL functionDFGTrue(ExecState*)
1202 {
1203     return JSValue::encode(jsBoolean(false));
1204 }
1205
1206 // Returns true if the current frame is a FTL frame.
1207 // Usage: isFTL = $vm.ftlTrue()
1208 static EncodedJSValue JSC_HOST_CALL functionFTLTrue(ExecState*)
1209 {
1210     return JSValue::encode(jsBoolean(false));
1211 }
1212
1213 static EncodedJSValue JSC_HOST_CALL functionCpuMfence(ExecState*)
1214 {
1215 #if CPU(X86_64) && !OS(WINDOWS)
1216     asm volatile("mfence" ::: "memory");
1217 #endif
1218     return JSValue::encode(jsUndefined());
1219 }
1220
1221 static EncodedJSValue JSC_HOST_CALL functionCpuRdtsc(ExecState*)
1222 {
1223 #if CPU(X86_64) && !OS(WINDOWS)
1224     unsigned high;
1225     unsigned low;
1226     asm volatile ("rdtsc" : "=a"(low), "=d"(high));
1227     return JSValue::encode(jsNumber(low));
1228 #else
1229     return JSValue::encode(jsNumber(0));
1230 #endif
1231 }
1232
1233 static EncodedJSValue JSC_HOST_CALL functionCpuCpuid(ExecState*)
1234 {
1235 #if CPU(X86_64) && !OS(WINDOWS)
1236     WTF::x86_cpuid();
1237 #endif
1238     return JSValue::encode(jsUndefined());
1239 }
1240
1241 static EncodedJSValue JSC_HOST_CALL functionCpuPause(ExecState*)
1242 {
1243 #if CPU(X86_64) && !OS(WINDOWS)
1244     asm volatile ("pause" ::: "memory");
1245 #endif
1246     return JSValue::encode(jsUndefined());
1247 }
1248
1249 // This takes either a JSArrayBuffer, JSArrayBufferView*, or any other object as its first
1250 // argument. The second argument is expected to be an integer.
1251 //
1252 // If the first argument is a JSArrayBuffer, it'll clflush on that buffer
1253 // plus the second argument as a byte offset. It'll also flush on the object
1254 // itself so its length, etc, aren't in the cache.
1255 //
1256 // If the first argument is not a JSArrayBuffer, we load the butterfly
1257 // and clflush at the address of the butterfly.
1258 static EncodedJSValue JSC_HOST_CALL functionCpuClflush(ExecState* exec)
1259 {
1260 #if CPU(X86_64) && !OS(WINDOWS)
1261     VM& vm = exec->vm();
1262
1263     if (!exec->argument(1).isInt32())
1264         return JSValue::encode(jsBoolean(false));
1265
1266     auto clflush = [] (void* ptr) {
1267         char* ptrToFlush = static_cast<char*>(ptr);
1268         asm volatile ("clflush %0" :: "m"(*ptrToFlush) : "memory");
1269     };
1270
1271     Vector<void*> toFlush;
1272
1273     uint32_t offset = exec->argument(1).asUInt32();
1274
1275     if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(vm, exec->argument(0)))
1276         toFlush.append(bitwise_cast<char*>(view->vector()) + offset);
1277     else if (JSObject* object = jsDynamicCast<JSObject*>(vm, exec->argument(0))) {
1278         switch (object->indexingType()) {
1279         case ALL_INT32_INDEXING_TYPES:
1280         case ALL_CONTIGUOUS_INDEXING_TYPES:
1281         case ALL_DOUBLE_INDEXING_TYPES:
1282             toFlush.append(bitwise_cast<char*>(object->butterfly()) + Butterfly::offsetOfVectorLength());
1283             toFlush.append(bitwise_cast<char*>(object->butterfly()) + Butterfly::offsetOfPublicLength());
1284         }
1285     }
1286
1287     if (!toFlush.size())
1288         return JSValue::encode(jsBoolean(false));
1289
1290     for (void* ptr : toFlush)
1291         clflush(ptr);
1292     return JSValue::encode(jsBoolean(true));
1293 #else
1294     UNUSED_PARAM(exec);
1295     return JSValue::encode(jsBoolean(false));
1296 #endif
1297 }
1298
1299 class CallerFrameJITTypeFunctor {
1300 public:
1301     CallerFrameJITTypeFunctor()
1302         : m_currentFrame(0)
1303         , m_jitType(JITType::None)
1304     {
1305     }
1306
1307     StackVisitor::Status operator()(StackVisitor& visitor) const
1308     {
1309         if (m_currentFrame++ > 1) {
1310             m_jitType = visitor->codeBlock()->jitType();
1311             return StackVisitor::Done;
1312         }
1313         return StackVisitor::Continue;
1314     }
1315     
1316     JITType jitType() { return m_jitType; }
1317
1318 private:
1319     mutable unsigned m_currentFrame;
1320     mutable JITType m_jitType;
1321 };
1322
1323 static FunctionExecutable* getExecutableForFunction(JSValue theFunctionValue)
1324 {
1325     if (!theFunctionValue.isCell())
1326         return nullptr;
1327     
1328     VM& vm = *theFunctionValue.asCell()->vm();
1329     JSFunction* theFunction = jsDynamicCast<JSFunction*>(vm, theFunctionValue);
1330     if (!theFunction)
1331         return nullptr;
1332     
1333     FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(vm,
1334         theFunction->executable());
1335
1336     return executable;
1337 }
1338
1339 // Returns true if the current frame is a LLInt frame.
1340 // Usage: isLLInt = $vm.llintTrue()
1341 static EncodedJSValue JSC_HOST_CALL functionLLintTrue(ExecState* exec)
1342 {
1343     if (!exec)
1344         return JSValue::encode(jsUndefined());
1345     CallerFrameJITTypeFunctor functor;
1346     exec->iterate(functor);
1347     return JSValue::encode(jsBoolean(functor.jitType() == JITType::InterpreterThunk));
1348 }
1349
1350 // Returns true if the current frame is a baseline JIT frame.
1351 // Usage: isBaselineJIT = $vm.jitTrue()
1352 static EncodedJSValue JSC_HOST_CALL functionJITTrue(ExecState* exec)
1353 {
1354     if (!exec)
1355         return JSValue::encode(jsUndefined());
1356     CallerFrameJITTypeFunctor functor;
1357     exec->iterate(functor);
1358     return JSValue::encode(jsBoolean(functor.jitType() == JITType::BaselineJIT));
1359 }
1360
1361 // Set that the argument function should not be inlined.
1362 // Usage:
1363 // function f() { };
1364 // $vm.noInline(f);
1365 static EncodedJSValue JSC_HOST_CALL functionNoInline(ExecState* exec)
1366 {
1367     if (exec->argumentCount() < 1)
1368         return JSValue::encode(jsUndefined());
1369     
1370     JSValue theFunctionValue = exec->uncheckedArgument(0);
1371
1372     if (FunctionExecutable* executable = getExecutableForFunction(theFunctionValue))
1373         executable->setNeverInline(true);
1374     
1375     return JSValue::encode(jsUndefined());
1376 }
1377
1378 // Runs a full GC synchronously.
1379 // Usage: $vm.gc()
1380 static EncodedJSValue JSC_HOST_CALL functionGC(ExecState* exec)
1381 {
1382     VMInspector::gc(exec);
1383     return JSValue::encode(jsUndefined());
1384 }
1385
1386 // Runs the edenGC synchronously.
1387 // Usage: $vm.edenGC()
1388 static EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState* exec)
1389 {
1390     VMInspector::edenGC(exec);
1391     return JSValue::encode(jsUndefined());
1392 }
1393
1394 // Gets a JSDollarVMCallFrame for a specified frame index.
1395 // Usage: var callFrame = $vm.callFrame(0) // frame 0 is the top frame.
1396 // Usage: var callFrame = $vm.callFrame() // implies frame 0 i.e. current frame.
1397 //
1398 // This gives you the ability to query the following:
1399 //    callFrame.valid; // false if we asked for a frame beyond the end of the stack, else true.
1400 //    callFrame.callee;
1401 //    callFrame.codeBlock;
1402 //    callFrame.unlinkedCodeBlock;
1403 //    callFrame.executable;
1404 //
1405 // Note: you cannot toString() a codeBlock, unlinkedCodeBlock, or executable because
1406 // there are internal objects and not a JS object. Hence, you cannot do string
1407 // concatenation with them.
1408 static EncodedJSValue JSC_HOST_CALL functionCallFrame(ExecState* exec)
1409 {
1410     unsigned frameNumber = 1;
1411     if (exec->argumentCount() >= 1) {
1412         JSValue value = exec->uncheckedArgument(0);
1413         if (!value.isUInt32())
1414             return JSValue::encode(jsUndefined());
1415
1416         // We need to inc the frame number because the caller would consider
1417         // its own frame as frame 0. Hence, we need discount the frame for this
1418         // function.
1419         frameNumber = value.asUInt32() + 1;
1420     }
1421
1422     return JSValue::encode(JSDollarVMCallFrame::create(exec, frameNumber));
1423 }
1424
1425 // Gets a token for the CodeBlock for a specified frame index.
1426 // Usage: codeBlockToken = $vm.codeBlockForFrame(0) // frame 0 is the top frame.
1427 // Usage: codeBlockToken = $vm.codeBlockForFrame() // implies frame 0 i.e. current frame.
1428 static EncodedJSValue JSC_HOST_CALL functionCodeBlockForFrame(ExecState* exec)
1429 {
1430     unsigned frameNumber = 1;
1431     if (exec->argumentCount() >= 1) {
1432         JSValue value = exec->uncheckedArgument(0);
1433         if (!value.isUInt32())
1434             return JSValue::encode(jsUndefined());
1435
1436         // We need to inc the frame number because the caller would consider
1437         // its own frame as frame 0. Hence, we need discount the frame for this
1438         // function.
1439         frameNumber = value.asUInt32() + 1;
1440     }
1441
1442     CodeBlock* codeBlock = VMInspector::codeBlockForFrame(exec, frameNumber);
1443     if (codeBlock)
1444         return JSValue::encode(codeBlock);
1445     return JSValue::encode(jsUndefined());
1446 }
1447
1448 static CodeBlock* codeBlockFromArg(ExecState* exec)
1449 {
1450     VM& vm = exec->vm();
1451     if (exec->argumentCount() < 1)
1452         return nullptr;
1453
1454     JSValue value = exec->uncheckedArgument(0);
1455     CodeBlock* candidateCodeBlock = nullptr;
1456     if (value.isCell()) {
1457         JSFunction* func = jsDynamicCast<JSFunction*>(vm, value.asCell());
1458         if (func) {
1459             if (func->isHostFunction())
1460                 candidateCodeBlock = nullptr;
1461             else
1462                 candidateCodeBlock = func->jsExecutable()->eitherCodeBlock();
1463         } else
1464             candidateCodeBlock = static_cast<CodeBlock*>(value.asCell());
1465     }
1466
1467     if (candidateCodeBlock && VMInspector::isValidCodeBlock(exec, candidateCodeBlock))
1468         return candidateCodeBlock;
1469
1470     if (candidateCodeBlock)
1471         dataLog("Invalid codeBlock: ", RawPointer(candidateCodeBlock), " ", value, "\n");
1472     else
1473         dataLog("Invalid codeBlock: ", value, "\n");
1474     return nullptr;
1475 }
1476
1477 // Usage: $vm.print("codeblock = ", $vm.codeBlockFor(functionObj))
1478 // Usage: $vm.print("codeblock = ", $vm.codeBlockFor(codeBlockToken))
1479 // Note: you cannot toString() a codeBlock because it's an internal object and not
1480 // a JS object. Hence, you cannot do string concatenation with it.
1481 static EncodedJSValue JSC_HOST_CALL functionCodeBlockFor(ExecState* exec)
1482 {
1483     CodeBlock* codeBlock = codeBlockFromArg(exec);
1484     WTF::StringPrintStream stream;
1485     if (codeBlock) {
1486         stream.print(*codeBlock);
1487         return JSValue::encode(jsString(exec, stream.toString()));
1488     }
1489     return JSValue::encode(jsUndefined());
1490 }
1491
1492 // Usage: $vm.dumpSourceFor(functionObj)
1493 // Usage: $vm.dumpSourceFor(codeBlockToken)
1494 static EncodedJSValue JSC_HOST_CALL functionDumpSourceFor(ExecState* exec)
1495 {
1496     CodeBlock* codeBlock = codeBlockFromArg(exec);
1497     if (codeBlock)
1498         codeBlock->dumpSource();
1499     return JSValue::encode(jsUndefined());
1500 }
1501
1502 // Usage: $vm.dumpBytecodeFor(functionObj)
1503 // Usage: $vm.dumpBytecodeFor(codeBlock)
1504 static EncodedJSValue JSC_HOST_CALL functionDumpBytecodeFor(ExecState* exec)
1505 {
1506     CodeBlock* codeBlock = codeBlockFromArg(exec);
1507     if (codeBlock)
1508         codeBlock->dumpBytecode();
1509     return JSValue::encode(jsUndefined());
1510 }
1511
1512 static EncodedJSValue doPrint(ExecState* exec, bool addLineFeed)
1513 {
1514     auto scope = DECLARE_THROW_SCOPE(exec->vm());
1515     for (unsigned i = 0; i < exec->argumentCount(); ++i) {
1516         JSValue arg = exec->uncheckedArgument(i);
1517         if (arg.isCell()
1518             && !arg.isObject()
1519             && !arg.isString()
1520             && !arg.isBigInt()) {
1521             dataLog(arg);
1522             continue;
1523         }
1524         String argStr = exec->uncheckedArgument(i).toWTFString(exec);
1525         RETURN_IF_EXCEPTION(scope, encodedJSValue());
1526         dataLog(argStr);
1527     }
1528     if (addLineFeed)
1529         dataLog("\n");
1530     return JSValue::encode(jsUndefined());
1531 }
1532
1533 // Prints a series of comma separate strings without appending a newline.
1534 // Usage: $vm.dataLog(str1, str2, str3)
1535 static EncodedJSValue JSC_HOST_CALL functionDataLog(ExecState* exec)
1536 {
1537     const bool addLineFeed = false;
1538     return doPrint(exec, addLineFeed);
1539 }
1540
1541 // Prints a series of comma separate strings and appends a newline.
1542 // Usage: $vm.print(str1, str2, str3)
1543 static EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
1544 {
1545     const bool addLineFeed = true;
1546     return doPrint(exec, addLineFeed);
1547 }
1548
1549 // Dumps the current CallFrame.
1550 // Usage: $vm.dumpCallFrame()
1551 static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec)
1552 {
1553     // When the callers call this function, they are expecting to dump their
1554     // own frame. So skip 1 for this frame.
1555     VMInspector::dumpCallFrame(exec, 1);
1556     return JSValue::encode(jsUndefined());
1557 }
1558
1559 // Dumps the JS stack.
1560 // Usage: $vm.printStack()
1561 static EncodedJSValue JSC_HOST_CALL functionDumpStack(ExecState* exec)
1562 {
1563     // When the callers call this function, they are expecting to dump the
1564     // stack starting their own frame. So skip 1 for this frame.
1565     VMInspector::dumpStack(exec, 1);
1566     return JSValue::encode(jsUndefined());
1567 }
1568
1569 // Dumps the current CallFrame.
1570 // Usage: $vm.dumpRegisters(N) // dump the registers of the Nth CallFrame.
1571 // Usage: $vm.dumpRegisters() // dump the registers of the current CallFrame.
1572 // FIXME: Currently, this function dumps the physical frame. We should make
1573 // it dump the logical frame (i.e. be able to dump inlined frames as well).
1574 static EncodedJSValue JSC_HOST_CALL functionDumpRegisters(ExecState* exec)
1575 {
1576     unsigned requestedFrameIndex = 1;
1577     if (exec->argumentCount() >= 1) {
1578         JSValue value = exec->uncheckedArgument(0);
1579         if (!value.isUInt32())
1580             return JSValue::encode(jsUndefined());
1581
1582         // We need to inc the frame number because the caller would consider
1583         // its own frame as frame 0. Hence, we need discount the frame for this
1584         // function.
1585         requestedFrameIndex = value.asUInt32() + 1;
1586     }
1587
1588     unsigned frameIndex = 0;
1589     exec->iterate([&] (StackVisitor& visitor) {
1590         if (frameIndex++ != requestedFrameIndex)
1591             return StackVisitor::Continue;
1592         VMInspector::dumpRegisters(visitor->callFrame());
1593         return StackVisitor::Done;
1594     });
1595
1596     return encodedJSUndefined();
1597 }
1598
1599 // Dumps the internal memory layout of a JSCell.
1600 // Usage: $vm.dumpCell(cell)
1601 static EncodedJSValue JSC_HOST_CALL functionDumpCell(ExecState* exec)
1602 {
1603     JSValue value = exec->argument(0);
1604     if (!value.isCell())
1605         return encodedJSUndefined();
1606     
1607     VMInspector::dumpCellMemory(value.asCell());
1608     return encodedJSUndefined();
1609 }
1610
1611 // Gets the dataLog dump of the indexingMode of the passed value.
1612 // Usage: $vm.print("indexingMode = " + $vm.indexingMode(jsValue))
1613 static EncodedJSValue JSC_HOST_CALL functionIndexingMode(ExecState* exec)
1614 {
1615     if (!exec->argument(0).isObject())
1616         return encodedJSUndefined();
1617
1618     WTF::StringPrintStream stream;
1619     stream.print(IndexingTypeDump(exec->uncheckedArgument(0).getObject()->indexingMode()));
1620     return JSValue::encode(jsString(exec, stream.toString()));
1621 }
1622
1623 static EncodedJSValue JSC_HOST_CALL functionInlineCapacity(ExecState* exec)
1624 {
1625     VM& vm = exec->vm();
1626     if (auto* object = jsDynamicCast<JSObject*>(vm, exec->argument(0)))
1627         return JSValue::encode(jsNumber(object->structure(vm)->inlineCapacity()));
1628
1629     return encodedJSUndefined();
1630 }
1631
1632 // Gets the dataLog dump of a given JS value as a string.
1633 // Usage: $vm.print("value = " + $vm.value(jsValue))
1634 static EncodedJSValue JSC_HOST_CALL functionValue(ExecState* exec)
1635 {
1636     WTF::StringPrintStream stream;
1637     for (unsigned i = 0; i < exec->argumentCount(); ++i) {
1638         if (i)
1639             stream.print(", ");
1640         stream.print(exec->uncheckedArgument(i));
1641     }
1642     
1643     return JSValue::encode(jsString(exec, stream.toString()));
1644 }
1645
1646 // Gets the pid of the current process.
1647 // Usage: $vm.print("pid = " + $vm.getpid())
1648 static EncodedJSValue JSC_HOST_CALL functionGetPID(ExecState*)
1649 {
1650     return JSValue::encode(jsNumber(getCurrentProcessID()));
1651 }
1652
1653 // Make the globalObject have a bad time. Does nothing if the object is not a JSGlobalObject.
1654 // Usage: $vm.haveABadTime(globalObject)
1655 static EncodedJSValue JSC_HOST_CALL functionHaveABadTime(ExecState* exec)
1656 {
1657     VM& vm = exec->vm();
1658     JSLockHolder lock(vm);
1659     JSValue objValue = exec->argument(0);
1660     if (!objValue.isObject())
1661         return JSValue::encode(jsBoolean(false));
1662
1663     JSObject* obj = asObject(objValue.asCell());
1664     JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(vm, obj);
1665     if (!globalObject)
1666         JSValue::encode(jsBoolean(false));
1667
1668     globalObject->haveABadTime(vm);
1669     return JSValue::encode(jsBoolean(true));
1670 }
1671
1672 // Checks if the object (or its global if the object is not a global) is having a bad time.
1673 // Usage: $vm.isHavingABadTime(obj)
1674 static EncodedJSValue JSC_HOST_CALL functionIsHavingABadTime(ExecState* exec)
1675 {
1676     VM& vm = exec->vm();
1677     JSLockHolder lock(vm);
1678     JSValue objValue = exec->argument(0);
1679     if (!objValue.isObject())
1680         return JSValue::encode(jsUndefined());
1681
1682     JSObject* obj = asObject(objValue.asCell());
1683     JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(vm, obj);
1684     if (globalObject)
1685         JSValue::encode(jsBoolean(globalObject->isHavingABadTime()));
1686
1687     globalObject = obj->globalObject();
1688     if (!globalObject)
1689         return JSValue::encode(jsUndefined());
1690
1691     return JSValue::encode(jsBoolean(globalObject->isHavingABadTime()));
1692 }
1693
1694 // Creates a new global object.
1695 // Usage: $vm.createGlobalObject()
1696 static EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(ExecState* exec)
1697 {
1698     VM& vm = exec->vm();
1699     JSLockHolder lock(vm);
1700     JSGlobalObject* globalObject = JSGlobalObject::create(vm, JSGlobalObject::createStructure(vm, jsNull()));
1701     return JSValue::encode(globalObject);
1702 }
1703
1704 static EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState* exec)
1705 {
1706     VM& vm = exec->vm();
1707     JSLockHolder lock(vm);
1708     JSValue target = exec->argument(0);
1709     if (!target.isObject())
1710         return JSValue::encode(jsUndefined());
1711     JSObject* jsTarget = asObject(target.asCell());
1712     Structure* structure = JSProxy::createStructure(vm, exec->lexicalGlobalObject(), jsTarget->getPrototypeDirect(vm), ImpureProxyType);
1713     JSProxy* proxy = JSProxy::create(vm, structure, jsTarget);
1714     return JSValue::encode(proxy);
1715 }
1716
1717 static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState* exec)
1718 {
1719     JSLockHolder lock(exec);
1720     RuntimeArray* array = RuntimeArray::create(exec);
1721     return JSValue::encode(array);
1722 }
1723
1724 static EncodedJSValue JSC_HOST_CALL functionCreateNullRopeString(ExecState* exec)
1725 {
1726     VM& vm = exec->vm();
1727     JSLockHolder lock(vm);
1728     return JSValue::encode(JSRopeString::createNullForTesting(vm));
1729 }
1730
1731 static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState* exec)
1732 {
1733     VM& vm = exec->vm();
1734     JSLockHolder lock(vm);
1735     JSValue target = exec->argument(0);
1736     JSObject* delegate = nullptr;
1737     if (target.isObject())
1738         delegate = asObject(target.asCell());
1739     Structure* structure = ImpureGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1740     ImpureGetter* result = ImpureGetter::create(vm, structure, delegate);
1741     return JSValue::encode(result);
1742 }
1743
1744 static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState* exec)
1745 {
1746     VM& vm = exec->vm();
1747     JSLockHolder lock(vm);
1748     Structure* structure = CustomGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1749     CustomGetter* result = CustomGetter::create(vm, structure);
1750     return JSValue::encode(result);
1751 }
1752
1753 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(ExecState* exec)
1754 {
1755     VM& vm = exec->vm();
1756     JSLockHolder lock(vm);
1757     Structure* structure = DOMJITNode::createStructure(vm, exec->lexicalGlobalObject(), DOMJITGetter::create(vm, DOMJITGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull())));
1758     DOMJITNode* result = DOMJITNode::create(vm, structure);
1759     return JSValue::encode(result);
1760 }
1761
1762 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(ExecState* exec)
1763 {
1764     VM& vm = exec->vm();
1765     JSLockHolder lock(vm);
1766     Structure* structure = DOMJITGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1767     DOMJITGetter* result = DOMJITGetter::create(vm, structure);
1768     return JSValue::encode(result);
1769 }
1770
1771 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(ExecState* exec)
1772 {
1773     VM& vm = exec->vm();
1774     JSLockHolder lock(vm);
1775     Structure* structure = DOMJITGetterComplex::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1776     DOMJITGetterComplex* result = DOMJITGetterComplex::create(vm, exec->lexicalGlobalObject(), structure);
1777     return JSValue::encode(result);
1778 }
1779
1780 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITFunctionObject(ExecState* exec)
1781 {
1782     VM& vm = exec->vm();
1783     JSLockHolder lock(vm);
1784     Structure* structure = DOMJITFunctionObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1785     DOMJITFunctionObject* result = DOMJITFunctionObject::create(vm, exec->lexicalGlobalObject(), structure);
1786     return JSValue::encode(result);
1787 }
1788
1789 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITCheckSubClassObject(ExecState* exec)
1790 {
1791     VM& vm = exec->vm();
1792     JSLockHolder lock(vm);
1793     Structure* structure = DOMJITCheckSubClassObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1794     DOMJITCheckSubClassObject* result = DOMJITCheckSubClassObject::create(vm, exec->lexicalGlobalObject(), structure);
1795     return JSValue::encode(result);
1796 }
1797
1798 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterBaseJSObject(ExecState* exec)
1799 {
1800     VM& vm = exec->vm();
1801     JSLockHolder lock(vm);
1802     Structure* structure = DOMJITGetterBaseJSObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1803     DOMJITGetterBaseJSObject* result = DOMJITGetterBaseJSObject::create(vm, structure);
1804     return JSValue::encode(result);
1805 }
1806
1807 #if ENABLE(WEBASSEMBLY)
1808 static EncodedJSValue JSC_HOST_CALL functionCreateWasmStreamingParser(ExecState* exec)
1809 {
1810     VM& vm = exec->vm();
1811     JSLockHolder lock(vm);
1812     return JSValue::encode(WasmStreamingParser::create(vm, exec->lexicalGlobalObject()));
1813 }
1814 #endif
1815
1816 static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState* exec)
1817 {
1818     VM& vm = exec->vm();
1819     JSLockHolder lock(vm);
1820     auto scope = DECLARE_THROW_SCOPE(vm);
1821
1822     JSValue base = exec->argument(0);
1823     if (!base.isObject())
1824         return JSValue::encode(jsUndefined());
1825     JSValue delegate = exec->argument(1);
1826     if (!delegate.isObject())
1827         return JSValue::encode(jsUndefined());
1828     ImpureGetter* impureGetter = jsDynamicCast<ImpureGetter*>(vm, asObject(base.asCell()));
1829     if (UNLIKELY(!impureGetter)) {
1830         throwTypeError(exec, scope, "argument is not an ImpureGetter"_s);
1831         return encodedJSValue();
1832     }
1833     impureGetter->setDelegate(vm, asObject(delegate.asCell()));
1834     return JSValue::encode(jsUndefined());
1835 }
1836
1837 static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState* exec)
1838 {
1839     VM& vm = exec->vm();
1840     auto scope = DECLARE_THROW_SCOPE(vm);
1841
1842     if (exec->argumentCount() < 1 || !exec->argument(0).isString())
1843         return JSValue::encode(jsUndefined());
1844
1845     String functionText = asString(exec->argument(0))->value(exec);
1846     RETURN_IF_EXCEPTION(scope, encodedJSValue());
1847
1848     const SourceCode& source = makeSource(functionText, { });
1849     JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, source), exec->lexicalGlobalObject());
1850
1851     return JSValue::encode(func);
1852 }
1853
1854 static EncodedJSValue JSC_HOST_CALL functionGetPrivateProperty(ExecState* exec)
1855 {
1856     VM& vm = exec->vm();
1857     auto scope = DECLARE_THROW_SCOPE(vm);
1858
1859     if (exec->argumentCount() < 2 || !exec->argument(1).isString())
1860         return encodedJSUndefined();
1861
1862     String str = asString(exec->argument(1))->value(exec);
1863
1864     SymbolImpl* symbol = vm.propertyNames->lookUpPrivateName(Identifier::fromString(exec, str));
1865     if (!symbol)
1866         return throwVMError(exec, scope, "Unknown private name.");
1867
1868     RELEASE_AND_RETURN(scope, JSValue::encode(exec->argument(0).get(exec, symbol)));
1869 }
1870
1871 static EncodedJSValue JSC_HOST_CALL functionCreateRoot(ExecState* exec)
1872 {
1873     VM& vm = exec->vm();
1874     JSLockHolder lock(vm);
1875     return JSValue::encode(Root::create(vm, exec->lexicalGlobalObject()));
1876 }
1877
1878 static EncodedJSValue JSC_HOST_CALL functionCreateElement(ExecState* exec)
1879 {
1880     VM& vm = exec->vm();
1881     JSLockHolder lock(vm);
1882     auto scope = DECLARE_THROW_SCOPE(vm);
1883
1884     Root* root = jsDynamicCast<Root*>(vm, exec->argument(0));
1885     if (!root)
1886         return JSValue::encode(throwException(exec, scope, createError(exec, "Cannot create Element without a Root."_s)));
1887     return JSValue::encode(Element::create(vm, exec->lexicalGlobalObject(), root));
1888 }
1889
1890 static EncodedJSValue JSC_HOST_CALL functionGetElement(ExecState* exec)
1891 {
1892     VM& vm = exec->vm();
1893     JSLockHolder lock(vm);
1894     Root* root = jsDynamicCast<Root*>(vm, exec->argument(0));
1895     if (!root)
1896         return JSValue::encode(jsUndefined());
1897     Element* result = root->element();
1898     return JSValue::encode(result ? result : jsUndefined());
1899 }
1900
1901 static EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(ExecState* exec)
1902 {
1903     VM& vm = exec->vm();
1904     JSLockHolder lock(vm);
1905     return JSValue::encode(SimpleObject::create(vm, exec->lexicalGlobalObject()));
1906 }
1907
1908 static EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(ExecState* exec)
1909 {
1910     VM& vm = exec->vm();
1911     JSLockHolder lock(vm);
1912     auto scope = DECLARE_THROW_SCOPE(vm);
1913
1914     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, exec->argument(0));
1915     if (UNLIKELY(!simpleObject)) {
1916         throwTypeError(exec, scope, "Invalid use of getHiddenValue test function"_s);
1917         return encodedJSValue();
1918     }
1919     return JSValue::encode(simpleObject->hiddenValue());
1920 }
1921
1922 static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState* exec)
1923 {
1924     VM& vm = exec->vm();
1925     JSLockHolder lock(vm);
1926     auto scope = DECLARE_THROW_SCOPE(vm);
1927
1928     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, exec->argument(0));
1929     if (UNLIKELY(!simpleObject)) {
1930         throwTypeError(exec, scope, "Invalid use of setHiddenValue test function"_s);
1931         return encodedJSValue();
1932     }
1933     JSValue value = exec->argument(1);
1934     simpleObject->setHiddenValue(vm, value);
1935     return JSValue::encode(jsUndefined());
1936 }
1937
1938 static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState* exec)
1939 {
1940     VM& vm = exec->vm();
1941     auto scope = DECLARE_THROW_SCOPE(vm);
1942     if (auto* shadowChicken = vm.shadowChicken()) {
1943         scope.release();
1944         return JSValue::encode(shadowChicken->functionsOnStack(exec));
1945     }
1946
1947     JSArray* result = constructEmptyArray(exec, 0);
1948     RETURN_IF_EXCEPTION(scope, { });
1949     StackVisitor::visit(exec, &vm, [&] (StackVisitor& visitor) -> StackVisitor::Status {
1950         if (visitor->isInlinedFrame())
1951             return StackVisitor::Continue;
1952         if (visitor->isWasmFrame())
1953             return StackVisitor::Continue;
1954         result->push(exec, jsCast<JSObject*>(visitor->callee().asCell()));
1955         scope.releaseAssertNoException(); // This function is only called from tests.
1956         return StackVisitor::Continue;
1957     });
1958     RETURN_IF_EXCEPTION(scope, { });
1959     return JSValue::encode(result);
1960 }
1961
1962 static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState* exec)
1963 {
1964     VM& vm = exec->vm();
1965     vm.setGlobalConstRedeclarationShouldThrow(false);
1966     return JSValue::encode(jsUndefined());
1967 }
1968
1969 static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState* exec)
1970 {
1971     VM& vm = exec->vm();
1972     RELEASE_ASSERT(vm.typeProfiler());
1973     vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionFindTypeForExpression"_s);
1974
1975     JSValue functionValue = exec->argument(0);
1976     RELEASE_ASSERT(functionValue.isFunction(vm));
1977     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
1978
1979     RELEASE_ASSERT(exec->argument(1).isString());
1980     String substring = asString(exec->argument(1))->value(exec);
1981     String sourceCodeText = executable->source().view().toString();
1982     unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
1983     
1984     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), vm);
1985     return JSValue::encode(JSONParse(exec, jsonString));
1986 }
1987
1988 static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState* exec)
1989 {
1990     VM& vm = exec->vm();
1991     RELEASE_ASSERT(vm.typeProfiler());
1992     vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionReturnTypeFor"_s);
1993
1994     JSValue functionValue = exec->argument(0);
1995     RELEASE_ASSERT(functionValue.isFunction(vm));
1996     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
1997
1998     unsigned offset = executable->typeProfilingStartOffset(vm);
1999     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), vm);
2000     return JSValue::encode(JSONParse(exec, jsonString));
2001 }
2002
2003 static EncodedJSValue JSC_HOST_CALL functionFlattenDictionaryObject(ExecState* exec)
2004 {
2005     VM& vm = exec->vm();
2006     JSValue value = exec->argument(0);
2007     RELEASE_ASSERT(value.isObject() && value.getObject()->structure()->isDictionary());
2008     value.getObject()->flattenDictionaryObject(vm);
2009     return encodedJSUndefined();
2010 }
2011
2012 static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState* exec)
2013 {
2014     VM& vm = exec->vm();
2015     RELEASE_ASSERT(vm.controlFlowProfiler());
2016     vm.controlFlowProfiler()->dumpData();
2017     return JSValue::encode(jsUndefined());
2018 }
2019
2020 static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState* exec)
2021 {
2022     VM& vm = exec->vm();
2023     RELEASE_ASSERT(vm.controlFlowProfiler());
2024
2025     JSValue functionValue = exec->argument(0);
2026     RELEASE_ASSERT(functionValue.isFunction(vm));
2027     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2028
2029     RELEASE_ASSERT(exec->argument(1).isString());
2030     String substring = asString(exec->argument(1))->value(exec);
2031     String sourceCodeText = executable->source().view().toString();
2032     RELEASE_ASSERT(sourceCodeText.contains(substring));
2033     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2034     
2035     bool hasExecuted = vm.controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset, executable->sourceID(), vm);
2036     return JSValue::encode(jsBoolean(hasExecuted));
2037 }
2038
2039 static EncodedJSValue JSC_HOST_CALL functionBasicBlockExecutionCount(ExecState* exec)
2040 {
2041     VM& vm = exec->vm();
2042     RELEASE_ASSERT(vm.controlFlowProfiler());
2043
2044     JSValue functionValue = exec->argument(0);
2045     RELEASE_ASSERT(functionValue.isFunction(vm));
2046     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2047
2048     RELEASE_ASSERT(exec->argument(1).isString());
2049     String substring = asString(exec->argument(1))->value(exec);
2050     String sourceCodeText = executable->source().view().toString();
2051     RELEASE_ASSERT(sourceCodeText.contains(substring));
2052     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2053     
2054     size_t executionCount = vm.controlFlowProfiler()->basicBlockExecutionCountAtTextOffset(offset, executable->sourceID(), vm);
2055     return JSValue::encode(JSValue(executionCount));
2056 }
2057
2058 static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*)
2059 {
2060     Options::useExceptionFuzz() = true;
2061     return JSValue::encode(jsUndefined());
2062 }
2063
2064 static EncodedJSValue changeDebuggerModeWhenIdle(ExecState* exec, DebuggerMode mode)
2065 {
2066     bool newDebuggerMode = (mode == DebuggerOn);
2067     if (Options::forceDebuggerBytecodeGeneration() == newDebuggerMode)
2068         return JSValue::encode(jsUndefined());
2069
2070     VM* vm = &exec->vm();
2071     vm->whenIdle([=] () {
2072         Options::forceDebuggerBytecodeGeneration() = newDebuggerMode;
2073         vm->deleteAllCode(PreventCollectionAndDeleteAllCode);
2074         if (mode == DebuggerMode::DebuggerOn)
2075             vm->ensureShadowChicken();
2076     });
2077     return JSValue::encode(jsUndefined());
2078 }
2079
2080 static EncodedJSValue JSC_HOST_CALL functionEnableDebuggerModeWhenIdle(ExecState* exec)
2081 {
2082     return changeDebuggerModeWhenIdle(exec, DebuggerOn);
2083 }
2084
2085 static EncodedJSValue JSC_HOST_CALL functionDisableDebuggerModeWhenIdle(ExecState* exec)
2086 {
2087     return changeDebuggerModeWhenIdle(exec, DebuggerOff);
2088 }
2089
2090 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectCount(ExecState* exec)
2091 {
2092     return JSValue::encode(jsNumber(exec->vm().heap.globalObjectCount()));
2093 }
2094
2095 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(ExecState* exec)
2096 {
2097     JSValue value = exec->argument(0);
2098     RELEASE_ASSERT(value.isObject());
2099     JSGlobalObject* globalObject = jsCast<JSObject*>(value)->globalObject(exec->vm());
2100     RELEASE_ASSERT(globalObject);
2101     return JSValue::encode(globalObject);
2102 }
2103
2104 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState* exec)
2105 {
2106     VM& vm = exec->vm();
2107     auto scope = DECLARE_THROW_SCOPE(vm);
2108
2109     JSValue value = exec->argument(0);
2110     if (!value.isObject())
2111         return JSValue::encode(jsUndefined());
2112
2113     JSValue property = exec->argument(1);
2114     if (!property.isString())
2115         return JSValue::encode(jsUndefined());
2116
2117     auto propertyName = asString(property)->toIdentifier(exec);
2118     RETURN_IF_EXCEPTION(scope, { });
2119
2120     PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry);
2121     value.getPropertySlot(exec, propertyName, slot);
2122     RETURN_IF_EXCEPTION(scope, { });
2123
2124     JSValue result;
2125     if (slot.isCacheableGetter())
2126         result = slot.getterSetter();
2127     else
2128         result = jsNull();
2129
2130     return JSValue::encode(result);
2131 }
2132
2133 static EncodedJSValue JSC_HOST_CALL functionLoadGetterFromGetterSetter(ExecState* exec)
2134 {
2135     VM& vm = exec->vm();
2136     auto scope = DECLARE_THROW_SCOPE(vm);
2137
2138     GetterSetter* getterSetter = jsDynamicCast<GetterSetter*>(vm, exec->argument(0));
2139     if (UNLIKELY(!getterSetter)) {
2140         throwTypeError(exec, scope, "Invalid use of loadGetterFromGetterSetter test function: argument is not a GetterSetter"_s);
2141         return encodedJSValue();
2142     }
2143
2144     JSObject* getter = getterSetter->getter();
2145     RELEASE_ASSERT(getter);
2146     return JSValue::encode(getter);
2147 }
2148
2149 static EncodedJSValue JSC_HOST_CALL functionCreateCustomTestGetterSetter(ExecState* exec)
2150 {
2151     VM& vm = exec->vm();
2152     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
2153     return JSValue::encode(JSTestCustomGetterSetter::create(vm, globalObject, JSTestCustomGetterSetter::createStructure(vm, globalObject)));
2154 }
2155
2156 static EncodedJSValue JSC_HOST_CALL functionDeltaBetweenButterflies(ExecState* exec)
2157 {
2158     VM& vm = exec->vm();
2159     JSObject* a = jsDynamicCast<JSObject*>(vm, exec->argument(0));
2160     JSObject* b = jsDynamicCast<JSObject*>(vm, exec->argument(1));
2161     if (!a || !b)
2162         return JSValue::encode(jsNumber(PNaN));
2163
2164     ptrdiff_t delta = bitwise_cast<char*>(a->butterfly()) - bitwise_cast<char*>(b->butterfly());
2165     if (delta < 0)
2166         return JSValue::encode(jsNumber(PNaN));
2167     if (delta > std::numeric_limits<int32_t>::max())
2168         return JSValue::encode(jsNumber(PNaN));
2169     return JSValue::encode(jsNumber(static_cast<int32_t>(delta)));
2170 }
2171
2172 static EncodedJSValue JSC_HOST_CALL functionTotalGCTime(ExecState* exec)
2173 {
2174     VM& vm = exec->vm();
2175     return JSValue::encode(jsNumber(vm.heap.totalGCTime().seconds()));
2176 }
2177
2178 void JSDollarVM::finishCreation(VM& vm)
2179 {
2180     Base::finishCreation(vm);
2181
2182     JSGlobalObject* globalObject = this->globalObject(vm);
2183
2184     auto addFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
2185         JSDollarVM::addFunction(vm, globalObject, name, function, arguments);
2186     };
2187     auto addConstructibleFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
2188         JSDollarVM::addConstructibleFunction(vm, globalObject, name, function, arguments);
2189     };
2190
2191     addFunction(vm, "abort", functionCrash, 0);
2192     addFunction(vm, "crash", functionCrash, 0);
2193     addFunction(vm, "breakpoint", functionBreakpoint, 0);
2194
2195     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "dfgTrue"), 0, functionDFGTrue, DFGTrueIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
2196     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "ftlTrue"), 0, functionFTLTrue, FTLTrueIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
2197
2198     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuMfence"), 0, functionCpuMfence, CPUMfenceIntrinsic, 0);
2199     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuRdtsc"), 0, functionCpuRdtsc, CPURdtscIntrinsic, 0);
2200     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuCpuid"), 0, functionCpuCpuid, CPUCpuidIntrinsic, 0);
2201     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuPause"), 0, functionCpuPause, CPUPauseIntrinsic, 0);
2202     addFunction(vm, "cpuClflush", functionCpuClflush, 2);
2203
2204     addFunction(vm, "llintTrue", functionLLintTrue, 0);
2205     addFunction(vm, "jitTrue", functionJITTrue, 0);
2206
2207     addFunction(vm, "noInline", functionNoInline, 1);
2208
2209     addFunction(vm, "gc", functionGC, 0);
2210     addFunction(vm, "edenGC", functionEdenGC, 0);
2211
2212     addFunction(vm, "callFrame", functionCallFrame, 1);
2213     addFunction(vm, "codeBlockFor", functionCodeBlockFor, 1);
2214     addFunction(vm, "codeBlockForFrame", functionCodeBlockForFrame, 1);
2215     addFunction(vm, "dumpSourceFor", functionDumpSourceFor, 1);
2216     addFunction(vm, "dumpBytecodeFor", functionDumpBytecodeFor, 1);
2217
2218     addFunction(vm, "dataLog", functionDataLog, 1);
2219     addFunction(vm, "print", functionPrint, 1);
2220     addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
2221     addFunction(vm, "dumpStack", functionDumpStack, 0);
2222     addFunction(vm, "dumpRegisters", functionDumpRegisters, 1);
2223
2224     addFunction(vm, "dumpCell", functionDumpCell, 1);
2225
2226     addFunction(vm, "indexingMode", functionIndexingMode, 1);
2227     addFunction(vm, "inlineCapacity", functionInlineCapacity, 1);
2228     addFunction(vm, "value", functionValue, 1);
2229     addFunction(vm, "getpid", functionGetPID, 0);
2230
2231     addFunction(vm, "haveABadTime", functionHaveABadTime, 1);
2232     addFunction(vm, "isHavingABadTime", functionIsHavingABadTime, 1);
2233
2234     addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0);
2235     addFunction(vm, "createProxy", functionCreateProxy, 1);
2236     addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);
2237     addFunction(vm, "createNullRopeString", functionCreateNullRopeString, 0);
2238
2239     addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
2240     addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0);
2241     addFunction(vm, "createDOMJITNodeObject", functionCreateDOMJITNodeObject, 0);
2242     addFunction(vm, "createDOMJITGetterObject", functionCreateDOMJITGetterObject, 0);
2243     addFunction(vm, "createDOMJITGetterComplexObject", functionCreateDOMJITGetterComplexObject, 0);
2244     addFunction(vm, "createDOMJITFunctionObject", functionCreateDOMJITFunctionObject, 0);
2245     addFunction(vm, "createDOMJITCheckSubClassObject", functionCreateDOMJITCheckSubClassObject, 0);
2246     addFunction(vm, "createDOMJITGetterBaseJSObject", functionCreateDOMJITGetterBaseJSObject, 0);
2247     addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);
2248 #if ENABLE(WEBASSEMBLY)
2249     addFunction(vm, "createWasmStreamingParser", functionCreateWasmStreamingParser, 0);
2250 #endif
2251     addFunction(vm, "getPrivateProperty", functionGetPrivateProperty, 2);
2252     addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
2253
2254     addConstructibleFunction(vm, "Root", functionCreateRoot, 0);
2255     addConstructibleFunction(vm, "Element", functionCreateElement, 1);
2256     addFunction(vm, "getElement", functionGetElement, 1);
2257
2258     addConstructibleFunction(vm, "SimpleObject", functionCreateSimpleObject, 0);
2259     addFunction(vm, "getHiddenValue", functionGetHiddenValue, 1);
2260     addFunction(vm, "setHiddenValue", functionSetHiddenValue, 2);
2261
2262     addFunction(vm, "shadowChickenFunctionsOnStack", functionShadowChickenFunctionsOnStack, 0);
2263     addFunction(vm, "setGlobalConstRedeclarationShouldNotThrow", functionSetGlobalConstRedeclarationShouldNotThrow, 0);
2264
2265     addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);
2266     addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);
2267
2268     addFunction(vm, "flattenDictionaryObject", functionFlattenDictionaryObject, 1);
2269
2270     addFunction(vm, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges , 0);
2271     addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
2272     addFunction(vm, "basicBlockExecutionCount", functionBasicBlockExecutionCount, 2);
2273
2274     addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);
2275
2276     addFunction(vm, "enableDebuggerModeWhenIdle", functionEnableDebuggerModeWhenIdle, 0);
2277     addFunction(vm, "disableDebuggerModeWhenIdle", functionDisableDebuggerModeWhenIdle, 0);
2278
2279     addFunction(vm, "globalObjectCount", functionGlobalObjectCount, 0);
2280     addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);
2281
2282     addFunction(vm, "getGetterSetter", functionGetGetterSetter, 2);
2283     addFunction(vm, "loadGetterFromGetterSetter", functionLoadGetterFromGetterSetter, 1);
2284     addFunction(vm, "createCustomTestGetterSetter", functionCreateCustomTestGetterSetter, 1);
2285
2286     addFunction(vm, "deltaBetweenButterflies", functionDeltaBetweenButterflies, 2);
2287     
2288     addFunction(vm, "totalGCTime", functionTotalGCTime, 0);
2289 }
2290
2291 void JSDollarVM::addFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
2292 {
2293     Identifier identifier = Identifier::fromString(&vm, name);
2294     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function));
2295 }
2296
2297 void JSDollarVM::addConstructibleFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
2298 {
2299     Identifier identifier = Identifier::fromString(&vm, name);
2300     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function, NoIntrinsic, function));
2301 }
2302
2303 } // namespace JSC