[JSC] llintTrue / jitTrue can encounter native functions
[WebKit.git] / Source / JavaScriptCore / tools / JSDollarVM.cpp
1 /*
2  * Copyright (C) 2015-2020 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 "ArrayPrototype.h"
30 #include "BuiltinNames.h"
31 #include "CodeBlock.h"
32 #include "DOMAttributeGetterSetter.h"
33 #include "DOMJITGetterSetter.h"
34 #include "Debugger.h"
35 #include "FrameTracers.h"
36 #include "FunctionCodeBlock.h"
37 #include "GetterSetter.h"
38 #include "JSArray.h"
39 #include "JSCInlines.h"
40 #include "JSONObject.h"
41 #include "JSString.h"
42 #include "Options.h"
43 #include "Parser.h"
44 #include "ProbeContext.h"
45 #include "ShadowChicken.h"
46 #include "Snippet.h"
47 #include "SnippetParams.h"
48 #include "TypeProfiler.h"
49 #include "TypeProfilerLog.h"
50 #include "VMInspector.h"
51 #include "WasmCapabilities.h"
52 #include <unicode/uversion.h>
53 #include <wtf/Atomics.h>
54 #include <wtf/CPUTime.h>
55 #include <wtf/DataLog.h>
56 #include <wtf/Language.h>
57 #include <wtf/ProcessID.h>
58 #include <wtf/StringPrintStream.h>
59
60 #if ENABLE(WEBASSEMBLY)
61 #include "JSWebAssemblyHelpers.h"
62 #include "WasmStreamingParser.h"
63 #endif
64
65 using namespace JSC;
66
67 IGNORE_WARNINGS_BEGIN("frame-address")
68
69 extern "C" void ctiMasmProbeTrampoline();
70
71 namespace JSC {
72
73 // This class is only here as a simple way to grant JSDollarVM friend privileges
74 // to all the classes that it needs special access to.
75 class JSDollarVMHelper {
76 public:
77     JSDollarVMHelper(VM& vm)
78         : m_vm(vm)
79     { }
80
81     void updateVMStackLimits() { return m_vm.updateStackLimits(); };
82
83     static EncodedJSValue JSC_HOST_CALL functionGetStructureTransitionList(JSGlobalObject*, CallFrame*);
84
85 private:
86     VM& m_vm;
87 };
88
89 } // namespace JSC
90
91 namespace {
92
93 // We must RELEASE_ASSERT(Options::useDollarVM()) in all JSDollarVM functions
94 // that are non-trivial at an eye's glance. This includes (but is not limited to):
95 //      constructors
96 //      create() factory
97 //      createStructure() factory
98 //      finishCreation()
99 //      HOST_CALL or operation functions
100 //      Constructors and methods of utility and test classes
101 //      lambda functions
102 //
103 // The way to do this RELEASE_ASSERT is with the DollarVMAssertScope below.
104 //
105 // The only exception are some constexpr constructors used for instantiating
106 // globals (since these must have trivial constructors) e.g. DOMJITAttribute.
107 // Instead, these constructors should always be ALWAYS_INLINE.
108
109 class JSDollarVMCallFrame : public JSNonFinalObject {
110     using Base = JSNonFinalObject;
111 public:
112     template<typename CellType, SubspaceAccess>
113     static CompleteSubspace* subspaceFor(VM& vm)
114     {
115         return &vm.cellSpace;
116     }
117
118     JSDollarVMCallFrame(VM& vm, Structure* structure)
119         : Base(vm, structure)
120     {
121         DollarVMAssertScope assertScope;
122     }
123
124     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
125     {
126         DollarVMAssertScope assertScope;
127         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
128     }
129
130     static JSDollarVMCallFrame* create(JSGlobalObject* globalObject, CallFrame* callFrame, unsigned requestedFrameIndex)
131     {
132         DollarVMAssertScope assertScope;
133         VM& vm = globalObject->vm();
134         Structure* structure = createStructure(vm, globalObject, jsNull());
135         JSDollarVMCallFrame* frame = new (NotNull, allocateCell<JSDollarVMCallFrame>(vm.heap)) JSDollarVMCallFrame(vm, structure);
136         frame->finishCreation(vm, callFrame, requestedFrameIndex);
137         return frame;
138     }
139
140     void finishCreation(VM& vm, CallFrame* callFrame, unsigned requestedFrameIndex)
141     {
142         DollarVMAssertScope assertScope;
143         Base::finishCreation(vm);
144
145         auto addProperty = [&] (VM& vm, const char* name, JSValue value) {
146             DollarVMAssertScope assertScope;
147             JSDollarVMCallFrame::addProperty(vm, name, value);
148         };
149
150         unsigned frameIndex = 0;
151         bool isValid = false;
152         callFrame->iterate(vm, [&] (StackVisitor& visitor) {
153             DollarVMAssertScope assertScope;
154
155             if (frameIndex++ != requestedFrameIndex)
156                 return StackVisitor::Continue;
157
158             addProperty(vm, "name", jsString(vm, visitor->functionName()));
159
160             if (visitor->callee().isCell())
161                 addProperty(vm, "callee", visitor->callee().asCell());
162
163             CodeBlock* codeBlock = visitor->codeBlock();
164             if (codeBlock) {
165                 addProperty(vm, "codeBlock", codeBlock);
166                 addProperty(vm, "unlinkedCodeBlock", codeBlock->unlinkedCodeBlock());
167                 addProperty(vm, "executable", codeBlock->ownerExecutable());
168             }
169             isValid = true;
170
171             return StackVisitor::Done;
172         });
173
174         addProperty(vm, "valid", jsBoolean(isValid));
175     }
176
177     DECLARE_INFO;
178
179 private:
180     void addProperty(VM& vm, const char* name, JSValue value)
181     {
182         DollarVMAssertScope assertScope;
183         Identifier identifier = Identifier::fromString(vm, name);
184         putDirect(vm, identifier, value);
185     }
186 };
187
188 const ClassInfo JSDollarVMCallFrame::s_info = { "CallFrame", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDollarVMCallFrame) };
189
190 class ElementHandleOwner;
191 class Root;
192
193 class Element : public JSNonFinalObject {
194 public:
195     Element(VM& vm, Structure* structure)
196         : Base(vm, structure)
197     {
198         DollarVMAssertScope assertScope;
199     }
200
201     typedef JSNonFinalObject Base;
202     template<typename CellType, SubspaceAccess>
203     static CompleteSubspace* subspaceFor(VM& vm)
204     {
205         return &vm.cellSpace;
206     }
207
208     Root* root() const { return m_root.get(); }
209     void setRoot(VM& vm, Root* root) { m_root.set(vm, this, root); }
210
211     static Element* create(VM& vm, JSGlobalObject* globalObject, Root* root)
212     {
213         DollarVMAssertScope assertScope;
214         Structure* structure = createStructure(vm, globalObject, jsNull());
215         Element* element = new (NotNull, allocateCell<Element>(vm.heap)) Element(vm, structure);
216         element->finishCreation(vm, root);
217         return element;
218     }
219
220     void finishCreation(VM&, Root*);
221
222     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
223     {
224         DollarVMAssertScope assertScope;
225         Element* thisObject = jsCast<Element*>(cell);
226         ASSERT_GC_OBJECT_INHERITS(thisObject, info());
227         Base::visitChildren(thisObject, visitor);
228         visitor.append(thisObject->m_root);
229     }
230
231     static ElementHandleOwner* handleOwner();
232
233     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
234     {
235         DollarVMAssertScope assertScope;
236         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
237     }
238
239     DECLARE_INFO;
240
241 private:
242     WriteBarrier<Root> m_root;
243 };
244
245 class ElementHandleOwner final : public WeakHandleOwner {
246     WTF_MAKE_FAST_ALLOCATED;
247 public:
248     bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason) final
249     {
250         DollarVMAssertScope assertScope;
251         if (UNLIKELY(reason))
252             *reason = "JSC::Element is opaque root";
253         Element* element = jsCast<Element*>(handle.slot()->asCell());
254         return visitor.containsOpaqueRoot(element->root());
255     }
256 };
257
258 class Root final : public JSDestructibleObject {
259 public:
260     using Base = JSDestructibleObject;
261     template<typename CellType, SubspaceAccess>
262     static CompleteSubspace* subspaceFor(VM& vm)
263     {
264         return &vm.destructibleObjectSpace;
265     }
266
267     Root(VM& vm, Structure* structure)
268         : Base(vm, structure)
269     {
270         DollarVMAssertScope assertScope;
271     }
272
273     Element* element()
274     {
275         return m_element.get();
276     }
277
278     void setElement(Element* element)
279     {
280         DollarVMAssertScope assertScope;
281         Weak<Element> newElement(element, Element::handleOwner());
282         m_element.swap(newElement);
283     }
284
285     static Root* create(VM& vm, JSGlobalObject* globalObject)
286     {
287         DollarVMAssertScope assertScope;
288         Structure* structure = createStructure(vm, globalObject, jsNull());
289         Root* root = new (NotNull, allocateCell<Root>(vm.heap)) Root(vm, structure);
290         root->finishCreation(vm);
291         return root;
292     }
293
294     DECLARE_INFO;
295
296     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
297     {
298         DollarVMAssertScope assertScope;
299         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
300     }
301
302     static void visitChildren(JSCell* thisObject, SlotVisitor& visitor)
303     {
304         DollarVMAssertScope assertScope;
305         ASSERT_GC_OBJECT_INHERITS(thisObject, info());
306         Base::visitChildren(thisObject, visitor);
307         visitor.addOpaqueRoot(thisObject);
308     }
309
310 private:
311     Weak<Element> m_element;
312 };
313
314 class SimpleObject : public JSNonFinalObject {
315 public:
316     SimpleObject(VM& vm, Structure* structure)
317         : Base(vm, structure)
318     {
319         DollarVMAssertScope assertScope;
320     }
321
322     typedef JSNonFinalObject Base;
323     template<typename CellType, SubspaceAccess>
324     static CompleteSubspace* subspaceFor(VM& vm)
325     {
326         return &vm.cellSpace;
327     }
328
329     static SimpleObject* create(VM& vm, JSGlobalObject* globalObject)
330     {
331         DollarVMAssertScope assertScope;
332         Structure* structure = createStructure(vm, globalObject, jsNull());
333         SimpleObject* simpleObject = new (NotNull, allocateCell<SimpleObject>(vm.heap)) SimpleObject(vm, structure);
334         simpleObject->finishCreation(vm);
335         return simpleObject;
336     }
337
338     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
339     {
340         DollarVMAssertScope assertScope;
341         SimpleObject* thisObject = jsCast<SimpleObject*>(cell);
342         ASSERT_GC_OBJECT_INHERITS(thisObject, info());
343         Base::visitChildren(thisObject, visitor);
344         visitor.append(thisObject->m_hiddenValue);
345     }
346
347     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
348     {
349         DollarVMAssertScope assertScope;
350         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
351     }
352
353     JSValue hiddenValue()
354     {
355         return m_hiddenValue.get();
356     }
357
358     void setHiddenValue(VM& vm, JSValue value)
359     {
360         ASSERT(value.isCell());
361         m_hiddenValue.set(vm, this, value);
362     }
363
364     static CallData getConstructData(JSCell*)
365     {
366         CallData constructData;
367         constructData.type = CallData::Type::Native;
368         constructData.native.function = callHostFunctionAsConstructor;
369         return constructData;
370     }
371
372     DECLARE_INFO;
373
374 private:
375     WriteBarrier<JSC::Unknown> m_hiddenValue;
376 };
377
378 class ImpureGetter : public JSNonFinalObject {
379 public:
380     ImpureGetter(VM& vm, Structure* structure)
381         : Base(vm, structure)
382     {
383         DollarVMAssertScope assertScope;
384     }
385
386     DECLARE_INFO;
387     typedef JSNonFinalObject Base;
388     static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::GetOwnPropertySlotIsImpure | JSC::OverridesGetOwnPropertySlot;
389
390     template<typename CellType, SubspaceAccess>
391     static CompleteSubspace* subspaceFor(VM& vm)
392     {
393         return &vm.cellSpace;
394     }
395
396     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
397     {
398         DollarVMAssertScope assertScope;
399         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
400     }
401
402     static ImpureGetter* create(VM& vm, Structure* structure, JSObject* delegate)
403     {
404         DollarVMAssertScope assertScope;
405         ImpureGetter* getter = new (NotNull, allocateCell<ImpureGetter>(vm.heap)) ImpureGetter(vm, structure);
406         getter->finishCreation(vm, delegate);
407         return getter;
408     }
409
410     void finishCreation(VM& vm, JSObject* delegate)
411     {
412         DollarVMAssertScope assertScope;
413         Base::finishCreation(vm);
414         if (delegate)
415             m_delegate.set(vm, this, delegate);
416     }
417
418     static bool getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName name, PropertySlot& slot)
419     {
420         DollarVMAssertScope assertScope;
421         VM& vm = globalObject->vm();
422         auto scope = DECLARE_THROW_SCOPE(vm);
423         ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);
424         
425         if (thisObject->m_delegate) {
426             if (thisObject->m_delegate->getPropertySlot(globalObject, name, slot))
427                 return true;
428             RETURN_IF_EXCEPTION(scope, false);
429         }
430
431         return Base::getOwnPropertySlot(object, globalObject, name, slot);
432     }
433
434     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
435     {
436         DollarVMAssertScope assertScope;
437         ASSERT_GC_OBJECT_INHERITS(cell, info());
438         Base::visitChildren(cell, visitor);
439         ImpureGetter* thisObject = jsCast<ImpureGetter*>(cell);
440         visitor.append(thisObject->m_delegate);
441     }
442
443     void setDelegate(VM& vm, JSObject* delegate)
444     {
445         m_delegate.set(vm, this, delegate);
446     }
447
448 private:
449     WriteBarrier<JSObject> m_delegate;
450 };
451
452 class CustomGetter : public JSNonFinalObject {
453 public:
454     CustomGetter(VM& vm, Structure* structure)
455         : Base(vm, structure)
456     {
457         DollarVMAssertScope assertScope;
458     }
459
460     DECLARE_INFO;
461     typedef JSNonFinalObject Base;
462     static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;
463
464     template<typename CellType, SubspaceAccess>
465     static CompleteSubspace* subspaceFor(VM& vm)
466     {
467         return &vm.cellSpace;
468     }
469
470     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
471     {
472         DollarVMAssertScope assertScope;
473         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
474     }
475
476     static CustomGetter* create(VM& vm, Structure* structure)
477     {
478         DollarVMAssertScope assertScope;
479         CustomGetter* getter = new (NotNull, allocateCell<CustomGetter>(vm.heap)) CustomGetter(vm, structure);
480         getter->finishCreation(vm);
481         return getter;
482     }
483
484     static bool getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
485     {
486         DollarVMAssertScope assertScope;
487         VM& vm = globalObject->vm();
488         CustomGetter* thisObject = jsCast<CustomGetter*>(object);
489         if (propertyName == PropertyName(Identifier::fromString(vm, "customGetter"))) {
490             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, thisObject->customGetter);
491             return true;
492         }
493         
494         if (propertyName == PropertyName(Identifier::fromString(vm, "customGetterAccessor"))) {
495             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor, thisObject->customGetterAcessor);
496             return true;
497         }
498         
499         return JSObject::getOwnPropertySlot(thisObject, globalObject, propertyName, slot);
500     }
501
502 private:
503     static EncodedJSValue customGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
504     {
505         DollarVMAssertScope assertScope;
506         VM& vm = globalObject->vm();
507         auto scope = DECLARE_THROW_SCOPE(vm);
508
509         CustomGetter* thisObject = jsDynamicCast<CustomGetter*>(vm, JSValue::decode(thisValue));
510         if (!thisObject)
511             return throwVMTypeError(globalObject, scope);
512         bool shouldThrow = thisObject->get(globalObject, PropertyName(Identifier::fromString(vm, "shouldThrow"))).toBoolean(globalObject);
513         RETURN_IF_EXCEPTION(scope, encodedJSValue());
514         if (shouldThrow)
515             return throwVMTypeError(globalObject, scope);
516         return JSValue::encode(jsNumber(100));
517     }
518     
519     static EncodedJSValue customGetterAcessor(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
520     {
521         DollarVMAssertScope assertScope;
522         VM& vm = globalObject->vm();
523         auto scope = DECLARE_THROW_SCOPE(vm);
524         
525         JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
526         if (!thisObject)
527             return throwVMTypeError(globalObject, scope);
528         bool shouldThrow = thisObject->get(globalObject, PropertyName(Identifier::fromString(vm, "shouldThrow"))).toBoolean(globalObject);
529         RETURN_IF_EXCEPTION(scope, encodedJSValue());
530         if (shouldThrow)
531             return throwVMTypeError(globalObject, scope);
532         return JSValue::encode(jsNumber(100));
533     }
534 };
535
536 class RuntimeArray : public JSArray {
537 public:
538     typedef JSArray Base;
539     static constexpr unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesAnyFormOfGetPropertyNames;
540
541 IGNORE_WARNINGS_BEGIN("unused-const-variable")
542     static constexpr bool needsDestruction = false;
543 IGNORE_WARNINGS_END
544
545     template<typename CellType, SubspaceAccess>
546     static CompleteSubspace* subspaceFor(VM& vm)
547     {
548         return &vm.cellSpace;
549     }
550
551     static RuntimeArray* create(JSGlobalObject* globalObject, CallFrame* callFrame)
552     {
553         DollarVMAssertScope assertScope;
554         VM& vm = globalObject->vm();
555         Structure* structure = createStructure(vm, globalObject, createPrototype(vm, globalObject));
556         RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(vm.heap)) RuntimeArray(globalObject, structure);
557         runtimeArray->finishCreation(globalObject, callFrame);
558         vm.heap.addFinalizer(runtimeArray, destroy);
559         return runtimeArray;
560     }
561
562     ~RuntimeArray() { }
563
564     static void destroy(JSCell* cell)
565     {
566         DollarVMAssertScope assertScope;
567         static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();
568     }
569
570     static bool getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
571     {
572         DollarVMAssertScope assertScope;
573         VM& vm = globalObject->vm();
574         RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
575         if (propertyName == vm.propertyNames->length) {
576             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, thisObject->lengthGetter);
577             return true;
578         }
579
580         Optional<uint32_t> index = parseIndex(propertyName);
581         if (index && index.value() < thisObject->getLength()) {
582             slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index.value()]));
583             return true;
584         }
585
586         return JSObject::getOwnPropertySlot(thisObject, globalObject, propertyName, slot);
587     }
588
589     static bool getOwnPropertySlotByIndex(JSObject* object, JSGlobalObject* globalObject, unsigned index, PropertySlot& slot)
590     {
591         DollarVMAssertScope assertScope;
592         RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
593         if (index < thisObject->getLength()) {
594             slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index]));
595             return true;
596         }
597
598         return JSObject::getOwnPropertySlotByIndex(thisObject, globalObject, index, slot);
599     }
600
601     static NO_RETURN_DUE_TO_CRASH bool put(JSCell*, JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&)
602     {
603         RELEASE_ASSERT_NOT_REACHED();
604     }
605
606     static NO_RETURN_DUE_TO_CRASH bool deleteProperty(JSCell*, JSGlobalObject*, PropertyName, DeletePropertySlot&)
607     {
608         RELEASE_ASSERT_NOT_REACHED();
609     }
610
611     unsigned getLength() const { return m_vector.size(); }
612
613     DECLARE_INFO;
614
615     static ArrayPrototype* createPrototype(VM&, JSGlobalObject* globalObject)
616     {
617         DollarVMAssertScope assertScope;
618         return globalObject->arrayPrototype();
619     }
620
621     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
622     {
623         DollarVMAssertScope assertScope;
624         return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass);
625     }
626
627 protected:
628     void finishCreation(JSGlobalObject* globalObject, CallFrame* callFrame)
629     {
630         DollarVMAssertScope assertScope;
631         VM& vm = globalObject->vm();
632         Base::finishCreation(vm);
633         ASSERT(inherits(vm, info()));
634
635         for (size_t i = 0; i < callFrame->argumentCount(); i++)
636             m_vector.append(callFrame->argument(i).toInt32(globalObject));
637     }
638
639 private:
640     RuntimeArray(JSGlobalObject* globalObject, Structure* structure)
641         : JSArray(globalObject->vm(), structure, nullptr)
642     {
643         DollarVMAssertScope assertScope;
644     }
645
646     static EncodedJSValue lengthGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
647     {
648         DollarVMAssertScope assertScope;
649         VM& vm = globalObject->vm();
650         auto scope = DECLARE_THROW_SCOPE(vm);
651
652         RuntimeArray* thisObject = jsDynamicCast<RuntimeArray*>(vm, JSValue::decode(thisValue));
653         if (!thisObject)
654             return throwVMTypeError(globalObject, scope);
655         return JSValue::encode(jsNumber(thisObject->getLength()));
656     }
657
658     Vector<int> m_vector;
659 };
660
661 static const struct CompactHashIndex staticCustomAccessorTableIndex[2] = {
662     { 0, -1 },
663     { -1, -1 },
664 };
665
666 static EncodedJSValue testStaticAccessorGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
667 {
668     DollarVMAssertScope assertScope;
669     VM& vm = globalObject->vm();
670     
671     JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
672     RELEASE_ASSERT(thisObject);
673
674     if (JSValue result = thisObject->getDirect(vm, PropertyName(Identifier::fromString(vm, "testField"))))
675         return JSValue::encode(result);
676     return JSValue::encode(jsUndefined());
677 }
678
679 static bool testStaticAccessorPutter(JSGlobalObject* globalObject, EncodedJSValue thisValue, EncodedJSValue value)
680 {
681     DollarVMAssertScope assertScope;
682     VM& vm = globalObject->vm();
683     
684     JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
685     RELEASE_ASSERT(thisObject);
686
687     return thisObject->putDirect(vm, PropertyName(Identifier::fromString(vm, "testField")), JSValue::decode(value));
688 }
689
690 static const struct HashTableValue staticCustomAccessorTableValues[1] = {
691     { "testStaticAccessor", static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(testStaticAccessorGetter), (intptr_t)static_cast<PutPropertySlot::PutValueFunc>(testStaticAccessorPutter) } },
692 };
693
694 static const struct HashTable staticCustomAccessorTable =
695     { 1, 1, true, nullptr, staticCustomAccessorTableValues, staticCustomAccessorTableIndex };
696
697 class StaticCustomAccessor : public JSNonFinalObject {
698     using Base = JSNonFinalObject;
699 public:
700     StaticCustomAccessor(VM& vm, Structure* structure)
701         : Base(vm, structure)
702     {
703         DollarVMAssertScope assertScope;
704     }
705
706     DECLARE_INFO;
707
708     static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable | OverridesGetOwnPropertySlot;
709
710     template<typename CellType, SubspaceAccess>
711     static CompleteSubspace* subspaceFor(VM& vm)
712     {
713         return &vm.cellSpace;
714     }
715
716     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
717     {
718         DollarVMAssertScope assertScope;
719         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
720     }
721
722     static StaticCustomAccessor* create(VM& vm, Structure* structure)
723     {
724         DollarVMAssertScope assertScope;
725         StaticCustomAccessor* accessor = new (NotNull, allocateCell<StaticCustomAccessor>(vm.heap)) StaticCustomAccessor(vm, structure);
726         accessor->finishCreation(vm);
727         return accessor;
728     }
729
730     static bool getOwnPropertySlot(JSObject* thisObject, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
731     {
732         if (String(propertyName.uid()) == "thinAirCustomGetter") {
733             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor, testStaticAccessorGetter);
734             return true;
735         }
736         return JSNonFinalObject::getOwnPropertySlot(thisObject, globalObject, propertyName, slot);
737     }
738 };
739
740 class ObjectDoingSideEffectPutWithoutCorrectSlotStatus : public JSNonFinalObject {
741     using Base = JSNonFinalObject;
742 public:
743     template<typename CellType, SubspaceAccess>
744     static CompleteSubspace* subspaceFor(VM& vm)
745     {
746         return &vm.cellSpace;
747     }
748
749     ObjectDoingSideEffectPutWithoutCorrectSlotStatus(VM& vm, Structure* structure)
750         : Base(vm, structure)
751     {
752         DollarVMAssertScope assertScope;
753     }
754
755     DECLARE_INFO;
756
757     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
758     {
759         DollarVMAssertScope assertScope;
760         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
761     }
762
763     static ObjectDoingSideEffectPutWithoutCorrectSlotStatus* create(VM& vm, Structure* structure)
764     {
765         DollarVMAssertScope assertScope;
766         ObjectDoingSideEffectPutWithoutCorrectSlotStatus* accessor = new (NotNull, allocateCell<ObjectDoingSideEffectPutWithoutCorrectSlotStatus>(vm.heap)) ObjectDoingSideEffectPutWithoutCorrectSlotStatus(vm, structure);
767         accessor->finishCreation(vm);
768         return accessor;
769     }
770
771     static bool put(JSCell* cell, JSGlobalObject* globalObject, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
772     {
773         DollarVMAssertScope assertScope;
774         auto* thisObject = jsCast<ObjectDoingSideEffectPutWithoutCorrectSlotStatus*>(cell);
775         auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
776         auto* string = value.toString(globalObject);
777         RETURN_IF_EXCEPTION(throwScope, false);
778         RELEASE_AND_RETURN(throwScope, Base::put(thisObject, globalObject, propertyName, string, slot));
779     }
780 };
781
782 class DOMJITNode : public JSNonFinalObject {
783 public:
784     DOMJITNode(VM& vm, Structure* structure)
785         : Base(vm, structure)
786     {
787         DollarVMAssertScope assertScope;
788     }
789
790     DECLARE_INFO;
791     typedef JSNonFinalObject Base;
792     static constexpr unsigned StructureFlags = Base::StructureFlags;
793
794     template<typename CellType, SubspaceAccess>
795     static CompleteSubspace* subspaceFor(VM& vm)
796     {
797         return &vm.cellSpace;
798     }
799
800     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
801     {
802         DollarVMAssertScope assertScope;
803         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
804     }
805
806 #if ENABLE(JIT)
807     static Ref<Snippet> checkSubClassSnippet()
808     {
809         DollarVMAssertScope assertScope;
810         Ref<Snippet> snippet = Snippet::create();
811         snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
812             DollarVMAssertScope assertScope;
813             CCallHelpers::JumpList failureCases;
814             failureCases.append(jit.branchIfNotType(params[0].gpr(), JSC::JSType(LastJSCObjectType + 1)));
815             return failureCases;
816         });
817         return snippet;
818     }
819 #endif
820
821     static DOMJITNode* create(VM& vm, Structure* structure)
822     {
823         DollarVMAssertScope assertScope;
824         DOMJITNode* getter = new (NotNull, allocateCell<DOMJITNode>(vm.heap)) DOMJITNode(vm, structure);
825         getter->finishCreation(vm);
826         return getter;
827     }
828
829     int32_t value() const
830     {
831         return m_value;
832     }
833
834     static ptrdiff_t offsetOfValue() { return OBJECT_OFFSETOF(DOMJITNode, m_value); }
835
836 private:
837     int32_t m_value { 42 };
838 };
839
840 class DOMJITGetter : public DOMJITNode {
841 public:
842     DOMJITGetter(VM& vm, Structure* structure)
843         : Base(vm, structure)
844     {
845         DollarVMAssertScope assertScope;
846     }
847
848     DECLARE_INFO;
849     typedef DOMJITNode Base;
850     static constexpr unsigned StructureFlags = Base::StructureFlags;
851
852     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
853     {
854         DollarVMAssertScope assertScope;
855         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
856     }
857
858     static DOMJITGetter* create(VM& vm, Structure* structure)
859     {
860         DollarVMAssertScope assertScope;
861         DOMJITGetter* getter = new (NotNull, allocateCell<DOMJITGetter>(vm.heap)) DOMJITGetter(vm, structure);
862         getter->finishCreation(vm);
863         return getter;
864     }
865
866     class DOMJITAttribute : public DOMJIT::GetterSetter {
867     public:
868         ALWAYS_INLINE constexpr DOMJITAttribute()
869             : DOMJIT::GetterSetter(
870                 DOMJITGetter::customGetter,
871 #if ENABLE(JIT)
872                 &callDOMGetter,
873 #else
874                 nullptr,
875 #endif
876                 SpecInt32Only)
877         {
878         }
879
880 #if ENABLE(JIT)
881         static EncodedJSValue JIT_OPERATION slowCall(JSGlobalObject* globalObject, void* pointer)
882         {
883             DollarVMAssertScope assertScope;
884             VM& vm = globalObject->vm();
885             CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
886             JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
887             return JSValue::encode(jsNumber(static_cast<DOMJITGetter*>(pointer)->value()));
888         }
889
890         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
891         {
892             DollarVMAssertScope assertScope;
893             Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
894             snippet->requireGlobalObject = true;
895             snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
896                 DollarVMAssertScope assertScope;
897                 JSValueRegs results = params[0].jsValueRegs();
898                 GPRReg domGPR = params[1].gpr();
899                 GPRReg globalObjectGPR = params[2].gpr();
900                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, globalObjectGPR, domGPR);
901                 return CCallHelpers::JumpList();
902
903             });
904             return snippet;
905         }
906 #endif
907     };
908
909 private:
910     void finishCreation(VM&);
911
912     static EncodedJSValue customGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
913     {
914         DollarVMAssertScope assertScope;
915         VM& vm = globalObject->vm();
916         DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, JSValue::decode(thisValue));
917         ASSERT(thisObject);
918         return JSValue::encode(jsNumber(thisObject->value()));
919     }
920 };
921
922 static const DOMJITGetter::DOMJITAttribute DOMJITGetterDOMJIT;
923
924 void DOMJITGetter::finishCreation(VM& vm)
925 {
926     DollarVMAssertScope assertScope;
927     Base::finishCreation(vm);
928     const DOMJIT::GetterSetter* domJIT = &DOMJITGetterDOMJIT;
929     auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITNode::info(), domJIT });
930     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
931 }
932
933 class DOMJITGetterNoEffects : public DOMJITNode {
934 public:
935     DOMJITGetterNoEffects(VM& vm, Structure* structure)
936         : Base(vm, structure)
937     {
938         DollarVMAssertScope assertScope;
939     }
940
941     DECLARE_INFO;
942     typedef DOMJITNode Base;
943     static constexpr unsigned StructureFlags = Base::StructureFlags;
944
945     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
946     {
947         DollarVMAssertScope assertScope;
948         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
949     }
950
951     static DOMJITGetterNoEffects* create(VM& vm, Structure* structure)
952     {
953         DollarVMAssertScope assertScope;
954         DOMJITGetterNoEffects* getter = new (NotNull, allocateCell<DOMJITGetterNoEffects>(vm.heap)) DOMJITGetterNoEffects(vm, structure);
955         getter->finishCreation(vm);
956         return getter;
957     }
958
959     class DOMJITAttribute : public DOMJIT::GetterSetter {
960     public:
961         ALWAYS_INLINE constexpr DOMJITAttribute()
962             : DOMJIT::GetterSetter(
963                 DOMJITGetterNoEffects::customGetter,
964 #if ENABLE(JIT)
965                 &callDOMGetter,
966 #else
967                 nullptr,
968 #endif
969                 SpecInt32Only)
970         {
971         }
972
973 #if ENABLE(JIT)
974         static EncodedJSValue JIT_OPERATION slowCall(JSGlobalObject* globalObject, void* pointer)
975         {
976             DollarVMAssertScope assertScope;
977             VM& vm = globalObject->vm();
978             CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
979             JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
980             return JSValue::encode(jsNumber(static_cast<DOMJITGetterNoEffects*>(pointer)->value()));
981         }
982
983         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
984         {
985             DollarVMAssertScope assertScope;
986             Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
987             snippet->effect = DOMJIT::Effect::forRead(DOMJIT::HeapRange(10, 11));
988             snippet->requireGlobalObject = true;
989             snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
990                 DollarVMAssertScope assertScope;
991                 JSValueRegs results = params[0].jsValueRegs();
992                 GPRReg domGPR = params[1].gpr();
993                 GPRReg globalObjectGPR = params[2].gpr();
994                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, globalObjectGPR, domGPR);
995                 return CCallHelpers::JumpList();
996
997             });
998             return snippet;
999         }
1000 #endif
1001     };
1002
1003 private:
1004     void finishCreation(VM&);
1005
1006     static EncodedJSValue customGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
1007     {
1008         DollarVMAssertScope assertScope;
1009         VM& vm = globalObject->vm();
1010         DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, JSValue::decode(thisValue));
1011         ASSERT(thisObject);
1012         return JSValue::encode(jsNumber(thisObject->value()));
1013     }
1014 };
1015
1016 static const DOMJITGetterNoEffects::DOMJITAttribute DOMJITGetterNoEffectsDOMJIT;
1017
1018 void DOMJITGetterNoEffects::finishCreation(VM& vm)
1019 {
1020     DollarVMAssertScope assertScope;
1021     Base::finishCreation(vm);
1022     const DOMJIT::GetterSetter* domJIT = &DOMJITGetterNoEffectsDOMJIT;
1023     auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITNode::info(), domJIT });
1024     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
1025 }
1026
1027 class DOMJITGetterComplex : public DOMJITNode {
1028 public:
1029     DOMJITGetterComplex(VM& vm, Structure* structure)
1030         : Base(vm, structure)
1031     {
1032         DollarVMAssertScope assertScope;
1033     }
1034
1035     DECLARE_INFO;
1036     typedef DOMJITNode Base;
1037     static constexpr unsigned StructureFlags = Base::StructureFlags;
1038
1039     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1040     {
1041         DollarVMAssertScope assertScope;
1042         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1043     }
1044
1045     static DOMJITGetterComplex* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
1046     {
1047         DollarVMAssertScope assertScope;
1048         DOMJITGetterComplex* getter = new (NotNull, allocateCell<DOMJITGetterComplex>(vm.heap)) DOMJITGetterComplex(vm, structure);
1049         getter->finishCreation(vm, globalObject);
1050         return getter;
1051     }
1052
1053     class DOMJITAttribute : public DOMJIT::GetterSetter {
1054     public:
1055         ALWAYS_INLINE constexpr DOMJITAttribute()
1056             : DOMJIT::GetterSetter(
1057                 DOMJITGetterComplex::customGetter,
1058 #if ENABLE(JIT)
1059                 &callDOMGetter,
1060 #else
1061                 nullptr,
1062 #endif
1063                 SpecInt32Only)
1064         {
1065         }
1066
1067 #if ENABLE(JIT)
1068         static EncodedJSValue JIT_OPERATION slowCall(JSGlobalObject* globalObject, void* pointer)
1069         {
1070             DollarVMAssertScope assertScope;
1071             VM& vm = globalObject->vm();
1072             CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1073             JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1074             auto scope = DECLARE_THROW_SCOPE(vm);
1075             auto* object = static_cast<DOMJITNode*>(pointer);
1076             auto* domjitGetterComplex = jsDynamicCast<DOMJITGetterComplex*>(vm, object);
1077             if (domjitGetterComplex) {
1078                 if (domjitGetterComplex->m_enableException)
1079                     return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "DOMJITGetterComplex slow call exception"_s)));
1080             }
1081             return JSValue::encode(jsNumber(object->value()));
1082         }
1083
1084         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
1085         {
1086             DollarVMAssertScope assertScope;
1087             Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
1088             static_assert(GPRInfo::numberOfRegisters >= 4, "Number of registers should be larger or equal to 4.");
1089             unsigned numGPScratchRegisters = GPRInfo::numberOfRegisters - 4;
1090             snippet->numGPScratchRegisters = numGPScratchRegisters;
1091             snippet->numFPScratchRegisters = 3;
1092             snippet->requireGlobalObject = true;
1093             snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1094                 DollarVMAssertScope assertScope;
1095                 JSValueRegs results = params[0].jsValueRegs();
1096                 GPRReg domGPR = params[1].gpr();
1097                 GPRReg globalObjectGPR = params[2].gpr();
1098                 for (unsigned i = 0; i < numGPScratchRegisters; ++i)
1099                     jit.move(CCallHelpers::TrustedImm32(42), params.gpScratch(i));
1100
1101                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, globalObjectGPR, domGPR);
1102                 return CCallHelpers::JumpList();
1103             });
1104             return snippet;
1105         }
1106 #endif
1107     };
1108
1109 private:
1110     void finishCreation(VM&, JSGlobalObject*);
1111
1112     static EncodedJSValue JSC_HOST_CALL functionEnableException(JSGlobalObject* globalObject, CallFrame* callFrame)
1113     {
1114         DollarVMAssertScope assertScope;
1115         VM& vm = globalObject->vm();
1116         auto* object = jsDynamicCast<DOMJITGetterComplex*>(vm, callFrame->thisValue());
1117         if (object)
1118             object->m_enableException = true;
1119         return JSValue::encode(jsUndefined());
1120     }
1121
1122     static EncodedJSValue customGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
1123     {
1124         DollarVMAssertScope assertScope;
1125         VM& vm = globalObject->vm();
1126         auto scope = DECLARE_THROW_SCOPE(vm);
1127
1128         auto* thisObject = jsDynamicCast<DOMJITGetterComplex*>(vm, JSValue::decode(thisValue));
1129         ASSERT(thisObject);
1130         if (thisObject->m_enableException)
1131             return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "DOMJITGetterComplex slow call exception"_s)));
1132         return JSValue::encode(jsNumber(thisObject->value()));
1133     }
1134
1135     bool m_enableException { false };
1136 };
1137
1138 static const DOMJITGetterComplex::DOMJITAttribute DOMJITGetterComplexDOMJIT;
1139
1140 void DOMJITGetterComplex::finishCreation(VM& vm, JSGlobalObject* globalObject)
1141 {
1142     DollarVMAssertScope assertScope;
1143     Base::finishCreation(vm);
1144     const DOMJIT::GetterSetter* domJIT = &DOMJITGetterComplexDOMJIT;
1145     auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITGetterComplex::info(), domJIT });
1146     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
1147     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "enableException"), 0, functionEnableException, NoIntrinsic, 0);
1148 }
1149
1150 class DOMJITFunctionObject : public DOMJITNode {
1151 public:
1152     DOMJITFunctionObject(VM& vm, Structure* structure)
1153         : Base(vm, structure)
1154     {
1155         DollarVMAssertScope assertScope;
1156     }
1157
1158     DECLARE_INFO;
1159     typedef DOMJITNode Base;
1160     static constexpr unsigned StructureFlags = Base::StructureFlags;
1161
1162     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1163     {
1164         DollarVMAssertScope assertScope;
1165         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1166     }
1167
1168     static DOMJITFunctionObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
1169     {
1170         DollarVMAssertScope assertScope;
1171         DOMJITFunctionObject* object = new (NotNull, allocateCell<DOMJITFunctionObject>(vm.heap)) DOMJITFunctionObject(vm, structure);
1172         object->finishCreation(vm, globalObject);
1173         return object;
1174     }
1175
1176     static EncodedJSValue JSC_HOST_CALL functionWithTypeCheck(JSGlobalObject* globalObject, CallFrame* callFrame)
1177     {
1178         DollarVMAssertScope assertScope;
1179         VM& vm = globalObject->vm();
1180         auto scope = DECLARE_THROW_SCOPE(vm);
1181
1182         DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, callFrame->thisValue());
1183         if (!thisObject)
1184             return throwVMTypeError(globalObject, scope);
1185         return JSValue::encode(jsNumber(thisObject->value()));
1186     }
1187
1188     static EncodedJSValue JIT_OPERATION functionWithoutTypeCheck(JSGlobalObject* globalObject, DOMJITNode* node)
1189     {
1190         DollarVMAssertScope assertScope;
1191         VM& vm = globalObject->vm();
1192         CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1193         JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1194         return JSValue::encode(jsNumber(node->value()));
1195     }
1196
1197 #if ENABLE(JIT)
1198     static Ref<Snippet> checkSubClassSnippet()
1199     {
1200         DollarVMAssertScope assertScope;
1201         Ref<Snippet> snippet = Snippet::create();
1202         snippet->numFPScratchRegisters = 1;
1203         snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1204             DollarVMAssertScope assertScope;
1205             static const double value = 42.0;
1206             CCallHelpers::JumpList failureCases;
1207             // May use scratch registers.
1208             jit.loadDouble(CCallHelpers::TrustedImmPtr(&value), params.fpScratch(0));
1209             failureCases.append(jit.branchIfNotType(params[0].gpr(), JSC::JSType(LastJSCObjectType + 1)));
1210             return failureCases;
1211         });
1212         return snippet;
1213     }
1214 #endif
1215
1216 private:
1217     void finishCreation(VM&, JSGlobalObject*);
1218 };
1219
1220 static const DOMJIT::Signature DOMJITFunctionObjectSignature(DOMJITFunctionObject::functionWithoutTypeCheck, DOMJITFunctionObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange(DOMJIT::HeapRange::ConstExpr, 0, 1)), SpecInt32Only);
1221
1222 void DOMJITFunctionObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
1223 {
1224     DollarVMAssertScope assertScope;
1225     Base::finishCreation(vm);
1226     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "func"), 0, functionWithTypeCheck, NoIntrinsic, &DOMJITFunctionObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));
1227 }
1228
1229 class DOMJITCheckJSCastObject : public DOMJITNode {
1230 public:
1231     DOMJITCheckJSCastObject(VM& vm, Structure* structure)
1232         : Base(vm, structure)
1233     {
1234         DollarVMAssertScope assertScope;
1235     }
1236
1237     DECLARE_INFO;
1238     typedef DOMJITNode Base;
1239     static constexpr unsigned StructureFlags = Base::StructureFlags;
1240
1241     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1242     {
1243         DollarVMAssertScope assertScope;
1244         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1245     }
1246
1247     static DOMJITCheckJSCastObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
1248     {
1249         DollarVMAssertScope assertScope;
1250         DOMJITCheckJSCastObject* object = new (NotNull, allocateCell<DOMJITCheckJSCastObject>(vm.heap)) DOMJITCheckJSCastObject(vm, structure);
1251         object->finishCreation(vm, globalObject);
1252         return object;
1253     }
1254
1255     static EncodedJSValue JSC_HOST_CALL functionWithTypeCheck(JSGlobalObject* globalObject, CallFrame* callFrame)
1256     {
1257         DollarVMAssertScope assertScope;
1258         VM& vm = globalObject->vm();
1259         auto scope = DECLARE_THROW_SCOPE(vm);
1260
1261         auto* thisObject = jsDynamicCast<DOMJITCheckJSCastObject*>(vm, callFrame->thisValue());
1262         if (!thisObject)
1263             return throwVMTypeError(globalObject, scope);
1264         return JSValue::encode(jsNumber(thisObject->value()));
1265     }
1266
1267     static EncodedJSValue JIT_OPERATION functionWithoutTypeCheck(JSGlobalObject* globalObject, DOMJITNode* node)
1268     {
1269         DollarVMAssertScope assertScope;
1270         VM& vm = globalObject->vm();
1271         CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1272         JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1273         return JSValue::encode(jsNumber(node->value()));
1274     }
1275
1276 private:
1277     void finishCreation(VM&, JSGlobalObject*);
1278 };
1279
1280 static const DOMJIT::Signature DOMJITCheckJSCastObjectSignature(DOMJITCheckJSCastObject::functionWithoutTypeCheck, DOMJITCheckJSCastObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);
1281
1282 void DOMJITCheckJSCastObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
1283 {
1284     DollarVMAssertScope assertScope;
1285     Base::finishCreation(vm);
1286     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "func"), 0, functionWithTypeCheck, NoIntrinsic, &DOMJITCheckJSCastObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));
1287 }
1288
1289 class DOMJITGetterBaseJSObject : public DOMJITNode {
1290 public:
1291     DOMJITGetterBaseJSObject(VM& vm, Structure* structure)
1292         : Base(vm, structure)
1293     {
1294         DollarVMAssertScope assertScope;
1295     }
1296
1297     DECLARE_INFO;
1298     using Base = DOMJITNode;
1299     static constexpr unsigned StructureFlags = Base::StructureFlags;
1300
1301     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1302     {
1303         DollarVMAssertScope assertScope;
1304         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1305     }
1306
1307     static DOMJITGetterBaseJSObject* create(VM& vm, Structure* structure)
1308     {
1309         DollarVMAssertScope assertScope;
1310         DOMJITGetterBaseJSObject* getter = new (NotNull, allocateCell<DOMJITGetterBaseJSObject>(vm.heap)) DOMJITGetterBaseJSObject(vm, structure);
1311         getter->finishCreation(vm);
1312         return getter;
1313     }
1314
1315     class DOMJITAttribute : public DOMJIT::GetterSetter {
1316     public:
1317         ALWAYS_INLINE constexpr DOMJITAttribute()
1318             : DOMJIT::GetterSetter(
1319                 DOMJITGetterBaseJSObject::customGetter,
1320 #if ENABLE(JIT)
1321                 &callDOMGetter,
1322 #else
1323                 nullptr,
1324 #endif
1325                 SpecBytecodeTop)
1326         {
1327         }
1328
1329 #if ENABLE(JIT)
1330         static EncodedJSValue JIT_OPERATION slowCall(JSGlobalObject* globalObject, void* pointer)
1331         {
1332             DollarVMAssertScope assertScope;
1333             VM& vm = globalObject->vm();
1334             CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1335             JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1336             JSObject* object = static_cast<JSObject*>(pointer);
1337             return JSValue::encode(object->getPrototypeDirect(vm));
1338         }
1339
1340         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
1341         {
1342             DollarVMAssertScope assertScope;
1343             Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
1344             snippet->requireGlobalObject = true;
1345             snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1346                 DollarVMAssertScope assertScope;
1347                 JSValueRegs results = params[0].jsValueRegs();
1348                 GPRReg domGPR = params[1].gpr();
1349                 GPRReg globalObjectGPR = params[2].gpr();
1350                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, globalObjectGPR, domGPR);
1351                 return CCallHelpers::JumpList();
1352
1353             });
1354             return snippet;
1355         }
1356 #endif
1357     };
1358
1359 private:
1360     void finishCreation(VM&);
1361
1362     static EncodedJSValue customGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
1363     {
1364         DollarVMAssertScope assertScope;
1365         VM& vm = globalObject->vm();
1366         JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
1367         RELEASE_ASSERT(thisObject);
1368         return JSValue::encode(thisObject->getPrototypeDirect(vm));
1369     }
1370 };
1371
1372 static const DOMJITGetterBaseJSObject::DOMJITAttribute DOMJITGetterBaseJSObjectDOMJIT;
1373
1374 void DOMJITGetterBaseJSObject::finishCreation(VM& vm)
1375 {
1376     DollarVMAssertScope assertScope;
1377     Base::finishCreation(vm);
1378     const DOMJIT::GetterSetter* domJIT = &DOMJITGetterBaseJSObjectDOMJIT;
1379     auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { JSObject::info(), domJIT });
1380     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
1381 }
1382
1383 class Message : public ThreadSafeRefCounted<Message> {
1384 public:
1385     Message(ArrayBufferContents&&, int32_t);
1386     ~Message();
1387
1388     ArrayBufferContents&& releaseContents() { return WTFMove(m_contents); }
1389     int32_t index() const { return m_index; }
1390
1391 private:
1392     ArrayBufferContents m_contents;
1393     int32_t m_index { 0 };
1394 };
1395
1396 class JSTestCustomGetterSetter : public JSNonFinalObject {
1397 public:
1398     using Base = JSNonFinalObject;
1399     static constexpr unsigned StructureFlags = Base::StructureFlags;
1400
1401     template<typename CellType, SubspaceAccess>
1402     static CompleteSubspace* subspaceFor(VM& vm)
1403     {
1404         return &vm.cellSpace;
1405     }
1406
1407     JSTestCustomGetterSetter(VM& vm, Structure* structure)
1408         : Base(vm, structure)
1409     {
1410         DollarVMAssertScope assertScope;
1411     }
1412
1413     static JSTestCustomGetterSetter* create(VM& vm, JSGlobalObject*, Structure* structure)
1414     {
1415         DollarVMAssertScope assertScope;
1416         JSTestCustomGetterSetter* result = new (NotNull, allocateCell<JSTestCustomGetterSetter>(vm.heap)) JSTestCustomGetterSetter(vm, structure);
1417         result->finishCreation(vm);
1418         return result;
1419     }
1420
1421     void finishCreation(VM&);
1422
1423     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
1424     {
1425         DollarVMAssertScope assertScope;
1426         return Structure::create(vm, globalObject, globalObject->objectPrototype(), TypeInfo(ObjectType, StructureFlags), info());
1427     }
1428
1429     DECLARE_INFO;
1430 };
1431
1432
1433 static EncodedJSValue customGetAccessor(JSGlobalObject*, EncodedJSValue thisValue, PropertyName)
1434 {
1435     // Passed |this|
1436     return thisValue;
1437 }
1438
1439 static EncodedJSValue customGetValue(JSGlobalObject* globalObject, EncodedJSValue slotValue, PropertyName)
1440 {
1441     RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>(globalObject->vm()));
1442     // Passed property holder.
1443     return slotValue;
1444 }
1445
1446 static EncodedJSValue customGetAccessorGlobalObject(JSGlobalObject* globalObject, EncodedJSValue, PropertyName)
1447 {
1448     return JSValue::encode(globalObject);
1449 }
1450
1451 static EncodedJSValue customGetValueGlobalObject(JSGlobalObject* globalObject, EncodedJSValue, PropertyName)
1452 {
1453     return JSValue::encode(globalObject);
1454 }
1455
1456 static bool customSetAccessor(JSGlobalObject* globalObject, EncodedJSValue thisObject, EncodedJSValue encodedValue)
1457 {
1458     DollarVMAssertScope assertScope;
1459     VM& vm = globalObject->vm();
1460
1461     JSValue value = JSValue::decode(encodedValue);
1462     RELEASE_ASSERT(value.isObject());
1463     JSObject* object = asObject(value);
1464     PutPropertySlot slot(object);
1465     object->put(object, globalObject, Identifier::fromString(vm, "result"), JSValue::decode(thisObject), slot);
1466
1467     return true;
1468 }
1469
1470 static bool customSetValue(JSGlobalObject* globalObject, EncodedJSValue slotValue, EncodedJSValue encodedValue)
1471 {
1472     DollarVMAssertScope assertScope;
1473     VM& vm = globalObject->vm();
1474
1475     RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>(globalObject->vm()));
1476
1477     JSValue value = JSValue::decode(encodedValue);
1478     RELEASE_ASSERT(value.isObject());
1479     JSObject* object = asObject(value);
1480     PutPropertySlot slot(object);
1481     object->put(object, globalObject, Identifier::fromString(vm, "result"), JSValue::decode(slotValue), slot);
1482
1483     return true;
1484 }
1485
1486 void JSTestCustomGetterSetter::finishCreation(VM& vm)
1487 {
1488     DollarVMAssertScope assertScope;
1489     Base::finishCreation(vm);
1490
1491     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customValue"),
1492         CustomGetterSetter::create(vm, customGetValue, customSetValue), 0);
1493     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customAccessor"),
1494         CustomGetterSetter::create(vm, customGetAccessor, customSetAccessor), static_cast<unsigned>(PropertyAttribute::CustomAccessor));
1495     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customValueGlobalObject"),
1496         CustomGetterSetter::create(vm, customGetValueGlobalObject, nullptr), 0);
1497     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customAccessorGlobalObject"),
1498         CustomGetterSetter::create(vm, customGetAccessorGlobalObject, nullptr), static_cast<unsigned>(PropertyAttribute::CustomAccessor));
1499
1500 }
1501
1502 const ClassInfo Element::s_info = { "Element", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Element) };
1503 const ClassInfo Root::s_info = { "Root", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Root) };
1504 const ClassInfo SimpleObject::s_info = { "SimpleObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(SimpleObject) };
1505 const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ImpureGetter) };
1506 const ClassInfo CustomGetter::s_info = { "CustomGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(CustomGetter) };
1507 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RuntimeArray) };
1508 #if ENABLE(JIT)
1509 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, &DOMJITNode::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITNode) };
1510 #else
1511 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITNode) };
1512 #endif
1513 const ClassInfo DOMJITGetter::s_info = { "DOMJITGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetter) };
1514 const ClassInfo DOMJITGetterNoEffects::s_info = { "DOMJITGetterNoEffects", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterNoEffects) };
1515 const ClassInfo DOMJITGetterComplex::s_info = { "DOMJITGetterComplex", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterComplex) };
1516 const ClassInfo DOMJITGetterBaseJSObject::s_info = { "DOMJITGetterBaseJSObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterBaseJSObject) };
1517 #if ENABLE(JIT)
1518 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, &DOMJITFunctionObject::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
1519 #else
1520 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
1521 #endif
1522 const ClassInfo DOMJITCheckJSCastObject::s_info = { "DOMJITCheckJSCastObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITCheckJSCastObject) };
1523 const ClassInfo JSTestCustomGetterSetter::s_info = { "JSTestCustomGetterSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestCustomGetterSetter) };
1524
1525 const ClassInfo StaticCustomAccessor::s_info = { "StaticCustomAccessor", &Base::s_info, &staticCustomAccessorTable, nullptr, CREATE_METHOD_TABLE(StaticCustomAccessor) };
1526 const ClassInfo ObjectDoingSideEffectPutWithoutCorrectSlotStatus::s_info = { "ObjectDoingSideEffectPutWithoutCorrectSlotStatus", &Base::s_info, &staticCustomAccessorTable, nullptr, CREATE_METHOD_TABLE(ObjectDoingSideEffectPutWithoutCorrectSlotStatus) };
1527
1528 ElementHandleOwner* Element::handleOwner()
1529 {
1530     DollarVMAssertScope assertScope;
1531     static ElementHandleOwner* owner = nullptr;
1532     if (!owner)
1533         owner = new ElementHandleOwner();
1534     return owner;
1535 }
1536
1537 void Element::finishCreation(VM& vm, Root* root)
1538 {
1539     DollarVMAssertScope assertScope;
1540     Base::finishCreation(vm);
1541     setRoot(vm, root);
1542     m_root->setElement(this);
1543 }
1544
1545 #if ENABLE(WEBASSEMBLY)
1546
1547 static EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserAddBytes(JSGlobalObject*, CallFrame*);
1548 static EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserFinalize(JSGlobalObject*, CallFrame*);
1549
1550 class WasmStreamingParser : public JSDestructibleObject {
1551 public:
1552     using Base = JSDestructibleObject;
1553     template<typename CellType, SubspaceAccess>
1554     static CompleteSubspace* subspaceFor(VM& vm)
1555     {
1556         return &vm.destructibleObjectSpace;
1557     }
1558
1559     class Client final : public Wasm::StreamingParserClient {
1560     public:
1561         explicit Client(WasmStreamingParser* parser)
1562             : m_parser(parser)
1563         {
1564         }
1565
1566         bool didReceiveSectionData(Wasm::Section) final { return true; }
1567         bool didReceiveFunctionData(unsigned, const Wasm::FunctionData&) final { return true; }
1568         void didFinishParsing() final { }
1569
1570         WasmStreamingParser* m_parser;
1571     };
1572
1573     WasmStreamingParser(VM& vm, Structure* structure)
1574         : Base(vm, structure)
1575         , m_info(Wasm::ModuleInformation::create())
1576         , m_client(this)
1577         , m_streamingParser(m_info.get(), m_client)
1578     {
1579         DollarVMAssertScope assertScope;
1580     }
1581
1582     static WasmStreamingParser* create(VM& vm, JSGlobalObject* globalObject)
1583     {
1584         DollarVMAssertScope assertScope;
1585         Structure* structure = createStructure(vm, globalObject, jsNull());
1586         WasmStreamingParser* result = new (NotNull, allocateCell<WasmStreamingParser>(vm.heap)) WasmStreamingParser(vm, structure);
1587         result->finishCreation(vm);
1588         return result;
1589     }
1590
1591     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1592     {
1593         DollarVMAssertScope assertScope;
1594         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
1595     }
1596
1597     Wasm::StreamingParser& streamingParser() { return m_streamingParser; }
1598
1599     void finishCreation(VM& vm)
1600     {
1601         DollarVMAssertScope assertScope;
1602         Base::finishCreation(vm);
1603
1604         JSGlobalObject* globalObject = this->globalObject(vm);
1605         putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "addBytes"), 0, functionWasmStreamingParserAddBytes, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
1606         putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "finalize"), 0, functionWasmStreamingParserFinalize, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
1607     }
1608
1609     DECLARE_INFO;
1610
1611     Ref<Wasm::ModuleInformation> m_info;
1612     Client m_client;
1613     Wasm::StreamingParser m_streamingParser;
1614 };
1615
1616 const ClassInfo WasmStreamingParser::s_info = { "WasmStreamingParser", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WasmStreamingParser) };
1617
1618 EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserAddBytes(JSGlobalObject* globalObject, CallFrame* callFrame)
1619 {
1620     DollarVMAssertScope assertScope;
1621     VM& vm = globalObject->vm();
1622     auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
1623
1624     auto* thisObject = jsDynamicCast<WasmStreamingParser*>(vm, callFrame->thisValue());
1625     if (!thisObject)
1626         RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(false)));
1627
1628     auto data = getWasmBufferFromValue(globalObject, callFrame->argument(0));
1629     RETURN_IF_EXCEPTION(scope, encodedJSValue());
1630     RELEASE_AND_RETURN(scope, JSValue::encode(jsNumber(static_cast<int32_t>(thisObject->streamingParser().addBytes(bitwise_cast<const uint8_t*>(data.first), data.second)))));
1631 }
1632
1633 EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserFinalize(JSGlobalObject* globalObject, CallFrame* callFrame)
1634 {
1635     DollarVMAssertScope assertScope;
1636     VM& vm = globalObject->vm();
1637     auto* thisObject = jsDynamicCast<WasmStreamingParser*>(vm, callFrame->thisValue());
1638     if (!thisObject)
1639         return JSValue::encode(jsBoolean(false));
1640     return JSValue::encode(jsNumber(static_cast<int32_t>(thisObject->streamingParser().finalize())));
1641 }
1642
1643 #endif
1644
1645 } // namespace
1646
1647 namespace JSC {
1648
1649 const ClassInfo JSDollarVM::s_info = { "DollarVM", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDollarVM) };
1650
1651 // Triggers a crash immediately.
1652 // Usage: $vm.crash()
1653 static NO_RETURN_DUE_TO_CRASH EncodedJSValue JSC_HOST_CALL functionCrash(JSGlobalObject*, CallFrame*)
1654 {
1655     DollarVMAssertScope assertScope;
1656     CRASH();
1657 }
1658
1659 // Executes a breakpoint instruction if the first argument is truthy or is unset.
1660 // Usage: $vm.breakpoint(<condition>)
1661 static EncodedJSValue JSC_HOST_CALL functionBreakpoint(JSGlobalObject* globalObject, CallFrame* callFrame)
1662 {
1663     DollarVMAssertScope assertScope;
1664     // Nothing should throw here but we might as well double check...
1665     VM& vm = globalObject->vm();
1666     auto scope = DECLARE_CATCH_SCOPE(vm);
1667     UNUSED_PARAM(scope);
1668     if (!callFrame->argumentCount() || callFrame->argument(0).toBoolean(globalObject))
1669         WTFBreakpointTrap();
1670
1671     return encodedJSUndefined();
1672 }
1673
1674 // Returns true if the current frame is a DFG frame.
1675 // Usage: isDFG = $vm.dfgTrue()
1676 static EncodedJSValue JSC_HOST_CALL functionDFGTrue(JSGlobalObject*, CallFrame*)
1677 {
1678     DollarVMAssertScope assertScope;
1679     return JSValue::encode(jsBoolean(false));
1680 }
1681
1682 // Returns true if the current frame is a FTL frame.
1683 // Usage: isFTL = $vm.ftlTrue()
1684 static EncodedJSValue JSC_HOST_CALL functionFTLTrue(JSGlobalObject*, CallFrame*)
1685 {
1686     DollarVMAssertScope assertScope;
1687     return JSValue::encode(jsBoolean(false));
1688 }
1689
1690 static EncodedJSValue JSC_HOST_CALL functionCpuMfence(JSGlobalObject*, CallFrame*)
1691 {
1692     DollarVMAssertScope assertScope;
1693 #if CPU(X86_64) && !OS(WINDOWS)
1694     asm volatile("mfence" ::: "memory");
1695 #endif
1696     return JSValue::encode(jsUndefined());
1697 }
1698
1699 static EncodedJSValue JSC_HOST_CALL functionCpuRdtsc(JSGlobalObject*, CallFrame*)
1700 {
1701     DollarVMAssertScope assertScope;
1702 #if CPU(X86_64) && !OS(WINDOWS)
1703     unsigned high;
1704     unsigned low;
1705     asm volatile ("rdtsc" : "=a"(low), "=d"(high));
1706     return JSValue::encode(jsNumber(low));
1707 #else
1708     return JSValue::encode(jsNumber(0));
1709 #endif
1710 }
1711
1712 static EncodedJSValue JSC_HOST_CALL functionCpuCpuid(JSGlobalObject*, CallFrame*)
1713 {
1714     DollarVMAssertScope assertScope;
1715 #if CPU(X86_64) && !OS(WINDOWS)
1716     WTF::x86_cpuid();
1717 #endif
1718     return JSValue::encode(jsUndefined());
1719 }
1720
1721 static EncodedJSValue JSC_HOST_CALL functionCpuPause(JSGlobalObject*, CallFrame*)
1722 {
1723     DollarVMAssertScope assertScope;
1724 #if CPU(X86_64) && !OS(WINDOWS)
1725     asm volatile ("pause" ::: "memory");
1726 #endif
1727     return JSValue::encode(jsUndefined());
1728 }
1729
1730 // This takes either a JSArrayBuffer, JSArrayBufferView*, or any other object as its first
1731 // argument. The second argument is expected to be an integer.
1732 //
1733 // If the first argument is a JSArrayBuffer, it'll clflush on that buffer
1734 // plus the second argument as a byte offset. It'll also flush on the object
1735 // itself so its length, etc, aren't in the cache.
1736 //
1737 // If the first argument is not a JSArrayBuffer, we load the butterfly
1738 // and clflush at the address of the butterfly.
1739 static EncodedJSValue JSC_HOST_CALL functionCpuClflush(JSGlobalObject* globalObject, CallFrame* callFrame)
1740 {
1741     DollarVMAssertScope assertScope;
1742 #if CPU(X86_64) && !OS(WINDOWS)
1743     VM& vm = globalObject->vm();
1744
1745     if (!callFrame->argument(1).isUInt32())
1746         return JSValue::encode(jsBoolean(false));
1747
1748     auto clflush = [] (void* ptr) {
1749         DollarVMAssertScope assertScope;
1750         char* ptrToFlush = static_cast<char*>(ptr);
1751         asm volatile ("clflush %0" :: "m"(*ptrToFlush) : "memory");
1752     };
1753
1754     Vector<void*> toFlush;
1755
1756     uint32_t offset = callFrame->argument(1).asUInt32();
1757
1758     if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(vm, callFrame->argument(0)))
1759         toFlush.append(bitwise_cast<char*>(view->vector()) + offset);
1760     else if (JSObject* object = jsDynamicCast<JSObject*>(vm, callFrame->argument(0))) {
1761         switch (object->indexingType()) {
1762         case ALL_INT32_INDEXING_TYPES:
1763         case ALL_CONTIGUOUS_INDEXING_TYPES:
1764         case ALL_DOUBLE_INDEXING_TYPES:
1765             toFlush.append(bitwise_cast<char*>(object->butterfly()) + Butterfly::offsetOfVectorLength());
1766             toFlush.append(bitwise_cast<char*>(object->butterfly()) + Butterfly::offsetOfPublicLength());
1767         }
1768     }
1769
1770     if (!toFlush.size())
1771         return JSValue::encode(jsBoolean(false));
1772
1773     for (void* ptr : toFlush)
1774         clflush(ptr);
1775     return JSValue::encode(jsBoolean(true));
1776 #else
1777     UNUSED_PARAM(globalObject);
1778     UNUSED_PARAM(callFrame);
1779     return JSValue::encode(jsBoolean(false));
1780 #endif
1781 }
1782
1783 class CallerFrameJITTypeFunctor {
1784 public:
1785     CallerFrameJITTypeFunctor()
1786     {
1787         DollarVMAssertScope assertScope;
1788     }
1789
1790     StackVisitor::Status operator()(StackVisitor& visitor) const
1791     {
1792         unsigned index = m_currentFrame++;
1793         // First frame (index 0) is `llintTrue` etc. function itself.
1794         if (index == 1) {
1795             if (visitor->codeBlock())
1796                 m_jitType = visitor->codeBlock()->jitType();
1797             return StackVisitor::Done;
1798         }
1799         return StackVisitor::Continue;
1800     }
1801     
1802     JITType jitType() { return m_jitType; }
1803
1804 private:
1805     mutable unsigned m_currentFrame { 0 };
1806     mutable JITType m_jitType { JITType::None };
1807 };
1808
1809 static FunctionExecutable* getExecutableForFunction(JSValue theFunctionValue)
1810 {
1811     DollarVMAssertScope assertScope;
1812     if (!theFunctionValue.isCell())
1813         return nullptr;
1814     
1815     VM& vm = theFunctionValue.asCell()->vm();
1816     JSFunction* theFunction = jsDynamicCast<JSFunction*>(vm, theFunctionValue);
1817     if (!theFunction)
1818         return nullptr;
1819     
1820     FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(vm,
1821         theFunction->executable());
1822
1823     return executable;
1824 }
1825
1826 // Returns true if the current frame is a LLInt frame.
1827 // Usage: isLLInt = $vm.llintTrue()
1828 static EncodedJSValue JSC_HOST_CALL functionLLintTrue(JSGlobalObject* globalObject, CallFrame* callFrame)
1829 {
1830     DollarVMAssertScope assertScope;
1831     VM& vm = globalObject->vm();
1832     if (!callFrame)
1833         return JSValue::encode(jsUndefined());
1834     CallerFrameJITTypeFunctor functor;
1835     callFrame->iterate(vm, functor);
1836     return JSValue::encode(jsBoolean(functor.jitType() == JITType::InterpreterThunk));
1837 }
1838
1839 // Returns true if the current frame is a baseline JIT frame.
1840 // Usage: isBaselineJIT = $vm.baselineJITTrue()
1841 static EncodedJSValue JSC_HOST_CALL functionBaselineJITTrue(JSGlobalObject* globalObject, CallFrame* callFrame)
1842 {
1843     DollarVMAssertScope assertScope;
1844     VM& vm = globalObject->vm();
1845     if (!callFrame)
1846         return JSValue::encode(jsUndefined());
1847     CallerFrameJITTypeFunctor functor;
1848     callFrame->iterate(vm, functor);
1849     return JSValue::encode(jsBoolean(functor.jitType() == JITType::BaselineJIT));
1850 }
1851
1852 // Set that the argument function should not be inlined.
1853 // Usage:
1854 // function f() { };
1855 // $vm.noInline(f);
1856 static EncodedJSValue JSC_HOST_CALL functionNoInline(JSGlobalObject*, CallFrame* callFrame)
1857 {
1858     DollarVMAssertScope assertScope;
1859     if (callFrame->argumentCount() < 1)
1860         return JSValue::encode(jsUndefined());
1861     
1862     JSValue theFunctionValue = callFrame->uncheckedArgument(0);
1863
1864     if (FunctionExecutable* executable = getExecutableForFunction(theFunctionValue))
1865         executable->setNeverInline(true);
1866     
1867     return JSValue::encode(jsUndefined());
1868 }
1869
1870 // Runs a full GC synchronously.
1871 // Usage: $vm.gc()
1872 static EncodedJSValue JSC_HOST_CALL functionGC(JSGlobalObject* globalObject, CallFrame*)
1873 {
1874     DollarVMAssertScope assertScope;
1875     VMInspector::gc(&globalObject->vm());
1876     return JSValue::encode(jsUndefined());
1877 }
1878
1879 // Runs the edenGC synchronously.
1880 // Usage: $vm.edenGC()
1881 static EncodedJSValue JSC_HOST_CALL functionEdenGC(JSGlobalObject* globalObject, CallFrame*)
1882 {
1883     DollarVMAssertScope assertScope;
1884     VMInspector::edenGC(&globalObject->vm());
1885     return JSValue::encode(jsUndefined());
1886 }
1887
1888 // Runs a full GC, but sweep asynchronously.
1889 // Usage: $vm.gcSweepAsynchronously()
1890 static EncodedJSValue JSC_HOST_CALL functionGCSweepAsynchronously(JSGlobalObject* globalObject, CallFrame*)
1891 {
1892     DollarVMAssertScope assertScope;
1893     globalObject->vm().heap.collectNow(Async, CollectionScope::Full);
1894     return JSValue::encode(jsUndefined());
1895 }
1896
1897 // Dumps the hashes of all subspaces currently registered with the VM.
1898 // Usage: $vm.dumpSubspaceHashes()
1899 static EncodedJSValue JSC_HOST_CALL functionDumpSubspaceHashes(JSGlobalObject* globalObject, CallFrame*)
1900 {
1901     DollarVMAssertScope assertScope;
1902     VM& vm = globalObject->vm();
1903     VMInspector::dumpSubspaceHashes(&vm);
1904     return JSValue::encode(jsUndefined());
1905 }
1906
1907 // Gets a JSDollarVMCallFrame for a specified frame index.
1908 // Usage: var callFrame = $vm.callFrame(0) // frame 0 is the top frame.
1909 // Usage: var callFrame = $vm.callFrame() // implies frame 0 i.e. current frame.
1910 //
1911 // This gives you the ability to query the following:
1912 //    callFrame.valid; // false if we asked for a frame beyond the end of the stack, else true.
1913 //    callFrame.callee;
1914 //    callFrame.codeBlock;
1915 //    callFrame.unlinkedCodeBlock;
1916 //    callFrame.executable;
1917 //
1918 // Note: you cannot toString() a codeBlock, unlinkedCodeBlock, or executable because
1919 // there are internal objects and not a JS object. Hence, you cannot do string
1920 // concatenation with them.
1921 static EncodedJSValue JSC_HOST_CALL functionCallFrame(JSGlobalObject* globalObject, CallFrame* callFrame)
1922 {
1923     DollarVMAssertScope assertScope;
1924     unsigned frameNumber = 1;
1925     if (callFrame->argumentCount() >= 1) {
1926         JSValue value = callFrame->uncheckedArgument(0);
1927         if (!value.isUInt32())
1928             return JSValue::encode(jsUndefined());
1929
1930         // We need to inc the frame number because the caller would consider
1931         // its own frame as frame 0. Hence, we need discount the frame for this
1932         // function.
1933         frameNumber = value.asUInt32() + 1;
1934     }
1935
1936     return JSValue::encode(JSDollarVMCallFrame::create(globalObject, callFrame, frameNumber));
1937 }
1938
1939 // Gets a token for the CodeBlock for a specified frame index.
1940 // Usage: codeBlockToken = $vm.codeBlockForFrame(0) // frame 0 is the top frame.
1941 // Usage: codeBlockToken = $vm.codeBlockForFrame() // implies frame 0 i.e. current frame.
1942 static EncodedJSValue JSC_HOST_CALL functionCodeBlockForFrame(JSGlobalObject* globalObject, CallFrame* callFrame)
1943 {
1944     DollarVMAssertScope assertScope;
1945     unsigned frameNumber = 1;
1946     if (callFrame->argumentCount() >= 1) {
1947         JSValue value = callFrame->uncheckedArgument(0);
1948         if (!value.isUInt32())
1949             return JSValue::encode(jsUndefined());
1950
1951         // We need to inc the frame number because the caller would consider
1952         // its own frame as frame 0. Hence, we need discount the frame for this
1953         // function.
1954         frameNumber = value.asUInt32() + 1;
1955     }
1956
1957     CodeBlock* codeBlock = VMInspector::codeBlockForFrame(&globalObject->vm(), callFrame, frameNumber);
1958     if (codeBlock)
1959         return JSValue::encode(codeBlock);
1960     return JSValue::encode(jsUndefined());
1961 }
1962
1963 static CodeBlock* codeBlockFromArg(JSGlobalObject* globalObject, CallFrame* callFrame)
1964 {
1965     DollarVMAssertScope assertScope;
1966     VM& vm = globalObject->vm();
1967     if (callFrame->argumentCount() < 1)
1968         return nullptr;
1969
1970     JSValue value = callFrame->uncheckedArgument(0);
1971     CodeBlock* candidateCodeBlock = nullptr;
1972     if (value.isCell()) {
1973         JSFunction* func = jsDynamicCast<JSFunction*>(vm, value.asCell());
1974         if (func) {
1975             if (func->isHostFunction())
1976                 candidateCodeBlock = nullptr;
1977             else
1978                 candidateCodeBlock = func->jsExecutable()->eitherCodeBlock();
1979         } else
1980             candidateCodeBlock = static_cast<CodeBlock*>(value.asCell());
1981     }
1982
1983     if (candidateCodeBlock && VMInspector::isValidCodeBlock(&vm, candidateCodeBlock))
1984         return candidateCodeBlock;
1985
1986     if (candidateCodeBlock)
1987         dataLog("Invalid codeBlock: ", RawPointer(candidateCodeBlock), " ", value, "\n");
1988     else
1989         dataLog("Invalid codeBlock: ", value, "\n");
1990     return nullptr;
1991 }
1992
1993 // Usage: $vm.print("codeblock = ", $vm.codeBlockFor(functionObj))
1994 // Usage: $vm.print("codeblock = ", $vm.codeBlockFor(codeBlockToken))
1995 // Note: you cannot toString() a codeBlock because it's an internal object and not
1996 // a JS object. Hence, you cannot do string concatenation with it.
1997 static EncodedJSValue JSC_HOST_CALL functionCodeBlockFor(JSGlobalObject* globalObject, CallFrame* callFrame)
1998 {
1999     DollarVMAssertScope assertScope;
2000     CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
2001     WTF::StringPrintStream stream;
2002     if (codeBlock) {
2003         stream.print(*codeBlock);
2004         return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2005     }
2006     return JSValue::encode(jsUndefined());
2007 }
2008
2009 // Usage: $vm.dumpSourceFor(functionObj)
2010 // Usage: $vm.dumpSourceFor(codeBlockToken)
2011 static EncodedJSValue JSC_HOST_CALL functionDumpSourceFor(JSGlobalObject* globalObject, CallFrame* callFrame)
2012 {
2013     DollarVMAssertScope assertScope;
2014     CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
2015     if (codeBlock)
2016         codeBlock->dumpSource();
2017     return JSValue::encode(jsUndefined());
2018 }
2019
2020 // Usage: $vm.dumpBytecodeFor(functionObj)
2021 // Usage: $vm.dumpBytecodeFor(codeBlock)
2022 static EncodedJSValue JSC_HOST_CALL functionDumpBytecodeFor(JSGlobalObject* globalObject, CallFrame* callFrame)
2023 {
2024     DollarVMAssertScope assertScope;
2025     CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
2026     if (codeBlock)
2027         codeBlock->dumpBytecode();
2028     return JSValue::encode(jsUndefined());
2029 }
2030
2031 static EncodedJSValue doPrint(JSGlobalObject* globalObject, CallFrame* callFrame, bool addLineFeed)
2032 {
2033     DollarVMAssertScope assertScope;
2034     auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
2035     for (unsigned i = 0; i < callFrame->argumentCount(); ++i) {
2036         JSValue arg = callFrame->uncheckedArgument(i);
2037         if (arg.isCell()
2038             && !arg.isObject()
2039             && !arg.isString()
2040             && !arg.isBigInt()) {
2041             dataLog(arg);
2042             continue;
2043         }
2044         String argStr = callFrame->uncheckedArgument(i).toWTFString(globalObject);
2045         RETURN_IF_EXCEPTION(scope, encodedJSValue());
2046         dataLog(argStr);
2047     }
2048     if (addLineFeed)
2049         dataLog("\n");
2050     return JSValue::encode(jsUndefined());
2051 }
2052
2053 // Prints a series of comma separate strings without appending a newline.
2054 // Usage: $vm.dataLog(str1, str2, str3)
2055 static EncodedJSValue JSC_HOST_CALL functionDataLog(JSGlobalObject* globalObject, CallFrame* callFrame)
2056 {
2057     DollarVMAssertScope assertScope;
2058     const bool addLineFeed = false;
2059     return doPrint(globalObject, callFrame, addLineFeed);
2060 }
2061
2062 // Prints a series of comma separate strings and appends a newline.
2063 // Usage: $vm.print(str1, str2, str3)
2064 static EncodedJSValue JSC_HOST_CALL functionPrint(JSGlobalObject* globalObject, CallFrame* callFrame)
2065 {
2066     DollarVMAssertScope assertScope;
2067     const bool addLineFeed = true;
2068     return doPrint(globalObject, callFrame, addLineFeed);
2069 }
2070
2071 // Dumps the current CallFrame.
2072 // Usage: $vm.dumpCallFrame()
2073 static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(JSGlobalObject* globalObject, CallFrame* callFrame)
2074 {
2075     DollarVMAssertScope assertScope;
2076     // When the callers call this function, they are expecting to dump their
2077     // own frame. So skip 1 for this frame.
2078     VMInspector::dumpCallFrame(&globalObject->vm(), callFrame, 1);
2079     return JSValue::encode(jsUndefined());
2080 }
2081
2082 // Dumps the JS stack.
2083 // Usage: $vm.printStack()
2084 static EncodedJSValue JSC_HOST_CALL functionDumpStack(JSGlobalObject* globalObject, CallFrame* callFrame)
2085 {
2086     DollarVMAssertScope assertScope;
2087     // When the callers call this function, they are expecting to dump the
2088     // stack starting their own frame. So skip 1 for this frame.
2089     VMInspector::dumpStack(&globalObject->vm(), callFrame, 1);
2090     return JSValue::encode(jsUndefined());
2091 }
2092
2093 // Dumps the current CallFrame.
2094 // Usage: $vm.dumpRegisters(N) // dump the registers of the Nth CallFrame.
2095 // Usage: $vm.dumpRegisters() // dump the registers of the current CallFrame.
2096 // FIXME: Currently, this function dumps the physical frame. We should make
2097 // it dump the logical frame (i.e. be able to dump inlined frames as well).
2098 static EncodedJSValue JSC_HOST_CALL functionDumpRegisters(JSGlobalObject* globalObject, CallFrame* callFrame)
2099 {
2100     DollarVMAssertScope assertScope;
2101     VM& vm = globalObject->vm();
2102     unsigned requestedFrameIndex = 1;
2103     if (callFrame->argumentCount() >= 1) {
2104         JSValue value = callFrame->uncheckedArgument(0);
2105         if (!value.isUInt32())
2106             return JSValue::encode(jsUndefined());
2107
2108         // We need to inc the frame number because the caller would consider
2109         // its own frame as frame 0. Hence, we need discount the frame for this
2110         // function.
2111         requestedFrameIndex = value.asUInt32() + 1;
2112     }
2113
2114     unsigned frameIndex = 0;
2115     callFrame->iterate(vm, [&] (StackVisitor& visitor) {
2116         DollarVMAssertScope assertScope;
2117         if (frameIndex++ != requestedFrameIndex)
2118             return StackVisitor::Continue;
2119         VMInspector::dumpRegisters(visitor->callFrame());
2120         return StackVisitor::Done;
2121     });
2122
2123     return encodedJSUndefined();
2124 }
2125
2126 // Dumps the internal memory layout of a JSCell.
2127 // Usage: $vm.dumpCell(cell)
2128 static EncodedJSValue JSC_HOST_CALL functionDumpCell(JSGlobalObject*, CallFrame* callFrame)
2129 {
2130     DollarVMAssertScope assertScope;
2131     JSValue value = callFrame->argument(0);
2132     if (!value.isCell())
2133         return encodedJSUndefined();
2134     
2135     VMInspector::dumpCellMemory(value.asCell());
2136     return encodedJSUndefined();
2137 }
2138
2139 // Gets the dataLog dump of the indexingMode of the passed value.
2140 // Usage: $vm.print("indexingMode = " + $vm.indexingMode(jsValue))
2141 static EncodedJSValue JSC_HOST_CALL functionIndexingMode(JSGlobalObject* globalObject, CallFrame* callFrame)
2142 {
2143     DollarVMAssertScope assertScope;
2144     if (!callFrame->argument(0).isObject())
2145         return encodedJSUndefined();
2146
2147     WTF::StringPrintStream stream;
2148     stream.print(IndexingTypeDump(callFrame->uncheckedArgument(0).getObject()->indexingMode()));
2149     return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2150 }
2151
2152 static EncodedJSValue JSC_HOST_CALL functionInlineCapacity(JSGlobalObject* globalObject, CallFrame* callFrame)
2153 {
2154     DollarVMAssertScope assertScope;
2155     VM& vm = globalObject->vm();
2156     if (auto* object = jsDynamicCast<JSObject*>(vm, callFrame->argument(0)))
2157         return JSValue::encode(jsNumber(object->structure(vm)->inlineCapacity()));
2158
2159     return encodedJSUndefined();
2160 }
2161
2162 // Gets the dataLog dump of a given JS value as a string.
2163 // Usage: $vm.print("value = " + $vm.value(jsValue))
2164 static EncodedJSValue JSC_HOST_CALL functionValue(JSGlobalObject* globalObject, CallFrame* callFrame)
2165 {
2166     DollarVMAssertScope assertScope;
2167     WTF::StringPrintStream stream;
2168     for (unsigned i = 0; i < callFrame->argumentCount(); ++i) {
2169         if (i)
2170             stream.print(", ");
2171         stream.print(callFrame->uncheckedArgument(i));
2172     }
2173     
2174     return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2175 }
2176
2177 // Gets the pid of the current process.
2178 // Usage: $vm.print("pid = " + $vm.getpid())
2179 static EncodedJSValue JSC_HOST_CALL functionGetPID(JSGlobalObject*, CallFrame*)
2180 {
2181     DollarVMAssertScope assertScope;
2182     return JSValue::encode(jsNumber(getCurrentProcessID()));
2183 }
2184
2185 // Make the globalObject have a bad time. Does nothing if the object is not a JSGlobalObject.
2186 // Usage: $vm.haveABadTime(globalObject)
2187 static EncodedJSValue JSC_HOST_CALL functionHaveABadTime(JSGlobalObject* globalObject, CallFrame* callFrame)
2188 {
2189     DollarVMAssertScope assertScope;
2190     VM& vm = globalObject->vm();
2191     auto scope = DECLARE_THROW_SCOPE(vm);
2192     JSGlobalObject* target = globalObject;
2193     if (!callFrame->argument(0).isUndefined()) {
2194         JSObject* obj = callFrame->argument(0).getObject();
2195         if (!obj)
2196             return throwVMTypeError(globalObject, scope, "haveABadTime expects first argument to be an object if provided");
2197         target = obj->globalObject();
2198     }
2199
2200     target->haveABadTime(vm);
2201     return JSValue::encode(jsBoolean(true));
2202 }
2203
2204 // Checks if the object (or its global if the object is not a global) is having a bad time.
2205 // Usage: $vm.isHavingABadTime(obj)
2206 static EncodedJSValue JSC_HOST_CALL functionIsHavingABadTime(JSGlobalObject* globalObject, CallFrame* callFrame)
2207 {
2208     DollarVMAssertScope assertScope;
2209     VM& vm = globalObject->vm();
2210     auto scope = DECLARE_THROW_SCOPE(vm);
2211     JSGlobalObject* target = globalObject;
2212     if (!callFrame->argument(0).isUndefined()) {
2213         JSObject* obj = callFrame->argument(0).getObject();
2214         if (!obj)
2215             return throwVMTypeError(globalObject, scope, "isHavingABadTime expects first argument to be an object if provided");
2216         target = obj->globalObject();
2217     }
2218
2219     return JSValue::encode(jsBoolean(target->isHavingABadTime()));
2220 }
2221
2222 // Calls the specified test function after adjusting the stack to have the specified
2223 // remaining size from the end of the physical stack.
2224 // Usage: $vm.callWithStackSize(funcToCall, desiredStackSize)
2225 //
2226 // This function will only work in test configurations, specifically, only if JSC
2227 // options are not frozen. For the jsc shell, the --disableOptionsFreezingForTesting
2228 // argument needs to be passed in on the command line.
2229
2230 #if ENABLE(MASM_PROBE)
2231 static void callWithStackSizeProbeFunction(Probe::State* state)
2232 {
2233     JSGlobalObject* globalObject = bitwise_cast<JSGlobalObject*>(state->arg);
2234     // The bits loaded from state->probeFunction will be tagged like
2235     // a C function. So, we'll need to untag it to extract the bits
2236     // for the JSFunction*.
2237     JSFunction* function = bitwise_cast<JSFunction*>(untagCodePtr<CFunctionPtrTag>(state->probeFunction));
2238     state->initializeStackFunction = nullptr;
2239     state->initializeStackArg = nullptr;
2240
2241     DollarVMAssertScope assertScope;
2242     VM& vm = globalObject->vm();
2243
2244     auto callData = getCallData(vm, function);
2245     MarkedArgumentBuffer args;
2246     call(globalObject, function, callData, jsUndefined(), args);
2247 }
2248 #endif // ENABLE(MASM_PROBE)
2249
2250 SUPPRESS_ASAN
2251 static EncodedJSValue JSC_HOST_CALL functionCallWithStackSize(JSGlobalObject* globalObject, CallFrame* callFrame)
2252 {
2253     DollarVMAssertScope assertScope;
2254     VM& vm = globalObject->vm();
2255     JSLockHolder lock(vm);
2256     auto throwScope = DECLARE_THROW_SCOPE(vm);
2257
2258 #if OS(DARWIN) && CPU(X86_64)
2259     constexpr bool isSupportedByPlatform = true;
2260 #else
2261     constexpr bool isSupportedByPlatform = false;
2262 #endif
2263
2264     if (!isSupportedByPlatform)
2265         return throwVMError(globalObject, throwScope, "Not supported for this platform");
2266
2267 #if ENABLE(MASM_PROBE)
2268     if (g_jscConfig.isPermanentlyFrozen() || !g_jscConfig.disabledFreezingForTesting)
2269         return throwVMError(globalObject, throwScope, "Options are frozen");
2270
2271     if (callFrame->argumentCount() < 2)
2272         return throwVMError(globalObject, throwScope, "Invalid number of arguments");
2273     JSValue arg0 = callFrame->argument(0);
2274     JSValue arg1 = callFrame->argument(1);
2275     if (!arg0.isCallable(vm))
2276         return throwVMError(globalObject, throwScope, "arg0 should be a function");
2277     if (!arg1.isNumber())
2278         return throwVMError(globalObject, throwScope, "arg1 should be a number");
2279
2280     JSFunction* function = jsCast<JSFunction*>(arg0);
2281     size_t desiredStackSize = arg1.asNumber();
2282
2283     const StackBounds& bounds = Thread::current().stack();
2284     uint8_t* currentStackPosition = bitwise_cast<uint8_t*>(currentStackPointer());
2285     uint8_t* end = bitwise_cast<uint8_t*>(bounds.end());
2286     uint8_t* desiredStart = end + desiredStackSize;
2287     if (desiredStart >= currentStackPosition)
2288         return throwVMError(globalObject, throwScope, "Unable to setup desired stack size");
2289
2290     JSDollarVMHelper helper(vm);
2291
2292     unsigned originalMaxPerThreadStackUsage = Options::maxPerThreadStackUsage();
2293     void* originalVMSoftStackLimit = vm.softStackLimit();
2294     void* originalVMStackLimit = vm.stackLimit();
2295
2296     // This is a hack to make the VM think it's stack limits are near the end
2297     // of the physical stack.
2298     uint8_t* vmStackStart = bitwise_cast<uint8_t*>(vm.stackPointerAtVMEntry());
2299     uint8_t* vmStackEnd = vmStackStart - originalMaxPerThreadStackUsage;
2300     ptrdiff_t sizeDiff = vmStackEnd - end;
2301     RELEASE_ASSERT(sizeDiff >= 0);
2302     RELEASE_ASSERT(static_cast<uint64_t>(sizeDiff) < UINT_MAX);
2303
2304     Options::maxPerThreadStackUsage() = originalMaxPerThreadStackUsage + sizeDiff;
2305     helper.updateVMStackLimits();
2306
2307 #if OS(DARWIN) && CPU(X86_64)
2308     __asm__ volatile (
2309         "subq %[sizeDiff], %%rsp" "\n"
2310         "pushq %%rax" "\n"
2311         "pushq %%rcx" "\n"
2312         "pushq %%rdx" "\n"
2313         "pushq %%rbx" "\n"
2314         "callq *%%rax" "\n"
2315         "addq %[sizeDiff], %%rsp" "\n"
2316         :
2317         : "a" (ctiMasmProbeTrampoline)
2318         , "c" (callWithStackSizeProbeFunction)
2319         , "d" (function)
2320         , "b" (globalObject)
2321         , [sizeDiff] "rm" (sizeDiff)
2322         : "memory"
2323     );
2324 #else
2325     UNUSED_PARAM(function);
2326 #if !COMPILER(MSVC)
2327     UNUSED_PARAM(callWithStackSizeProbeFunction);
2328 #endif
2329 #endif // OS(DARWIN) && CPU(X86_64)
2330
2331     Options::maxPerThreadStackUsage() = originalMaxPerThreadStackUsage;
2332     helper.updateVMStackLimits();
2333     RELEASE_ASSERT(vm.softStackLimit() == originalVMSoftStackLimit);
2334     RELEASE_ASSERT(vm.stackLimit() == originalVMStackLimit);
2335
2336     throwScope.release();
2337     return encodedJSUndefined();
2338
2339 #else // not ENABLE(MASM_PROBE)
2340     UNUSED_PARAM(callFrame);
2341     return throwVMError(globalObject, throwScope, "Not supported for this platform");
2342 #endif // ENABLE(MASM_PROBE)
2343 }
2344
2345 // Creates a new global object.
2346 // Usage: $vm.createGlobalObject()
2347 static EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(JSGlobalObject* globalObject, CallFrame*)
2348 {
2349     DollarVMAssertScope assertScope;
2350     VM& vm = globalObject->vm();
2351     JSLockHolder lock(vm);
2352     return JSValue::encode(JSGlobalObject::create(vm, JSGlobalObject::createStructure(vm, jsNull())));
2353 }
2354
2355 static EncodedJSValue JSC_HOST_CALL functionCreateProxy(JSGlobalObject* globalObject, CallFrame* callFrame)
2356 {
2357     DollarVMAssertScope assertScope;
2358     VM& vm = globalObject->vm();
2359     JSLockHolder lock(vm);
2360     JSValue target = callFrame->argument(0);
2361     if (!target.isObject())
2362         return JSValue::encode(jsUndefined());
2363     JSObject* jsTarget = asObject(target.asCell());
2364     Structure* structure = JSProxy::createStructure(vm, globalObject, jsTarget->getPrototypeDirect(vm), ImpureProxyType);
2365     JSProxy* proxy = JSProxy::create(vm, structure, jsTarget);
2366     return JSValue::encode(proxy);
2367 }
2368
2369 static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(JSGlobalObject* globalObject, CallFrame* callFrame)
2370 {
2371     DollarVMAssertScope assertScope;
2372     JSLockHolder lock(globalObject);
2373     RuntimeArray* array = RuntimeArray::create(globalObject, callFrame);
2374     return JSValue::encode(array);
2375 }
2376
2377 static EncodedJSValue JSC_HOST_CALL functionCreateNullRopeString(JSGlobalObject* globalObject, CallFrame*)
2378 {
2379     DollarVMAssertScope assertScope;
2380     VM& vm = globalObject->vm();
2381     JSLockHolder lock(vm);
2382     return JSValue::encode(JSRopeString::createNullForTesting(vm));
2383 }
2384
2385 static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(JSGlobalObject* globalObject, CallFrame* callFrame)
2386 {
2387     DollarVMAssertScope assertScope;
2388     VM& vm = globalObject->vm();
2389     JSLockHolder lock(vm);
2390     JSValue target = callFrame->argument(0);
2391     JSObject* delegate = nullptr;
2392     if (target.isObject())
2393         delegate = asObject(target.asCell());
2394     Structure* structure = ImpureGetter::createStructure(vm, globalObject, jsNull());
2395     ImpureGetter* result = ImpureGetter::create(vm, structure, delegate);
2396     return JSValue::encode(result);
2397 }
2398
2399 static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(JSGlobalObject* globalObject, CallFrame*)
2400 {
2401     DollarVMAssertScope assertScope;
2402     VM& vm = globalObject->vm();
2403     JSLockHolder lock(vm);
2404     Structure* structure = CustomGetter::createStructure(vm, globalObject, jsNull());
2405     CustomGetter* result = CustomGetter::create(vm, structure);
2406     return JSValue::encode(result);
2407 }
2408
2409 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(JSGlobalObject* globalObject, CallFrame*)
2410 {
2411     DollarVMAssertScope assertScope;
2412     VM& vm = globalObject->vm();
2413     JSLockHolder lock(vm);
2414     Structure* structure = DOMJITNode::createStructure(vm, globalObject, DOMJITGetter::create(vm, DOMJITGetter::createStructure(vm, globalObject, jsNull())));
2415     DOMJITNode* result = DOMJITNode::create(vm, structure);
2416     return JSValue::encode(result);
2417 }
2418
2419 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(JSGlobalObject* globalObject, CallFrame*)
2420 {
2421     DollarVMAssertScope assertScope;
2422     VM& vm = globalObject->vm();
2423     JSLockHolder lock(vm);
2424     Structure* structure = DOMJITGetter::createStructure(vm, globalObject, jsNull());
2425     DOMJITGetter* result = DOMJITGetter::create(vm, structure);
2426     return JSValue::encode(result);
2427 }
2428
2429 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterNoEffectsObject(JSGlobalObject* globalObject, CallFrame*)
2430 {
2431     DollarVMAssertScope assertScope;
2432     VM& vm = globalObject->vm();
2433     JSLockHolder lock(vm);
2434     Structure* structure = DOMJITGetterNoEffects::createStructure(vm, globalObject, jsNull());
2435     DOMJITGetterNoEffects* result = DOMJITGetterNoEffects::create(vm, structure);
2436     return JSValue::encode(result);
2437 }
2438
2439 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(JSGlobalObject* globalObject, CallFrame*)
2440 {
2441     DollarVMAssertScope assertScope;
2442     VM& vm = globalObject->vm();
2443     JSLockHolder lock(vm);
2444     Structure* structure = DOMJITGetterComplex::createStructure(vm, globalObject, jsNull());
2445     DOMJITGetterComplex* result = DOMJITGetterComplex::create(vm, globalObject, structure);
2446     return JSValue::encode(result);
2447 }
2448
2449 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITFunctionObject(JSGlobalObject* globalObject, CallFrame*)
2450 {
2451     DollarVMAssertScope assertScope;
2452     VM& vm = globalObject->vm();
2453     JSLockHolder lock(vm);
2454     Structure* structure = DOMJITFunctionObject::createStructure(vm, globalObject, jsNull());
2455     DOMJITFunctionObject* result = DOMJITFunctionObject::create(vm, globalObject, structure);
2456     return JSValue::encode(result);
2457 }
2458
2459 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITCheckJSCastObject(JSGlobalObject* globalObject, CallFrame*)
2460 {
2461     DollarVMAssertScope assertScope;
2462     VM& vm = globalObject->vm();
2463     JSLockHolder lock(vm);
2464     Structure* structure = DOMJITCheckJSCastObject::createStructure(vm, globalObject, jsNull());
2465     DOMJITCheckJSCastObject* result = DOMJITCheckJSCastObject::create(vm, globalObject, structure);
2466     return JSValue::encode(result);
2467 }
2468
2469 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterBaseJSObject(JSGlobalObject* globalObject, CallFrame*)
2470 {
2471     DollarVMAssertScope assertScope;
2472     VM& vm = globalObject->vm();
2473     JSLockHolder lock(vm);
2474     Structure* structure = DOMJITGetterBaseJSObject::createStructure(vm, globalObject, jsNull());
2475     DOMJITGetterBaseJSObject* result = DOMJITGetterBaseJSObject::create(vm, structure);
2476     return JSValue::encode(result);
2477 }
2478
2479 #if ENABLE(WEBASSEMBLY)
2480 static EncodedJSValue JSC_HOST_CALL functionCreateWasmStreamingParser(JSGlobalObject* globalObject, CallFrame*)
2481 {
2482     DollarVMAssertScope assertScope;
2483     VM& vm = globalObject->vm();
2484     JSLockHolder lock(vm);
2485     return JSValue::encode(WasmStreamingParser::create(vm, globalObject));
2486 }
2487 #endif
2488
2489 static EncodedJSValue JSC_HOST_CALL functionCreateStaticCustomAccessor(JSGlobalObject* globalObject, CallFrame*)
2490 {
2491     DollarVMAssertScope assertScope;
2492     VM& vm = globalObject->vm();
2493     JSLockHolder lock(vm);
2494     Structure* structure = StaticCustomAccessor::createStructure(vm, globalObject, jsNull());
2495     auto* result = StaticCustomAccessor::create(vm, structure);
2496     return JSValue::encode(result);
2497 }
2498
2499 static EncodedJSValue JSC_HOST_CALL functionCreateObjectDoingSideEffectPutWithoutCorrectSlotStatus(JSGlobalObject* globalObject, CallFrame* callFrame)
2500 {
2501     DollarVMAssertScope assertScope;
2502     VM& vm = globalObject->vm();
2503     JSLockHolder lock(vm);
2504
2505     auto* dollarVM = jsDynamicCast<JSDollarVM*>(vm, callFrame->thisValue());
2506     RELEASE_ASSERT(dollarVM);
2507     auto* result = ObjectDoingSideEffectPutWithoutCorrectSlotStatus::create(vm, dollarVM->objectDoingSideEffectPutWithoutCorrectSlotStatusStructure());
2508     return JSValue::encode(result);
2509 }
2510
2511 static EncodedJSValue JSC_HOST_CALL functionCreateEmptyFunctionWithName(JSGlobalObject* globalObject, CallFrame* callFrame)
2512 {
2513     DollarVMAssertScope assertScope;
2514     VM& vm = globalObject->vm();
2515     JSLockHolder lock(vm);
2516     auto scope = DECLARE_THROW_SCOPE(vm);
2517
2518     const String name = callFrame->argument(0).toWTFString(globalObject);
2519     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2520
2521     RELEASE_AND_RETURN(scope, JSValue::encode(JSFunction::create(vm, globalObject, 1, name, functionCreateEmptyFunctionWithName)));
2522 }
2523
2524 static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(JSGlobalObject* globalObject, CallFrame* callFrame)
2525 {
2526     DollarVMAssertScope assertScope;
2527     VM& vm = globalObject->vm();
2528     JSLockHolder lock(vm);
2529     auto scope = DECLARE_THROW_SCOPE(vm);
2530
2531     JSValue base = callFrame->argument(0);
2532     if (!base.isObject())
2533         return JSValue::encode(jsUndefined());
2534     JSValue delegate = callFrame->argument(1);
2535     if (!delegate.isObject())
2536         return JSValue::encode(jsUndefined());
2537     ImpureGetter* impureGetter = jsDynamicCast<ImpureGetter*>(vm, asObject(base.asCell()));
2538     if (UNLIKELY(!impureGetter)) {
2539         throwTypeError(globalObject, scope, "argument is not an ImpureGetter"_s);
2540         return encodedJSValue();
2541     }
2542     impureGetter->setDelegate(vm, asObject(delegate.asCell()));
2543     return JSValue::encode(jsUndefined());
2544 }
2545
2546 static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(JSGlobalObject* globalObject, CallFrame* callFrame)
2547 {
2548     DollarVMAssertScope assertScope;
2549     VM& vm = globalObject->vm();
2550     auto scope = DECLARE_THROW_SCOPE(vm);
2551
2552     if (callFrame->argumentCount() < 1 || !callFrame->argument(0).isString())
2553         return JSValue::encode(jsUndefined());
2554
2555     String functionText = asString(callFrame->argument(0))->value(globalObject);
2556     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2557
2558     SourceCode source = makeSource(functionText, { });
2559     JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, nullptr, source), globalObject);
2560
2561     return JSValue::encode(func);
2562 }
2563
2564 static EncodedJSValue JSC_HOST_CALL functionGetPrivateProperty(JSGlobalObject* globalObject, CallFrame* callFrame)
2565 {
2566     DollarVMAssertScope assertScope;
2567     VM& vm = globalObject->vm();
2568     auto scope = DECLARE_THROW_SCOPE(vm);
2569
2570     if (callFrame->argumentCount() < 2 || !callFrame->argument(1).isString())
2571         return encodedJSUndefined();
2572
2573     String str = asString(callFrame->argument(1))->value(globalObject);
2574     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2575
2576     SymbolImpl* symbol = vm.propertyNames->builtinNames().lookUpPrivateName(str);
2577     if (!symbol)
2578         return throwVMError(globalObject, scope, "Unknown private name.");
2579
2580     RELEASE_AND_RETURN(scope, JSValue::encode(callFrame->argument(0).get(globalObject, symbol)));
2581 }
2582
2583 static EncodedJSValue JSC_HOST_CALL functionCreateRoot(JSGlobalObject* globalObject, CallFrame*)
2584 {
2585     DollarVMAssertScope assertScope;
2586     VM& vm = globalObject->vm();
2587     JSLockHolder lock(vm);
2588     return JSValue::encode(Root::create(vm, globalObject));
2589 }
2590
2591 static EncodedJSValue JSC_HOST_CALL functionCreateElement(JSGlobalObject* globalObject, CallFrame* callFrame)
2592 {
2593     DollarVMAssertScope assertScope;
2594     VM& vm = globalObject->vm();
2595     JSLockHolder lock(vm);
2596     auto scope = DECLARE_THROW_SCOPE(vm);
2597
2598     Root* root = jsDynamicCast<Root*>(vm, callFrame->argument(0));
2599     if (!root)
2600         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Cannot create Element without a Root."_s)));
2601     return JSValue::encode(Element::create(vm, globalObject, root));
2602 }
2603
2604 static EncodedJSValue JSC_HOST_CALL functionGetElement(JSGlobalObject* globalObject, CallFrame* callFrame)
2605 {
2606     DollarVMAssertScope assertScope;
2607     VM& vm = globalObject->vm();
2608     JSLockHolder lock(vm);
2609     Root* root = jsDynamicCast<Root*>(vm, callFrame->argument(0));
2610     if (!root)
2611         return JSValue::encode(jsUndefined());
2612     Element* result = root->element();
2613     return JSValue::encode(result ? result : jsUndefined());
2614 }
2615
2616 static EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(JSGlobalObject* globalObject, CallFrame*)
2617 {
2618     DollarVMAssertScope assertScope;
2619     VM& vm = globalObject->vm();
2620     JSLockHolder lock(vm);
2621     return JSValue::encode(SimpleObject::create(vm, globalObject));
2622 }
2623
2624 static EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(JSGlobalObject* globalObject, CallFrame* callFrame)
2625 {
2626     DollarVMAssertScope assertScope;
2627     VM& vm = globalObject->vm();
2628     JSLockHolder lock(vm);
2629     auto scope = DECLARE_THROW_SCOPE(vm);
2630
2631     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, callFrame->argument(0));
2632     if (UNLIKELY(!simpleObject)) {
2633         throwTypeError(globalObject, scope, "Invalid use of getHiddenValue test function"_s);
2634         return encodedJSValue();
2635     }
2636     return JSValue::encode(simpleObject->hiddenValue());
2637 }
2638
2639 static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(JSGlobalObject* globalObject, CallFrame* callFrame)
2640 {
2641     DollarVMAssertScope assertScope;
2642     VM& vm = globalObject->vm();
2643     JSLockHolder lock(vm);
2644     auto scope = DECLARE_THROW_SCOPE(vm);
2645
2646     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, callFrame->argument(0));
2647     if (UNLIKELY(!simpleObject)) {
2648         throwTypeError(globalObject, scope, "Invalid use of setHiddenValue test function"_s);
2649         return encodedJSValue();
2650     }
2651     JSValue value = callFrame->argument(1);
2652     simpleObject->setHiddenValue(vm, value);
2653     return JSValue::encode(jsUndefined());
2654 }
2655
2656 static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(JSGlobalObject* globalObject, CallFrame* callFrame)
2657 {
2658     DollarVMAssertScope assertScope;
2659     VM& vm = globalObject->vm();
2660     auto scope = DECLARE_THROW_SCOPE(vm);
2661     if (auto* shadowChicken = vm.shadowChicken()) {
2662         scope.release();
2663         return JSValue::encode(shadowChicken->functionsOnStack(globalObject, callFrame));
2664     }
2665
2666     JSArray* result = constructEmptyArray(globalObject, nullptr);
2667     RETURN_IF_EXCEPTION(scope, { });
2668     StackVisitor::visit(callFrame, vm, [&] (StackVisitor& visitor) -> StackVisitor::Status {
2669         DollarVMAssertScope assertScope;
2670         if (visitor->isInlinedFrame())
2671             return StackVisitor::Continue;
2672         if (visitor->isWasmFrame())
2673             return StackVisitor::Continue;
2674         result->push(globalObject, jsCast<JSObject*>(visitor->callee().asCell()));
2675         scope.releaseAssertNoException(); // This function is only called from tests.
2676         return StackVisitor::Continue;
2677     });
2678     RETURN_IF_EXCEPTION(scope, { });
2679     return JSValue::encode(result);
2680 }
2681
2682 static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(JSGlobalObject* globalObject, CallFrame*)
2683 {
2684     DollarVMAssertScope assertScope;
2685     VM& vm = globalObject->vm();
2686     vm.setGlobalConstRedeclarationShouldThrow(false);
2687     return JSValue::encode(jsUndefined());
2688 }
2689
2690 static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(JSGlobalObject* globalObject, CallFrame* callFrame)
2691 {
2692     DollarVMAssertScope assertScope;
2693     VM& vm = globalObject->vm();
2694     RELEASE_ASSERT(vm.typeProfiler());
2695     vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionFindTypeForExpression"_s);
2696
2697     JSValue functionValue = callFrame->argument(0);
2698     RELEASE_ASSERT(functionValue.isCallable(vm));
2699     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2700
2701     RELEASE_ASSERT(callFrame->argument(1).isString());
2702     String substring = asString(callFrame->argument(1))->value(globalObject);
2703     String sourceCodeText = executable->source().view().toString();
2704     unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
2705     
2706     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), vm);
2707     return JSValue::encode(JSONParse(globalObject, jsonString));
2708 }
2709
2710 static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(JSGlobalObject* globalObject, CallFrame* callFrame)
2711 {
2712     DollarVMAssertScope assertScope;
2713     VM& vm = globalObject->vm();
2714     RELEASE_ASSERT(vm.typeProfiler());
2715     vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionReturnTypeFor"_s);
2716
2717     JSValue functionValue = callFrame->argument(0);
2718     RELEASE_ASSERT(functionValue.isCallable(vm));
2719     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2720
2721     unsigned offset = executable->typeProfilingStartOffset(vm);
2722     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), vm);
2723     return JSValue::encode(JSONParse(globalObject, jsonString));
2724 }
2725
2726 static EncodedJSValue JSC_HOST_CALL functionFlattenDictionaryObject(JSGlobalObject* globalObject, CallFrame* callFrame)
2727 {
2728     DollarVMAssertScope assertScope;
2729     VM& vm = globalObject->vm();
2730     JSValue value = callFrame->argument(0);
2731     RELEASE_ASSERT(value.isObject() && value.getObject()->structure()->isDictionary());
2732     value.getObject()->flattenDictionaryObject(vm);
2733     return encodedJSUndefined();
2734 }
2735
2736 static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(JSGlobalObject* globalObject, CallFrame*)
2737 {
2738     DollarVMAssertScope assertScope;
2739     VM& vm = globalObject->vm();
2740     RELEASE_ASSERT(vm.controlFlowProfiler());
2741     vm.controlFlowProfiler()->dumpData();
2742     return JSValue::encode(jsUndefined());
2743 }
2744
2745 static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(JSGlobalObject* globalObject, CallFrame* callFrame)
2746 {
2747     DollarVMAssertScope assertScope;
2748     VM& vm = globalObject->vm();
2749     RELEASE_ASSERT(vm.controlFlowProfiler());
2750
2751     JSValue functionValue = callFrame->argument(0);
2752     RELEASE_ASSERT(functionValue.isCallable(vm));
2753     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2754
2755     RELEASE_ASSERT(callFrame->argument(1).isString());
2756     String substring = asString(callFrame->argument(1))->value(globalObject);
2757     String sourceCodeText = executable->source().view().toString();
2758     RELEASE_ASSERT(sourceCodeText.contains(substring));
2759     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2760     
2761     bool hasExecuted = vm.controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset, executable->sourceID(), vm);
2762     return JSValue::encode(jsBoolean(hasExecuted));
2763 }
2764
2765 static EncodedJSValue JSC_HOST_CALL functionBasicBlockExecutionCount(JSGlobalObject* globalObject, CallFrame* callFrame)
2766 {
2767     DollarVMAssertScope assertScope;
2768     VM& vm = globalObject->vm();
2769     RELEASE_ASSERT(vm.controlFlowProfiler());
2770
2771     JSValue functionValue = callFrame->argument(0);
2772     RELEASE_ASSERT(functionValue.isCallable(vm));
2773     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2774
2775     RELEASE_ASSERT(callFrame->argument(1).isString());
2776     String substring = asString(callFrame->argument(1))->value(globalObject);
2777     String sourceCodeText = executable->source().view().toString();
2778     RELEASE_ASSERT(sourceCodeText.contains(substring));
2779     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2780     
2781     size_t executionCount = vm.controlFlowProfiler()->basicBlockExecutionCountAtTextOffset(offset, executable->sourceID(), vm);
2782     return JSValue::encode(JSValue(executionCount));
2783 }
2784
2785 class DoNothingDebugger final : public Debugger {
2786     WTF_MAKE_NONCOPYABLE(DoNothingDebugger);
2787     WTF_MAKE_FAST_ALLOCATED;
2788 public:
2789     DoNothingDebugger(VM& vm)
2790         : Debugger(vm)
2791     {
2792         DollarVMAssertScope assertScope;
2793         setSuppressAllPauses(true);
2794     }
2795
2796 private:
2797     void sourceParsed(JSGlobalObject*, SourceProvider*, int, const WTF::String&) final
2798     {
2799         DollarVMAssertScope assertScope;
2800     }
2801 };
2802
2803 static EncodedJSValue changeDebuggerModeWhenIdle(JSGlobalObject* globalObject, OptionSet<CodeGenerationMode> codeGenerationMode)
2804 {
2805     DollarVMAssertScope assertScope;
2806
2807     bool debuggerRequested = codeGenerationMode.contains(CodeGenerationMode::Debugger);
2808     if (debuggerRequested == globalObject->hasDebugger())
2809         return JSValue::encode(jsUndefined());
2810
2811     VM* vm = &globalObject->vm();
2812     vm->whenIdle([=] () {
2813         DollarVMAssertScope assertScope;
2814         if (debuggerRequested) {
2815             Debugger* debugger = new DoNothingDebugger(globalObject->vm());
2816             globalObject->setDebugger(debugger);
2817             debugger->activateBreakpoints(); // Also deletes all code.
2818         } else {
2819             Debugger* debugger = globalObject->debugger();
2820             debugger->deactivateBreakpoints(); // Also deletes all code.
2821             globalObject->setDebugger(nullptr);
2822             delete debugger;
2823         }
2824     });
2825     return JSValue::encode(jsUndefined());
2826 }
2827
2828 static EncodedJSValue JSC_HOST_CALL functionEnableDebuggerModeWhenIdle(JSGlobalObject* globalObject, CallFrame*)
2829 {
2830     DollarVMAssertScope assertScope;
2831     return changeDebuggerModeWhenIdle(globalObject, { CodeGenerationMode::Debugger });
2832 }
2833
2834 static EncodedJSValue JSC_HOST_CALL functionDisableDebuggerModeWhenIdle(JSGlobalObject* globalObject, CallFrame*)
2835 {
2836     DollarVMAssertScope assertScope;
2837     return changeDebuggerModeWhenIdle(globalObject, { });
2838 }
2839
2840 static EncodedJSValue JSC_HOST_CALL functionDeleteAllCodeWhenIdle(JSGlobalObject* globalObject, CallFrame*)
2841 {
2842     DollarVMAssertScope assertScope;
2843     VM* vm = &globalObject->vm();
2844     vm->whenIdle([=] () {
2845         DollarVMAssertScope assertScope;
2846         vm->deleteAllCode(PreventCollectionAndDeleteAllCode);
2847     });
2848     return JSValue::encode(jsUndefined());
2849 }
2850
2851 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectCount(JSGlobalObject* globalObject, CallFrame*)
2852 {
2853     DollarVMAssertScope assertScope;
2854     return JSValue::encode(jsNumber(globalObject->vm().heap.globalObjectCount()));
2855 }
2856
2857 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(JSGlobalObject* globalObject, CallFrame* callFrame)
2858 {
2859     DollarVMAssertScope assertScope;
2860     JSValue value = callFrame->argument(0);
2861     RELEASE_ASSERT(value.isObject());
2862     JSGlobalObject* result = jsCast<JSObject*>(value)->globalObject(globalObject->vm());
2863     RELEASE_ASSERT(result);
2864     return JSValue::encode(result);
2865 }
2866
2867 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(JSGlobalObject* globalObject, CallFrame* callFrame)
2868 {
2869     DollarVMAssertScope assertScope;
2870     VM& vm = globalObject->vm();
2871     auto scope = DECLARE_THROW_SCOPE(vm);
2872
2873     JSValue value = callFrame->argument(0);
2874     if (!value.isObject())
2875         return JSValue::encode(jsUndefined());
2876
2877     JSValue property = callFrame->argument(1);
2878     if (!property.isString())
2879         return JSValue::encode(jsUndefined());
2880
2881     auto propertyName = asString(property)->toIdentifier(globalObject);
2882     RETURN_IF_EXCEPTION(scope, { });
2883
2884     PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry);
2885     value.getPropertySlot(globalObject, propertyName, slot);
2886     RETURN_IF_EXCEPTION(scope, { });
2887
2888     JSValue result;
2889     if (slot.isCacheableGetter())
2890         result = slot.getterSetter();
2891     else
2892         result = jsNull();
2893
2894     return JSValue::encode(result);
2895 }
2896
2897 static EncodedJSValue JSC_HOST_CALL functionLoadGetterFromGetterSetter(JSGlobalObject* globalObject, CallFrame* callFrame)
2898 {
2899     DollarVMAssertScope assertScope;
2900     VM& vm = globalObject->vm();
2901     auto scope = DECLARE_THROW_SCOPE(vm);
2902
2903     GetterSetter* getterSetter = jsDynamicCast<GetterSetter*>(vm, callFrame->argument(0));
2904     if (UNLIKELY(!getterSetter)) {
2905         throwTypeError(globalObject, scope, "Invalid use of loadGetterFromGetterSetter test function: argument is not a GetterSetter"_s);
2906         return encodedJSValue();
2907     }
2908
2909     JSObject* getter = getterSetter->getter();
2910     RELEASE_ASSERT(getter);
2911     return JSValue::encode(getter);
2912 }
2913
2914 static EncodedJSValue JSC_HOST_CALL functionCreateCustomTestGetterSetter(JSGlobalObject* globalObject, CallFrame*)
2915 {
2916     DollarVMAssertScope assertScope;
2917     VM& vm = globalObject->vm();
2918     return JSValue::encode(JSTestCustomGetterSetter::create(vm, globalObject, JSTestCustomGetterSetter::createStructure(vm, globalObject)));
2919 }
2920
2921 static EncodedJSValue JSC_HOST_CALL functionDeltaBetweenButterflies(JSGlobalObject* globalObject, CallFrame* callFrame)
2922 {
2923     DollarVMAssertScope assertScope;
2924     VM& vm = globalObject->vm();
2925     JSObject* a = jsDynamicCast<JSObject*>(vm, callFrame->argument(0));
2926     JSObject* b = jsDynamicCast<JSObject*>(vm, callFrame->argument(1));
2927     if (!a || !b)
2928         return JSValue::encode(jsNumber(PNaN));
2929
2930     ptrdiff_t delta = bitwise_cast<char*>(a->butterfly()) - bitwise_cast<char*>(b->butterfly());
2931     if (delta < 0)
2932         return JSValue::encode(jsNumber(PNaN));
2933     if (delta > std::numeric_limits<int32_t>::max())
2934         return JSValue::encode(jsNumber(PNaN));
2935     return JSValue::encode(jsNumber(static_cast<int32_t>(delta)));
2936 }
2937
2938 static EncodedJSValue JSC_HOST_CALL functionCurrentCPUTime(JSGlobalObject*, CallFrame*)
2939 {
2940     DollarVMAssertScope assertScope;
2941     return JSValue::encode(jsNumber(CPUTime::forCurrentThread().value()));
2942 }
2943
2944 static EncodedJSValue JSC_HOST_CALL functionTotalGCTime(JSGlobalObject* globalObject, CallFrame*)
2945 {
2946     DollarVMAssertScope assertScope;
2947     VM& vm = globalObject->vm();
2948     return JSValue::encode(jsNumber(vm.heap.totalGCTime().seconds()));
2949 }
2950
2951 static EncodedJSValue JSC_HOST_CALL functionParseCount(JSGlobalObject*, CallFrame*)
2952 {
2953     DollarVMAssertScope assertScope;
2954     return JSValue::encode(jsNumber(globalParseCount.load()));
2955 }
2956
2957 static EncodedJSValue JSC_HOST_CALL functionIsWasmSupported(JSGlobalObject*, CallFrame*)
2958 {
2959     DollarVMAssertScope assertScope;
2960 #if ENABLE(WEBASSEMBLY)
2961     return JSValue::encode(jsBoolean(Wasm::isSupported()));
2962 #else
2963     return JSValue::encode(jsBoolean(false));
2964 #endif
2965 }
2966
2967 static EncodedJSValue JSC_HOST_CALL functionMake16BitStringIfPossible(JSGlobalObject* globalObject, CallFrame* callFrame)
2968 {
2969     DollarVMAssertScope assertScope;
2970     VM& vm = globalObject->vm();
2971     auto scope = DECLARE_THROW_SCOPE(vm);
2972     String string = callFrame->argument(0).toWTFString(globalObject);
2973     RETURN_IF_EXCEPTION(scope, { });
2974     if (!string.is8Bit())
2975         return JSValue::encode(jsString(vm, WTFMove(string)));
2976     Vector<UChar> buffer;
2977     buffer.resize(string.length());
2978     StringImpl::copyCharacters(buffer.data(), string.characters8(), string.length());
2979     return JSValue::encode(jsString(vm, String::adopt(WTFMove(buffer))));
2980 }
2981
2982 EncodedJSValue JSC_HOST_CALL JSDollarVMHelper::functionGetStructureTransitionList(JSGlobalObject* globalObject, CallFrame* callFrame)
2983 {
2984     DollarVMAssertScope assertScope;
2985     VM& vm = globalObject->vm();
2986     auto scope = DECLARE_THROW_SCOPE(vm);
2987     JSObject* obj = callFrame->argument(0).toObject(globalObject);
2988     RETURN_IF_EXCEPTION(scope, { });
2989     if (!obj)
2990         return JSValue::encode(jsNull());
2991     Vector<Structure*, 8> structures;
2992
2993     for (auto* structure = obj->structure(); structure; structure = structure->previousID())
2994         structures.append(structure);
2995
2996     JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0);
2997     RETURN_IF_EXCEPTION(scope, { });
2998
2999     for (size_t i = 0; i < structures.size(); ++i) {
3000         auto* structure = structures[structures.size() - i - 1];
3001         result->push(globalObject, JSValue(structure->id()));
3002         RETURN_IF_EXCEPTION(scope, { });
3003         result->push(globalObject, JSValue(structure->transitionOffset()));
3004         RETURN_IF_EXCEPTION(scope, { });
3005         result->push(globalObject, JSValue(structure->maxOffset()));
3006         RETURN_IF_EXCEPTION(scope, { });
3007         if (structure->m_transitionPropertyName)
3008             result->push(globalObject, jsString(vm, String(*structure->m_transitionPropertyName)));
3009         else
3010             result->push(globalObject, jsNull());
3011         RETURN_IF_EXCEPTION(scope, { });
3012         result->push(globalObject, JSValue(structure->isPropertyDeletionTransition()));
3013         RETURN_IF_EXCEPTION(scope, { });
3014     }
3015
3016     return JSValue::encode(result);
3017 }
3018
3019 static EncodedJSValue JSC_HOST_CALL functionGetConcurrently(JSGlobalObject* globalObject, CallFrame* callFrame)
3020 {
3021     DollarVMAssertScope assertScope;
3022     VM& vm = globalObject->vm();
3023     auto scope = DECLARE_THROW_SCOPE(vm);
3024     JSObject* obj = callFrame->argument(0).toObject(globalObject);
3025     RETURN_IF_EXCEPTION(scope, { });
3026     if (!obj)
3027         return JSValue::encode(jsNull());
3028     String property = callFrame->argument(1).toWTFString(globalObject);
3029     RETURN_IF_EXCEPTION(scope, { });
3030     auto name = PropertyName(Identifier::fromString(vm, property));
3031     auto offset = obj->structure()->getConcurrently(name.uid());
3032     if (offset != invalidOffset)
3033         ASSERT(JSValue::encode(obj->getDirect(offset)));
3034     JSValue result = JSValue(offset != invalidOffset);
3035     RETURN_IF_EXCEPTION(scope, { });
3036     return JSValue::encode(result);
3037 }
3038
3039 static EncodedJSValue JSC_HOST_CALL functionHasOwnLengthProperty(JSGlobalObject* globalObject, CallFrame* callFrame)
3040 {
3041     VM& vm = globalObject->vm();
3042
3043     JSObject* target = asObject(callFrame->uncheckedArgument(0));
3044     JSFunction* function = jsDynamicCast<JSFunction*>(vm, target);
3045     return JSValue::encode(jsBoolean(function->canAssumeNameAndLengthAreOriginal(vm)));
3046 }
3047
3048 static EncodedJSValue JSC_HOST_CALL functionRejectPromiseAsHandled(JSGlobalObject* globalObject, CallFrame* callFrame)
3049 {
3050     JSPromise* promise = jsCast<JSPromise*>(callFrame->uncheckedArgument(0));
3051     JSValue reason = callFrame->uncheckedArgument(1);
3052     promise->rejectAsHandled(globalObject, reason);
3053     return JSValue::encode(jsUndefined());
3054 }
3055
3056 static EncodedJSValue JSC_HOST_CALL functionSetUserPreferredLanguages(JSGlobalObject* globalObject, CallFrame* callFrame)
3057 {
3058     VM& vm = globalObject->vm();
3059     auto scope = DECLARE_THROW_SCOPE(vm);
3060
3061     JSArray* array = jsDynamicCast<JSArray*>(vm, callFrame->argument(0));
3062     if (!array)
3063         return throwVMTypeError(globalObject, scope, "Expected first argument to be an array"_s);
3064
3065     Vector<String> languages;
3066     unsigned length = array->length();
3067     for (unsigned i = 0; i < length; i++) {
3068         String language = array->get(globalObject, i).toWTFString(globalObject);
3069         RETURN_IF_EXCEPTION(scope, encodedJSValue());
3070         languages.append(language);
3071     }
3072
3073     overrideUserPreferredLanguages(languages);
3074     return JSValue::encode(jsUndefined());
3075 }
3076
3077 static EncodedJSValue JSC_HOST_CALL functionICUVersion(JSGlobalObject*, CallFrame*)
3078 {
3079     UVersionInfo versionInfo;
3080     u_getVersion(versionInfo);
3081     return JSValue::encode(jsNumber(versionInfo[0]));
3082 }
3083
3084 static EncodedJSValue JSC_HOST_CALL functionAssertEnabled(JSGlobalObject*, CallFrame*)
3085 {
3086     return JSValue::encode(jsBoolean(ASSERT_ENABLED));
3087 }
3088
3089 static EncodedJSValue JSC_HOST_CALL functionIsMemoryLimited(JSGlobalObject*, CallFrame*)
3090 {
3091 #if PLATFORM(IOS) || PLATFORM(APPLETV) || PLATFORM(WATCHOS)
3092     return JSValue::encode(jsBoolean(true));
3093 #else
3094     return JSValue::encode(jsBoolean(false));
3095 #endif
3096 }
3097
3098 static EncodedJSValue JSC_HOST_CALL functionUseJIT(JSGlobalObject*, CallFrame*)
3099 {
3100     return JSValue::encode(jsBoolean(Options::useJIT()));
3101 }
3102
3103 constexpr unsigned jsDollarVMPropertyAttributes = PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete;
3104
3105 void JSDollarVM::finishCreation(VM& vm)
3106 {
3107     DollarVMAssertScope assertScope;
3108     Base::finishCreation(vm);
3109
3110     JSGlobalObject* globalObject = this->globalObject(vm);
3111
3112     auto addFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
3113         DollarVMAssertScope assertScope;
3114         JSDollarVM::addFunction(vm, globalObject, name, function, arguments);
3115     };
3116     auto addConstructibleFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
3117         DollarVMAssertScope assertScope;
3118         JSDollarVM::addConstructibleFunction(vm, globalObject, name, function, arguments);
3119     };
3120
3121     addFunction(vm, "abort", functionCrash, 0);
3122     addFunction(vm, "crash", functionCrash, 0);
3123     addFunction(vm, "breakpoint", functionBreakpoint, 0);
3124
3125     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "dfgTrue"), 0, functionDFGTrue, DFGTrueIntrinsic, jsDollarVMPropertyAttributes);
3126     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "ftlTrue"), 0, functionFTLTrue, FTLTrueIntrinsic, jsDollarVMPropertyAttributes);
3127
3128     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuMfence"), 0, functionCpuMfence, CPUMfenceIntrinsic, jsDollarVMPropertyAttributes);
3129     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuRdtsc"), 0, functionCpuRdtsc, CPURdtscIntrinsic, jsDollarVMPropertyAttributes);
3130     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuCpuid"), 0, functionCpuCpuid, CPUCpuidIntrinsic, jsDollarVMPropertyAttributes);
3131     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuPause"), 0, functionCpuPause, CPUPauseIntrinsic, jsDollarVMPropertyAttributes);
3132     addFunction(vm, "cpuClflush", functionCpuClflush, 2);
3133
3134     addFunction(vm, "llintTrue", functionLLintTrue, 0);
3135     addFunction(vm, "baselineJITTrue", functionBaselineJITTrue, 0);
3136
3137     addFunction(vm, "noInline", functionNoInline, 1);
3138
3139     addFunction(vm, "gc", functionGC, 0);
3140     addFunction(vm, "gcSweepAsynchronously", functionGCSweepAsynchronously, 0);
3141     addFunction(vm, "edenGC", functionEdenGC, 0);
3142     addFunction(vm, "dumpSubspaceHashes", functionDumpSubspaceHashes, 0);
3143
3144     addFunction(vm, "callFrame", functionCallFrame, 1);
3145     addFunction(vm, "codeBlockFor", functionCodeBlockFor, 1);
3146     addFunction(vm, "codeBlockForFrame", functionCodeBlockForFrame, 1);
3147     addFunction(vm, "dumpSourceFor", functionDumpSourceFor, 1);
3148     addFunction(vm, "dumpBytecodeFor", functionDumpBytecodeFor, 1);
3149
3150     addFunction(vm, "dataLog", functionDataLog, 1);
3151     addFunction(vm, "print", functionPrint, 1);
3152     addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
3153     addFunction(vm, "dumpStack", functionDumpStack, 0);
3154     addFunction(vm, "dumpRegisters", functionDumpRegisters, 1);
3155
3156     addFunction(vm, "dumpCell", functionDumpCell, 1);
3157
3158     addFunction(vm, "indexingMode", functionIndexingMode, 1);
3159     addFunction(vm, "inlineCapacity", functionInlineCapacity, 1);
3160     addFunction(vm, "value", functionValue, 1);
3161     addFunction(vm, "getpid", functionGetPID, 0);
3162
3163     addFunction(vm, "haveABadTime", functionHaveABadTime, 1);
3164     addFunction(vm, "isHavingABadTime", functionIsHavingABadTime, 1);
3165
3166     addFunction(vm, "callWithStackSize", functionCallWithStackSize, 2);
3167
3168     addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0);
3169     addFunction(vm, "createProxy", functionCreateProxy, 1);
3170     addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);
3171     addFunction(vm, "createNullRopeString", functionCreateNullRopeString, 0);
3172
3173     addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
3174     addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0);
3175     addFunction(vm, "createDOMJITNodeObject", functionCreateDOMJITNodeObject, 0);
3176     addFunction(vm, "createDOMJITGetterObject", functionCreateDOMJITGetterObject, 0);
3177     addFunction(vm, "createDOMJITGetterNoEffectsObject", functionCreateDOMJITGetterNoEffectsObject, 0);
3178     addFunction(vm, "createDOMJITGetterComplexObject", functionCreateDOMJITGetterComplexObject, 0);
3179     addFunction(vm, "createDOMJITFunctionObject", functionCreateDOMJITFunctionObject, 0);
3180     addFunction(vm, "createDOMJITCheckJSCastObject", functionCreateDOMJITCheckJSCastObject, 0);
3181     addFunction(vm, "createDOMJITGetterBaseJSObject", functionCreateDOMJITGetterBaseJSObject, 0);
3182     addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);
3183 #if ENABLE(WEBASSEMBLY)
3184     addFunction(vm, "createWasmStreamingParser", functionCreateWasmStreamingParser, 0);
3185 #endif
3186     addFunction(vm, "createStaticCustomAccessor", functionCreateStaticCustomAccessor, 0);
3187     addFunction(vm, "createObjectDoingSideEffectPutWithoutCorrectSlotStatus", functionCreateObjectDoingSideEffectPutWithoutCorrectSlotStatus, 0);
3188     addFunction(vm, "createEmptyFunctionWithName", functionCreateEmptyFunctionWithName, 1);
3189     addFunction(vm, "getPrivateProperty", functionGetPrivateProperty, 2);
3190     addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
3191
3192     addConstructibleFunction(vm, "Root", functionCreateRoot, 0);
3193     addConstructibleFunction(vm, "Element", functionCreateElement, 1);
3194     addFunction(vm, "getElement", functionGetElement, 1);
3195
3196     addConstructibleFunction(vm, "SimpleObject", functionCreateSimpleObject, 0);
3197     addFunction(vm, "getHiddenValue", functionGetHiddenValue, 1);
3198     addFunction(vm, "setHiddenValue", functionSetHiddenValue, 2);
3199
3200     addFunction(vm, "shadowChickenFunctionsOnStack", functionShadowChickenFunctionsOnStack, 0);
3201     addFunction(vm, "setGlobalConstRedeclarationShouldNotThrow", functionSetGlobalConstRedeclarationShouldNotThrow, 0);
3202
3203     addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);
3204     addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);
3205
3206     addFunction(vm, "flattenDictionaryObject", functionFlattenDictionaryObject, 1);
3207
3208     addFunction(vm, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges , 0);
3209     addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
3210     addFunction(vm, "basicBlockExecutionCount", functionBasicBlockExecutionCount, 2);
3211
3212     addFunction(vm, "enableDebuggerModeWhenIdle", functionEnableDebuggerModeWhenIdle, 0);
3213     addFunction(vm, "disableDebuggerModeWhenIdle", functionDisableDebuggerModeWhenIdle, 0);
3214
3215     addFunction(vm, "deleteAllCodeWhenIdle", functionDeleteAllCodeWhenIdle, 0);
3216
3217     addFunction(vm, "globalObjectCount", functionGlobalObjectCount, 0);
3218     addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);
3219
3220     addFunction(vm, "getGetterSetter", functionGetGetterSetter, 2);
3221     addFunction(vm, "loadGetterFromGetterSetter", functionLoadGetterFromGetterSetter, 1);
3222     addFunction(vm, "createCustomTestGetterSetter", functionCreateCustomTestGetterSetter, 1);
3223
3224     addFunction(vm, "deltaBetweenButterflies", functionDeltaBetweenButterflies, 2);
3225     
3226     addFunction(vm, "currentCPUTime", functionCurrentCPUTime, 0);
3227     addFunction(vm, "totalGCTime", functionTotalGCTime, 0);
3228
3229     addFunction(vm, "parseCount", functionParseCount, 0);
3230
3231     addFunction(vm, "isWasmSupported", functionIsWasmSupported, 0);
3232     addFunction(vm, "make16BitStringIfPossible", functionMake16BitStringIfPossible, 1);
3233
3234     addFunction(vm, "getStructureTransitionList", JSDollarVMHelper::functionGetStructureTransitionList, 1);
3235     addFunction(vm, "getConcurrently", functionGetConcurrently, 2);
3236
3237     addFunction(vm, "hasOwnLengthProperty", functionHasOwnLengthProperty, 1);
3238     addFunction(vm, "rejectPromiseAsHandled", functionRejectPromiseAsHandled, 1);
3239
3240     addFunction(vm, "setUserPreferredLanguages", functionSetUserPreferredLanguages, 1);
3241     addFunction(vm, "icuVersion", functionICUVersion, 0);
3242
3243     addFunction(vm, "assertEnabled", functionAssertEnabled, 0);
3244
3245     addFunction(vm, "isMemoryLimited", functionIsMemoryLimited, 0);
3246     addFunction(vm, "useJIT", functionUseJIT, 0);
3247
3248     m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure.set(vm, this, ObjectDoingSideEffectPutWithoutCorrectSlotStatus::createStructure(vm, globalObject, jsNull()));
3249 }
3250
3251 void JSDollarVM::addFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
3252 {
3253     DollarVMAssertScope assertScope;
3254     Identifier identifier = Identifier::fromString(vm, name);
3255     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function), jsDollarVMPropertyAttributes);
3256 }
3257
3258 void JSDollarVM::addConstructibleFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
3259 {
3260     DollarVMAssertScope assertScope;
3261     Identifier identifier = Identifier::fromString(vm, name);
3262     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function, NoIntrinsic, function), jsDollarVMPropertyAttributes);
3263 }
3264
3265 void JSDollarVM::visitChildren(JSCell* cell, SlotVisitor& visitor)
3266 {
3267     JSDollarVM* thisObject = jsCast<JSDollarVM*>(cell);
3268     Base::visitChildren(thisObject, visitor);
3269     visitor.append(thisObject->m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure);
3270 }
3271
3272 } // namespace JSC
3273
3274 IGNORE_WARNINGS_END