Fix warnings on ARM and MIPS
[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(JITCode::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     JITCode::JITType jitType() { return m_jitType; }
1317
1318 private:
1319     mutable unsigned m_currentFrame;
1320     mutable JITCode::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() == JITCode::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() == JITCode::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 functionCreateImpureGetter(ExecState* exec)
1725 {
1726     VM& vm = exec->vm();
1727     JSLockHolder lock(vm);
1728     JSValue target = exec->argument(0);
1729     JSObject* delegate = nullptr;
1730     if (target.isObject())
1731         delegate = asObject(target.asCell());
1732     Structure* structure = ImpureGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1733     ImpureGetter* result = ImpureGetter::create(vm, structure, delegate);
1734     return JSValue::encode(result);
1735 }
1736
1737 static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState* exec)
1738 {
1739     VM& vm = exec->vm();
1740     JSLockHolder lock(vm);
1741     Structure* structure = CustomGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1742     CustomGetter* result = CustomGetter::create(vm, structure);
1743     return JSValue::encode(result);
1744 }
1745
1746 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(ExecState* exec)
1747 {
1748     VM& vm = exec->vm();
1749     JSLockHolder lock(vm);
1750     Structure* structure = DOMJITNode::createStructure(vm, exec->lexicalGlobalObject(), DOMJITGetter::create(vm, DOMJITGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull())));
1751     DOMJITNode* result = DOMJITNode::create(vm, structure);
1752     return JSValue::encode(result);
1753 }
1754
1755 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(ExecState* exec)
1756 {
1757     VM& vm = exec->vm();
1758     JSLockHolder lock(vm);
1759     Structure* structure = DOMJITGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1760     DOMJITGetter* result = DOMJITGetter::create(vm, structure);
1761     return JSValue::encode(result);
1762 }
1763
1764 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(ExecState* exec)
1765 {
1766     VM& vm = exec->vm();
1767     JSLockHolder lock(vm);
1768     Structure* structure = DOMJITGetterComplex::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1769     DOMJITGetterComplex* result = DOMJITGetterComplex::create(vm, exec->lexicalGlobalObject(), structure);
1770     return JSValue::encode(result);
1771 }
1772
1773 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITFunctionObject(ExecState* exec)
1774 {
1775     VM& vm = exec->vm();
1776     JSLockHolder lock(vm);
1777     Structure* structure = DOMJITFunctionObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1778     DOMJITFunctionObject* result = DOMJITFunctionObject::create(vm, exec->lexicalGlobalObject(), structure);
1779     return JSValue::encode(result);
1780 }
1781
1782 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITCheckSubClassObject(ExecState* exec)
1783 {
1784     VM& vm = exec->vm();
1785     JSLockHolder lock(vm);
1786     Structure* structure = DOMJITCheckSubClassObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1787     DOMJITCheckSubClassObject* result = DOMJITCheckSubClassObject::create(vm, exec->lexicalGlobalObject(), structure);
1788     return JSValue::encode(result);
1789 }
1790
1791 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterBaseJSObject(ExecState* exec)
1792 {
1793     VM& vm = exec->vm();
1794     JSLockHolder lock(vm);
1795     Structure* structure = DOMJITGetterBaseJSObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
1796     DOMJITGetterBaseJSObject* result = DOMJITGetterBaseJSObject::create(vm, structure);
1797     return JSValue::encode(result);
1798 }
1799
1800 #if ENABLE(WEBASSEMBLY)
1801 static EncodedJSValue JSC_HOST_CALL functionCreateWasmStreamingParser(ExecState* exec)
1802 {
1803     VM& vm = exec->vm();
1804     JSLockHolder lock(vm);
1805     return JSValue::encode(WasmStreamingParser::create(vm, exec->lexicalGlobalObject()));
1806 }
1807 #endif
1808
1809 static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState* exec)
1810 {
1811     VM& vm = exec->vm();
1812     JSLockHolder lock(vm);
1813     auto scope = DECLARE_THROW_SCOPE(vm);
1814
1815     JSValue base = exec->argument(0);
1816     if (!base.isObject())
1817         return JSValue::encode(jsUndefined());
1818     JSValue delegate = exec->argument(1);
1819     if (!delegate.isObject())
1820         return JSValue::encode(jsUndefined());
1821     ImpureGetter* impureGetter = jsDynamicCast<ImpureGetter*>(vm, asObject(base.asCell()));
1822     if (UNLIKELY(!impureGetter)) {
1823         throwTypeError(exec, scope, "argument is not an ImpureGetter"_s);
1824         return encodedJSValue();
1825     }
1826     impureGetter->setDelegate(vm, asObject(delegate.asCell()));
1827     return JSValue::encode(jsUndefined());
1828 }
1829
1830 static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState* exec)
1831 {
1832     VM& vm = exec->vm();
1833     auto scope = DECLARE_THROW_SCOPE(vm);
1834
1835     if (exec->argumentCount() < 1 || !exec->argument(0).isString())
1836         return JSValue::encode(jsUndefined());
1837
1838     String functionText = asString(exec->argument(0))->value(exec);
1839     RETURN_IF_EXCEPTION(scope, encodedJSValue());
1840
1841     const SourceCode& source = makeSource(functionText, { });
1842     JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, source), exec->lexicalGlobalObject());
1843
1844     return JSValue::encode(func);
1845 }
1846
1847 static EncodedJSValue JSC_HOST_CALL functionGetPrivateProperty(ExecState* exec)
1848 {
1849     VM& vm = exec->vm();
1850     auto scope = DECLARE_THROW_SCOPE(vm);
1851
1852     if (exec->argumentCount() < 2 || !exec->argument(1).isString())
1853         return encodedJSUndefined();
1854
1855     String str = asString(exec->argument(1))->value(exec);
1856
1857     SymbolImpl* symbol = vm.propertyNames->lookUpPrivateName(Identifier::fromString(exec, str));
1858     if (!symbol)
1859         return throwVMError(exec, scope, "Unknown private name.");
1860
1861     RELEASE_AND_RETURN(scope, JSValue::encode(exec->argument(0).get(exec, symbol)));
1862 }
1863
1864 static EncodedJSValue JSC_HOST_CALL functionCreateRoot(ExecState* exec)
1865 {
1866     VM& vm = exec->vm();
1867     JSLockHolder lock(vm);
1868     return JSValue::encode(Root::create(vm, exec->lexicalGlobalObject()));
1869 }
1870
1871 static EncodedJSValue JSC_HOST_CALL functionCreateElement(ExecState* exec)
1872 {
1873     VM& vm = exec->vm();
1874     JSLockHolder lock(vm);
1875     auto scope = DECLARE_THROW_SCOPE(vm);
1876
1877     Root* root = jsDynamicCast<Root*>(vm, exec->argument(0));
1878     if (!root)
1879         return JSValue::encode(throwException(exec, scope, createError(exec, "Cannot create Element without a Root."_s)));
1880     return JSValue::encode(Element::create(vm, exec->lexicalGlobalObject(), root));
1881 }
1882
1883 static EncodedJSValue JSC_HOST_CALL functionGetElement(ExecState* exec)
1884 {
1885     VM& vm = exec->vm();
1886     JSLockHolder lock(vm);
1887     Root* root = jsDynamicCast<Root*>(vm, exec->argument(0));
1888     if (!root)
1889         return JSValue::encode(jsUndefined());
1890     Element* result = root->element();
1891     return JSValue::encode(result ? result : jsUndefined());
1892 }
1893
1894 static EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(ExecState* exec)
1895 {
1896     VM& vm = exec->vm();
1897     JSLockHolder lock(vm);
1898     return JSValue::encode(SimpleObject::create(vm, exec->lexicalGlobalObject()));
1899 }
1900
1901 static EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(ExecState* exec)
1902 {
1903     VM& vm = exec->vm();
1904     JSLockHolder lock(vm);
1905     auto scope = DECLARE_THROW_SCOPE(vm);
1906
1907     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, exec->argument(0));
1908     if (UNLIKELY(!simpleObject)) {
1909         throwTypeError(exec, scope, "Invalid use of getHiddenValue test function"_s);
1910         return encodedJSValue();
1911     }
1912     return JSValue::encode(simpleObject->hiddenValue());
1913 }
1914
1915 static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState* exec)
1916 {
1917     VM& vm = exec->vm();
1918     JSLockHolder lock(vm);
1919     auto scope = DECLARE_THROW_SCOPE(vm);
1920
1921     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, exec->argument(0));
1922     if (UNLIKELY(!simpleObject)) {
1923         throwTypeError(exec, scope, "Invalid use of setHiddenValue test function"_s);
1924         return encodedJSValue();
1925     }
1926     JSValue value = exec->argument(1);
1927     simpleObject->setHiddenValue(vm, value);
1928     return JSValue::encode(jsUndefined());
1929 }
1930
1931 static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState* exec)
1932 {
1933     VM& vm = exec->vm();
1934     auto scope = DECLARE_THROW_SCOPE(vm);
1935     if (auto* shadowChicken = vm.shadowChicken()) {
1936         scope.release();
1937         return JSValue::encode(shadowChicken->functionsOnStack(exec));
1938     }
1939
1940     JSArray* result = constructEmptyArray(exec, 0);
1941     RETURN_IF_EXCEPTION(scope, { });
1942     StackVisitor::visit(exec, &vm, [&] (StackVisitor& visitor) -> StackVisitor::Status {
1943         if (visitor->isInlinedFrame())
1944             return StackVisitor::Continue;
1945         if (visitor->isWasmFrame())
1946             return StackVisitor::Continue;
1947         result->push(exec, jsCast<JSObject*>(visitor->callee().asCell()));
1948         scope.releaseAssertNoException(); // This function is only called from tests.
1949         return StackVisitor::Continue;
1950     });
1951     RETURN_IF_EXCEPTION(scope, { });
1952     return JSValue::encode(result);
1953 }
1954
1955 static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState* exec)
1956 {
1957     VM& vm = exec->vm();
1958     vm.setGlobalConstRedeclarationShouldThrow(false);
1959     return JSValue::encode(jsUndefined());
1960 }
1961
1962 static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState* exec)
1963 {
1964     VM& vm = exec->vm();
1965     RELEASE_ASSERT(vm.typeProfiler());
1966     vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionFindTypeForExpression"_s);
1967
1968     JSValue functionValue = exec->argument(0);
1969     RELEASE_ASSERT(functionValue.isFunction(vm));
1970     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
1971
1972     RELEASE_ASSERT(exec->argument(1).isString());
1973     String substring = asString(exec->argument(1))->value(exec);
1974     String sourceCodeText = executable->source().view().toString();
1975     unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
1976     
1977     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), vm);
1978     return JSValue::encode(JSONParse(exec, jsonString));
1979 }
1980
1981 static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState* exec)
1982 {
1983     VM& vm = exec->vm();
1984     RELEASE_ASSERT(vm.typeProfiler());
1985     vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionReturnTypeFor"_s);
1986
1987     JSValue functionValue = exec->argument(0);
1988     RELEASE_ASSERT(functionValue.isFunction(vm));
1989     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
1990
1991     unsigned offset = executable->typeProfilingStartOffset(vm);
1992     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), vm);
1993     return JSValue::encode(JSONParse(exec, jsonString));
1994 }
1995
1996 static EncodedJSValue JSC_HOST_CALL functionFlattenDictionaryObject(ExecState* exec)
1997 {
1998     VM& vm = exec->vm();
1999     JSValue value = exec->argument(0);
2000     RELEASE_ASSERT(value.isObject() && value.getObject()->structure()->isDictionary());
2001     value.getObject()->flattenDictionaryObject(vm);
2002     return encodedJSUndefined();
2003 }
2004
2005 static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState* exec)
2006 {
2007     VM& vm = exec->vm();
2008     RELEASE_ASSERT(vm.controlFlowProfiler());
2009     vm.controlFlowProfiler()->dumpData();
2010     return JSValue::encode(jsUndefined());
2011 }
2012
2013 static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState* exec)
2014 {
2015     VM& vm = exec->vm();
2016     RELEASE_ASSERT(vm.controlFlowProfiler());
2017
2018     JSValue functionValue = exec->argument(0);
2019     RELEASE_ASSERT(functionValue.isFunction(vm));
2020     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2021
2022     RELEASE_ASSERT(exec->argument(1).isString());
2023     String substring = asString(exec->argument(1))->value(exec);
2024     String sourceCodeText = executable->source().view().toString();
2025     RELEASE_ASSERT(sourceCodeText.contains(substring));
2026     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2027     
2028     bool hasExecuted = vm.controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset, executable->sourceID(), vm);
2029     return JSValue::encode(jsBoolean(hasExecuted));
2030 }
2031
2032 static EncodedJSValue JSC_HOST_CALL functionBasicBlockExecutionCount(ExecState* exec)
2033 {
2034     VM& vm = exec->vm();
2035     RELEASE_ASSERT(vm.controlFlowProfiler());
2036
2037     JSValue functionValue = exec->argument(0);
2038     RELEASE_ASSERT(functionValue.isFunction(vm));
2039     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2040
2041     RELEASE_ASSERT(exec->argument(1).isString());
2042     String substring = asString(exec->argument(1))->value(exec);
2043     String sourceCodeText = executable->source().view().toString();
2044     RELEASE_ASSERT(sourceCodeText.contains(substring));
2045     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2046     
2047     size_t executionCount = vm.controlFlowProfiler()->basicBlockExecutionCountAtTextOffset(offset, executable->sourceID(), vm);
2048     return JSValue::encode(JSValue(executionCount));
2049 }
2050
2051 static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*)
2052 {
2053     Options::useExceptionFuzz() = true;
2054     return JSValue::encode(jsUndefined());
2055 }
2056
2057 static EncodedJSValue changeDebuggerModeWhenIdle(ExecState* exec, DebuggerMode mode)
2058 {
2059     bool newDebuggerMode = (mode == DebuggerOn);
2060     if (Options::forceDebuggerBytecodeGeneration() == newDebuggerMode)
2061         return JSValue::encode(jsUndefined());
2062
2063     VM* vm = &exec->vm();
2064     vm->whenIdle([=] () {
2065         Options::forceDebuggerBytecodeGeneration() = newDebuggerMode;
2066         vm->deleteAllCode(PreventCollectionAndDeleteAllCode);
2067         if (mode == DebuggerMode::DebuggerOn)
2068             vm->ensureShadowChicken();
2069     });
2070     return JSValue::encode(jsUndefined());
2071 }
2072
2073 static EncodedJSValue JSC_HOST_CALL functionEnableDebuggerModeWhenIdle(ExecState* exec)
2074 {
2075     return changeDebuggerModeWhenIdle(exec, DebuggerOn);
2076 }
2077
2078 static EncodedJSValue JSC_HOST_CALL functionDisableDebuggerModeWhenIdle(ExecState* exec)
2079 {
2080     return changeDebuggerModeWhenIdle(exec, DebuggerOff);
2081 }
2082
2083 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectCount(ExecState* exec)
2084 {
2085     return JSValue::encode(jsNumber(exec->vm().heap.globalObjectCount()));
2086 }
2087
2088 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(ExecState* exec)
2089 {
2090     JSValue value = exec->argument(0);
2091     RELEASE_ASSERT(value.isObject());
2092     JSGlobalObject* globalObject = jsCast<JSObject*>(value)->globalObject(exec->vm());
2093     RELEASE_ASSERT(globalObject);
2094     return JSValue::encode(globalObject);
2095 }
2096
2097 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState* exec)
2098 {
2099     JSValue value = exec->argument(0);
2100     if (!value.isObject())
2101         return JSValue::encode(jsUndefined());
2102
2103     JSValue property = exec->argument(1);
2104     if (!property.isString())
2105         return JSValue::encode(jsUndefined());
2106
2107     PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry);
2108     value.getPropertySlot(exec, asString(property)->toIdentifier(exec), slot);
2109
2110     JSValue result;
2111     if (slot.isCacheableGetter())
2112         result = slot.getterSetter();
2113     else
2114         result = jsNull();
2115
2116     return JSValue::encode(result);
2117 }
2118
2119 static EncodedJSValue JSC_HOST_CALL functionLoadGetterFromGetterSetter(ExecState* exec)
2120 {
2121     VM& vm = exec->vm();
2122     auto scope = DECLARE_THROW_SCOPE(vm);
2123
2124     GetterSetter* getterSetter = jsDynamicCast<GetterSetter*>(vm, exec->argument(0));
2125     if (UNLIKELY(!getterSetter)) {
2126         throwTypeError(exec, scope, "Invalid use of loadGetterFromGetterSetter test function: argument is not a GetterSetter"_s);
2127         return encodedJSValue();
2128     }
2129
2130     JSObject* getter = getterSetter->getter();
2131     RELEASE_ASSERT(getter);
2132     return JSValue::encode(getter);
2133 }
2134
2135 static EncodedJSValue JSC_HOST_CALL functionCreateCustomTestGetterSetter(ExecState* exec)
2136 {
2137     VM& vm = exec->vm();
2138     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
2139     return JSValue::encode(JSTestCustomGetterSetter::create(vm, globalObject, JSTestCustomGetterSetter::createStructure(vm, globalObject)));
2140 }
2141
2142 static EncodedJSValue JSC_HOST_CALL functionDeltaBetweenButterflies(ExecState* exec)
2143 {
2144     VM& vm = exec->vm();
2145     JSObject* a = jsDynamicCast<JSObject*>(vm, exec->argument(0));
2146     JSObject* b = jsDynamicCast<JSObject*>(vm, exec->argument(1));
2147     if (!a || !b)
2148         return JSValue::encode(jsNumber(PNaN));
2149
2150     ptrdiff_t delta = bitwise_cast<char*>(a->butterfly()) - bitwise_cast<char*>(b->butterfly());
2151     if (delta < 0)
2152         return JSValue::encode(jsNumber(PNaN));
2153     if (delta > std::numeric_limits<int32_t>::max())
2154         return JSValue::encode(jsNumber(PNaN));
2155     return JSValue::encode(jsNumber(static_cast<int32_t>(delta)));
2156 }
2157
2158 static EncodedJSValue JSC_HOST_CALL functionTotalGCTime(ExecState* exec)
2159 {
2160     VM& vm = exec->vm();
2161     return JSValue::encode(jsNumber(vm.heap.totalGCTime().seconds()));
2162 }
2163
2164 void JSDollarVM::finishCreation(VM& vm)
2165 {
2166     Base::finishCreation(vm);
2167
2168     JSGlobalObject* globalObject = this->globalObject(vm);
2169
2170     auto addFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
2171         JSDollarVM::addFunction(vm, globalObject, name, function, arguments);
2172     };
2173     auto addConstructibleFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
2174         JSDollarVM::addConstructibleFunction(vm, globalObject, name, function, arguments);
2175     };
2176
2177     addFunction(vm, "abort", functionCrash, 0);
2178     addFunction(vm, "crash", functionCrash, 0);
2179     addFunction(vm, "breakpoint", functionBreakpoint, 0);
2180
2181     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "dfgTrue"), 0, functionDFGTrue, DFGTrueIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
2182     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "ftlTrue"), 0, functionFTLTrue, FTLTrueIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
2183
2184     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuMfence"), 0, functionCpuMfence, CPUMfenceIntrinsic, 0);
2185     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuRdtsc"), 0, functionCpuRdtsc, CPURdtscIntrinsic, 0);
2186     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuCpuid"), 0, functionCpuCpuid, CPUCpuidIntrinsic, 0);
2187     putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuPause"), 0, functionCpuPause, CPUPauseIntrinsic, 0);
2188     addFunction(vm, "cpuClflush", functionCpuClflush, 2);
2189
2190     addFunction(vm, "llintTrue", functionLLintTrue, 0);
2191     addFunction(vm, "jitTrue", functionJITTrue, 0);
2192
2193     addFunction(vm, "noInline", functionNoInline, 1);
2194
2195     addFunction(vm, "gc", functionGC, 0);
2196     addFunction(vm, "edenGC", functionEdenGC, 0);
2197
2198     addFunction(vm, "callFrame", functionCallFrame, 1);
2199     addFunction(vm, "codeBlockFor", functionCodeBlockFor, 1);
2200     addFunction(vm, "codeBlockForFrame", functionCodeBlockForFrame, 1);
2201     addFunction(vm, "dumpSourceFor", functionDumpSourceFor, 1);
2202     addFunction(vm, "dumpBytecodeFor", functionDumpBytecodeFor, 1);
2203
2204     addFunction(vm, "dataLog", functionDataLog, 1);
2205     addFunction(vm, "print", functionPrint, 1);
2206     addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
2207     addFunction(vm, "dumpStack", functionDumpStack, 0);
2208     addFunction(vm, "dumpRegisters", functionDumpRegisters, 1);
2209
2210     addFunction(vm, "dumpCell", functionDumpCell, 1);
2211
2212     addFunction(vm, "indexingMode", functionIndexingMode, 1);
2213     addFunction(vm, "inlineCapacity", functionInlineCapacity, 1);
2214     addFunction(vm, "value", functionValue, 1);
2215     addFunction(vm, "getpid", functionGetPID, 0);
2216
2217     addFunction(vm, "haveABadTime", functionHaveABadTime, 1);
2218     addFunction(vm, "isHavingABadTime", functionIsHavingABadTime, 1);
2219
2220     addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0);
2221     addFunction(vm, "createProxy", functionCreateProxy, 1);
2222     addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);
2223
2224     addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
2225     addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0);
2226     addFunction(vm, "createDOMJITNodeObject", functionCreateDOMJITNodeObject, 0);
2227     addFunction(vm, "createDOMJITGetterObject", functionCreateDOMJITGetterObject, 0);
2228     addFunction(vm, "createDOMJITGetterComplexObject", functionCreateDOMJITGetterComplexObject, 0);
2229     addFunction(vm, "createDOMJITFunctionObject", functionCreateDOMJITFunctionObject, 0);
2230     addFunction(vm, "createDOMJITCheckSubClassObject", functionCreateDOMJITCheckSubClassObject, 0);
2231     addFunction(vm, "createDOMJITGetterBaseJSObject", functionCreateDOMJITGetterBaseJSObject, 0);
2232     addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);
2233 #if ENABLE(WEBASSEMBLY)
2234     addFunction(vm, "createWasmStreamingParser", functionCreateWasmStreamingParser, 0);
2235 #endif
2236     addFunction(vm, "getPrivateProperty", functionGetPrivateProperty, 2);
2237     addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
2238
2239     addConstructibleFunction(vm, "Root", functionCreateRoot, 0);
2240     addConstructibleFunction(vm, "Element", functionCreateElement, 1);
2241     addFunction(vm, "getElement", functionGetElement, 1);
2242
2243     addConstructibleFunction(vm, "SimpleObject", functionCreateSimpleObject, 0);
2244     addFunction(vm, "getHiddenValue", functionGetHiddenValue, 1);
2245     addFunction(vm, "setHiddenValue", functionSetHiddenValue, 2);
2246
2247     addFunction(vm, "shadowChickenFunctionsOnStack", functionShadowChickenFunctionsOnStack, 0);
2248     addFunction(vm, "setGlobalConstRedeclarationShouldNotThrow", functionSetGlobalConstRedeclarationShouldNotThrow, 0);
2249
2250     addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);
2251     addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);
2252
2253     addFunction(vm, "flattenDictionaryObject", functionFlattenDictionaryObject, 1);
2254
2255     addFunction(vm, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges , 0);
2256     addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
2257     addFunction(vm, "basicBlockExecutionCount", functionBasicBlockExecutionCount, 2);
2258
2259     addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);
2260
2261     addFunction(vm, "enableDebuggerModeWhenIdle", functionEnableDebuggerModeWhenIdle, 0);
2262     addFunction(vm, "disableDebuggerModeWhenIdle", functionDisableDebuggerModeWhenIdle, 0);
2263
2264     addFunction(vm, "globalObjectCount", functionGlobalObjectCount, 0);
2265     addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);
2266
2267     addFunction(vm, "getGetterSetter", functionGetGetterSetter, 2);
2268     addFunction(vm, "loadGetterFromGetterSetter", functionLoadGetterFromGetterSetter, 1);
2269     addFunction(vm, "createCustomTestGetterSetter", functionCreateCustomTestGetterSetter, 1);
2270
2271     addFunction(vm, "deltaBetweenButterflies", functionDeltaBetweenButterflies, 2);
2272     
2273     addFunction(vm, "totalGCTime", functionTotalGCTime, 0);
2274 }
2275
2276 void JSDollarVM::addFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
2277 {
2278     Identifier identifier = Identifier::fromString(&vm, name);
2279     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function));
2280 }
2281
2282 void JSDollarVM::addConstructibleFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
2283 {
2284     Identifier identifier = Identifier::fromString(&vm, name);
2285     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function, NoIntrinsic, function));
2286 }
2287
2288 } // namespace JSC