bb0c982f4c0073c9c1ea20ad0067acc4344e68f3
[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         : m_currentFrame(0)
1787         , m_jitType(JITType::None)
1788     {
1789         DollarVMAssertScope assertScope;
1790     }
1791
1792     StackVisitor::Status operator()(StackVisitor& visitor) const
1793     {
1794         if (m_currentFrame++ > 1) {
1795             m_jitType = visitor->codeBlock()->jitType();
1796             return StackVisitor::Done;
1797         }
1798         return StackVisitor::Continue;
1799     }
1800     
1801     JITType jitType() { return m_jitType; }
1802
1803 private:
1804     mutable unsigned m_currentFrame;
1805     mutable JITType m_jitType;
1806 };
1807
1808 static FunctionExecutable* getExecutableForFunction(JSValue theFunctionValue)
1809 {
1810     DollarVMAssertScope assertScope;
1811     if (!theFunctionValue.isCell())
1812         return nullptr;
1813     
1814     VM& vm = theFunctionValue.asCell()->vm();
1815     JSFunction* theFunction = jsDynamicCast<JSFunction*>(vm, theFunctionValue);
1816     if (!theFunction)
1817         return nullptr;
1818     
1819     FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(vm,
1820         theFunction->executable());
1821
1822     return executable;
1823 }
1824
1825 // Returns true if the current frame is a LLInt frame.
1826 // Usage: isLLInt = $vm.llintTrue()
1827 static EncodedJSValue JSC_HOST_CALL functionLLintTrue(JSGlobalObject* globalObject, CallFrame* callFrame)
1828 {
1829     DollarVMAssertScope assertScope;
1830     VM& vm = globalObject->vm();
1831     if (!callFrame)
1832         return JSValue::encode(jsUndefined());
1833     CallerFrameJITTypeFunctor functor;
1834     callFrame->iterate(vm, functor);
1835     return JSValue::encode(jsBoolean(functor.jitType() == JITType::InterpreterThunk));
1836 }
1837
1838 // Returns true if the current frame is a baseline JIT frame.
1839 // Usage: isBaselineJIT = $vm.jitTrue()
1840 static EncodedJSValue JSC_HOST_CALL functionJITTrue(JSGlobalObject* globalObject, CallFrame* callFrame)
1841 {
1842     DollarVMAssertScope assertScope;
1843     VM& vm = globalObject->vm();
1844     if (!callFrame)
1845         return JSValue::encode(jsUndefined());
1846     CallerFrameJITTypeFunctor functor;
1847     callFrame->iterate(vm, functor);
1848     return JSValue::encode(jsBoolean(functor.jitType() == JITType::BaselineJIT));
1849 }
1850
1851 // Set that the argument function should not be inlined.
1852 // Usage:
1853 // function f() { };
1854 // $vm.noInline(f);
1855 static EncodedJSValue JSC_HOST_CALL functionNoInline(JSGlobalObject*, CallFrame* callFrame)
1856 {
1857     DollarVMAssertScope assertScope;
1858     if (callFrame->argumentCount() < 1)
1859         return JSValue::encode(jsUndefined());
1860     
1861     JSValue theFunctionValue = callFrame->uncheckedArgument(0);
1862
1863     if (FunctionExecutable* executable = getExecutableForFunction(theFunctionValue))
1864         executable->setNeverInline(true);
1865     
1866     return JSValue::encode(jsUndefined());
1867 }
1868
1869 // Runs a full GC synchronously.
1870 // Usage: $vm.gc()
1871 static EncodedJSValue JSC_HOST_CALL functionGC(JSGlobalObject* globalObject, CallFrame*)
1872 {
1873     DollarVMAssertScope assertScope;
1874     VMInspector::gc(&globalObject->vm());
1875     return JSValue::encode(jsUndefined());
1876 }
1877
1878 // Runs the edenGC synchronously.
1879 // Usage: $vm.edenGC()
1880 static EncodedJSValue JSC_HOST_CALL functionEdenGC(JSGlobalObject* globalObject, CallFrame*)
1881 {
1882     DollarVMAssertScope assertScope;
1883     VMInspector::edenGC(&globalObject->vm());
1884     return JSValue::encode(jsUndefined());
1885 }
1886
1887 // Runs a full GC, but sweep asynchronously.
1888 // Usage: $vm.gcSweepAsynchronously()
1889 static EncodedJSValue JSC_HOST_CALL functionGCSweepAsynchronously(JSGlobalObject* globalObject, CallFrame*)
1890 {
1891     DollarVMAssertScope assertScope;
1892     globalObject->vm().heap.collectNow(Async, CollectionScope::Full);
1893     return JSValue::encode(jsUndefined());
1894 }
1895
1896 // Dumps the hashes of all subspaces currently registered with the VM.
1897 // Usage: $vm.dumpSubspaceHashes()
1898 static EncodedJSValue JSC_HOST_CALL functionDumpSubspaceHashes(JSGlobalObject* globalObject, CallFrame*)
1899 {
1900     DollarVMAssertScope assertScope;
1901     VM& vm = globalObject->vm();
1902     VMInspector::dumpSubspaceHashes(&vm);
1903     return JSValue::encode(jsUndefined());
1904 }
1905
1906 // Gets a JSDollarVMCallFrame for a specified frame index.
1907 // Usage: var callFrame = $vm.callFrame(0) // frame 0 is the top frame.
1908 // Usage: var callFrame = $vm.callFrame() // implies frame 0 i.e. current frame.
1909 //
1910 // This gives you the ability to query the following:
1911 //    callFrame.valid; // false if we asked for a frame beyond the end of the stack, else true.
1912 //    callFrame.callee;
1913 //    callFrame.codeBlock;
1914 //    callFrame.unlinkedCodeBlock;
1915 //    callFrame.executable;
1916 //
1917 // Note: you cannot toString() a codeBlock, unlinkedCodeBlock, or executable because
1918 // there are internal objects and not a JS object. Hence, you cannot do string
1919 // concatenation with them.
1920 static EncodedJSValue JSC_HOST_CALL functionCallFrame(JSGlobalObject* globalObject, CallFrame* callFrame)
1921 {
1922     DollarVMAssertScope assertScope;
1923     unsigned frameNumber = 1;
1924     if (callFrame->argumentCount() >= 1) {
1925         JSValue value = callFrame->uncheckedArgument(0);
1926         if (!value.isUInt32())
1927             return JSValue::encode(jsUndefined());
1928
1929         // We need to inc the frame number because the caller would consider
1930         // its own frame as frame 0. Hence, we need discount the frame for this
1931         // function.
1932         frameNumber = value.asUInt32() + 1;
1933     }
1934
1935     return JSValue::encode(JSDollarVMCallFrame::create(globalObject, callFrame, frameNumber));
1936 }
1937
1938 // Gets a token for the CodeBlock for a specified frame index.
1939 // Usage: codeBlockToken = $vm.codeBlockForFrame(0) // frame 0 is the top frame.
1940 // Usage: codeBlockToken = $vm.codeBlockForFrame() // implies frame 0 i.e. current frame.
1941 static EncodedJSValue JSC_HOST_CALL functionCodeBlockForFrame(JSGlobalObject* globalObject, CallFrame* callFrame)
1942 {
1943     DollarVMAssertScope assertScope;
1944     unsigned frameNumber = 1;
1945     if (callFrame->argumentCount() >= 1) {
1946         JSValue value = callFrame->uncheckedArgument(0);
1947         if (!value.isUInt32())
1948             return JSValue::encode(jsUndefined());
1949
1950         // We need to inc the frame number because the caller would consider
1951         // its own frame as frame 0. Hence, we need discount the frame for this
1952         // function.
1953         frameNumber = value.asUInt32() + 1;
1954     }
1955
1956     CodeBlock* codeBlock = VMInspector::codeBlockForFrame(&globalObject->vm(), callFrame, frameNumber);
1957     if (codeBlock)
1958         return JSValue::encode(codeBlock);
1959     return JSValue::encode(jsUndefined());
1960 }
1961
1962 static CodeBlock* codeBlockFromArg(JSGlobalObject* globalObject, CallFrame* callFrame)
1963 {
1964     DollarVMAssertScope assertScope;
1965     VM& vm = globalObject->vm();
1966     if (callFrame->argumentCount() < 1)
1967         return nullptr;
1968
1969     JSValue value = callFrame->uncheckedArgument(0);
1970     CodeBlock* candidateCodeBlock = nullptr;
1971     if (value.isCell()) {
1972         JSFunction* func = jsDynamicCast<JSFunction*>(vm, value.asCell());
1973         if (func) {
1974             if (func->isHostFunction())
1975                 candidateCodeBlock = nullptr;
1976             else
1977                 candidateCodeBlock = func->jsExecutable()->eitherCodeBlock();
1978         } else
1979             candidateCodeBlock = static_cast<CodeBlock*>(value.asCell());
1980     }
1981
1982     if (candidateCodeBlock && VMInspector::isValidCodeBlock(&vm, candidateCodeBlock))
1983         return candidateCodeBlock;
1984
1985     if (candidateCodeBlock)
1986         dataLog("Invalid codeBlock: ", RawPointer(candidateCodeBlock), " ", value, "\n");
1987     else
1988         dataLog("Invalid codeBlock: ", value, "\n");
1989     return nullptr;
1990 }
1991
1992 // Usage: $vm.print("codeblock = ", $vm.codeBlockFor(functionObj))
1993 // Usage: $vm.print("codeblock = ", $vm.codeBlockFor(codeBlockToken))
1994 // Note: you cannot toString() a codeBlock because it's an internal object and not
1995 // a JS object. Hence, you cannot do string concatenation with it.
1996 static EncodedJSValue JSC_HOST_CALL functionCodeBlockFor(JSGlobalObject* globalObject, CallFrame* callFrame)
1997 {
1998     DollarVMAssertScope assertScope;
1999     CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
2000     WTF::StringPrintStream stream;
2001     if (codeBlock) {
2002         stream.print(*codeBlock);
2003         return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2004     }
2005     return JSValue::encode(jsUndefined());
2006 }
2007
2008 // Usage: $vm.dumpSourceFor(functionObj)
2009 // Usage: $vm.dumpSourceFor(codeBlockToken)
2010 static EncodedJSValue JSC_HOST_CALL functionDumpSourceFor(JSGlobalObject* globalObject, CallFrame* callFrame)
2011 {
2012     DollarVMAssertScope assertScope;
2013     CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
2014     if (codeBlock)
2015         codeBlock->dumpSource();
2016     return JSValue::encode(jsUndefined());
2017 }
2018
2019 // Usage: $vm.dumpBytecodeFor(functionObj)
2020 // Usage: $vm.dumpBytecodeFor(codeBlock)
2021 static EncodedJSValue JSC_HOST_CALL functionDumpBytecodeFor(JSGlobalObject* globalObject, CallFrame* callFrame)
2022 {
2023     DollarVMAssertScope assertScope;
2024     CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
2025     if (codeBlock)
2026         codeBlock->dumpBytecode();
2027     return JSValue::encode(jsUndefined());
2028 }
2029
2030 static EncodedJSValue doPrint(JSGlobalObject* globalObject, CallFrame* callFrame, bool addLineFeed)
2031 {
2032     DollarVMAssertScope assertScope;
2033     auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
2034     for (unsigned i = 0; i < callFrame->argumentCount(); ++i) {
2035         JSValue arg = callFrame->uncheckedArgument(i);
2036         if (arg.isCell()
2037             && !arg.isObject()
2038             && !arg.isString()
2039             && !arg.isBigInt()) {
2040             dataLog(arg);
2041             continue;
2042         }
2043         String argStr = callFrame->uncheckedArgument(i).toWTFString(globalObject);
2044         RETURN_IF_EXCEPTION(scope, encodedJSValue());
2045         dataLog(argStr);
2046     }
2047     if (addLineFeed)
2048         dataLog("\n");
2049     return JSValue::encode(jsUndefined());
2050 }
2051
2052 // Prints a series of comma separate strings without appending a newline.
2053 // Usage: $vm.dataLog(str1, str2, str3)
2054 static EncodedJSValue JSC_HOST_CALL functionDataLog(JSGlobalObject* globalObject, CallFrame* callFrame)
2055 {
2056     DollarVMAssertScope assertScope;
2057     const bool addLineFeed = false;
2058     return doPrint(globalObject, callFrame, addLineFeed);
2059 }
2060
2061 // Prints a series of comma separate strings and appends a newline.
2062 // Usage: $vm.print(str1, str2, str3)
2063 static EncodedJSValue JSC_HOST_CALL functionPrint(JSGlobalObject* globalObject, CallFrame* callFrame)
2064 {
2065     DollarVMAssertScope assertScope;
2066     const bool addLineFeed = true;
2067     return doPrint(globalObject, callFrame, addLineFeed);
2068 }
2069
2070 // Dumps the current CallFrame.
2071 // Usage: $vm.dumpCallFrame()
2072 static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(JSGlobalObject* globalObject, CallFrame* callFrame)
2073 {
2074     DollarVMAssertScope assertScope;
2075     // When the callers call this function, they are expecting to dump their
2076     // own frame. So skip 1 for this frame.
2077     VMInspector::dumpCallFrame(&globalObject->vm(), callFrame, 1);
2078     return JSValue::encode(jsUndefined());
2079 }
2080
2081 // Dumps the JS stack.
2082 // Usage: $vm.printStack()
2083 static EncodedJSValue JSC_HOST_CALL functionDumpStack(JSGlobalObject* globalObject, CallFrame* callFrame)
2084 {
2085     DollarVMAssertScope assertScope;
2086     // When the callers call this function, they are expecting to dump the
2087     // stack starting their own frame. So skip 1 for this frame.
2088     VMInspector::dumpStack(&globalObject->vm(), callFrame, 1);
2089     return JSValue::encode(jsUndefined());
2090 }
2091
2092 // Dumps the current CallFrame.
2093 // Usage: $vm.dumpRegisters(N) // dump the registers of the Nth CallFrame.
2094 // Usage: $vm.dumpRegisters() // dump the registers of the current CallFrame.
2095 // FIXME: Currently, this function dumps the physical frame. We should make
2096 // it dump the logical frame (i.e. be able to dump inlined frames as well).
2097 static EncodedJSValue JSC_HOST_CALL functionDumpRegisters(JSGlobalObject* globalObject, CallFrame* callFrame)
2098 {
2099     DollarVMAssertScope assertScope;
2100     VM& vm = globalObject->vm();
2101     unsigned requestedFrameIndex = 1;
2102     if (callFrame->argumentCount() >= 1) {
2103         JSValue value = callFrame->uncheckedArgument(0);
2104         if (!value.isUInt32())
2105             return JSValue::encode(jsUndefined());
2106
2107         // We need to inc the frame number because the caller would consider
2108         // its own frame as frame 0. Hence, we need discount the frame for this
2109         // function.
2110         requestedFrameIndex = value.asUInt32() + 1;
2111     }
2112
2113     unsigned frameIndex = 0;
2114     callFrame->iterate(vm, [&] (StackVisitor& visitor) {
2115         DollarVMAssertScope assertScope;
2116         if (frameIndex++ != requestedFrameIndex)
2117             return StackVisitor::Continue;
2118         VMInspector::dumpRegisters(visitor->callFrame());
2119         return StackVisitor::Done;
2120     });
2121
2122     return encodedJSUndefined();
2123 }
2124
2125 // Dumps the internal memory layout of a JSCell.
2126 // Usage: $vm.dumpCell(cell)
2127 static EncodedJSValue JSC_HOST_CALL functionDumpCell(JSGlobalObject*, CallFrame* callFrame)
2128 {
2129     DollarVMAssertScope assertScope;
2130     JSValue value = callFrame->argument(0);
2131     if (!value.isCell())
2132         return encodedJSUndefined();
2133     
2134     VMInspector::dumpCellMemory(value.asCell());
2135     return encodedJSUndefined();
2136 }
2137
2138 // Gets the dataLog dump of the indexingMode of the passed value.
2139 // Usage: $vm.print("indexingMode = " + $vm.indexingMode(jsValue))
2140 static EncodedJSValue JSC_HOST_CALL functionIndexingMode(JSGlobalObject* globalObject, CallFrame* callFrame)
2141 {
2142     DollarVMAssertScope assertScope;
2143     if (!callFrame->argument(0).isObject())
2144         return encodedJSUndefined();
2145
2146     WTF::StringPrintStream stream;
2147     stream.print(IndexingTypeDump(callFrame->uncheckedArgument(0).getObject()->indexingMode()));
2148     return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2149 }
2150
2151 static EncodedJSValue JSC_HOST_CALL functionInlineCapacity(JSGlobalObject* globalObject, CallFrame* callFrame)
2152 {
2153     DollarVMAssertScope assertScope;
2154     VM& vm = globalObject->vm();
2155     if (auto* object = jsDynamicCast<JSObject*>(vm, callFrame->argument(0)))
2156         return JSValue::encode(jsNumber(object->structure(vm)->inlineCapacity()));
2157
2158     return encodedJSUndefined();
2159 }
2160
2161 // Gets the dataLog dump of a given JS value as a string.
2162 // Usage: $vm.print("value = " + $vm.value(jsValue))
2163 static EncodedJSValue JSC_HOST_CALL functionValue(JSGlobalObject* globalObject, CallFrame* callFrame)
2164 {
2165     DollarVMAssertScope assertScope;
2166     WTF::StringPrintStream stream;
2167     for (unsigned i = 0; i < callFrame->argumentCount(); ++i) {
2168         if (i)
2169             stream.print(", ");
2170         stream.print(callFrame->uncheckedArgument(i));
2171     }
2172     
2173     return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2174 }
2175
2176 // Gets the pid of the current process.
2177 // Usage: $vm.print("pid = " + $vm.getpid())
2178 static EncodedJSValue JSC_HOST_CALL functionGetPID(JSGlobalObject*, CallFrame*)
2179 {
2180     DollarVMAssertScope assertScope;
2181     return JSValue::encode(jsNumber(getCurrentProcessID()));
2182 }
2183
2184 // Make the globalObject have a bad time. Does nothing if the object is not a JSGlobalObject.
2185 // Usage: $vm.haveABadTime(globalObject)
2186 static EncodedJSValue JSC_HOST_CALL functionHaveABadTime(JSGlobalObject* globalObject, CallFrame* callFrame)
2187 {
2188     DollarVMAssertScope assertScope;
2189     VM& vm = globalObject->vm();
2190     auto scope = DECLARE_THROW_SCOPE(vm);
2191     JSGlobalObject* target = globalObject;
2192     if (!callFrame->argument(0).isUndefined()) {
2193         JSObject* obj = callFrame->argument(0).getObject();
2194         if (!obj)
2195             return throwVMTypeError(globalObject, scope, "haveABadTime expects first argument to be an object if provided");
2196         target = obj->globalObject();
2197     }
2198
2199     target->haveABadTime(vm);
2200     return JSValue::encode(jsBoolean(true));
2201 }
2202
2203 // Checks if the object (or its global if the object is not a global) is having a bad time.
2204 // Usage: $vm.isHavingABadTime(obj)
2205 static EncodedJSValue JSC_HOST_CALL functionIsHavingABadTime(JSGlobalObject* globalObject, CallFrame* callFrame)
2206 {
2207     DollarVMAssertScope assertScope;
2208     VM& vm = globalObject->vm();
2209     auto scope = DECLARE_THROW_SCOPE(vm);
2210     JSGlobalObject* target = globalObject;
2211     if (!callFrame->argument(0).isUndefined()) {
2212         JSObject* obj = callFrame->argument(0).getObject();
2213         if (!obj)
2214             return throwVMTypeError(globalObject, scope, "isHavingABadTime expects first argument to be an object if provided");
2215         target = obj->globalObject();
2216     }
2217
2218     return JSValue::encode(jsBoolean(target->isHavingABadTime()));
2219 }
2220
2221 // Calls the specified test function after adjusting the stack to have the specified
2222 // remaining size from the end of the physical stack.
2223 // Usage: $vm.callWithStackSize(funcToCall, desiredStackSize)
2224 //
2225 // This function will only work in test configurations, specifically, only if JSC
2226 // options are not frozen. For the jsc shell, the --disableOptionsFreezingForTesting
2227 // argument needs to be passed in on the command line.
2228
2229 #if ENABLE(MASM_PROBE)
2230 static void callWithStackSizeProbeFunction(Probe::State* state)
2231 {
2232     JSGlobalObject* globalObject = bitwise_cast<JSGlobalObject*>(state->arg);
2233     // The bits loaded from state->probeFunction will be tagged like
2234     // a C function. So, we'll need to untag it to extract the bits
2235     // for the JSFunction*.
2236     JSFunction* function = bitwise_cast<JSFunction*>(untagCodePtr<CFunctionPtrTag>(state->probeFunction));
2237     state->initializeStackFunction = nullptr;
2238     state->initializeStackArg = nullptr;
2239
2240     DollarVMAssertScope assertScope;
2241     VM& vm = globalObject->vm();
2242
2243     auto callData = getCallData(vm, function);
2244     MarkedArgumentBuffer args;
2245     call(globalObject, function, callData, jsUndefined(), args);
2246 }
2247 #endif // ENABLE(MASM_PROBE)
2248
2249 SUPPRESS_ASAN
2250 static EncodedJSValue JSC_HOST_CALL functionCallWithStackSize(JSGlobalObject* globalObject, CallFrame* callFrame)
2251 {
2252     DollarVMAssertScope assertScope;
2253     VM& vm = globalObject->vm();
2254     JSLockHolder lock(vm);
2255     auto throwScope = DECLARE_THROW_SCOPE(vm);
2256
2257 #if OS(DARWIN) && CPU(X86_64)
2258     constexpr bool isSupportedByPlatform = true;
2259 #else
2260     constexpr bool isSupportedByPlatform = false;
2261 #endif
2262
2263     if (!isSupportedByPlatform)
2264         return throwVMError(globalObject, throwScope, "Not supported for this platform");
2265
2266 #if ENABLE(MASM_PROBE)
2267     if (g_jscConfig.isPermanentlyFrozen() || !g_jscConfig.disabledFreezingForTesting)
2268         return throwVMError(globalObject, throwScope, "Options are frozen");
2269
2270     if (callFrame->argumentCount() < 2)
2271         return throwVMError(globalObject, throwScope, "Invalid number of arguments");
2272     JSValue arg0 = callFrame->argument(0);
2273     JSValue arg1 = callFrame->argument(1);
2274     if (!arg0.isCallable(vm))
2275         return throwVMError(globalObject, throwScope, "arg0 should be a function");
2276     if (!arg1.isNumber())
2277         return throwVMError(globalObject, throwScope, "arg1 should be a number");
2278
2279     JSFunction* function = jsCast<JSFunction*>(arg0);
2280     size_t desiredStackSize = arg1.asNumber();
2281
2282     const StackBounds& bounds = Thread::current().stack();
2283     uint8_t* currentStackPosition = bitwise_cast<uint8_t*>(currentStackPointer());
2284     uint8_t* end = bitwise_cast<uint8_t*>(bounds.end());
2285     uint8_t* desiredStart = end + desiredStackSize;
2286     if (desiredStart >= currentStackPosition)
2287         return throwVMError(globalObject, throwScope, "Unable to setup desired stack size");
2288
2289     JSDollarVMHelper helper(vm);
2290
2291     unsigned originalMaxPerThreadStackUsage = Options::maxPerThreadStackUsage();
2292     void* originalVMSoftStackLimit = vm.softStackLimit();
2293     void* originalVMStackLimit = vm.stackLimit();
2294
2295     // This is a hack to make the VM think it's stack limits are near the end
2296     // of the physical stack.
2297     uint8_t* vmStackStart = bitwise_cast<uint8_t*>(vm.stackPointerAtVMEntry());
2298     uint8_t* vmStackEnd = vmStackStart - originalMaxPerThreadStackUsage;
2299     ptrdiff_t sizeDiff = vmStackEnd - end;
2300     RELEASE_ASSERT(sizeDiff >= 0);
2301     RELEASE_ASSERT(static_cast<uint64_t>(sizeDiff) < UINT_MAX);
2302
2303     Options::maxPerThreadStackUsage() = originalMaxPerThreadStackUsage + sizeDiff;
2304     helper.updateVMStackLimits();
2305
2306 #if OS(DARWIN) && CPU(X86_64)
2307     __asm__ volatile (
2308         "subq %[sizeDiff], %%rsp" "\n"
2309         "pushq %%rax" "\n"
2310         "pushq %%rcx" "\n"
2311         "pushq %%rdx" "\n"
2312         "pushq %%rbx" "\n"
2313         "callq *%%rax" "\n"
2314         "addq %[sizeDiff], %%rsp" "\n"
2315         :
2316         : "a" (ctiMasmProbeTrampoline)
2317         , "c" (callWithStackSizeProbeFunction)
2318         , "d" (function)
2319         , "b" (globalObject)
2320         , [sizeDiff] "rm" (sizeDiff)
2321         : "memory"
2322     );
2323 #else
2324     UNUSED_PARAM(function);
2325 #if !COMPILER(MSVC)
2326     UNUSED_PARAM(callWithStackSizeProbeFunction);
2327 #endif
2328 #endif // OS(DARWIN) && CPU(X86_64)
2329
2330     Options::maxPerThreadStackUsage() = originalMaxPerThreadStackUsage;
2331     helper.updateVMStackLimits();
2332     RELEASE_ASSERT(vm.softStackLimit() == originalVMSoftStackLimit);
2333     RELEASE_ASSERT(vm.stackLimit() == originalVMStackLimit);
2334
2335     throwScope.release();
2336     return encodedJSUndefined();
2337
2338 #else // not ENABLE(MASM_PROBE)
2339     UNUSED_PARAM(callFrame);
2340     return throwVMError(globalObject, throwScope, "Not supported for this platform");
2341 #endif // ENABLE(MASM_PROBE)
2342 }
2343
2344 // Creates a new global object.
2345 // Usage: $vm.createGlobalObject()
2346 static EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(JSGlobalObject* globalObject, CallFrame*)
2347 {
2348     DollarVMAssertScope assertScope;
2349     VM& vm = globalObject->vm();
2350     JSLockHolder lock(vm);
2351     return JSValue::encode(JSGlobalObject::create(vm, JSGlobalObject::createStructure(vm, jsNull())));
2352 }
2353
2354 static EncodedJSValue JSC_HOST_CALL functionCreateProxy(JSGlobalObject* globalObject, CallFrame* callFrame)
2355 {
2356     DollarVMAssertScope assertScope;
2357     VM& vm = globalObject->vm();
2358     JSLockHolder lock(vm);
2359     JSValue target = callFrame->argument(0);
2360     if (!target.isObject())
2361         return JSValue::encode(jsUndefined());
2362     JSObject* jsTarget = asObject(target.asCell());
2363     Structure* structure = JSProxy::createStructure(vm, globalObject, jsTarget->getPrototypeDirect(vm), ImpureProxyType);
2364     JSProxy* proxy = JSProxy::create(vm, structure, jsTarget);
2365     return JSValue::encode(proxy);
2366 }
2367
2368 static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(JSGlobalObject* globalObject, CallFrame* callFrame)
2369 {
2370     DollarVMAssertScope assertScope;
2371     JSLockHolder lock(globalObject);
2372     RuntimeArray* array = RuntimeArray::create(globalObject, callFrame);
2373     return JSValue::encode(array);
2374 }
2375
2376 static EncodedJSValue JSC_HOST_CALL functionCreateNullRopeString(JSGlobalObject* globalObject, CallFrame*)
2377 {
2378     DollarVMAssertScope assertScope;
2379     VM& vm = globalObject->vm();
2380     JSLockHolder lock(vm);
2381     return JSValue::encode(JSRopeString::createNullForTesting(vm));
2382 }
2383
2384 static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(JSGlobalObject* globalObject, CallFrame* callFrame)
2385 {
2386     DollarVMAssertScope assertScope;
2387     VM& vm = globalObject->vm();
2388     JSLockHolder lock(vm);
2389     JSValue target = callFrame->argument(0);
2390     JSObject* delegate = nullptr;
2391     if (target.isObject())
2392         delegate = asObject(target.asCell());
2393     Structure* structure = ImpureGetter::createStructure(vm, globalObject, jsNull());
2394     ImpureGetter* result = ImpureGetter::create(vm, structure, delegate);
2395     return JSValue::encode(result);
2396 }
2397
2398 static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(JSGlobalObject* globalObject, CallFrame*)
2399 {
2400     DollarVMAssertScope assertScope;
2401     VM& vm = globalObject->vm();
2402     JSLockHolder lock(vm);
2403     Structure* structure = CustomGetter::createStructure(vm, globalObject, jsNull());
2404     CustomGetter* result = CustomGetter::create(vm, structure);
2405     return JSValue::encode(result);
2406 }
2407
2408 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(JSGlobalObject* globalObject, CallFrame*)
2409 {
2410     DollarVMAssertScope assertScope;
2411     VM& vm = globalObject->vm();
2412     JSLockHolder lock(vm);
2413     Structure* structure = DOMJITNode::createStructure(vm, globalObject, DOMJITGetter::create(vm, DOMJITGetter::createStructure(vm, globalObject, jsNull())));
2414     DOMJITNode* result = DOMJITNode::create(vm, structure);
2415     return JSValue::encode(result);
2416 }
2417
2418 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(JSGlobalObject* globalObject, CallFrame*)
2419 {
2420     DollarVMAssertScope assertScope;
2421     VM& vm = globalObject->vm();
2422     JSLockHolder lock(vm);
2423     Structure* structure = DOMJITGetter::createStructure(vm, globalObject, jsNull());
2424     DOMJITGetter* result = DOMJITGetter::create(vm, structure);
2425     return JSValue::encode(result);
2426 }
2427
2428 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterNoEffectsObject(JSGlobalObject* globalObject, CallFrame*)
2429 {
2430     DollarVMAssertScope assertScope;
2431     VM& vm = globalObject->vm();
2432     JSLockHolder lock(vm);
2433     Structure* structure = DOMJITGetterNoEffects::createStructure(vm, globalObject, jsNull());
2434     DOMJITGetterNoEffects* result = DOMJITGetterNoEffects::create(vm, structure);
2435     return JSValue::encode(result);
2436 }
2437
2438 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(JSGlobalObject* globalObject, CallFrame*)
2439 {
2440     DollarVMAssertScope assertScope;
2441     VM& vm = globalObject->vm();
2442     JSLockHolder lock(vm);
2443     Structure* structure = DOMJITGetterComplex::createStructure(vm, globalObject, jsNull());
2444     DOMJITGetterComplex* result = DOMJITGetterComplex::create(vm, globalObject, structure);
2445     return JSValue::encode(result);
2446 }
2447
2448 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITFunctionObject(JSGlobalObject* globalObject, CallFrame*)
2449 {
2450     DollarVMAssertScope assertScope;
2451     VM& vm = globalObject->vm();
2452     JSLockHolder lock(vm);
2453     Structure* structure = DOMJITFunctionObject::createStructure(vm, globalObject, jsNull());
2454     DOMJITFunctionObject* result = DOMJITFunctionObject::create(vm, globalObject, structure);
2455     return JSValue::encode(result);
2456 }
2457
2458 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITCheckJSCastObject(JSGlobalObject* globalObject, CallFrame*)
2459 {
2460     DollarVMAssertScope assertScope;
2461     VM& vm = globalObject->vm();
2462     JSLockHolder lock(vm);
2463     Structure* structure = DOMJITCheckJSCastObject::createStructure(vm, globalObject, jsNull());
2464     DOMJITCheckJSCastObject* result = DOMJITCheckJSCastObject::create(vm, globalObject, structure);
2465     return JSValue::encode(result);
2466 }
2467
2468 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterBaseJSObject(JSGlobalObject* globalObject, CallFrame*)
2469 {
2470     DollarVMAssertScope assertScope;
2471     VM& vm = globalObject->vm();
2472     JSLockHolder lock(vm);
2473     Structure* structure = DOMJITGetterBaseJSObject::createStructure(vm, globalObject, jsNull());
2474     DOMJITGetterBaseJSObject* result = DOMJITGetterBaseJSObject::create(vm, structure);
2475     return JSValue::encode(result);
2476 }
2477
2478 #if ENABLE(WEBASSEMBLY)
2479 static EncodedJSValue JSC_HOST_CALL functionCreateWasmStreamingParser(JSGlobalObject* globalObject, CallFrame*)
2480 {
2481     DollarVMAssertScope assertScope;
2482     VM& vm = globalObject->vm();
2483     JSLockHolder lock(vm);
2484     return JSValue::encode(WasmStreamingParser::create(vm, globalObject));
2485 }
2486 #endif
2487
2488 static EncodedJSValue JSC_HOST_CALL functionCreateStaticCustomAccessor(JSGlobalObject* globalObject, CallFrame*)
2489 {
2490     DollarVMAssertScope assertScope;
2491     VM& vm = globalObject->vm();
2492     JSLockHolder lock(vm);
2493     Structure* structure = StaticCustomAccessor::createStructure(vm, globalObject, jsNull());
2494     auto* result = StaticCustomAccessor::create(vm, structure);
2495     return JSValue::encode(result);
2496 }
2497
2498 static EncodedJSValue JSC_HOST_CALL functionCreateObjectDoingSideEffectPutWithoutCorrectSlotStatus(JSGlobalObject* globalObject, CallFrame* callFrame)
2499 {
2500     DollarVMAssertScope assertScope;
2501     VM& vm = globalObject->vm();
2502     JSLockHolder lock(vm);
2503
2504     auto* dollarVM = jsDynamicCast<JSDollarVM*>(vm, callFrame->thisValue());
2505     RELEASE_ASSERT(dollarVM);
2506     auto* result = ObjectDoingSideEffectPutWithoutCorrectSlotStatus::create(vm, dollarVM->objectDoingSideEffectPutWithoutCorrectSlotStatusStructure());
2507     return JSValue::encode(result);
2508 }
2509
2510 static EncodedJSValue JSC_HOST_CALL functionCreateEmptyFunctionWithName(JSGlobalObject* globalObject, CallFrame* callFrame)
2511 {
2512     DollarVMAssertScope assertScope;
2513     VM& vm = globalObject->vm();
2514     JSLockHolder lock(vm);
2515     auto scope = DECLARE_THROW_SCOPE(vm);
2516
2517     const String name = callFrame->argument(0).toWTFString(globalObject);
2518     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2519
2520     RELEASE_AND_RETURN(scope, JSValue::encode(JSFunction::create(vm, globalObject, 1, name, functionCreateEmptyFunctionWithName)));
2521 }
2522
2523 static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(JSGlobalObject* globalObject, CallFrame* callFrame)
2524 {
2525     DollarVMAssertScope assertScope;
2526     VM& vm = globalObject->vm();
2527     JSLockHolder lock(vm);
2528     auto scope = DECLARE_THROW_SCOPE(vm);
2529
2530     JSValue base = callFrame->argument(0);
2531     if (!base.isObject())
2532         return JSValue::encode(jsUndefined());
2533     JSValue delegate = callFrame->argument(1);
2534     if (!delegate.isObject())
2535         return JSValue::encode(jsUndefined());
2536     ImpureGetter* impureGetter = jsDynamicCast<ImpureGetter*>(vm, asObject(base.asCell()));
2537     if (UNLIKELY(!impureGetter)) {
2538         throwTypeError(globalObject, scope, "argument is not an ImpureGetter"_s);
2539         return encodedJSValue();
2540     }
2541     impureGetter->setDelegate(vm, asObject(delegate.asCell()));
2542     return JSValue::encode(jsUndefined());
2543 }
2544
2545 static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(JSGlobalObject* globalObject, CallFrame* callFrame)
2546 {
2547     DollarVMAssertScope assertScope;
2548     VM& vm = globalObject->vm();
2549     auto scope = DECLARE_THROW_SCOPE(vm);
2550
2551     if (callFrame->argumentCount() < 1 || !callFrame->argument(0).isString())
2552         return JSValue::encode(jsUndefined());
2553
2554     String functionText = asString(callFrame->argument(0))->value(globalObject);
2555     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2556
2557     SourceCode source = makeSource(functionText, { });
2558     JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, nullptr, source), globalObject);
2559
2560     return JSValue::encode(func);
2561 }
2562
2563 static EncodedJSValue JSC_HOST_CALL functionGetPrivateProperty(JSGlobalObject* globalObject, CallFrame* callFrame)
2564 {
2565     DollarVMAssertScope assertScope;
2566     VM& vm = globalObject->vm();
2567     auto scope = DECLARE_THROW_SCOPE(vm);
2568
2569     if (callFrame->argumentCount() < 2 || !callFrame->argument(1).isString())
2570         return encodedJSUndefined();
2571
2572     String str = asString(callFrame->argument(1))->value(globalObject);
2573     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2574
2575     SymbolImpl* symbol = vm.propertyNames->builtinNames().lookUpPrivateName(str);
2576     if (!symbol)
2577         return throwVMError(globalObject, scope, "Unknown private name.");
2578
2579     RELEASE_AND_RETURN(scope, JSValue::encode(callFrame->argument(0).get(globalObject, symbol)));
2580 }
2581
2582 static EncodedJSValue JSC_HOST_CALL functionCreateRoot(JSGlobalObject* globalObject, CallFrame*)
2583 {
2584     DollarVMAssertScope assertScope;
2585     VM& vm = globalObject->vm();
2586     JSLockHolder lock(vm);
2587     return JSValue::encode(Root::create(vm, globalObject));
2588 }
2589
2590 static EncodedJSValue JSC_HOST_CALL functionCreateElement(JSGlobalObject* globalObject, CallFrame* callFrame)
2591 {
2592     DollarVMAssertScope assertScope;
2593     VM& vm = globalObject->vm();
2594     JSLockHolder lock(vm);
2595     auto scope = DECLARE_THROW_SCOPE(vm);
2596
2597     Root* root = jsDynamicCast<Root*>(vm, callFrame->argument(0));
2598     if (!root)
2599         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Cannot create Element without a Root."_s)));
2600     return JSValue::encode(Element::create(vm, globalObject, root));
2601 }
2602
2603 static EncodedJSValue JSC_HOST_CALL functionGetElement(JSGlobalObject* globalObject, CallFrame* callFrame)
2604 {
2605     DollarVMAssertScope assertScope;
2606     VM& vm = globalObject->vm();
2607     JSLockHolder lock(vm);
2608     Root* root = jsDynamicCast<Root*>(vm, callFrame->argument(0));
2609     if (!root)
2610         return JSValue::encode(jsUndefined());
2611     Element* result = root->element();
2612     return JSValue::encode(result ? result : jsUndefined());
2613 }
2614
2615 static EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(JSGlobalObject* globalObject, CallFrame*)
2616 {
2617     DollarVMAssertScope assertScope;
2618     VM& vm = globalObject->vm();
2619     JSLockHolder lock(vm);
2620     return JSValue::encode(SimpleObject::create(vm, globalObject));
2621 }
2622
2623 static EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(JSGlobalObject* globalObject, CallFrame* callFrame)
2624 {
2625     DollarVMAssertScope assertScope;
2626     VM& vm = globalObject->vm();
2627     JSLockHolder lock(vm);
2628     auto scope = DECLARE_THROW_SCOPE(vm);
2629
2630     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, callFrame->argument(0));
2631     if (UNLIKELY(!simpleObject)) {
2632         throwTypeError(globalObject, scope, "Invalid use of getHiddenValue test function"_s);
2633         return encodedJSValue();
2634     }
2635     return JSValue::encode(simpleObject->hiddenValue());
2636 }
2637
2638 static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(JSGlobalObject* globalObject, CallFrame* callFrame)
2639 {
2640     DollarVMAssertScope assertScope;
2641     VM& vm = globalObject->vm();
2642     JSLockHolder lock(vm);
2643     auto scope = DECLARE_THROW_SCOPE(vm);
2644
2645     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, callFrame->argument(0));
2646     if (UNLIKELY(!simpleObject)) {
2647         throwTypeError(globalObject, scope, "Invalid use of setHiddenValue test function"_s);
2648         return encodedJSValue();
2649     }
2650     JSValue value = callFrame->argument(1);
2651     simpleObject->setHiddenValue(vm, value);
2652     return JSValue::encode(jsUndefined());
2653 }
2654
2655 static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(JSGlobalObject* globalObject, CallFrame* callFrame)
2656 {
2657     DollarVMAssertScope assertScope;
2658     VM& vm = globalObject->vm();
2659     auto scope = DECLARE_THROW_SCOPE(vm);
2660     if (auto* shadowChicken = vm.shadowChicken()) {
2661         scope.release();
2662         return JSValue::encode(shadowChicken->functionsOnStack(globalObject, callFrame));
2663     }
2664
2665     JSArray* result = constructEmptyArray(globalObject, nullptr);
2666     RETURN_IF_EXCEPTION(scope, { });
2667     StackVisitor::visit(callFrame, vm, [&] (StackVisitor& visitor) -> StackVisitor::Status {
2668         DollarVMAssertScope assertScope;
2669         if (visitor->isInlinedFrame())
2670             return StackVisitor::Continue;
2671         if (visitor->isWasmFrame())
2672             return StackVisitor::Continue;
2673         result->push(globalObject, jsCast<JSObject*>(visitor->callee().asCell()));
2674         scope.releaseAssertNoException(); // This function is only called from tests.
2675         return StackVisitor::Continue;
2676     });
2677     RETURN_IF_EXCEPTION(scope, { });
2678     return JSValue::encode(result);
2679 }
2680
2681 static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(JSGlobalObject* globalObject, CallFrame*)
2682 {
2683     DollarVMAssertScope assertScope;
2684     VM& vm = globalObject->vm();
2685     vm.setGlobalConstRedeclarationShouldThrow(false);
2686     return JSValue::encode(jsUndefined());
2687 }
2688
2689 static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(JSGlobalObject* globalObject, CallFrame* callFrame)
2690 {
2691     DollarVMAssertScope assertScope;
2692     VM& vm = globalObject->vm();
2693     RELEASE_ASSERT(vm.typeProfiler());
2694     vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionFindTypeForExpression"_s);
2695
2696     JSValue functionValue = callFrame->argument(0);
2697     RELEASE_ASSERT(functionValue.isCallable(vm));
2698     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2699
2700     RELEASE_ASSERT(callFrame->argument(1).isString());
2701     String substring = asString(callFrame->argument(1))->value(globalObject);
2702     String sourceCodeText = executable->source().view().toString();
2703     unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
2704     
2705     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), vm);
2706     return JSValue::encode(JSONParse(globalObject, jsonString));
2707 }
2708
2709 static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(JSGlobalObject* globalObject, CallFrame* callFrame)
2710 {
2711     DollarVMAssertScope assertScope;
2712     VM& vm = globalObject->vm();
2713     RELEASE_ASSERT(vm.typeProfiler());
2714     vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionReturnTypeFor"_s);
2715
2716     JSValue functionValue = callFrame->argument(0);
2717     RELEASE_ASSERT(functionValue.isCallable(vm));
2718     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2719
2720     unsigned offset = executable->typeProfilingStartOffset(vm);
2721     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), vm);
2722     return JSValue::encode(JSONParse(globalObject, jsonString));
2723 }
2724
2725 static EncodedJSValue JSC_HOST_CALL functionFlattenDictionaryObject(JSGlobalObject* globalObject, CallFrame* callFrame)
2726 {
2727     DollarVMAssertScope assertScope;
2728     VM& vm = globalObject->vm();
2729     JSValue value = callFrame->argument(0);
2730     RELEASE_ASSERT(value.isObject() && value.getObject()->structure()->isDictionary());
2731     value.getObject()->flattenDictionaryObject(vm);
2732     return encodedJSUndefined();
2733 }
2734
2735 static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(JSGlobalObject* globalObject, CallFrame*)
2736 {
2737     DollarVMAssertScope assertScope;
2738     VM& vm = globalObject->vm();
2739     RELEASE_ASSERT(vm.controlFlowProfiler());
2740     vm.controlFlowProfiler()->dumpData();
2741     return JSValue::encode(jsUndefined());
2742 }
2743
2744 static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(JSGlobalObject* globalObject, CallFrame* callFrame)
2745 {
2746     DollarVMAssertScope assertScope;
2747     VM& vm = globalObject->vm();
2748     RELEASE_ASSERT(vm.controlFlowProfiler());
2749
2750     JSValue functionValue = callFrame->argument(0);
2751     RELEASE_ASSERT(functionValue.isCallable(vm));
2752     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2753
2754     RELEASE_ASSERT(callFrame->argument(1).isString());
2755     String substring = asString(callFrame->argument(1))->value(globalObject);
2756     String sourceCodeText = executable->source().view().toString();
2757     RELEASE_ASSERT(sourceCodeText.contains(substring));
2758     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2759     
2760     bool hasExecuted = vm.controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset, executable->sourceID(), vm);
2761     return JSValue::encode(jsBoolean(hasExecuted));
2762 }
2763
2764 static EncodedJSValue JSC_HOST_CALL functionBasicBlockExecutionCount(JSGlobalObject* globalObject, CallFrame* callFrame)
2765 {
2766     DollarVMAssertScope assertScope;
2767     VM& vm = globalObject->vm();
2768     RELEASE_ASSERT(vm.controlFlowProfiler());
2769
2770     JSValue functionValue = callFrame->argument(0);
2771     RELEASE_ASSERT(functionValue.isCallable(vm));
2772     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2773
2774     RELEASE_ASSERT(callFrame->argument(1).isString());
2775     String substring = asString(callFrame->argument(1))->value(globalObject);
2776     String sourceCodeText = executable->source().view().toString();
2777     RELEASE_ASSERT(sourceCodeText.contains(substring));
2778     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2779     
2780     size_t executionCount = vm.controlFlowProfiler()->basicBlockExecutionCountAtTextOffset(offset, executable->sourceID(), vm);
2781     return JSValue::encode(JSValue(executionCount));
2782 }
2783
2784 class DoNothingDebugger final : public Debugger {
2785     WTF_MAKE_NONCOPYABLE(DoNothingDebugger);
2786     WTF_MAKE_FAST_ALLOCATED;
2787 public:
2788     DoNothingDebugger(VM& vm)
2789         : Debugger(vm)
2790     {
2791         DollarVMAssertScope assertScope;
2792         setSuppressAllPauses(true);
2793     }
2794
2795 private:
2796     void sourceParsed(JSGlobalObject*, SourceProvider*, int, const WTF::String&) final
2797     {
2798         DollarVMAssertScope assertScope;
2799     }
2800 };
2801
2802 static EncodedJSValue changeDebuggerModeWhenIdle(JSGlobalObject* globalObject, OptionSet<CodeGenerationMode> codeGenerationMode)
2803 {
2804     DollarVMAssertScope assertScope;
2805
2806     bool debuggerRequested = codeGenerationMode.contains(CodeGenerationMode::Debugger);
2807     if (debuggerRequested == globalObject->hasDebugger())
2808         return JSValue::encode(jsUndefined());
2809
2810     VM* vm = &globalObject->vm();
2811     vm->whenIdle([=] () {
2812         DollarVMAssertScope assertScope;
2813         if (debuggerRequested) {
2814             Debugger* debugger = new DoNothingDebugger(globalObject->vm());
2815             globalObject->setDebugger(debugger);
2816             debugger->activateBreakpoints(); // Also deletes all code.
2817         } else {
2818             Debugger* debugger = globalObject->debugger();
2819             debugger->deactivateBreakpoints(); // Also deletes all code.
2820             globalObject->setDebugger(nullptr);
2821             delete debugger;
2822         }
2823     });
2824     return JSValue::encode(jsUndefined());
2825 }
2826
2827 static EncodedJSValue JSC_HOST_CALL functionEnableDebuggerModeWhenIdle(JSGlobalObject* globalObject, CallFrame*)
2828 {
2829     DollarVMAssertScope assertScope;
2830     return changeDebuggerModeWhenIdle(globalObject, { CodeGenerationMode::Debugger });
2831 }
2832
2833 static EncodedJSValue JSC_HOST_CALL functionDisableDebuggerModeWhenIdle(JSGlobalObject* globalObject, CallFrame*)
2834 {
2835     DollarVMAssertScope assertScope;
2836     return changeDebuggerModeWhenIdle(globalObject, { });
2837 }
2838
2839 static EncodedJSValue JSC_HOST_CALL functionDeleteAllCodeWhenIdle(JSGlobalObject* globalObject, CallFrame*)
2840 {
2841     DollarVMAssertScope assertScope;
2842     VM* vm = &globalObject->vm();
2843     vm->whenIdle([=] () {
2844         DollarVMAssertScope assertScope;
2845         vm->deleteAllCode(PreventCollectionAndDeleteAllCode);
2846     });
2847     return JSValue::encode(jsUndefined());
2848 }
2849
2850 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectCount(JSGlobalObject* globalObject, CallFrame*)
2851 {
2852     DollarVMAssertScope assertScope;
2853     return JSValue::encode(jsNumber(globalObject->vm().heap.globalObjectCount()));
2854 }
2855
2856 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(JSGlobalObject* globalObject, CallFrame* callFrame)
2857 {
2858     DollarVMAssertScope assertScope;
2859     JSValue value = callFrame->argument(0);
2860     RELEASE_ASSERT(value.isObject());
2861     JSGlobalObject* result = jsCast<JSObject*>(value)->globalObject(globalObject->vm());
2862     RELEASE_ASSERT(result);
2863     return JSValue::encode(result);
2864 }
2865
2866 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(JSGlobalObject* globalObject, CallFrame* callFrame)
2867 {
2868     DollarVMAssertScope assertScope;
2869     VM& vm = globalObject->vm();
2870     auto scope = DECLARE_THROW_SCOPE(vm);
2871
2872     JSValue value = callFrame->argument(0);
2873     if (!value.isObject())
2874         return JSValue::encode(jsUndefined());
2875
2876     JSValue property = callFrame->argument(1);
2877     if (!property.isString())
2878         return JSValue::encode(jsUndefined());
2879
2880     auto propertyName = asString(property)->toIdentifier(globalObject);
2881     RETURN_IF_EXCEPTION(scope, { });
2882
2883     PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry);
2884     value.getPropertySlot(globalObject, propertyName, slot);
2885     RETURN_IF_EXCEPTION(scope, { });
2886
2887     JSValue result;
2888     if (slot.isCacheableGetter())
2889         result = slot.getterSetter();
2890     else
2891         result = jsNull();
2892
2893     return JSValue::encode(result);
2894 }
2895
2896 static EncodedJSValue JSC_HOST_CALL functionLoadGetterFromGetterSetter(JSGlobalObject* globalObject, CallFrame* callFrame)
2897 {
2898     DollarVMAssertScope assertScope;
2899     VM& vm = globalObject->vm();
2900     auto scope = DECLARE_THROW_SCOPE(vm);
2901
2902     GetterSetter* getterSetter = jsDynamicCast<GetterSetter*>(vm, callFrame->argument(0));
2903     if (UNLIKELY(!getterSetter)) {
2904         throwTypeError(globalObject, scope, "Invalid use of loadGetterFromGetterSetter test function: argument is not a GetterSetter"_s);
2905         return encodedJSValue();
2906     }
2907
2908     JSObject* getter = getterSetter->getter();
2909     RELEASE_ASSERT(getter);
2910     return JSValue::encode(getter);
2911 }
2912
2913 static EncodedJSValue JSC_HOST_CALL functionCreateCustomTestGetterSetter(JSGlobalObject* globalObject, CallFrame*)
2914 {
2915     DollarVMAssertScope assertScope;
2916     VM& vm = globalObject->vm();
2917     return JSValue::encode(JSTestCustomGetterSetter::create(vm, globalObject, JSTestCustomGetterSetter::createStructure(vm, globalObject)));
2918 }
2919
2920 static EncodedJSValue JSC_HOST_CALL functionDeltaBetweenButterflies(JSGlobalObject* globalObject, CallFrame* callFrame)
2921 {
2922     DollarVMAssertScope assertScope;
2923     VM& vm = globalObject->vm();
2924     JSObject* a = jsDynamicCast<JSObject*>(vm, callFrame->argument(0));
2925     JSObject* b = jsDynamicCast<JSObject*>(vm, callFrame->argument(1));
2926     if (!a || !b)
2927         return JSValue::encode(jsNumber(PNaN));
2928
2929     ptrdiff_t delta = bitwise_cast<char*>(a->butterfly()) - bitwise_cast<char*>(b->butterfly());
2930     if (delta < 0)
2931         return JSValue::encode(jsNumber(PNaN));
2932     if (delta > std::numeric_limits<int32_t>::max())
2933         return JSValue::encode(jsNumber(PNaN));
2934     return JSValue::encode(jsNumber(static_cast<int32_t>(delta)));
2935 }
2936
2937 static EncodedJSValue JSC_HOST_CALL functionCurrentCPUTime(JSGlobalObject*, CallFrame*)
2938 {
2939     DollarVMAssertScope assertScope;
2940     return JSValue::encode(jsNumber(CPUTime::forCurrentThread().value()));
2941 }
2942
2943 static EncodedJSValue JSC_HOST_CALL functionTotalGCTime(JSGlobalObject* globalObject, CallFrame*)
2944 {
2945     DollarVMAssertScope assertScope;
2946     VM& vm = globalObject->vm();
2947     return JSValue::encode(jsNumber(vm.heap.totalGCTime().seconds()));
2948 }
2949
2950 static EncodedJSValue JSC_HOST_CALL functionParseCount(JSGlobalObject*, CallFrame*)
2951 {
2952     DollarVMAssertScope assertScope;
2953     return JSValue::encode(jsNumber(globalParseCount.load()));
2954 }
2955
2956 static EncodedJSValue JSC_HOST_CALL functionIsWasmSupported(JSGlobalObject*, CallFrame*)
2957 {
2958     DollarVMAssertScope assertScope;
2959 #if ENABLE(WEBASSEMBLY)
2960     return JSValue::encode(jsBoolean(Wasm::isSupported()));
2961 #else
2962     return JSValue::encode(jsBoolean(false));
2963 #endif
2964 }
2965
2966 static EncodedJSValue JSC_HOST_CALL functionMake16BitStringIfPossible(JSGlobalObject* globalObject, CallFrame* callFrame)
2967 {
2968     DollarVMAssertScope assertScope;
2969     VM& vm = globalObject->vm();
2970     auto scope = DECLARE_THROW_SCOPE(vm);
2971     String string = callFrame->argument(0).toWTFString(globalObject);
2972     RETURN_IF_EXCEPTION(scope, { });
2973     if (!string.is8Bit())
2974         return JSValue::encode(jsString(vm, WTFMove(string)));
2975     Vector<UChar> buffer;
2976     buffer.resize(string.length());
2977     StringImpl::copyCharacters(buffer.data(), string.characters8(), string.length());
2978     return JSValue::encode(jsString(vm, String::adopt(WTFMove(buffer))));
2979 }
2980
2981 EncodedJSValue JSC_HOST_CALL JSDollarVMHelper::functionGetStructureTransitionList(JSGlobalObject* globalObject, CallFrame* callFrame)
2982 {
2983     DollarVMAssertScope assertScope;
2984     VM& vm = globalObject->vm();
2985     auto scope = DECLARE_THROW_SCOPE(vm);
2986     JSObject* obj = callFrame->argument(0).toObject(globalObject);
2987     RETURN_IF_EXCEPTION(scope, { });
2988     if (!obj)
2989         return JSValue::encode(jsNull());
2990     Vector<Structure*, 8> structures;
2991
2992     for (auto* structure = obj->structure(); structure; structure = structure->previousID())
2993         structures.append(structure);
2994
2995     JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0);
2996     RETURN_IF_EXCEPTION(scope, { });
2997
2998     for (size_t i = 0; i < structures.size(); ++i) {
2999         auto* structure = structures[structures.size() - i - 1];
3000         result->push(globalObject, JSValue(structure->id()));
3001         RETURN_IF_EXCEPTION(scope, { });
3002         result->push(globalObject, JSValue(structure->transitionOffset()));
3003         RETURN_IF_EXCEPTION(scope, { });
3004         result->push(globalObject, JSValue(structure->maxOffset()));
3005         RETURN_IF_EXCEPTION(scope, { });
3006         if (structure->m_transitionPropertyName)
3007             result->push(globalObject, jsString(vm, String(*structure->m_transitionPropertyName)));
3008         else
3009             result->push(globalObject, jsNull());
3010         RETURN_IF_EXCEPTION(scope, { });
3011         result->push(globalObject, JSValue(structure->isPropertyDeletionTransition()));
3012         RETURN_IF_EXCEPTION(scope, { });
3013     }
3014
3015     return JSValue::encode(result);
3016 }
3017
3018 static EncodedJSValue JSC_HOST_CALL functionGetConcurrently(JSGlobalObject* globalObject, CallFrame* callFrame)
3019 {
3020     DollarVMAssertScope assertScope;
3021     VM& vm = globalObject->vm();
3022     auto scope = DECLARE_THROW_SCOPE(vm);
3023     JSObject* obj = callFrame->argument(0).toObject(globalObject);
3024     RETURN_IF_EXCEPTION(scope, { });
3025     if (!obj)
3026         return JSValue::encode(jsNull());
3027     String property = callFrame->argument(1).toWTFString(globalObject);
3028     RETURN_IF_EXCEPTION(scope, { });
3029     auto name = PropertyName(Identifier::fromString(vm, property));
3030     auto offset = obj->structure()->getConcurrently(name.uid());
3031     if (offset != invalidOffset)
3032         ASSERT(JSValue::encode(obj->getDirect(offset)));
3033     JSValue result = JSValue(offset != invalidOffset);
3034     RETURN_IF_EXCEPTION(scope, { });
3035     return JSValue::encode(result);
3036 }
3037
3038 static EncodedJSValue JSC_HOST_CALL functionHasOwnLengthProperty(JSGlobalObject* globalObject, CallFrame* callFrame)
3039 {
3040     VM& vm = globalObject->vm();
3041
3042     JSObject* target = asObject(callFrame->uncheckedArgument(0));
3043     JSFunction* function = jsDynamicCast<JSFunction*>(vm, target);
3044     return JSValue::encode(jsBoolean(function->canAssumeNameAndLengthAreOriginal(vm)));
3045 }
3046
3047 static EncodedJSValue JSC_HOST_CALL functionRejectPromiseAsHandled(JSGlobalObject* globalObject, CallFrame* callFrame)
3048 {
3049     JSPromise* promise = jsCast<JSPromise*>(callFrame->uncheckedArgument(0));
3050     JSValue reason = callFrame->uncheckedArgument(1);
3051     promise->rejectAsHandled(globalObject, reason);
3052     return JSValue::encode(jsUndefined());
3053 }
3054
3055 static EncodedJSValue JSC_HOST_CALL functionSetUserPreferredLanguages(JSGlobalObject* globalObject, CallFrame* callFrame)
3056 {
3057     VM& vm = globalObject->vm();
3058     auto scope = DECLARE_THROW_SCOPE(vm);
3059
3060     JSArray* array = jsDynamicCast<JSArray*>(vm, callFrame->argument(0));
3061     if (!array)
3062         return throwVMTypeError(globalObject, scope, "Expected first argument to be an array"_s);
3063
3064     Vector<String> languages;
3065     unsigned length = array->length();
3066     for (unsigned i = 0; i < length; i++) {
3067         String language = array->get(globalObject, i).toWTFString(globalObject);
3068         RETURN_IF_EXCEPTION(scope, encodedJSValue());
3069         languages.append(language);
3070     }
3071
3072     overrideUserPreferredLanguages(languages);
3073     return JSValue::encode(jsUndefined());
3074 }
3075
3076 static EncodedJSValue JSC_HOST_CALL functionICUVersion(JSGlobalObject*, CallFrame*)
3077 {
3078     UVersionInfo versionInfo;
3079     u_getVersion(versionInfo);
3080     return JSValue::encode(jsNumber(versionInfo[0]));
3081 }
3082
3083 static EncodedJSValue JSC_HOST_CALL functionAssertEnabled(JSGlobalObject*, CallFrame*)
3084 {
3085     return JSValue::encode(jsBoolean(ASSERT_ENABLED));
3086 }
3087
3088 static EncodedJSValue JSC_HOST_CALL functionIsMemoryLimited(JSGlobalObject*, CallFrame*)
3089 {
3090 #if PLATFORM(IOS) || PLATFORM(APPLETV) || PLATFORM(WATCHOS)
3091     return JSValue::encode(jsBoolean(true));
3092 #else
3093     return JSValue::encode(jsBoolean(false));
3094 #endif
3095 }
3096
3097 static EncodedJSValue JSC_HOST_CALL functionUseJIT(JSGlobalObject*, CallFrame*)
3098 {
3099     return JSValue::encode(jsBoolean(Options::useJIT()));
3100 }
3101
3102 constexpr unsigned jsDollarVMPropertyAttributes = PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete;
3103
3104 void JSDollarVM::finishCreation(VM& vm)
3105 {
3106     DollarVMAssertScope assertScope;
3107     Base::finishCreation(vm);
3108
3109     JSGlobalObject* globalObject = this->globalObject(vm);
3110
3111     auto addFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
3112         DollarVMAssertScope assertScope;
3113         JSDollarVM::addFunction(vm, globalObject, name, function, arguments);
3114     };
3115     auto addConstructibleFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
3116         DollarVMAssertScope assertScope;
3117         JSDollarVM::addConstructibleFunction(vm, globalObject, name, function, arguments);
3118     };
3119
3120     addFunction(vm, "abort", functionCrash, 0);
3121     addFunction(vm, "crash", functionCrash, 0);
3122     addFunction(vm, "breakpoint", functionBreakpoint, 0);
3123
3124     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "dfgTrue"), 0, functionDFGTrue, DFGTrueIntrinsic, jsDollarVMPropertyAttributes);
3125     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "ftlTrue"), 0, functionFTLTrue, FTLTrueIntrinsic, jsDollarVMPropertyAttributes);
3126
3127     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuMfence"), 0, functionCpuMfence, CPUMfenceIntrinsic, jsDollarVMPropertyAttributes);
3128     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuRdtsc"), 0, functionCpuRdtsc, CPURdtscIntrinsic, jsDollarVMPropertyAttributes);
3129     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuCpuid"), 0, functionCpuCpuid, CPUCpuidIntrinsic, jsDollarVMPropertyAttributes);
3130     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuPause"), 0, functionCpuPause, CPUPauseIntrinsic, jsDollarVMPropertyAttributes);
3131     addFunction(vm, "cpuClflush", functionCpuClflush, 2);
3132
3133     addFunction(vm, "llintTrue", functionLLintTrue, 0);
3134     addFunction(vm, "jitTrue", functionJITTrue, 0);
3135
3136     addFunction(vm, "noInline", functionNoInline, 1);
3137
3138     addFunction(vm, "gc", functionGC, 0);
3139     addFunction(vm, "gcSweepAsynchronously", functionGCSweepAsynchronously, 0);
3140     addFunction(vm, "edenGC", functionEdenGC, 0);
3141     addFunction(vm, "dumpSubspaceHashes", functionDumpSubspaceHashes, 0);
3142
3143     addFunction(vm, "callFrame", functionCallFrame, 1);
3144     addFunction(vm, "codeBlockFor", functionCodeBlockFor, 1);
3145     addFunction(vm, "codeBlockForFrame", functionCodeBlockForFrame, 1);
3146     addFunction(vm, "dumpSourceFor", functionDumpSourceFor, 1);
3147     addFunction(vm, "dumpBytecodeFor", functionDumpBytecodeFor, 1);
3148
3149     addFunction(vm, "dataLog", functionDataLog, 1);
3150     addFunction(vm, "print", functionPrint, 1);
3151     addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
3152     addFunction(vm, "dumpStack", functionDumpStack, 0);
3153     addFunction(vm, "dumpRegisters", functionDumpRegisters, 1);
3154
3155     addFunction(vm, "dumpCell", functionDumpCell, 1);
3156
3157     addFunction(vm, "indexingMode", functionIndexingMode, 1);
3158     addFunction(vm, "inlineCapacity", functionInlineCapacity, 1);
3159     addFunction(vm, "value", functionValue, 1);
3160     addFunction(vm, "getpid", functionGetPID, 0);
3161
3162     addFunction(vm, "haveABadTime", functionHaveABadTime, 1);
3163     addFunction(vm, "isHavingABadTime", functionIsHavingABadTime, 1);
3164
3165     addFunction(vm, "callWithStackSize", functionCallWithStackSize, 2);
3166
3167     addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0);
3168     addFunction(vm, "createProxy", functionCreateProxy, 1);
3169     addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);
3170     addFunction(vm, "createNullRopeString", functionCreateNullRopeString, 0);
3171
3172     addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
3173     addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0);
3174     addFunction(vm, "createDOMJITNodeObject", functionCreateDOMJITNodeObject, 0);
3175     addFunction(vm, "createDOMJITGetterObject", functionCreateDOMJITGetterObject, 0);
3176     addFunction(vm, "createDOMJITGetterNoEffectsObject", functionCreateDOMJITGetterNoEffectsObject, 0);
3177     addFunction(vm, "createDOMJITGetterComplexObject", functionCreateDOMJITGetterComplexObject, 0);
3178     addFunction(vm, "createDOMJITFunctionObject", functionCreateDOMJITFunctionObject, 0);
3179     addFunction(vm, "createDOMJITCheckJSCastObject", functionCreateDOMJITCheckJSCastObject, 0);
3180     addFunction(vm, "createDOMJITGetterBaseJSObject", functionCreateDOMJITGetterBaseJSObject, 0);
3181     addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);
3182 #if ENABLE(WEBASSEMBLY)
3183     addFunction(vm, "createWasmStreamingParser", functionCreateWasmStreamingParser, 0);
3184 #endif
3185     addFunction(vm, "createStaticCustomAccessor", functionCreateStaticCustomAccessor, 0);
3186     addFunction(vm, "createObjectDoingSideEffectPutWithoutCorrectSlotStatus", functionCreateObjectDoingSideEffectPutWithoutCorrectSlotStatus, 0);
3187     addFunction(vm, "createEmptyFunctionWithName", functionCreateEmptyFunctionWithName, 1);
3188     addFunction(vm, "getPrivateProperty", functionGetPrivateProperty, 2);
3189     addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
3190
3191     addConstructibleFunction(vm, "Root", functionCreateRoot, 0);
3192     addConstructibleFunction(vm, "Element", functionCreateElement, 1);
3193     addFunction(vm, "getElement", functionGetElement, 1);
3194
3195     addConstructibleFunction(vm, "SimpleObject", functionCreateSimpleObject, 0);
3196     addFunction(vm, "getHiddenValue", functionGetHiddenValue, 1);
3197     addFunction(vm, "setHiddenValue", functionSetHiddenValue, 2);
3198
3199     addFunction(vm, "shadowChickenFunctionsOnStack", functionShadowChickenFunctionsOnStack, 0);
3200     addFunction(vm, "setGlobalConstRedeclarationShouldNotThrow", functionSetGlobalConstRedeclarationShouldNotThrow, 0);
3201
3202     addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);
3203     addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);
3204
3205     addFunction(vm, "flattenDictionaryObject", functionFlattenDictionaryObject, 1);
3206
3207     addFunction(vm, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges , 0);
3208     addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
3209     addFunction(vm, "basicBlockExecutionCount", functionBasicBlockExecutionCount, 2);
3210
3211     addFunction(vm, "enableDebuggerModeWhenIdle", functionEnableDebuggerModeWhenIdle, 0);
3212     addFunction(vm, "disableDebuggerModeWhenIdle", functionDisableDebuggerModeWhenIdle, 0);
3213
3214     addFunction(vm, "deleteAllCodeWhenIdle", functionDeleteAllCodeWhenIdle, 0);
3215
3216     addFunction(vm, "globalObjectCount", functionGlobalObjectCount, 0);
3217     addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);
3218
3219     addFunction(vm, "getGetterSetter", functionGetGetterSetter, 2);
3220     addFunction(vm, "loadGetterFromGetterSetter", functionLoadGetterFromGetterSetter, 1);
3221     addFunction(vm, "createCustomTestGetterSetter", functionCreateCustomTestGetterSetter, 1);
3222
3223     addFunction(vm, "deltaBetweenButterflies", functionDeltaBetweenButterflies, 2);
3224     
3225     addFunction(vm, "currentCPUTime", functionCurrentCPUTime, 0);
3226     addFunction(vm, "totalGCTime", functionTotalGCTime, 0);
3227
3228     addFunction(vm, "parseCount", functionParseCount, 0);
3229
3230     addFunction(vm, "isWasmSupported", functionIsWasmSupported, 0);
3231     addFunction(vm, "make16BitStringIfPossible", functionMake16BitStringIfPossible, 1);
3232
3233     addFunction(vm, "getStructureTransitionList", JSDollarVMHelper::functionGetStructureTransitionList, 1);
3234     addFunction(vm, "getConcurrently", functionGetConcurrently, 2);
3235
3236     addFunction(vm, "hasOwnLengthProperty", functionHasOwnLengthProperty, 1);
3237     addFunction(vm, "rejectPromiseAsHandled", functionRejectPromiseAsHandled, 1);
3238
3239     addFunction(vm, "setUserPreferredLanguages", functionSetUserPreferredLanguages, 1);
3240     addFunction(vm, "icuVersion", functionICUVersion, 0);
3241
3242     addFunction(vm, "assertEnabled", functionAssertEnabled, 0);
3243
3244     addFunction(vm, "isMemoryLimited", functionIsMemoryLimited, 0);
3245     addFunction(vm, "useJIT", functionUseJIT, 0);
3246
3247     m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure.set(vm, this, ObjectDoingSideEffectPutWithoutCorrectSlotStatus::createStructure(vm, globalObject, jsNull()));
3248 }
3249
3250 void JSDollarVM::addFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
3251 {
3252     DollarVMAssertScope assertScope;
3253     Identifier identifier = Identifier::fromString(vm, name);
3254     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function), jsDollarVMPropertyAttributes);
3255 }
3256
3257 void JSDollarVM::addConstructibleFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
3258 {
3259     DollarVMAssertScope assertScope;
3260     Identifier identifier = Identifier::fromString(vm, name);
3261     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function, NoIntrinsic, function), jsDollarVMPropertyAttributes);
3262 }
3263
3264 void JSDollarVM::visitChildren(JSCell* cell, SlotVisitor& visitor)
3265 {
3266     JSDollarVM* thisObject = jsCast<JSDollarVM*>(cell);
3267     Base::visitChildren(thisObject, visitor);
3268     visitor.append(thisObject->m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure);
3269 }
3270
3271 } // namespace JSC
3272
3273 IGNORE_WARNINGS_END