[BigInt] Add ValueBitLShift into DFG
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGOperations.cpp
1 /*
2  * Copyright (C) 2011-2019 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 "DFGOperations.h"
28
29 #include "ArrayConstructor.h"
30 #include "ButterflyInlines.h"
31 #include "ClonedArguments.h"
32 #include "CodeBlock.h"
33 #include "CommonSlowPaths.h"
34 #include "DFGDriver.h"
35 #include "DFGJITCode.h"
36 #include "DFGOSRExit.h"
37 #include "DFGThunks.h"
38 #include "DFGToFTLDeferredCompilationCallback.h"
39 #include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
40 #include "DFGWorklist.h"
41 #include "DefinePropertyAttributes.h"
42 #include "DirectArguments.h"
43 #include "FTLForOSREntryJITCode.h"
44 #include "FTLOSREntry.h"
45 #include "FrameTracers.h"
46 #include "HasOwnPropertyCache.h"
47 #include "HostCallReturnValue.h"
48 #include "Interpreter.h"
49 #include "JIT.h"
50 #include "JITExceptions.h"
51 #include "JSArrayInlines.h"
52 #include "JSBigInt.h"
53 #include "JSCInlines.h"
54 #include "JSFixedArray.h"
55 #include "JSGenericTypedArrayViewConstructorInlines.h"
56 #include "JSGlobalObjectFunctions.h"
57 #include "JSImmutableButterfly.h"
58 #include "JSLexicalEnvironment.h"
59 #include "JSMap.h"
60 #include "JSPropertyNameEnumerator.h"
61 #include "JSSet.h"
62 #include "JSWeakMap.h"
63 #include "JSWeakSet.h"
64 #include "NumberConstructor.h"
65 #include "ObjectConstructor.h"
66 #include "Operations.h"
67 #include "ParseInt.h"
68 #include "RegExpGlobalDataInlines.h"
69 #include "RegExpMatchesArray.h"
70 #include "RegExpObjectInlines.h"
71 #include "Repatch.h"
72 #include "ScopedArguments.h"
73 #include "StringConstructor.h"
74 #include "StringPrototypeInlines.h"
75 #include "SuperSampler.h"
76 #include "Symbol.h"
77 #include "TypeProfilerLog.h"
78 #include "TypedArrayInlines.h"
79 #include "VMInlines.h"
80 #include <wtf/InlineASM.h>
81 #include <wtf/Variant.h>
82
83 #if ENABLE(JIT)
84 #if ENABLE(DFG_JIT)
85
86 namespace JSC { namespace DFG {
87
88 template<bool strict, bool direct>
89 static inline void putByVal(ExecState* exec, VM& vm, JSValue baseValue, uint32_t index, JSValue value)
90 {
91     ASSERT(isIndex(index));
92     if (direct) {
93         RELEASE_ASSERT(baseValue.isObject());
94         asObject(baseValue)->putDirectIndex(exec, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
95         return;
96     }
97     if (baseValue.isObject()) {
98         JSObject* object = asObject(baseValue);
99         if (object->canSetIndexQuickly(index)) {
100             object->setIndexQuickly(vm, index, value);
101             return;
102         }
103
104         object->methodTable(vm)->putByIndex(object, exec, index, value, strict);
105         return;
106     }
107
108     baseValue.putByIndex(exec, index, value, strict);
109 }
110
111 template<bool strict, bool direct>
112 ALWAYS_INLINE static void putByValInternal(ExecState* exec, VM& vm, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
113 {
114     auto scope = DECLARE_THROW_SCOPE(vm);
115
116     JSValue baseValue = JSValue::decode(encodedBase);
117     JSValue property = JSValue::decode(encodedProperty);
118     JSValue value = JSValue::decode(encodedValue);
119
120     if (LIKELY(property.isUInt32())) {
121         // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
122         ASSERT(isIndex(property.asUInt32()));
123         scope.release();
124         putByVal<strict, direct>(exec, vm, baseValue, property.asUInt32(), value);
125         return;
126     }
127
128     if (property.isDouble()) {
129         double propertyAsDouble = property.asDouble();
130         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
131         if (propertyAsDouble == propertyAsUInt32 && isIndex(propertyAsUInt32)) {
132             scope.release();
133             putByVal<strict, direct>(exec, vm, baseValue, propertyAsUInt32, value);
134             return;
135         }
136     }
137
138     // Don't put to an object if toString throws an exception.
139     auto propertyName = property.toPropertyKey(exec);
140     RETURN_IF_EXCEPTION(scope, void());
141
142     PutPropertySlot slot(baseValue, strict);
143     if (direct) {
144         RELEASE_ASSERT(baseValue.isObject());
145         JSObject* baseObject = asObject(baseValue);
146         if (Optional<uint32_t> index = parseIndex(propertyName)) {
147             scope.release();
148             baseObject->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
149             return;
150         }
151         scope.release();
152         CommonSlowPaths::putDirectWithReify(vm, exec, baseObject, propertyName, value, slot);
153         return;
154     }
155     scope.release();
156     baseValue.put(exec, propertyName, value, slot);
157 }
158
159 template<bool strict, bool direct>
160 ALWAYS_INLINE static void putByValCellInternal(ExecState* exec, VM& vm, JSCell* base, PropertyName propertyName, JSValue value)
161 {
162     PutPropertySlot slot(base, strict);
163     if (direct) {
164         RELEASE_ASSERT(base->isObject());
165         JSObject* baseObject = asObject(base);
166         if (Optional<uint32_t> index = parseIndex(propertyName)) {
167             baseObject->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
168             return;
169         }
170         CommonSlowPaths::putDirectWithReify(vm, exec, baseObject, propertyName, value, slot);
171         return;
172     }
173     base->putInline(exec, propertyName, value, slot);
174 }
175
176 template<bool strict, bool direct>
177 ALWAYS_INLINE static void putByValCellStringInternal(ExecState* exec, VM& vm, JSCell* base, JSString* property, JSValue value)
178 {
179     auto scope = DECLARE_THROW_SCOPE(vm);
180
181     auto propertyName = property->toIdentifier(exec);
182     RETURN_IF_EXCEPTION(scope, void());
183
184     scope.release();
185     putByValCellInternal<strict, direct>(exec, vm, base, propertyName, value);
186 }
187
188 template<typename ViewClass>
189 char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size, char* vector)
190 {
191     VM& vm = exec->vm();
192     NativeCallFrameTracer tracer(&vm, exec);
193     auto scope = DECLARE_THROW_SCOPE(vm);
194
195     if (size < 0) {
196         throwException(exec, scope, createRangeError(exec, "Requested length is negative"_s));
197         return 0;
198     }
199     
200     if (vector)
201         return bitwise_cast<char*>(ViewClass::createWithFastVector(exec, structure, size, untagArrayPtr(vector, size)));
202
203     RELEASE_AND_RETURN(scope, bitwise_cast<char*>(ViewClass::create(exec, structure, size)));
204 }
205
206 template <bool strict>
207 static ALWAYS_INLINE void putWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, const Identifier& ident)
208 {
209     JSValue baseValue = JSValue::decode(encodedBase);
210     JSValue thisVal = JSValue::decode(encodedThis);
211     JSValue putValue = JSValue::decode(encodedValue);
212     PutPropertySlot slot(thisVal, strict);
213     baseValue.putInline(exec, ident, putValue, slot);
214 }
215
216 template<typename BigIntOperation, typename NumberOperation>
217 static ALWAYS_INLINE EncodedJSValue binaryOp(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BigIntOperation&& bigIntOp, NumberOperation&& numberOp, const char* errorMessage)
218 {
219     VM* vm = &exec->vm();
220     NativeCallFrameTracer tracer(vm, exec);
221     auto scope = DECLARE_THROW_SCOPE(*vm);
222
223     JSValue op1 = JSValue::decode(encodedOp1);
224     JSValue op2 = JSValue::decode(encodedOp2);
225
226     auto leftNumeric = op1.toNumeric(exec);
227     RETURN_IF_EXCEPTION(scope, encodedJSValue());
228     auto rightNumeric = op2.toNumeric(exec);
229     RETURN_IF_EXCEPTION(scope, encodedJSValue());
230
231     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
232         if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric))
233             RELEASE_AND_RETURN(scope, JSValue::encode(bigIntOp(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric))));
234
235         return throwVMTypeError(exec, scope, errorMessage);
236     }
237
238     scope.release();
239
240     return JSValue::encode(jsNumber(numberOp(WTF::get<double>(leftNumeric), WTF::get<double>(rightNumeric))));
241 }
242
243 template<typename BigIntOperation, typename Int32Operation>
244 static ALWAYS_INLINE EncodedJSValue bitwiseBinaryOp(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BigIntOperation&& bigIntOp, Int32Operation&& int32Op, const char* errorMessage)
245 {
246     VM* vm = &exec->vm();
247     NativeCallFrameTracer tracer(vm, exec);
248     auto scope = DECLARE_THROW_SCOPE(*vm);
249
250     JSValue op1 = JSValue::decode(encodedOp1);
251     JSValue op2 = JSValue::decode(encodedOp2);
252
253     auto leftNumeric = op1.toBigIntOrInt32(exec);
254     RETURN_IF_EXCEPTION(scope, encodedJSValue());
255     auto rightNumeric = op2.toBigIntOrInt32(exec);
256     RETURN_IF_EXCEPTION(scope, encodedJSValue());
257
258     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
259         if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric))
260             RELEASE_AND_RETURN(scope, JSValue::encode(bigIntOp(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric))));
261
262         return throwVMTypeError(exec, scope, errorMessage);
263     }
264
265     scope.release();
266
267     return JSValue::encode(jsNumber(int32Op(WTF::get<int32_t>(leftNumeric), WTF::get<int32_t>(rightNumeric))));
268 }
269
270 static ALWAYS_INLINE EncodedJSValue parseIntResult(double input)
271 {
272     int asInt = static_cast<int>(input);
273     if (static_cast<double>(asInt) == input)
274         return JSValue::encode(jsNumber(asInt));
275     return JSValue::encode(jsNumber(input));
276 }
277
278 ALWAYS_INLINE static JSValue getByValObject(ExecState* exec, VM& vm, JSObject* base, PropertyName propertyName)
279 {
280     Structure& structure = *base->structure(vm);
281     if (JSCell::canUseFastGetOwnProperty(structure)) {
282         if (JSValue result = base->fastGetOwnProperty(vm, structure, propertyName))
283             return result;
284     }
285     return base->get(exec, propertyName);
286 }
287
288 extern "C" {
289
290 EncodedJSValue JIT_OPERATION operationToThis(ExecState* exec, EncodedJSValue encodedOp)
291 {
292     VM* vm = &exec->vm();
293     NativeCallFrameTracer tracer(vm, exec);
294
295     return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, NotStrictMode));
296 }
297
298 EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState* exec, EncodedJSValue encodedOp)
299 {
300     VM* vm = &exec->vm();
301     NativeCallFrameTracer tracer(vm, exec);
302
303     return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, StrictMode));
304 }
305
306 JSArray* JIT_OPERATION operationObjectKeys(ExecState* exec, EncodedJSValue encodedObject)
307 {
308     VM& vm = exec->vm();
309     NativeCallFrameTracer tracer(&vm, exec);
310     auto scope = DECLARE_THROW_SCOPE(vm);
311
312     JSObject* object = JSValue::decode(encodedObject).toObject(exec);
313     RETURN_IF_EXCEPTION(scope, nullptr);
314     scope.release();
315     return ownPropertyKeys(exec, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude);
316 }
317
318 JSArray* JIT_OPERATION operationObjectKeysObject(ExecState* exec, JSObject* object)
319 {
320     VM& vm = exec->vm();
321     NativeCallFrameTracer tracer(&vm, exec);
322     return ownPropertyKeys(exec, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude);
323 }
324
325 JSCell* JIT_OPERATION operationObjectCreate(ExecState* exec, EncodedJSValue encodedPrototype)
326 {
327     VM& vm = exec->vm();
328     NativeCallFrameTracer tracer(&vm, exec);
329     auto scope = DECLARE_THROW_SCOPE(vm);
330
331     JSValue prototype = JSValue::decode(encodedPrototype);
332
333     if (!prototype.isObject() && !prototype.isNull()) {
334         throwVMTypeError(exec, scope, "Object prototype may only be an Object or null."_s);
335         return nullptr;
336     }
337
338     if (prototype.isObject())
339         RELEASE_AND_RETURN(scope, constructEmptyObject(exec, asObject(prototype)));
340     RELEASE_AND_RETURN(scope, constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure()));
341 }
342
343 JSCell* JIT_OPERATION operationObjectCreateObject(ExecState* exec, JSObject* prototype)
344 {
345     VM& vm = exec->vm();
346     NativeCallFrameTracer tracer(&vm, exec);
347     return constructEmptyObject(exec, prototype);
348 }
349
350 JSCell* JIT_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, uint32_t inlineCapacity)
351 {
352     VM& vm = exec->vm();
353     NativeCallFrameTracer tracer(&vm, exec);
354     auto scope = DECLARE_THROW_SCOPE(vm);
355     if (constructor->type() == JSFunctionType && jsCast<JSFunction*>(constructor)->canUseAllocationProfile()) {
356         auto rareData = jsCast<JSFunction*>(constructor)->ensureRareDataAndAllocationProfile(exec, inlineCapacity);
357         scope.releaseAssertNoException();
358         ObjectAllocationProfileWithPrototype* allocationProfile = rareData->objectAllocationProfile();
359         Structure* structure = allocationProfile->structure();
360         JSObject* result = constructEmptyObject(exec, structure);
361         if (structure->hasPolyProto()) {
362             JSObject* prototype = allocationProfile->prototype();
363             ASSERT(prototype == jsCast<JSFunction*>(constructor)->prototypeForConstruction(vm, exec));
364             result->putDirect(vm, knownPolyProtoOffset, prototype);
365             prototype->didBecomePrototype();
366             ASSERT_WITH_MESSAGE(!hasIndexedProperties(result->indexingType()), "We rely on JSFinalObject not starting out with an indexing type otherwise we would potentially need to convert to slow put storage");
367         }
368         return result;
369     }
370
371     JSValue proto = constructor->get(exec, vm.propertyNames->prototype);
372     RETURN_IF_EXCEPTION(scope, nullptr);
373     if (proto.isObject())
374         return constructEmptyObject(exec, asObject(proto));
375     return constructEmptyObject(exec);
376 }
377
378 JSCell* JIT_OPERATION operationCallObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget)
379 {
380     VM* vm = &exec->vm();
381     NativeCallFrameTracer tracer(vm, exec);
382
383     JSValue value = JSValue::decode(encodedTarget);
384     ASSERT(!value.isObject());
385
386     if (value.isUndefinedOrNull())
387         return constructEmptyObject(exec, globalObject->objectPrototype());
388     return value.toObject(exec, globalObject);
389 }
390
391 JSCell* JIT_OPERATION operationToObject(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget, UniquedStringImpl* errorMessage)
392 {
393     VM* vm = &exec->vm();
394     NativeCallFrameTracer tracer(vm, exec);
395     auto scope = DECLARE_THROW_SCOPE(*vm);
396
397     JSValue value = JSValue::decode(encodedTarget);
398     ASSERT(!value.isObject());
399
400     if (UNLIKELY(value.isUndefinedOrNull())) {
401         if (errorMessage->length()) {
402             throwVMTypeError(exec, scope, errorMessage);
403             return nullptr;
404         }
405     }
406
407     RELEASE_AND_RETURN(scope, value.toObject(exec, globalObject));
408 }
409
410 EncodedJSValue JIT_OPERATION operationValueMod(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
411 {
412     auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* {
413         return JSBigInt::remainder(exec, left, right);
414     };
415
416     auto numberOp = [] (double left, double right) -> double {
417         return jsMod(left, right);
418     };
419
420     return binaryOp(exec, encodedOp1, encodedOp2, bigIntOp, numberOp, "Invalid mix of BigInt and other type in remainder operation.");
421 }
422
423 EncodedJSValue JIT_OPERATION operationValueBitNot(ExecState* exec, EncodedJSValue encodedOp1)
424 {
425     VM* vm = &exec->vm();
426     NativeCallFrameTracer tracer(vm, exec);
427     auto scope = DECLARE_THROW_SCOPE(*vm);
428
429     JSValue op1 = JSValue::decode(encodedOp1);
430
431     auto operandNumeric = op1.toBigIntOrInt32(exec);
432     RETURN_IF_EXCEPTION(scope, encodedJSValue());
433
434     if (WTF::holds_alternative<JSBigInt*>(operandNumeric))
435         RELEASE_AND_RETURN(scope, JSValue::encode(JSBigInt::bitwiseNot(exec, WTF::get<JSBigInt*>(operandNumeric))));
436
437     return JSValue::encode(jsNumber(~WTF::get<int32_t>(operandNumeric)));
438 }
439
440 EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
441 {
442     auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* {
443         return JSBigInt::bitwiseAnd(exec, left, right);
444     };
445
446     auto int32Op = [] (int32_t left, int32_t right) -> int32_t {
447         return left & right;
448     };
449
450     return bitwiseBinaryOp(exec, encodedOp1, encodedOp2, bigIntOp, int32Op, "Invalid mix of BigInt and other type in bitwise 'and' operation."_s);
451 }
452
453 EncodedJSValue JIT_OPERATION operationValueBitOr(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
454 {
455     auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* {
456         return JSBigInt::bitwiseOr(exec, left, right);
457     };
458
459     auto int32Op = [] (int32_t left, int32_t right) -> int32_t {
460         return left | right;
461     };
462
463     return bitwiseBinaryOp(exec, encodedOp1, encodedOp2, bigIntOp, int32Op, "Invalid mix of BigInt and other type in bitwise 'or' operation."_s);
464 }
465
466 EncodedJSValue JIT_OPERATION operationValueBitXor(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
467 {
468     auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* {
469         return JSBigInt::bitwiseXor(exec, left, right);
470     };
471
472     auto int32Op = [] (int32_t left, int32_t right) -> int32_t {
473         return left ^ right;
474     };
475
476     return bitwiseBinaryOp(exec, encodedOp1, encodedOp2, bigIntOp, int32Op, "Invalid mix of BigInt and other type in bitwise 'xor' operation."_s);
477 }
478
479 EncodedJSValue JIT_OPERATION operationValueBitLShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
480 {
481     auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* {
482         return JSBigInt::leftShift(exec, left, right);
483     };
484
485     auto int32Op = [] (int32_t left, int32_t right) -> int32_t {
486         return left << (right & 0x1f);
487     };
488
489     return bitwiseBinaryOp(exec, encodedOp1, encodedOp2, bigIntOp, int32Op, "Invalid mix of BigInt and other type in left shift operation."_s);
490 }
491
492 EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
493 {
494     VM* vm = &exec->vm();
495     NativeCallFrameTracer tracer(vm, exec);
496     auto scope = DECLARE_THROW_SCOPE(*vm);
497
498     JSValue op1 = JSValue::decode(encodedOp1);
499     JSValue op2 = JSValue::decode(encodedOp2);
500
501     int32_t a = op1.toInt32(exec);
502     RETURN_IF_EXCEPTION(scope, encodedJSValue());
503     scope.release();
504     uint32_t b = op2.toUInt32(exec);
505     return JSValue::encode(jsNumber(a >> (b & 0x1f)));
506 }
507
508 EncodedJSValue JIT_OPERATION operationValueBitURShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
509 {
510     VM* vm = &exec->vm();
511     NativeCallFrameTracer tracer(vm, exec);
512     auto scope = DECLARE_THROW_SCOPE(*vm);
513
514     JSValue op1 = JSValue::decode(encodedOp1);
515     JSValue op2 = JSValue::decode(encodedOp2);
516
517     uint32_t a = op1.toUInt32(exec);
518     RETURN_IF_EXCEPTION(scope, encodedJSValue());
519     scope.release();
520     uint32_t b = op2.toUInt32(exec);
521     return JSValue::encode(jsNumber(static_cast<int32_t>(a >> (b & 0x1f))));
522 }
523
524 EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
525 {
526     VM* vm = &exec->vm();
527     NativeCallFrameTracer tracer(vm, exec);
528     
529     JSValue op1 = JSValue::decode(encodedOp1);
530     JSValue op2 = JSValue::decode(encodedOp2);
531     
532     return JSValue::encode(jsAddNonNumber(exec, op1, op2));
533 }
534
535 EncodedJSValue JIT_OPERATION operationValueDiv(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
536 {
537     auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* {
538         return JSBigInt::divide(exec, left, right);
539     };
540
541     auto numberOp = [] (double left, double right) -> double {
542         return left / right;
543     };
544
545     return binaryOp(exec, encodedOp1, encodedOp2, bigIntOp, numberOp, "Invalid mix of BigInt and other type in division operation.");
546 }
547
548 EncodedJSValue JIT_OPERATION operationValuePow(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
549 {
550     auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* {
551         return JSBigInt::exponentiate(exec, left, right);
552     };
553
554     auto numberOp = [] (double left, double right) -> double {
555         return operationMathPow(left, right);
556     };
557
558     return binaryOp(exec, encodedOp1, encodedOp2, bigIntOp, numberOp, "Invalid mix of BigInt and other type in exponentiation operation."_s);
559 }
560
561 double JIT_OPERATION operationArithAbs(ExecState* exec, EncodedJSValue encodedOp1)
562 {
563     VM* vm = &exec->vm();
564     NativeCallFrameTracer tracer(vm, exec);
565     auto scope = DECLARE_THROW_SCOPE(*vm);
566
567     JSValue op1 = JSValue::decode(encodedOp1);
568     double a = op1.toNumber(exec);
569     RETURN_IF_EXCEPTION(scope, PNaN);
570     return fabs(a);
571 }
572
573 uint32_t JIT_OPERATION operationArithClz32(ExecState* exec, EncodedJSValue encodedOp1)
574 {
575     VM* vm = &exec->vm();
576     NativeCallFrameTracer tracer(vm, exec);
577     auto scope = DECLARE_THROW_SCOPE(*vm);
578
579     JSValue op1 = JSValue::decode(encodedOp1);
580     uint32_t value = op1.toUInt32(exec);
581     RETURN_IF_EXCEPTION(scope, 0);
582     return clz(value);
583 }
584
585 double JIT_OPERATION operationArithFRound(ExecState* exec, EncodedJSValue encodedOp1)
586 {
587     VM* vm = &exec->vm();
588     NativeCallFrameTracer tracer(vm, exec);
589     auto scope = DECLARE_THROW_SCOPE(*vm);
590
591     JSValue op1 = JSValue::decode(encodedOp1);
592     double a = op1.toNumber(exec);
593     RETURN_IF_EXCEPTION(scope, PNaN);
594     return static_cast<float>(a);
595 }
596
597 #define DFG_ARITH_UNARY(capitalizedName, lowerName) \
598 double JIT_OPERATION operationArith##capitalizedName(ExecState* exec, EncodedJSValue encodedOp1) \
599 { \
600     VM* vm = &exec->vm(); \
601     NativeCallFrameTracer tracer(vm, exec); \
602     auto scope = DECLARE_THROW_SCOPE(*vm); \
603     JSValue op1 = JSValue::decode(encodedOp1); \
604     double result = op1.toNumber(exec); \
605     RETURN_IF_EXCEPTION(scope, PNaN); \
606     return JSC::Math::lowerName(result); \
607 }
608     FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
609 #undef DFG_ARITH_UNARY
610
611 double JIT_OPERATION operationArithSqrt(ExecState* exec, EncodedJSValue encodedOp1)
612 {
613     VM* vm = &exec->vm();
614     NativeCallFrameTracer tracer(vm, exec);
615     auto scope = DECLARE_THROW_SCOPE(*vm);
616
617     JSValue op1 = JSValue::decode(encodedOp1);
618     double a = op1.toNumber(exec);
619     RETURN_IF_EXCEPTION(scope, PNaN);
620     return sqrt(a);
621 }
622
623 EncodedJSValue JIT_OPERATION operationArithRound(ExecState* exec, EncodedJSValue encodedArgument)
624 {
625     VM* vm = &exec->vm();
626     NativeCallFrameTracer tracer(vm, exec);
627     auto scope = DECLARE_THROW_SCOPE(*vm);
628
629     JSValue argument = JSValue::decode(encodedArgument);
630     double valueOfArgument = argument.toNumber(exec);
631     RETURN_IF_EXCEPTION(scope, encodedJSValue());
632     return JSValue::encode(jsNumber(jsRound(valueOfArgument)));
633 }
634
635 EncodedJSValue JIT_OPERATION operationArithFloor(ExecState* exec, EncodedJSValue encodedArgument)
636 {
637     VM* vm = &exec->vm();
638     NativeCallFrameTracer tracer(vm, exec);
639     auto scope = DECLARE_THROW_SCOPE(*vm);
640
641     JSValue argument = JSValue::decode(encodedArgument);
642     double valueOfArgument = argument.toNumber(exec);
643     RETURN_IF_EXCEPTION(scope, encodedJSValue());
644     return JSValue::encode(jsNumber(floor(valueOfArgument)));
645 }
646
647 EncodedJSValue JIT_OPERATION operationArithCeil(ExecState* exec, EncodedJSValue encodedArgument)
648 {
649     VM* vm = &exec->vm();
650     NativeCallFrameTracer tracer(vm, exec);
651     auto scope = DECLARE_THROW_SCOPE(*vm);
652
653     JSValue argument = JSValue::decode(encodedArgument);
654     double valueOfArgument = argument.toNumber(exec);
655     RETURN_IF_EXCEPTION(scope, encodedJSValue());
656     return JSValue::encode(jsNumber(ceil(valueOfArgument)));
657 }
658
659 EncodedJSValue JIT_OPERATION operationArithTrunc(ExecState* exec, EncodedJSValue encodedArgument)
660 {
661     VM* vm = &exec->vm();
662     NativeCallFrameTracer tracer(vm, exec);
663     auto scope = DECLARE_THROW_SCOPE(*vm);
664
665     JSValue argument = JSValue::decode(encodedArgument);
666     double truncatedValueOfArgument = argument.toIntegerPreserveNaN(exec);
667     RETURN_IF_EXCEPTION(scope, encodedJSValue());
668     return JSValue::encode(jsNumber(truncatedValueOfArgument));
669 }
670
671 static ALWAYS_INLINE EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
672 {
673     VM& vm = exec->vm();
674     NativeCallFrameTracer tracer(&vm, exec);
675     
676     if (base->isObject()) {
677         JSObject* object = asObject(base);
678         if (object->canGetIndexQuickly(index))
679             return JSValue::encode(object->getIndexQuickly(index));
680     }
681
682     if (isJSString(base) && asString(base)->canGetIndex(index))
683         return JSValue::encode(asString(base)->getIndex(exec, index));
684
685     return JSValue::encode(JSValue(base).get(exec, index));
686 }
687
688 EncodedJSValue JIT_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
689 {
690     VM& vm = exec->vm();
691     NativeCallFrameTracer tracer(&vm, exec);
692     auto scope = DECLARE_THROW_SCOPE(vm);
693
694     JSValue baseValue = JSValue::decode(encodedBase);
695     JSValue property = JSValue::decode(encodedProperty);
696
697     if (LIKELY(baseValue.isCell())) {
698         JSCell* base = baseValue.asCell();
699
700         if (property.isUInt32())
701             RELEASE_AND_RETURN(scope, getByVal(exec, base, property.asUInt32()));
702
703         if (property.isDouble()) {
704             double propertyAsDouble = property.asDouble();
705             uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
706             if (propertyAsUInt32 == propertyAsDouble && isIndex(propertyAsUInt32))
707                 RELEASE_AND_RETURN(scope, getByVal(exec, base, propertyAsUInt32));
708
709         } else if (property.isString()) {
710             Structure& structure = *base->structure(vm);
711             if (JSCell::canUseFastGetOwnProperty(structure)) {
712                 RefPtr<AtomStringImpl> existingAtomString = asString(property)->toExistingAtomString(exec);
713                 RETURN_IF_EXCEPTION(scope, encodedJSValue());
714                 if (existingAtomString) {
715                     if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomString.get()))
716                         return JSValue::encode(result);
717                 }
718             }
719         }
720     }
721
722     baseValue.requireObjectCoercible(exec);
723     RETURN_IF_EXCEPTION(scope, encodedJSValue());
724     auto propertyName = property.toPropertyKey(exec);
725     RETURN_IF_EXCEPTION(scope, encodedJSValue());
726     RELEASE_AND_RETURN(scope, JSValue::encode(baseValue.get(exec, propertyName)));
727 }
728
729 EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
730 {
731     VM& vm = exec->vm();
732     NativeCallFrameTracer tracer(&vm, exec);
733     auto scope = DECLARE_THROW_SCOPE(vm);
734
735     JSValue property = JSValue::decode(encodedProperty);
736
737     if (property.isUInt32())
738         RELEASE_AND_RETURN(scope, getByVal(exec, base, property.asUInt32()));
739
740     if (property.isDouble()) {
741         double propertyAsDouble = property.asDouble();
742         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
743         if (propertyAsUInt32 == propertyAsDouble)
744             RELEASE_AND_RETURN(scope, getByVal(exec, base, propertyAsUInt32));
745
746     } else if (property.isString()) {
747         Structure& structure = *base->structure(vm);
748         if (JSCell::canUseFastGetOwnProperty(structure)) {
749             RefPtr<AtomStringImpl> existingAtomString = asString(property)->toExistingAtomString(exec);
750             RETURN_IF_EXCEPTION(scope, encodedJSValue());
751             if (existingAtomString) {
752                 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomString.get()))
753                     return JSValue::encode(result);
754             }
755         }
756     }
757
758     auto propertyName = property.toPropertyKey(exec);
759     RETURN_IF_EXCEPTION(scope, encodedJSValue());
760     RELEASE_AND_RETURN(scope, JSValue::encode(JSValue(base).get(exec, propertyName)));
761 }
762
763 ALWAYS_INLINE EncodedJSValue getByValCellInt(ExecState* exec, JSCell* base, int32_t index)
764 {
765     VM* vm = &exec->vm();
766     NativeCallFrameTracer tracer(vm, exec);
767     
768     if (index < 0) {
769         // Go the slowest way possible because negative indices don't use indexed storage.
770         return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
771     }
772
773     // Use this since we know that the value is out of bounds.
774     return JSValue::encode(JSValue(base).get(exec, static_cast<unsigned>(index)));
775 }
776
777 EncodedJSValue JIT_OPERATION operationGetByValObjectInt(ExecState* exec, JSObject* base, int32_t index)
778 {
779     return getByValCellInt(exec, base, index);
780 }
781
782 EncodedJSValue JIT_OPERATION operationGetByValStringInt(ExecState* exec, JSString* base, int32_t index)
783 {
784     return getByValCellInt(exec, base, index);
785 }
786
787 EncodedJSValue JIT_OPERATION operationGetByValObjectString(ExecState* exec, JSCell* base, JSCell* string)
788 {
789     VM& vm = exec->vm();
790     NativeCallFrameTracer tracer(&vm, exec);
791
792     auto scope = DECLARE_THROW_SCOPE(vm);
793
794     auto propertyName = asString(string)->toIdentifier(exec);
795     RETURN_IF_EXCEPTION(scope, encodedJSValue());
796
797     RELEASE_AND_RETURN(scope, JSValue::encode(getByValObject(exec, vm, asObject(base), propertyName)));
798 }
799
800 EncodedJSValue JIT_OPERATION operationGetByValObjectSymbol(ExecState* exec, JSCell* base, JSCell* symbol)
801 {
802     VM& vm = exec->vm();
803     NativeCallFrameTracer tracer(&vm, exec);
804
805     auto propertyName = asSymbol(symbol)->privateName();
806     return JSValue::encode(getByValObject(exec, vm, asObject(base), propertyName));
807 }
808
809 void JIT_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
810 {
811     VM& vm = exec->vm();
812     NativeCallFrameTracer tracer(&vm, exec);
813     
814     putByValInternal<true, false>(exec, vm, encodedBase, encodedProperty, encodedValue);
815 }
816
817 void JIT_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
818 {
819     VM& vm = exec->vm();
820     NativeCallFrameTracer tracer(&vm, exec);
821     
822     putByValInternal<false, false>(exec, vm, encodedBase, encodedProperty, encodedValue);
823 }
824
825 void JIT_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
826 {
827     VM& vm = exec->vm();
828     NativeCallFrameTracer tracer(&vm, exec);
829     
830     putByValInternal<true, false>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
831 }
832
833 void JIT_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
834 {
835     VM& vm = exec->vm();
836     NativeCallFrameTracer tracer(&vm, exec);
837     
838     putByValInternal<false, false>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
839 }
840
841 void JIT_OPERATION operationPutByValCellStringStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
842 {
843     VM& vm = exec->vm();
844     NativeCallFrameTracer tracer(&vm, exec);
845
846     putByValCellStringInternal<true, false>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
847 }
848
849 void JIT_OPERATION operationPutByValCellStringNonStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
850 {
851     VM& vm = exec->vm();
852     NativeCallFrameTracer tracer(&vm, exec);
853
854     putByValCellStringInternal<false, false>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
855 }
856
857 void JIT_OPERATION operationPutByValCellSymbolStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
858 {
859     VM& vm = exec->vm();
860     NativeCallFrameTracer tracer(&vm, exec);
861
862     auto propertyName = asSymbol(symbol)->privateName();
863     putByValCellInternal<true, false>(exec, vm, cell, propertyName, JSValue::decode(encodedValue));
864 }
865
866 void JIT_OPERATION operationPutByValCellSymbolNonStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
867 {
868     VM& vm = exec->vm();
869     NativeCallFrameTracer tracer(&vm, exec);
870
871     auto propertyName = asSymbol(symbol)->privateName();
872     putByValCellInternal<false, false>(exec, vm, cell, propertyName, JSValue::decode(encodedValue));
873 }
874
875 void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* object, int32_t index, EncodedJSValue encodedValue)
876 {
877     VM& vm = exec->vm();
878     NativeCallFrameTracer tracer(&vm, exec);
879     
880     if (index >= 0) {
881         object->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
882         return;
883     }
884     
885     PutPropertySlot slot(object, true);
886     object->methodTable(vm)->put(
887         object, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
888 }
889
890 void JIT_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* object, int32_t index, EncodedJSValue encodedValue)
891 {
892     VM* vm = &exec->vm();
893     NativeCallFrameTracer tracer(vm, exec);
894     
895     if (index >= 0) {
896         object->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
897         return;
898     }
899     
900     PutPropertySlot slot(object, false);
901     object->methodTable(*vm)->put(
902         object, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
903 }
904
905 void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* object, int32_t index, double value)
906 {
907     VM* vm = &exec->vm();
908     NativeCallFrameTracer tracer(vm, exec);
909     
910     JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
911     
912     if (index >= 0) {
913         object->putByIndexInline(exec, index, jsValue, true);
914         return;
915     }
916     
917     PutPropertySlot slot(object, true);
918     object->methodTable(*vm)->put(
919         object, exec, Identifier::from(exec, index), jsValue, slot);
920 }
921
922 void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* object, int32_t index, double value)
923 {
924     VM* vm = &exec->vm();
925     NativeCallFrameTracer tracer(vm, exec);
926     
927     JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
928     
929     if (index >= 0) {
930         object->putByIndexInline(exec, index, jsValue, false);
931         return;
932     }
933     
934     PutPropertySlot slot(object, false);
935     object->methodTable(*vm)->put(
936         object, exec, Identifier::from(exec, index), jsValue, slot);
937 }
938
939 void JIT_OPERATION operationPutDoubleByValDirectBeyondArrayBoundsStrict(ExecState* exec, JSObject* object, int32_t index, double value)
940 {
941     VM& vm = exec->vm();
942     NativeCallFrameTracer tracer(&vm, exec);
943
944     JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
945
946     if (index >= 0) {
947         object->putDirectIndex(exec, index, jsValue, 0, PutDirectIndexShouldThrow);
948         return;
949     }
950
951     PutPropertySlot slot(object, true);
952     CommonSlowPaths::putDirectWithReify(vm, exec, object, Identifier::from(exec, index), jsValue, slot);
953 }
954
955 void JIT_OPERATION operationPutDoubleByValDirectBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* object, int32_t index, double value)
956 {
957     VM& vm = exec->vm();
958     NativeCallFrameTracer tracer(&vm, exec);
959
960     JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
961
962     if (index >= 0) {
963         object->putDirectIndex(exec, index, jsValue);
964         return;
965     }
966
967     PutPropertySlot slot(object, false);
968     CommonSlowPaths::putDirectWithReify(vm, exec, object, Identifier::from(exec, index), jsValue, slot);
969 }
970
971 void JIT_OPERATION operationPutByValDirectStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
972 {
973     VM& vm = exec->vm();
974     NativeCallFrameTracer tracer(&vm, exec);
975     
976     putByValInternal<true, true>(exec, vm, encodedBase, encodedProperty, encodedValue);
977 }
978
979 void JIT_OPERATION operationPutByValDirectNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
980 {
981     VM& vm = exec->vm();
982     NativeCallFrameTracer tracer(&vm, exec);
983     
984     putByValInternal<false, true>(exec, vm, encodedBase, encodedProperty, encodedValue);
985 }
986
987 void JIT_OPERATION operationPutByValDirectCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
988 {
989     VM& vm = exec->vm();
990     NativeCallFrameTracer tracer(&vm, exec);
991     
992     putByValInternal<true, true>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
993 }
994
995 void JIT_OPERATION operationPutByValDirectCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
996 {
997     VM& vm = exec->vm();
998     NativeCallFrameTracer tracer(&vm, exec);
999     
1000     putByValInternal<false, true>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
1001 }
1002
1003 void JIT_OPERATION operationPutByValDirectCellStringStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
1004 {
1005     VM& vm = exec->vm();
1006     NativeCallFrameTracer tracer(&vm, exec);
1007
1008     putByValCellStringInternal<true, true>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
1009 }
1010
1011 void JIT_OPERATION operationPutByValDirectCellStringNonStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
1012 {
1013     VM& vm = exec->vm();
1014     NativeCallFrameTracer tracer(&vm, exec);
1015
1016     putByValCellStringInternal<false, true>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
1017 }
1018
1019 void JIT_OPERATION operationPutByValDirectCellSymbolStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
1020 {
1021     VM& vm = exec->vm();
1022     NativeCallFrameTracer tracer(&vm, exec);
1023
1024     auto propertyName = asSymbol(symbol)->privateName();
1025     putByValCellInternal<true, true>(exec, vm, cell, propertyName, JSValue::decode(encodedValue));
1026 }
1027
1028 void JIT_OPERATION operationPutByValDirectCellSymbolNonStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
1029 {
1030     VM& vm = exec->vm();
1031     NativeCallFrameTracer tracer(&vm, exec);
1032
1033     auto propertyName = asSymbol(symbol)->privateName();
1034     putByValCellInternal<false, true>(exec, vm, cell, propertyName, JSValue::decode(encodedValue));
1035 }
1036
1037 void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState* exec, JSObject* object, int32_t index, EncodedJSValue encodedValue)
1038 {
1039     VM& vm = exec->vm();
1040     NativeCallFrameTracer tracer(&vm, exec);
1041     if (index >= 0) {
1042         object->putDirectIndex(exec, index, JSValue::decode(encodedValue), 0, PutDirectIndexShouldThrow);
1043         return;
1044     }
1045     
1046     PutPropertySlot slot(object, true);
1047     CommonSlowPaths::putDirectWithReify(vm, exec, object, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
1048 }
1049
1050 void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* object, int32_t index, EncodedJSValue encodedValue)
1051 {
1052     VM& vm = exec->vm();
1053     NativeCallFrameTracer tracer(&vm, exec);
1054
1055     if (index >= 0) {
1056         object->putDirectIndex(exec, index, JSValue::decode(encodedValue));
1057         return;
1058     }
1059     
1060     PutPropertySlot slot(object, false);
1061     CommonSlowPaths::putDirectWithReify(vm, exec, object, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
1062 }
1063
1064 EncodedJSValue JIT_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
1065 {
1066     VM* vm = &exec->vm();
1067     NativeCallFrameTracer tracer(vm, exec);
1068     
1069     array->pushInline(exec, JSValue::decode(encodedValue));
1070     return JSValue::encode(jsNumber(array->length()));
1071 }
1072
1073 EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
1074 {
1075     VM* vm = &exec->vm();
1076     NativeCallFrameTracer tracer(vm, exec);
1077     
1078     array->pushInline(exec, JSValue(JSValue::EncodeAsDouble, value));
1079     return JSValue::encode(jsNumber(array->length()));
1080 }
1081
1082 EncodedJSValue JIT_OPERATION operationArrayPushMultiple(ExecState* exec, JSArray* array, void* buffer, int32_t elementCount)
1083 {
1084     VM& vm = exec->vm();
1085     NativeCallFrameTracer tracer(&vm, exec);
1086     auto scope = DECLARE_THROW_SCOPE(vm);
1087
1088     // We assume that multiple JSArray::push calls with ArrayWithInt32/ArrayWithContiguous do not cause JS traps.
1089     // If it can cause any JS interactions, we can call the caller JS function of this function and overwrite the
1090     // content of ScratchBuffer. If the IndexingType is now ArrayWithInt32/ArrayWithContiguous, we can ensure
1091     // that there is no indexed accessors in this object and its prototype chain.
1092     //
1093     // ArrayWithArrayStorage is also OK. It can have indexed accessors. But if you define an indexed accessor, the array's length
1094     // becomes larger than that index. So Array#push never overlaps with this accessor. So accessors are never called unless
1095     // the IndexingType is ArrayWithSlowPutArrayStorage which could have an indexed accessor in a prototype chain.
1096     RELEASE_ASSERT(!shouldUseSlowPut(array->indexingType()));
1097
1098     EncodedJSValue* values = static_cast<EncodedJSValue*>(buffer);
1099     for (int32_t i = 0; i < elementCount; ++i) {
1100         array->pushInline(exec, JSValue::decode(values[i]));
1101         RETURN_IF_EXCEPTION(scope, encodedJSValue());
1102     }
1103     return JSValue::encode(jsNumber(array->length()));
1104 }
1105
1106 EncodedJSValue JIT_OPERATION operationArrayPushDoubleMultiple(ExecState* exec, JSArray* array, void* buffer, int32_t elementCount)
1107 {
1108     VM& vm = exec->vm();
1109     NativeCallFrameTracer tracer(&vm, exec);
1110     auto scope = DECLARE_THROW_SCOPE(vm);
1111
1112     // We assume that multiple JSArray::push calls with ArrayWithDouble do not cause JS traps.
1113     // If it can cause any JS interactions, we can call the caller JS function of this function and overwrite the
1114     // content of ScratchBuffer. If the IndexingType is now ArrayWithDouble, we can ensure
1115     // that there is no indexed accessors in this object and its prototype chain.
1116     ASSERT(array->indexingMode() == ArrayWithDouble);
1117
1118     double* values = static_cast<double*>(buffer);
1119     for (int32_t i = 0; i < elementCount; ++i) {
1120         array->pushInline(exec, JSValue(JSValue::EncodeAsDouble, values[i]));
1121         RETURN_IF_EXCEPTION(scope, encodedJSValue());
1122     }
1123     return JSValue::encode(jsNumber(array->length()));
1124 }
1125
1126 EncodedJSValue JIT_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
1127 {
1128     VM* vm = &exec->vm();
1129     NativeCallFrameTracer tracer(vm, exec);
1130     
1131     return JSValue::encode(array->pop(exec));
1132 }
1133         
1134 EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
1135 {
1136     VM* vm = &exec->vm();
1137     NativeCallFrameTracer tracer(vm, exec);
1138     
1139     array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
1140     
1141     return JSValue::encode(array->pop(exec));
1142 }
1143         
1144 EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* argument)
1145 {
1146     SuperSamplerScope superSamplerScope(false);
1147     
1148     VM& vm = globalObject->vm();
1149     NativeCallFrameTracer tracer(&vm, exec);
1150     
1151     return JSValue::encode(regExpObject->execInline(exec, globalObject, argument));
1152 }
1153         
1154 EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
1155 {
1156     SuperSamplerScope superSamplerScope(false);
1157     
1158     VM& vm = globalObject->vm();
1159     NativeCallFrameTracer tracer(&vm, exec);
1160     auto scope = DECLARE_THROW_SCOPE(vm);
1161     
1162     JSValue argument = JSValue::decode(encodedArgument);
1163
1164     JSString* input = argument.toStringOrNull(exec);
1165     EXCEPTION_ASSERT(!!scope.exception() == !input);
1166     if (!input)
1167         return encodedJSValue();
1168     RELEASE_AND_RETURN(scope, JSValue::encode(regExpObject->execInline(exec, globalObject, input)));
1169 }
1170         
1171 EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
1172 {
1173     SuperSamplerScope superSamplerScope(false);
1174     
1175     VM& vm = globalObject->vm();
1176     NativeCallFrameTracer tracer(&vm, exec);
1177     auto scope = DECLARE_THROW_SCOPE(vm);
1178
1179     JSValue base = JSValue::decode(encodedBase);
1180     JSValue argument = JSValue::decode(encodedArgument);
1181     
1182     auto* regexp = jsDynamicCast<RegExpObject*>(vm, base);
1183     if (UNLIKELY(!regexp))
1184         return throwVMTypeError(exec, scope);
1185
1186     JSString* input = argument.toStringOrNull(exec);
1187     EXCEPTION_ASSERT(!!scope.exception() == !input);
1188     if (!input)
1189         return JSValue::encode(jsUndefined());
1190     RELEASE_AND_RETURN(scope, JSValue::encode(regexp->exec(exec, globalObject, input)));
1191 }
1192
1193 EncodedJSValue JIT_OPERATION operationRegExpExecNonGlobalOrSticky(ExecState* exec, JSGlobalObject* globalObject, RegExp* regExp, JSString* string)
1194 {
1195     SuperSamplerScope superSamplerScope(false);
1196
1197     VM& vm = globalObject->vm();
1198     NativeCallFrameTracer tracer(&vm, exec);
1199
1200     auto scope = DECLARE_THROW_SCOPE(vm);
1201
1202     String input = string->value(exec);
1203     RETURN_IF_EXCEPTION(scope, { });
1204
1205     unsigned lastIndex = 0;
1206     MatchResult result;
1207     JSArray* array = createRegExpMatchesArray(vm, globalObject, string, input, regExp, lastIndex, result);
1208     if (!array) {
1209         ASSERT(!scope.exception());
1210         return JSValue::encode(jsNull());
1211     }
1212
1213     RETURN_IF_EXCEPTION(scope, { });
1214     globalObject->regExpGlobalData().recordMatch(vm, globalObject, regExp, string, result);
1215     return JSValue::encode(array);
1216 }
1217
1218 EncodedJSValue JIT_OPERATION operationRegExpMatchFastString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* argument)
1219 {
1220     SuperSamplerScope superSamplerScope(false);
1221
1222     VM& vm = globalObject->vm();
1223     NativeCallFrameTracer tracer(&vm, exec);
1224
1225     if (!regExpObject->regExp()->global())
1226         return JSValue::encode(regExpObject->execInline(exec, globalObject, argument));
1227     return JSValue::encode(regExpObject->matchGlobal(exec, globalObject, argument));
1228 }
1229
1230 EncodedJSValue JIT_OPERATION operationRegExpMatchFastGlobalString(ExecState* exec, JSGlobalObject* globalObject, RegExp* regExp, JSString* string)
1231 {
1232     SuperSamplerScope superSamplerScope(false);
1233
1234     VM& vm = globalObject->vm();
1235     NativeCallFrameTracer tracer(&vm, exec);
1236
1237     auto scope = DECLARE_THROW_SCOPE(vm);
1238
1239     ASSERT(regExp->global());
1240
1241     String s = string->value(exec);
1242     RETURN_IF_EXCEPTION(scope, { });
1243
1244     if (regExp->unicode()) {
1245         unsigned stringLength = s.length();
1246         RELEASE_AND_RETURN(scope, JSValue::encode(collectMatches(
1247             vm, exec, string, s, globalObject, regExp,
1248             [&] (size_t end) -> size_t {
1249                 return advanceStringUnicode(s, stringLength, end);
1250             })));
1251     }
1252
1253     RELEASE_AND_RETURN(scope, JSValue::encode(collectMatches(
1254         vm, exec, string, s, globalObject, regExp,
1255         [&] (size_t end) -> size_t {
1256             return end + 1;
1257         })));
1258 }
1259
1260 EncodedJSValue JIT_OPERATION operationParseIntNoRadixGeneric(ExecState* exec, EncodedJSValue value)
1261 {
1262     VM& vm = exec->vm();
1263     NativeCallFrameTracer tracer(&vm, exec);
1264
1265     return toStringView(exec, JSValue::decode(value), [&] (StringView view) {
1266         // This version is as if radix was undefined. Hence, undefined.toNumber() === 0.
1267         return parseIntResult(parseInt(view, 0));
1268     });
1269 }
1270
1271 EncodedJSValue JIT_OPERATION operationParseIntStringNoRadix(ExecState* exec, JSString* string)
1272 {
1273     VM& vm = exec->vm();
1274     NativeCallFrameTracer tracer(&vm, exec);
1275     auto scope = DECLARE_THROW_SCOPE(vm);
1276
1277     auto viewWithString = string->viewWithUnderlyingString(exec);
1278     RETURN_IF_EXCEPTION(scope, { });
1279
1280     // This version is as if radix was undefined. Hence, undefined.toNumber() === 0.
1281     return parseIntResult(parseInt(viewWithString.view, 0));
1282 }
1283
1284 EncodedJSValue JIT_OPERATION operationParseIntString(ExecState* exec, JSString* string, int32_t radix)
1285 {
1286     VM& vm = exec->vm();
1287     NativeCallFrameTracer tracer(&vm, exec);
1288     auto scope = DECLARE_THROW_SCOPE(vm);
1289
1290     auto viewWithString = string->viewWithUnderlyingString(exec);
1291     RETURN_IF_EXCEPTION(scope, { });
1292
1293     return parseIntResult(parseInt(viewWithString.view, radix));
1294 }
1295
1296 EncodedJSValue JIT_OPERATION operationParseIntGeneric(ExecState* exec, EncodedJSValue value, int32_t radix)
1297 {
1298     VM& vm = exec->vm();
1299     NativeCallFrameTracer tracer(&vm, exec);
1300
1301     return toStringView(exec, JSValue::decode(value), [&] (StringView view) {
1302         return parseIntResult(parseInt(view, radix));
1303     });
1304 }
1305         
1306 size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* input)
1307 {
1308     SuperSamplerScope superSamplerScope(false);
1309     
1310     VM& vm = globalObject->vm();
1311     NativeCallFrameTracer tracer(&vm, exec);
1312
1313     return regExpObject->testInline(exec, globalObject, input);
1314 }
1315
1316 size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
1317 {
1318     SuperSamplerScope superSamplerScope(false);
1319     
1320     VM& vm = globalObject->vm();
1321     NativeCallFrameTracer tracer(&vm, exec);
1322
1323     JSValue argument = JSValue::decode(encodedArgument);
1324
1325     JSString* input = argument.toStringOrNull(exec);
1326     if (!input)
1327         return false;
1328     return regExpObject->testInline(exec, globalObject, input);
1329 }
1330
1331 size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
1332 {
1333     SuperSamplerScope superSamplerScope(false);
1334     
1335     VM& vm = globalObject->vm();
1336     NativeCallFrameTracer tracer(&vm, exec);
1337     auto scope = DECLARE_THROW_SCOPE(vm);
1338
1339     JSValue base = JSValue::decode(encodedBase);
1340     JSValue argument = JSValue::decode(encodedArgument);
1341
1342     auto* regexp = jsDynamicCast<RegExpObject*>(vm, base);
1343     if (UNLIKELY(!regexp)) {
1344         throwTypeError(exec, scope);
1345         return false;
1346     }
1347
1348     JSString* input = argument.toStringOrNull(exec);
1349     EXCEPTION_ASSERT(!!scope.exception() == !input);
1350     if (!input)
1351         return false;
1352     RELEASE_AND_RETURN(scope, regexp->test(exec, globalObject, input));
1353 }
1354
1355 JSCell* JIT_OPERATION operationSubBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
1356 {
1357     VM* vm = &exec->vm();
1358     NativeCallFrameTracer tracer(vm, exec);
1359     
1360     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
1361     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
1362     
1363     return JSBigInt::sub(exec, leftOperand, rightOperand);
1364 }
1365
1366 JSCell* JIT_OPERATION operationBitNotBigInt(ExecState* exec, JSCell* op1)
1367 {
1368     VM* vm = &exec->vm();
1369     NativeCallFrameTracer tracer(vm, exec);
1370
1371     JSBigInt* operand = jsCast<JSBigInt*>(op1);
1372
1373     return JSBigInt::bitwiseNot(exec, operand);
1374 }
1375
1376 JSCell* JIT_OPERATION operationMulBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
1377 {
1378     VM* vm = &exec->vm();
1379     NativeCallFrameTracer tracer(vm, exec);
1380
1381     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
1382     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
1383
1384     return JSBigInt::multiply(exec, leftOperand, rightOperand);
1385 }
1386     
1387 JSCell* JIT_OPERATION operationModBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
1388 {
1389     VM* vm = &exec->vm();
1390     NativeCallFrameTracer tracer(vm, exec);
1391     
1392     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
1393     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
1394     
1395     return JSBigInt::remainder(exec, leftOperand, rightOperand);
1396 }
1397
1398 JSCell* JIT_OPERATION operationDivBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
1399 {
1400     VM* vm = &exec->vm();
1401     NativeCallFrameTracer tracer(vm, exec);
1402     
1403     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
1404     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
1405     
1406     return JSBigInt::divide(exec, leftOperand, rightOperand);
1407 }
1408
1409 JSCell* JIT_OPERATION operationPowBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
1410 {
1411     VM* vm = &exec->vm();
1412     NativeCallFrameTracer tracer(vm, exec);
1413     
1414     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
1415     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
1416     
1417     return JSBigInt::exponentiate(exec, leftOperand, rightOperand);
1418 }
1419
1420 JSCell* JIT_OPERATION operationBitAndBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
1421 {
1422     VM* vm = &exec->vm();
1423     NativeCallFrameTracer tracer(vm, exec);
1424
1425     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
1426     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
1427
1428     return JSBigInt::bitwiseAnd(exec, leftOperand, rightOperand);
1429 }
1430
1431 JSCell* JIT_OPERATION operationBitLShiftBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
1432 {
1433     VM* vm = &exec->vm();
1434     NativeCallFrameTracer tracer(vm, exec);
1435
1436     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
1437     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
1438
1439     return JSBigInt::leftShift(exec, leftOperand, rightOperand);
1440 }
1441
1442 JSCell* JIT_OPERATION operationAddBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
1443 {
1444     VM* vm = &exec->vm();
1445     NativeCallFrameTracer tracer(vm, exec);
1446     
1447     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
1448     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
1449     
1450     return JSBigInt::add(exec, leftOperand, rightOperand);
1451 }
1452
1453 JSCell* JIT_OPERATION operationBitOrBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
1454 {
1455     VM* vm = &exec->vm();
1456     NativeCallFrameTracer tracer(vm, exec);
1457     
1458     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
1459     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
1460     
1461     return JSBigInt::bitwiseOr(exec, leftOperand, rightOperand);
1462 }
1463
1464 JSCell* JIT_OPERATION operationBitXorBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
1465 {
1466     VM* vm = &exec->vm();
1467     NativeCallFrameTracer tracer(vm, exec);
1468
1469     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
1470     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
1471
1472     return JSBigInt::bitwiseXor(exec, leftOperand, rightOperand);
1473 }
1474
1475 size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, JSCell* op1, JSCell* op2)
1476 {
1477     VM* vm = &exec->vm();
1478     NativeCallFrameTracer tracer(vm, exec);
1479     
1480     return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
1481 }
1482
1483 size_t JIT_OPERATION operationSameValue(ExecState* exec, EncodedJSValue arg1, EncodedJSValue arg2)
1484 {
1485     VM& vm = exec->vm();
1486     NativeCallFrameTracer tracer(&vm, exec);
1487
1488     return sameValue(exec, JSValue::decode(arg1), JSValue::decode(arg2));
1489 }
1490
1491 EncodedJSValue JIT_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
1492 {
1493     VM* vm = &exec->vm();
1494     NativeCallFrameTracer tracer(vm, exec);
1495     
1496     return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
1497 }
1498
1499 EncodedJSValue JIT_OPERATION operationToNumber(ExecState* exec, EncodedJSValue value)
1500 {
1501     VM* vm = &exec->vm();
1502     NativeCallFrameTracer tracer(vm, exec);
1503
1504     return JSValue::encode(jsNumber(JSValue::decode(value).toNumber(exec)));
1505 }
1506
1507 EncodedJSValue JIT_OPERATION operationGetByValWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript)
1508 {
1509     VM& vm = exec->vm();
1510     NativeCallFrameTracer tracer(&vm, exec);
1511     auto scope = DECLARE_THROW_SCOPE(vm);
1512
1513     JSValue baseValue = JSValue::decode(encodedBase);
1514     JSValue thisVal = JSValue::decode(encodedThis);
1515     JSValue subscript = JSValue::decode(encodedSubscript);
1516
1517     if (LIKELY(baseValue.isCell() && subscript.isString())) {
1518         Structure& structure = *baseValue.asCell()->structure(vm);
1519         if (JSCell::canUseFastGetOwnProperty(structure)) {
1520             RefPtr<AtomStringImpl> existingAtomString = asString(subscript)->toExistingAtomString(exec);
1521             RETURN_IF_EXCEPTION(scope, encodedJSValue());
1522             if (existingAtomString) {
1523                 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomString.get()))
1524                     return JSValue::encode(result);
1525             }
1526         }
1527     }
1528     
1529     PropertySlot slot(thisVal, PropertySlot::PropertySlot::InternalMethodType::Get);
1530     if (subscript.isUInt32()) {
1531         uint32_t i = subscript.asUInt32();
1532         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
1533             return JSValue::encode(asString(baseValue)->getIndex(exec, i));
1534         
1535         RELEASE_AND_RETURN(scope, JSValue::encode(baseValue.get(exec, i, slot)));
1536     }
1537
1538     baseValue.requireObjectCoercible(exec);
1539     RETURN_IF_EXCEPTION(scope, encodedJSValue());
1540
1541     auto property = subscript.toPropertyKey(exec);
1542     RETURN_IF_EXCEPTION(scope, encodedJSValue());
1543     RELEASE_AND_RETURN(scope, JSValue::encode(baseValue.get(exec, property, slot)));
1544 }
1545
1546 void JIT_OPERATION operationPutByIdWithThisStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, UniquedStringImpl* impl)
1547 {
1548     VM& vm = exec->vm();
1549     NativeCallFrameTracer tracer(&vm, exec);
1550
1551     putWithThis<true>(exec, encodedBase, encodedThis, encodedValue, Identifier::fromUid(exec, impl));
1552 }
1553
1554 void JIT_OPERATION operationPutByIdWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, UniquedStringImpl* impl)
1555 {
1556     VM& vm = exec->vm();
1557     NativeCallFrameTracer tracer(&vm, exec);
1558
1559     putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, Identifier::fromUid(exec, impl));
1560 }
1561
1562 void JIT_OPERATION operationPutByValWithThisStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
1563 {
1564     VM& vm = exec->vm();
1565     NativeCallFrameTracer tracer(&vm, exec);
1566     auto scope = DECLARE_THROW_SCOPE(vm);
1567
1568     Identifier property = JSValue::decode(encodedSubscript).toPropertyKey(exec);
1569     RETURN_IF_EXCEPTION(scope, void());
1570     scope.release();
1571     putWithThis<true>(exec, encodedBase, encodedThis, encodedValue, property);
1572 }
1573
1574 void JIT_OPERATION operationPutByValWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
1575 {
1576     VM& vm = exec->vm();
1577     NativeCallFrameTracer tracer(&vm, exec);
1578     auto scope = DECLARE_THROW_SCOPE(vm);
1579
1580     Identifier property = JSValue::decode(encodedSubscript).toPropertyKey(exec);
1581     RETURN_IF_EXCEPTION(scope, void());
1582     scope.release();
1583     putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, property);
1584 }
1585
1586 ALWAYS_INLINE static void defineDataProperty(ExecState* exec, VM& vm, JSObject* base, const Identifier& propertyName, JSValue value, int32_t attributes)
1587 {
1588     PropertyDescriptor descriptor = toPropertyDescriptor(value, jsUndefined(), jsUndefined(), DefinePropertyAttributes(attributes));
1589     ASSERT((descriptor.attributes() & PropertyAttribute::Accessor) || (!descriptor.isAccessorDescriptor()));
1590     if (base->methodTable(vm)->defineOwnProperty == JSObject::defineOwnProperty)
1591         JSObject::defineOwnProperty(base, exec, propertyName, descriptor, true);
1592     else
1593         base->methodTable(vm)->defineOwnProperty(base, exec, propertyName, descriptor, true);
1594 }
1595
1596 void JIT_OPERATION operationDefineDataProperty(ExecState* exec, JSObject* base, EncodedJSValue encodedProperty, EncodedJSValue encodedValue, int32_t attributes)
1597 {
1598     VM& vm = exec->vm();
1599     NativeCallFrameTracer tracer(&vm, exec);
1600     auto scope = DECLARE_THROW_SCOPE(vm);
1601
1602     Identifier propertyName = JSValue::decode(encodedProperty).toPropertyKey(exec);
1603     RETURN_IF_EXCEPTION(scope, void());
1604     scope.release();
1605     defineDataProperty(exec, vm, base, propertyName, JSValue::decode(encodedValue), attributes);
1606 }
1607
1608 void JIT_OPERATION operationDefineDataPropertyString(ExecState* exec, JSObject* base, JSString* property, EncodedJSValue encodedValue, int32_t attributes)
1609 {
1610     VM& vm = exec->vm();
1611     NativeCallFrameTracer tracer(&vm, exec);
1612     auto scope = DECLARE_THROW_SCOPE(vm);
1613
1614     Identifier propertyName = property->toIdentifier(exec);
1615     RETURN_IF_EXCEPTION(scope, void());
1616     scope.release();
1617     defineDataProperty(exec, vm, base, propertyName, JSValue::decode(encodedValue), attributes);
1618 }
1619
1620 void JIT_OPERATION operationDefineDataPropertyStringIdent(ExecState* exec, JSObject* base, UniquedStringImpl* property, EncodedJSValue encodedValue, int32_t attributes)
1621 {
1622     VM& vm = exec->vm();
1623     NativeCallFrameTracer tracer(&vm, exec);
1624     defineDataProperty(exec, vm, base, Identifier::fromUid(&vm, property), JSValue::decode(encodedValue), attributes);
1625 }
1626
1627 void JIT_OPERATION operationDefineDataPropertySymbol(ExecState* exec, JSObject* base, Symbol* property, EncodedJSValue encodedValue, int32_t attributes)
1628 {
1629     VM& vm = exec->vm();
1630     NativeCallFrameTracer tracer(&vm, exec);
1631     defineDataProperty(exec, vm, base, Identifier::fromUid(property->privateName()), JSValue::decode(encodedValue), attributes);
1632 }
1633
1634 ALWAYS_INLINE static void defineAccessorProperty(ExecState* exec, VM& vm, JSObject* base, const Identifier& propertyName, JSObject* getter, JSObject* setter, int32_t attributes)
1635 {
1636     PropertyDescriptor descriptor = toPropertyDescriptor(jsUndefined(), getter, setter, DefinePropertyAttributes(attributes));
1637     ASSERT((descriptor.attributes() & PropertyAttribute::Accessor) || (!descriptor.isAccessorDescriptor()));
1638     if (base->methodTable(vm)->defineOwnProperty == JSObject::defineOwnProperty)
1639         JSObject::defineOwnProperty(base, exec, propertyName, descriptor, true);
1640     else
1641         base->methodTable(vm)->defineOwnProperty(base, exec, propertyName, descriptor, true);
1642 }
1643
1644 void JIT_OPERATION operationDefineAccessorProperty(ExecState* exec, JSObject* base, EncodedJSValue encodedProperty, JSObject* getter, JSObject* setter, int32_t attributes)
1645 {
1646     VM& vm = exec->vm();
1647     NativeCallFrameTracer tracer(&vm, exec);
1648     auto scope = DECLARE_THROW_SCOPE(vm);
1649
1650     Identifier propertyName = JSValue::decode(encodedProperty).toPropertyKey(exec);
1651     RETURN_IF_EXCEPTION(scope, void());
1652     defineAccessorProperty(exec, vm, base, propertyName, getter, setter, attributes);
1653 }
1654
1655 void JIT_OPERATION operationDefineAccessorPropertyString(ExecState* exec, JSObject* base, JSString* property, JSObject* getter, JSObject* setter, int32_t attributes)
1656 {
1657     VM& vm = exec->vm();
1658     NativeCallFrameTracer tracer(&vm, exec);
1659     auto scope = DECLARE_THROW_SCOPE(vm);
1660
1661     Identifier propertyName = property->toIdentifier(exec);
1662     RETURN_IF_EXCEPTION(scope, void());
1663     defineAccessorProperty(exec, vm, base, propertyName, getter, setter, attributes);
1664 }
1665
1666 void JIT_OPERATION operationDefineAccessorPropertyStringIdent(ExecState* exec, JSObject* base, UniquedStringImpl* property, JSObject* getter, JSObject* setter, int32_t attributes)
1667 {
1668     VM& vm = exec->vm();
1669     NativeCallFrameTracer tracer(&vm, exec);
1670     defineAccessorProperty(exec, vm, base, Identifier::fromUid(&vm, property), getter, setter, attributes);
1671 }
1672
1673 void JIT_OPERATION operationDefineAccessorPropertySymbol(ExecState* exec, JSObject* base, Symbol* property, JSObject* getter, JSObject* setter, int32_t attributes)
1674 {
1675     VM& vm = exec->vm();
1676     NativeCallFrameTracer tracer(&vm, exec);
1677     defineAccessorProperty(exec, vm, base, Identifier::fromUid(property->privateName()), getter, setter, attributes);
1678 }
1679
1680 char* JIT_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
1681 {
1682     VM* vm = &exec->vm();
1683     NativeCallFrameTracer tracer(vm, exec);
1684     
1685     return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
1686 }
1687
1688 char* JIT_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
1689 {
1690     VM* vm = &exec->vm();
1691     NativeCallFrameTracer tracer(vm, exec);
1692     
1693     return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
1694 }
1695
1696 char* JIT_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size, Butterfly* butterfly)
1697 {
1698     VM& vm = exec->vm();
1699     NativeCallFrameTracer tracer(&vm, exec);
1700     auto scope = DECLARE_THROW_SCOPE(vm);
1701
1702     if (UNLIKELY(size < 0))
1703         return bitwise_cast<char*>(throwException(exec, scope, createRangeError(exec, "Array size is not a small enough positive integer."_s)));
1704
1705     JSArray* result;
1706     if (butterfly)
1707         result = JSArray::createWithButterfly(vm, nullptr, arrayStructure, butterfly);
1708     else
1709         result = JSArray::create(vm, arrayStructure, size);
1710     return bitwise_cast<char*>(result);
1711 }
1712
1713 char* JIT_OPERATION operationNewArrayWithSizeAndHint(ExecState* exec, Structure* arrayStructure, int32_t size, int32_t vectorLengthHint, Butterfly* butterfly)
1714 {
1715     VM& vm = exec->vm();
1716     NativeCallFrameTracer tracer(&vm, exec);
1717     auto scope = DECLARE_THROW_SCOPE(vm);
1718
1719     if (UNLIKELY(size < 0))
1720         return bitwise_cast<char*>(throwException(exec, scope, createRangeError(exec, "Array size is not a small enough positive integer."_s)));
1721
1722     JSArray* result;
1723     if (butterfly)
1724         result = JSArray::createWithButterfly(vm, nullptr, arrayStructure, butterfly);
1725     else {
1726         result = JSArray::tryCreate(vm, arrayStructure, size, vectorLengthHint);
1727         RELEASE_ASSERT(result);
1728     }
1729     return bitwise_cast<char*>(result);
1730 }
1731
1732 JSCell* JIT_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, JSCell* immutableButterflyCell)
1733 {
1734     VM& vm = exec->vm();
1735     NativeCallFrameTracer tracer(&vm, exec);
1736     ASSERT(!arrayStructure->outOfLineCapacity());
1737     auto* immutableButterfly = jsCast<JSImmutableButterfly*>(immutableButterflyCell);
1738     ASSERT(arrayStructure->indexingMode() == immutableButterfly->indexingMode() || hasAnyArrayStorage(arrayStructure->indexingMode()));
1739     auto* result = CommonSlowPaths::allocateNewArrayBuffer(vm, arrayStructure, immutableButterfly);
1740     ASSERT(result->indexingMode() == result->structure(vm)->indexingMode());
1741     ASSERT(result->structure(vm) == arrayStructure);
1742     return result;
1743 }
1744
1745 char* JIT_OPERATION operationNewInt8ArrayWithSize(
1746     ExecState* exec, Structure* structure, int32_t length, char* vector)
1747 {
1748     return newTypedArrayWithSize<JSInt8Array>(exec, structure, length, vector);
1749 }
1750
1751 char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
1752     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1753 {
1754     VM& vm = exec->vm();
1755     NativeCallFrameTracer tracer(&vm, exec);
1756     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt8Array>(exec, structure, encodedValue, 0, WTF::nullopt));
1757 }
1758
1759 char* JIT_OPERATION operationNewInt16ArrayWithSize(
1760     ExecState* exec, Structure* structure, int32_t length, char* vector)
1761 {
1762     return newTypedArrayWithSize<JSInt16Array>(exec, structure, length, vector);
1763 }
1764
1765 char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
1766     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1767 {
1768     VM& vm = exec->vm();
1769     NativeCallFrameTracer tracer(&vm, exec);
1770     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt16Array>(exec, structure, encodedValue, 0, WTF::nullopt));
1771 }
1772
1773 char* JIT_OPERATION operationNewInt32ArrayWithSize(
1774     ExecState* exec, Structure* structure, int32_t length, char* vector)
1775 {
1776     return newTypedArrayWithSize<JSInt32Array>(exec, structure, length, vector);
1777 }
1778
1779 char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
1780     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1781 {
1782     VM& vm = exec->vm();
1783     NativeCallFrameTracer tracer(&vm, exec);
1784     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt32Array>(exec, structure, encodedValue, 0, WTF::nullopt));
1785 }
1786
1787 char* JIT_OPERATION operationNewUint8ArrayWithSize(
1788     ExecState* exec, Structure* structure, int32_t length, char* vector)
1789 {
1790     return newTypedArrayWithSize<JSUint8Array>(exec, structure, length, vector);
1791 }
1792
1793 char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
1794     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1795 {
1796     VM& vm = exec->vm();
1797     NativeCallFrameTracer tracer(&vm, exec);
1798     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8Array>(exec, structure, encodedValue, 0, WTF::nullopt));
1799 }
1800
1801 char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(
1802     ExecState* exec, Structure* structure, int32_t length, char* vector)
1803 {
1804     return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length, vector);
1805 }
1806
1807 char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
1808     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1809 {
1810     VM& vm = exec->vm();
1811     NativeCallFrameTracer tracer(&vm, exec);
1812     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8ClampedArray>(exec, structure, encodedValue, 0, WTF::nullopt));
1813 }
1814
1815 char* JIT_OPERATION operationNewUint16ArrayWithSize(
1816     ExecState* exec, Structure* structure, int32_t length, char* vector)
1817 {
1818     return newTypedArrayWithSize<JSUint16Array>(exec, structure, length, vector);
1819 }
1820
1821 char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
1822     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1823 {
1824     VM& vm = exec->vm();
1825     NativeCallFrameTracer tracer(&vm, exec);
1826     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint16Array>(exec, structure, encodedValue, 0, WTF::nullopt));
1827 }
1828
1829 char* JIT_OPERATION operationNewUint32ArrayWithSize(
1830     ExecState* exec, Structure* structure, int32_t length, char* vector)
1831 {
1832     return newTypedArrayWithSize<JSUint32Array>(exec, structure, length, vector);
1833 }
1834
1835 char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
1836     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1837 {
1838     VM& vm = exec->vm();
1839     NativeCallFrameTracer tracer(&vm, exec);
1840     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint32Array>(exec, structure, encodedValue, 0, WTF::nullopt));
1841 }
1842
1843 char* JIT_OPERATION operationNewFloat32ArrayWithSize(
1844     ExecState* exec, Structure* structure, int32_t length, char* vector)
1845 {
1846     return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length, vector);
1847 }
1848
1849 char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
1850     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1851 {
1852     VM& vm = exec->vm();
1853     NativeCallFrameTracer tracer(&vm, exec);
1854     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat32Array>(exec, structure, encodedValue, 0, WTF::nullopt));
1855 }
1856
1857 char* JIT_OPERATION operationNewFloat64ArrayWithSize(
1858     ExecState* exec, Structure* structure, int32_t length, char* vector)
1859 {
1860     return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length, vector);
1861 }
1862
1863 char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
1864     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1865 {
1866     VM& vm = exec->vm();
1867     NativeCallFrameTracer tracer(&vm, exec);
1868     return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat64Array>(exec, structure, encodedValue, 0, WTF::nullopt));
1869 }
1870
1871 JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState* exec, Structure* structure, JSScope* scope, SymbolTable* table, EncodedJSValue initialValueEncoded)
1872 {
1873     JSValue initialValue = JSValue::decode(initialValueEncoded);
1874     ASSERT(initialValue == jsUndefined() || initialValue == jsTDZValue());
1875     VM& vm = exec->vm();
1876     NativeCallFrameTracer tracer(&vm, exec);
1877     return JSLexicalEnvironment::create(vm, structure, scope, table, initialValue);
1878 }
1879
1880 JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState* exec, Structure* structure, uint32_t length, uint32_t minCapacity)
1881 {
1882     VM& vm = exec->vm();
1883     NativeCallFrameTracer target(&vm, exec);
1884     DirectArguments* result = DirectArguments::create(
1885         vm, structure, length, std::max(length, minCapacity));
1886     // The caller will store to this object without barriers. Most likely, at this point, this is
1887     // still a young object and so no barriers are needed. But it's good to be careful anyway,
1888     // since the GC should be allowed to do crazy (like pretenuring, for example).
1889     vm.heap.writeBarrier(result);
1890     return result;
1891 }
1892
1893 JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState* exec, Structure* structure, Register* argumentStart, uint32_t length, JSFunction* callee, JSLexicalEnvironment* scope)
1894 {
1895     VM& vm = exec->vm();
1896     NativeCallFrameTracer target(&vm, exec);
1897     
1898     // We could pass the ScopedArgumentsTable* as an argument. We currently don't because I
1899     // didn't feel like changing the max number of arguments for a slow path call from 6 to 7.
1900     ScopedArgumentsTable* table = scope->symbolTable()->arguments();
1901     
1902     return ScopedArguments::createByCopyingFrom(
1903         vm, structure, argumentStart, length, callee, table, scope);
1904 }
1905
1906 JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState* exec, Structure* structure, Register* argumentStart, uint32_t length, JSFunction* callee)
1907 {
1908     VM& vm = exec->vm();
1909     NativeCallFrameTracer target(&vm, exec);
1910     return ClonedArguments::createByCopyingFrom(
1911         exec, structure, argumentStart, length, callee);
1912 }
1913
1914 JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, uint32_t argumentCount)
1915 {
1916     VM& vm = exec->vm();
1917     NativeCallFrameTracer target(&vm, exec);
1918     
1919     DeferGCForAWhile deferGC(vm.heap);
1920     
1921     CodeBlock* codeBlock;
1922     if (inlineCallFrame)
1923         codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
1924     else
1925         codeBlock = exec->codeBlock();
1926     
1927     unsigned length = argumentCount - 1;
1928     unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
1929     DirectArguments* result = DirectArguments::create(
1930         vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
1931     
1932     result->setCallee(vm, callee);
1933     
1934     Register* arguments =
1935         exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
1936         CallFrame::argumentOffset(0);
1937     for (unsigned i = length; i--;)
1938         result->setIndexQuickly(vm, i, arguments[i].jsValue());
1939     
1940     return result;
1941 }
1942
1943 JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, uint32_t argumentCount)
1944 {
1945     VM& vm = exec->vm();
1946     NativeCallFrameTracer target(&vm, exec);
1947     
1948     DeferGCForAWhile deferGC(vm.heap);
1949     
1950     CodeBlock* codeBlock;
1951     if (inlineCallFrame)
1952         codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
1953     else
1954         codeBlock = exec->codeBlock();
1955     
1956     unsigned length = argumentCount - 1;
1957     ClonedArguments* result = ClonedArguments::createEmpty(
1958         vm, codeBlock->globalObject()->clonedArgumentsStructure(), callee, length);
1959     
1960     Register* arguments =
1961         exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
1962         CallFrame::argumentOffset(0);
1963     for (unsigned i = length; i--;)
1964         result->putDirectIndex(exec, i, arguments[i].jsValue());
1965
1966     
1967     return result;
1968 }
1969
1970 JSCell* JIT_OPERATION operationCreateRest(ExecState* exec, Register* argumentStart, unsigned numberOfParamsToSkip, unsigned arraySize)
1971 {
1972     VM* vm = &exec->vm();
1973     NativeCallFrameTracer tracer(vm, exec);
1974
1975     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
1976     Structure* structure = globalObject->restParameterStructure();
1977     static_assert(sizeof(Register) == sizeof(JSValue), "This is a strong assumption here.");
1978     JSValue* argumentsToCopyRegion = bitwise_cast<JSValue*>(argumentStart) + numberOfParamsToSkip;
1979     return constructArray(exec, structure, argumentsToCopyRegion, arraySize);
1980 }
1981
1982 size_t JIT_OPERATION operationObjectIsObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1983 {
1984     VM& vm = exec->vm();
1985     NativeCallFrameTracer tracer(&vm, exec);
1986
1987     ASSERT(jsDynamicCast<JSObject*>(vm, object));
1988     
1989     if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1990         return false;
1991     if (object->isFunction(vm))
1992         return false;
1993     return true;
1994 }
1995
1996 size_t JIT_OPERATION operationObjectIsFunction(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1997 {
1998     VM& vm = exec->vm();
1999     NativeCallFrameTracer tracer(&vm, exec);
2000
2001     ASSERT(jsDynamicCast<JSObject*>(vm, object));
2002     
2003     if (object->structure(vm)->masqueradesAsUndefined(globalObject))
2004         return false;
2005     if (object->isFunction(vm))
2006         return true;
2007     return false;
2008 }
2009
2010 JSCell* JIT_OPERATION operationTypeOfObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
2011 {
2012     VM& vm = exec->vm();
2013     NativeCallFrameTracer tracer(&vm, exec);
2014
2015     ASSERT(jsDynamicCast<JSObject*>(vm, object));
2016     
2017     if (object->structure(vm)->masqueradesAsUndefined(globalObject))
2018         return vm.smallStrings.undefinedString();
2019     if (object->isFunction(vm))
2020         return vm.smallStrings.functionString();
2021     return vm.smallStrings.objectString();
2022 }
2023
2024 int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
2025 {
2026     VM& vm = exec->vm();
2027     NativeCallFrameTracer tracer(&vm, exec);
2028
2029     ASSERT(jsDynamicCast<JSObject*>(vm, object));
2030     
2031     if (object->structure(vm)->masqueradesAsUndefined(globalObject))
2032         return static_cast<int32_t>(TypeofType::Undefined);
2033     if (object->isFunction(vm))
2034         return static_cast<int32_t>(TypeofType::Function);
2035     return static_cast<int32_t>(TypeofType::Object);
2036 }
2037
2038 char* JIT_OPERATION operationAllocateSimplePropertyStorageWithInitialCapacity(ExecState* exec)
2039 {
2040     VM& vm = exec->vm();
2041     NativeCallFrameTracer tracer(&vm, exec);
2042
2043     return reinterpret_cast<char*>(
2044         Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
2045 }
2046
2047 char* JIT_OPERATION operationAllocateSimplePropertyStorage(ExecState* exec, size_t newSize)
2048 {
2049     VM& vm = exec->vm();
2050     NativeCallFrameTracer tracer(&vm, exec);
2051
2052     return reinterpret_cast<char*>(
2053         Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
2054 }
2055
2056 char* JIT_OPERATION operationAllocateComplexPropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
2057 {
2058     VM& vm = exec->vm();
2059     NativeCallFrameTracer tracer(&vm, exec);
2060
2061     ASSERT(!object->structure(vm)->outOfLineCapacity());
2062     return reinterpret_cast<char*>(
2063         object->allocateMoreOutOfLineStorage(vm, 0, initialOutOfLineCapacity));
2064 }
2065
2066 char* JIT_OPERATION operationAllocateComplexPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
2067 {
2068     VM& vm = exec->vm();
2069     NativeCallFrameTracer tracer(&vm, exec);
2070
2071     return reinterpret_cast<char*>(
2072         object->allocateMoreOutOfLineStorage(vm, object->structure(vm)->outOfLineCapacity(), newSize));
2073 }
2074
2075 char* JIT_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
2076 {
2077     VM& vm = exec->vm();
2078     NativeCallFrameTracer tracer(&vm, exec);
2079     
2080     if (!cell->isObject())
2081         return 0;
2082
2083     auto* result = reinterpret_cast<char*>(asObject(cell)->tryMakeWritableInt32(vm).data());
2084     ASSERT((!isCopyOnWrite(asObject(cell)->indexingMode()) && hasInt32(cell->indexingMode())) || !result);
2085     return result;
2086 }
2087
2088 char* JIT_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
2089 {
2090     VM& vm = exec->vm();
2091     NativeCallFrameTracer tracer(&vm, exec);
2092     
2093     if (!cell->isObject())
2094         return 0;
2095
2096     auto* result = reinterpret_cast<char*>(asObject(cell)->tryMakeWritableDouble(vm).data());
2097     ASSERT((!isCopyOnWrite(asObject(cell)->indexingMode()) && hasDouble(cell->indexingMode())) || !result);
2098     return result;
2099 }
2100
2101 char* JIT_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
2102 {
2103     VM& vm = exec->vm();
2104     NativeCallFrameTracer tracer(&vm, exec);
2105     
2106     if (!cell->isObject())
2107         return 0;
2108     
2109     auto* result = reinterpret_cast<char*>(asObject(cell)->tryMakeWritableContiguous(vm).data());
2110     ASSERT((!isCopyOnWrite(asObject(cell)->indexingMode()) && hasContiguous(cell->indexingMode())) || !result);
2111     return result;
2112 }
2113
2114 char* JIT_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
2115 {
2116     VM& vm = exec->vm();
2117     NativeCallFrameTracer tracer(&vm, exec);
2118     
2119     if (!cell->isObject())
2120         return 0;
2121
2122     auto* result = reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
2123     ASSERT((!isCopyOnWrite(asObject(cell)->indexingMode()) && hasAnyArrayStorage(cell->indexingMode())) || !result);
2124     return result;
2125 }
2126
2127 EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState* exec, EncodedJSValue encodedBaseValue, JSCell* property)
2128 {
2129     VM& vm = exec->vm();
2130     NativeCallFrameTracer tracer(&vm, exec);
2131     auto scope = DECLARE_THROW_SCOPE(vm);
2132
2133     JSValue baseValue = JSValue::decode(encodedBaseValue);
2134     if (baseValue.isUndefinedOrNull())
2135         return JSValue::encode(jsBoolean(false));
2136
2137     JSObject* base = baseValue.toObject(exec);
2138     if (!base)
2139         return JSValue::encode(JSValue());
2140     auto propertyName = asString(property)->toIdentifier(exec);
2141     RETURN_IF_EXCEPTION(scope, { });
2142     RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(base->hasPropertyGeneric(exec, propertyName, PropertySlot::InternalMethodType::GetOwnProperty))));
2143 }
2144
2145 size_t JIT_OPERATION operationHasIndexedPropertyByInt(ExecState* exec, JSCell* baseCell, int32_t subscript, int32_t internalMethodType)
2146 {
2147     VM& vm = exec->vm();
2148     NativeCallFrameTracer tracer(&vm, exec);
2149     JSObject* object = baseCell->toObject(exec, exec->lexicalGlobalObject());
2150     if (UNLIKELY(subscript < 0)) {
2151         // Go the slowest way possible because negative indices don't use indexed storage.
2152         return object->hasPropertyGeneric(exec, Identifier::from(exec, subscript), static_cast<PropertySlot::InternalMethodType>(internalMethodType));
2153     }
2154     return object->hasPropertyGeneric(exec, subscript, static_cast<PropertySlot::InternalMethodType>(internalMethodType));
2155 }
2156
2157 JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState* exec, EncodedJSValue encodedBase)
2158 {
2159     VM& vm = exec->vm();
2160     NativeCallFrameTracer tracer(&vm, exec);
2161     auto scope = DECLARE_THROW_SCOPE(vm);
2162
2163     JSValue base = JSValue::decode(encodedBase);
2164     if (base.isUndefinedOrNull())
2165         return JSPropertyNameEnumerator::create(vm);
2166
2167     JSObject* baseObject = base.toObject(exec);
2168     RETURN_IF_EXCEPTION(scope, { });
2169
2170     RELEASE_AND_RETURN(scope, propertyNameEnumerator(exec, baseObject));
2171 }
2172
2173 JSCell* JIT_OPERATION operationGetPropertyEnumeratorCell(ExecState* exec, JSCell* cell)
2174 {
2175     VM& vm = exec->vm();
2176     NativeCallFrameTracer tracer(&vm, exec);
2177     auto scope = DECLARE_THROW_SCOPE(vm);
2178
2179     JSObject* base = cell->toObject(exec, exec->lexicalGlobalObject());
2180     RETURN_IF_EXCEPTION(scope, { });
2181
2182     RELEASE_AND_RETURN(scope, propertyNameEnumerator(exec, base));
2183 }
2184
2185 JSCell* JIT_OPERATION operationToIndexString(ExecState* exec, int32_t index)
2186 {
2187     VM& vm = exec->vm();
2188     NativeCallFrameTracer tracer(&vm, exec);
2189     return jsString(exec, Identifier::from(exec, index).string());
2190 }
2191
2192 JSCell* JIT_OPERATION operationNewRegexpWithLastIndex(ExecState* exec, JSCell* regexpPtr, EncodedJSValue encodedLastIndex)
2193 {
2194     VM& vm = exec->vm();
2195     NativeCallFrameTracer tracer(&vm, exec);
2196
2197     RegExp* regexp = static_cast<RegExp*>(regexpPtr);
2198     ASSERT(regexp->isValid());
2199     return RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regexp, JSValue::decode(encodedLastIndex));
2200 }
2201
2202 StringImpl* JIT_OPERATION operationResolveRope(ExecState* exec, JSString* string)
2203 {
2204     VM& vm = exec->vm();
2205     NativeCallFrameTracer tracer(&vm, exec);
2206
2207     return string->value(exec).impl();
2208 }
2209
2210 JSString* JIT_OPERATION operationStringValueOf(ExecState* exec, EncodedJSValue encodedArgument)
2211 {
2212     VM& vm = exec->vm();
2213     NativeCallFrameTracer tracer(&vm, exec);
2214     auto scope = DECLARE_THROW_SCOPE(vm);
2215
2216     JSValue argument = JSValue::decode(encodedArgument);
2217
2218     if (argument.isString())
2219         return asString(argument);
2220
2221     if (auto* stringObject = jsDynamicCast<StringObject*>(vm, argument))
2222         return stringObject->internalValue();
2223
2224     throwVMTypeError(exec, scope);
2225     return nullptr;
2226 }
2227
2228 JSCell* JIT_OPERATION operationStringSubstr(ExecState* exec, JSCell* cell, int32_t from, int32_t span)
2229 {
2230     VM& vm = exec->vm();
2231     NativeCallFrameTracer tracer(&vm, exec);
2232
2233     return jsSubstring(vm, exec, jsCast<JSString*>(cell), from, span);
2234 }
2235
2236 JSCell* JIT_OPERATION operationStringSlice(ExecState* exec, JSCell* cell, int32_t start, int32_t end)
2237 {
2238     VM& vm = exec->vm();
2239     NativeCallFrameTracer tracer(&vm, exec);
2240
2241     JSString* string = asString(cell);
2242     static_assert(static_cast<uint64_t>(JSString::MaxLength) <= static_cast<uint64_t>(std::numeric_limits<int32_t>::max()), "");
2243     return stringSlice(exec, vm, string, string->length(), start, end);
2244 }
2245
2246 JSString* JIT_OPERATION operationToLowerCase(ExecState* exec, JSString* string, uint32_t failingIndex)
2247 {
2248     VM& vm = exec->vm();
2249     NativeCallFrameTracer tracer(&vm, exec);
2250
2251     auto scope = DECLARE_THROW_SCOPE(vm);
2252
2253     const String& inputString = string->value(exec);
2254     RETURN_IF_EXCEPTION(scope, nullptr);
2255     if (!inputString.length())
2256         return vm.smallStrings.emptyString();
2257
2258     String lowercasedString = inputString.is8Bit() ? inputString.convertToLowercaseWithoutLocaleStartingAtFailingIndex8Bit(failingIndex) : inputString.convertToLowercaseWithoutLocale();
2259     if (lowercasedString.impl() == inputString.impl())
2260         return string;
2261     RELEASE_AND_RETURN(scope, jsString(exec, lowercasedString));
2262 }
2263
2264 char* JIT_OPERATION operationInt32ToString(ExecState* exec, int32_t value, int32_t radix)
2265 {
2266     VM& vm = exec->vm();
2267     NativeCallFrameTracer tracer(&vm, exec);
2268
2269     auto scope = DECLARE_THROW_SCOPE(vm);
2270
2271     if (radix < 2 || radix > 36) {
2272         throwVMError(exec, scope, createRangeError(exec, "toString() radix argument must be between 2 and 36"_s));
2273         return nullptr;
2274     }
2275
2276     return reinterpret_cast<char*>(int32ToString(vm, value, radix));
2277 }
2278
2279 char* JIT_OPERATION operationInt52ToString(ExecState* exec, int64_t value, int32_t radix)
2280 {
2281     VM& vm = exec->vm();
2282     NativeCallFrameTracer tracer(&vm, exec);
2283
2284     auto scope = DECLARE_THROW_SCOPE(vm);
2285
2286     if (radix < 2 || radix > 36) {
2287         throwVMError(exec, scope, createRangeError(exec, "toString() radix argument must be between 2 and 36"_s));
2288         return nullptr;
2289     }
2290
2291     return reinterpret_cast<char*>(int52ToString(vm, value, radix));
2292 }
2293
2294 char* JIT_OPERATION operationDoubleToString(ExecState* exec, double value, int32_t radix)
2295 {
2296     VM& vm = exec->vm();
2297     NativeCallFrameTracer tracer(&vm, exec);
2298
2299     auto scope = DECLARE_THROW_SCOPE(vm);
2300
2301     if (radix < 2 || radix > 36) {
2302         throwVMError(exec, scope, createRangeError(exec, "toString() radix argument must be between 2 and 36"_s));
2303         return nullptr;
2304     }
2305
2306     return reinterpret_cast<char*>(numberToString(vm, value, radix));
2307 }
2308
2309 char* JIT_OPERATION operationInt32ToStringWithValidRadix(ExecState* exec, int32_t value, int32_t radix)
2310 {
2311     VM& vm = exec->vm();
2312     NativeCallFrameTracer tracer(&vm, exec);
2313
2314     return reinterpret_cast<char*>(int32ToString(vm, value, radix));
2315 }
2316
2317 char* JIT_OPERATION operationInt52ToStringWithValidRadix(ExecState* exec, int64_t value, int32_t radix)
2318 {
2319     VM& vm = exec->vm();
2320     NativeCallFrameTracer tracer(&vm, exec);
2321
2322     return reinterpret_cast<char*>(int52ToString(vm, value, radix));
2323 }
2324
2325 char* JIT_OPERATION operationDoubleToStringWithValidRadix(ExecState* exec, double value, int32_t radix)
2326 {
2327     VM& vm = exec->vm();
2328     NativeCallFrameTracer tracer(&vm, exec);
2329
2330     return reinterpret_cast<char*>(numberToString(vm, value, radix));
2331 }
2332
2333 JSString* JIT_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
2334 {
2335     VM& vm = exec->vm();
2336     NativeCallFrameTracer tracer(&vm, exec);
2337     
2338     return jsSingleCharacterString(exec, static_cast<UChar>(character));
2339 }
2340
2341 Symbol* JIT_OPERATION operationNewSymbol(ExecState* exec)
2342 {
2343     VM& vm = exec->vm();
2344     NativeCallFrameTracer tracer(&vm, exec);
2345
2346     return Symbol::create(vm);
2347 }
2348
2349 Symbol* JIT_OPERATION operationNewSymbolWithDescription(ExecState* exec, JSString* description)
2350 {
2351     VM& vm = exec->vm();
2352     NativeCallFrameTracer tracer(&vm, exec);
2353     auto scope = DECLARE_THROW_SCOPE(vm);
2354
2355     String string = description->value(exec);
2356     RETURN_IF_EXCEPTION(scope, nullptr);
2357
2358     return Symbol::createWithDescription(vm, string);
2359 }
2360
2361 JSCell* JIT_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
2362 {
2363     VM& vm = exec->vm();
2364     NativeCallFrameTracer tracer(&vm, exec);
2365     
2366     return StringObject::create(vm, structure, string);
2367 }
2368
2369 JSString* JIT_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
2370 {
2371     VM& vm = exec->vm();
2372     NativeCallFrameTracer tracer(&vm, exec);
2373     
2374     return JSValue(cell).toString(exec);
2375 }
2376
2377 JSString* JIT_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
2378 {
2379     VM& vm = exec->vm();
2380     NativeCallFrameTracer tracer(&vm, exec);
2381
2382     return JSValue::decode(value).toString(exec);
2383 }
2384
2385 JSString* JIT_OPERATION operationCallStringConstructorOnCell(ExecState* exec, JSCell* cell)
2386 {
2387     VM& vm = exec->vm();
2388     NativeCallFrameTracer tracer(&vm, exec);
2389
2390     return stringConstructor(exec, cell);
2391 }
2392
2393 JSString* JIT_OPERATION operationCallStringConstructor(ExecState* exec, EncodedJSValue value)
2394 {
2395     VM& vm = exec->vm();
2396     NativeCallFrameTracer tracer(&vm, exec);
2397
2398     return stringConstructor(exec, JSValue::decode(value));
2399 }
2400
2401 JSString* JIT_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
2402 {
2403     VM& vm = exec->vm();
2404     NativeCallFrameTracer tracer(&vm, exec);
2405
2406     return jsString(exec, left, right);
2407 }
2408
2409 JSString* JIT_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
2410 {
2411     VM& vm = exec->vm();
2412     NativeCallFrameTracer tracer(&vm, exec);
2413
2414     return jsString(exec, a, b, c);
2415 }
2416
2417 JSString* JIT_OPERATION operationStrCat2(ExecState* exec, EncodedJSValue a, EncodedJSValue b)
2418 {
2419     VM& vm = exec->vm();
2420     NativeCallFrameTracer tracer(&vm, exec);
2421     auto scope = DECLARE_THROW_SCOPE(vm);
2422
2423     ASSERT(!JSValue::decode(a).isSymbol());
2424     ASSERT(!JSValue::decode(b).isSymbol());
2425     JSString* str1 = JSValue::decode(a).toString(exec);
2426     scope.assertNoException(); // Impossible, since we must have been given non-Symbol primitives.
2427     JSString* str2 = JSValue::decode(b).toString(exec);
2428     scope.assertNoException();
2429
2430     RELEASE_AND_RETURN(scope, jsString(exec, str1, str2));
2431 }
2432     
2433 JSString* JIT_OPERATION operationStrCat3(ExecState* exec, EncodedJSValue a, EncodedJSValue b, EncodedJSValue c)
2434 {
2435     VM& vm = exec->vm();
2436     NativeCallFrameTracer tracer(&vm, exec);
2437     auto scope = DECLARE_THROW_SCOPE(vm);
2438
2439     ASSERT(!JSValue::decode(a).isSymbol());
2440     ASSERT(!JSValue::decode(b).isSymbol());
2441     ASSERT(!JSValue::decode(c).isSymbol());
2442     JSString* str1 = JSValue::decode(a).toString(exec);
2443     scope.assertNoException(); // Impossible, since we must have been given non-Symbol primitives.
2444     JSString* str2 = JSValue::decode(b).toString(exec);
2445     scope.assertNoException();
2446     JSString* str3 = JSValue::decode(c).toString(exec);
2447     scope.assertNoException();
2448
2449     RELEASE_AND_RETURN(scope, jsString(exec, str1, str2, str3));
2450 }
2451
2452 char* JIT_OPERATION operationFindSwitchImmTargetForDouble(
2453     ExecState* exec, EncodedJSValue encodedValue, size_t tableIndex)
2454 {
2455     VM& vm = exec->vm();
2456     NativeCallFrameTracer tracer(&vm, exec);
2457     CodeBlock* codeBlock = exec->codeBlock();
2458     SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
2459     JSValue value = JSValue::decode(encodedValue);
2460     ASSERT(value.isDouble());
2461     double asDouble = value.asDouble();
2462     int32_t asInt32 = static_cast<int32_t>(asDouble);
2463     if (asDouble == asInt32)
2464         return table.ctiForValue(asInt32).executableAddress<char*>();
2465     return table.ctiDefault.executableAddress<char*>();
2466 }
2467
2468 char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JSString* string)
2469 {
2470     VM& vm = exec->vm();
2471     NativeCallFrameTracer tracer(&vm, exec);
2472     auto throwScope = DECLARE_THROW_SCOPE(vm);
2473
2474     StringImpl* strImpl = string->value(exec).impl();
2475
2476     RETURN_IF_EXCEPTION(throwScope, nullptr);
2477
2478     return exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(strImpl).executableAddress<char*>();
2479 }
2480
2481 int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)
2482 {
2483     VM& vm = exec->vm();
2484     NativeCallFrameTracer tracer(&vm, exec);
2485     auto throwScope = DECLARE_THROW_SCOPE(vm);
2486
2487     StringImpl* strImpl = string->value(exec).impl();
2488
2489     RETURN_IF_EXCEPTION(throwScope, 0);
2490
2491     return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(strImpl, std::numeric_limits<int32_t>::min());
2492 }
2493
2494 uintptr_t JIT_OPERATION operationCompareStringImplLess(StringImpl* a, StringImpl* b)
2495 {
2496     return codePointCompare(a, b) < 0;
2497 }
2498
2499 uintptr_t JIT_OPERATION operationCompareStringImplLessEq(StringImpl* a, StringImpl* b)
2500 {
2501     return codePointCompare(a, b) <= 0;
2502 }
2503
2504 uintptr_t JIT_OPERATION operationCompareStringImplGreater(StringImpl* a, StringImpl* b)
2505 {
2506     return codePointCompare(a, b) > 0;
2507 }
2508
2509 uintptr_t JIT_OPERATION operationCompareStringImplGreaterEq(StringImpl* a, StringImpl* b)
2510 {
2511     return codePointCompare(a, b) >= 0;
2512 }
2513
2514 uintptr_t JIT_OPERATION operationCompareStringLess(ExecState* exec, JSString* a, JSString* b)
2515 {
2516     VM& vm = exec->vm();
2517     NativeCallFrameTracer tracer(&vm, exec);
2518
2519     return codePointCompareLessThan(asString(a)->value(exec), asString(b)->value(exec));
2520 }
2521
2522 uintptr_t JIT_OPERATION operationCompareStringLessEq(ExecState* exec, JSString* a, JSString* b)
2523 {
2524     VM& vm = exec->vm();
2525     NativeCallFrameTracer tracer(&vm, exec);
2526
2527     return !codePointCompareLessThan(asString(b)->value(exec), asString(a)->value(exec));
2528 }
2529
2530 uintptr_t JIT_OPERATION operationCompareStringGreater(ExecState* exec, JSString* a, JSString* b)
2531 {
2532     VM& vm = exec->vm();
2533     NativeCallFrameTracer tracer(&vm, exec);
2534
2535     return codePointCompareLessThan(asString(b)->value(exec), asString(a)->value(exec));
2536 }
2537
2538 uintptr_t JIT_OPERATION operationCompareStringGreaterEq(ExecState* exec, JSString* a, JSString* b)
2539 {
2540     VM& vm = exec->vm();
2541     NativeCallFrameTracer tracer(&vm, exec);
2542
2543     return !codePointCompareLessThan(asString(a)->value(exec), asString(b)->value(exec));
2544 }
2545
2546 void JIT_OPERATION operationNotifyWrite(ExecState* exec, WatchpointSet* set)
2547 {
2548     VM& vm = exec->vm();
2549     NativeCallFrameTracer tracer(&vm, exec);
2550
2551     set->touch(vm, "Executed NotifyWrite");
2552 }
2553
2554 void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
2555 {
2556     VM& vm = exec->vm();
2557     NativeCallFrameTracer tracer(&vm, exec);
2558     auto scope = DECLARE_THROW_SCOPE(vm);
2559     throwStackOverflowError(exec, scope);
2560 }
2561
2562 int32_t JIT_OPERATION operationSizeOfVarargs(ExecState* exec, EncodedJSValue encodedArguments, uint32_t firstVarArgOffset)
2563 {
2564     VM& vm = exec->vm();
2565     NativeCallFrameTracer tracer(&vm, exec);
2566     JSValue arguments = JSValue::decode(encodedArguments);
2567     
2568     return sizeOfVarargs(exec, arguments, firstVarArgOffset);
2569 }
2570
2571 int32_t JIT_OPERATION operationHasOwnProperty(ExecState* exec, JSObject* thisObject, EncodedJSValue encodedKey)
2572 {
2573     VM& vm = exec->vm();
2574     NativeCallFrameTracer tracer(&vm, exec);
2575     auto scope = DECLARE_THROW_SCOPE(vm);
2576
2577     JSValue key = JSValue::decode(encodedKey);
2578     Identifier propertyName = key.toPropertyKey(exec);
2579     RETURN_IF_EXCEPTION(scope, false);
2580
2581     PropertySlot slot(thisObject, PropertySlot::InternalMethodType::GetOwnProperty);
2582     bool result = thisObject->hasOwnProperty(exec, propertyName.impl(), slot);
2583     RETURN_IF_EXCEPTION(scope, false);
2584
2585     HasOwnPropertyCache* hasOwnPropertyCache = vm.hasOwnPropertyCache();
2586     ASSERT(hasOwnPropertyCache);
2587     hasOwnPropertyCache->tryAdd(vm, slot, thisObject, propertyName.impl(), result);
2588     return result;
2589 }
2590
2591 int32_t JIT_OPERATION operationNumberIsInteger(ExecState* exec, EncodedJSValue value)
2592 {
2593     VM& vm = exec->vm();
2594     NativeCallFrameTracer tracer(&vm, exec);
2595     return NumberConstructor::isIntegerImpl(JSValue::decode(value));
2596 }
2597
2598 int32_t JIT_OPERATION operationArrayIndexOfString(ExecState* exec, Butterfly* butterfly, JSString* searchElement, int32_t index)
2599 {
2600     VM& vm = exec->vm();
2601     NativeCallFrameTracer tracer(&vm, exec);
2602     auto scope = DECLARE_THROW_SCOPE(vm);
2603
2604     int32_t length = butterfly->publicLength();
2605     auto data = butterfly->contiguous().data();
2606     for (; index < length; ++index) {
2607         JSValue value = data[index].get();
2608         if (!value || !value.isString())
2609             continue;
2610         auto* string = asString(value);
2611         if (string == searchElement)
2612             return index;
2613         if (string->equal(exec, searchElement)) {
2614             scope.assertNoException();
2615             return index;
2616         }
2617         RETURN_IF_EXCEPTION(scope, { });
2618     }
2619     return -1;
2620 }
2621
2622 int32_t JIT_OPERATION operationArrayIndexOfValueInt32OrContiguous(ExecState* exec, Butterfly* butterfly, EncodedJSValue encodedValue, int32_t index)
2623 {
2624     VM& vm = exec->vm();
2625     NativeCallFrameTracer tracer(&vm, exec);
2626     auto scope = DECLARE_THROW_SCOPE(vm);
2627
2628     JSValue searchElement = JSValue::decode(encodedValue);
2629
2630     int32_t length = butterfly->publicLength();
2631     auto data = butterfly->contiguous().data();
2632     for (; index < length; ++index) {
2633         JSValue value = data[index].get();
2634         if (!value)
2635             continue;
2636         bool isEqual = JSValue::strictEqual(exec, searchElement, value);
2637         RETURN_IF_EXCEPTION(scope, { });
2638         if (isEqual)
2639             return index;
2640     }
2641     return -1;
2642 }
2643
2644 int32_t JIT_OPERATION operationArrayIndexOfValueDouble(ExecState* exec, Butterfly* butterfly, EncodedJSValue encodedValue, int32_t index)
2645 {
2646     VM& vm = exec->vm();
2647     NativeCallFrameTracer tracer(&vm, exec);
2648
2649     JSValue searchElement = JSValue::decode(encodedValue);
2650
2651     if (!searchElement.isNumber())
2652         return -1;
2653     double number = searchElement.asNumber();
2654
2655     int32_t length = butterfly->publicLength();
2656     const double* data = butterfly->contiguousDouble().data();
2657     for (; index < length; ++index) {
2658         // This comparison ignores NaN.
2659         if (data[index] == number)
2660             return index;
2661     }
2662     return -1;
2663 }
2664
2665 void JIT_OPERATION operationLoadVarargs(ExecState* exec, int32_t firstElementDest, EncodedJSValue encodedArguments, uint32_t offset, uint32_t length, uint32_t mandatoryMinimum)
2666 {
2667     VM& vm = exec->vm();
2668     NativeCallFrameTracer tracer(&vm, exec);
2669     JSValue arguments = JSValue::decode(encodedArguments);
2670     
2671     loadVarargs(exec, VirtualRegister(firstElementDest), arguments, offset, length);
2672     
2673     for (uint32_t i = length; i < mandatoryMinimum; ++i)
2674         exec->r(firstElementDest + i) = jsUndefined();
2675 }
2676
2677 double JIT_OPERATION operationFModOnInts(int32_t a, int32_t b)
2678 {
2679     return fmod(a, b);
2680 }
2681
2682 #if USE(JSVALUE32_64)
2683 double JIT_OPERATION operationRandom(JSGlobalObject* globalObject)
2684 {
2685     return globalObject->weakRandomNumber();
2686 }
2687 #endif
2688
2689 JSCell* JIT_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
2690 {
2691     VM* vm = &exec->vm();
2692     NativeCallFrameTracer tracer(vm, exec);
2693     return JSC::stringFromCharCode(exec, op1);
2694 }
2695
2696 EncodedJSValue JIT_OPERATION operationStringFromCharCodeUntyped(ExecState* exec, EncodedJSValue encodedValue)
2697 {
2698     VM* vm = &exec->vm();
2699     NativeCallFrameTracer tracer(vm, exec);
2700     JSValue charValue = JSValue::decode(encodedValue);
2701     int32_t chInt = charValue.toUInt32(exec);
2702     return JSValue::encode(JSC::stringFromCharCode(exec, chInt));
2703 }
2704
2705 int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue encodedValue)
2706 {
2707     JSValue value = JSValue::decode(encodedValue);
2708     if (!value.isDouble())
2709         return JSValue::notInt52;
2710     return tryConvertToInt52(value.asDouble());
2711 }
2712
2713 int64_t JIT_OPERATION operationConvertDoubleToInt52(double value)
2714 {
2715     return tryConvertToInt52(value);
2716 }
2717
2718 char* JIT_OPERATION operationNewRawObject(ExecState* exec, Structure* structure, int32_t length, Butterfly* butterfly)
2719 {
2720     VM& vm = exec->vm();
2721     NativeCallFrameTracer tracer(&vm, exec);
2722
2723     if (!butterfly
2724         && (structure->outOfLineCapacity() || hasIndexedProperties(structure->indexingType()))) {
2725         IndexingHeader header;
2726         header.setVectorLength(length);
2727         header.setPublicLength(0);
2728         
2729         butterfly = Butterfly::create(
2730             vm, nullptr, 0, structure->outOfLineCapacity(),
2731             hasIndexedProperties(structure->indexingType()), header,
2732             length * sizeof(EncodedJSValue));
2733     }
2734
2735     JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
2736     result->butterfly(); // Ensure that the butterfly is in to-space.
2737     return bitwise_cast<char*>(result);
2738 }
2739
2740 JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState* exec, Structure* structure, Butterfly* butterfly)
2741 {
2742     VM& vm = exec->vm();
2743     NativeCallFrameTracer tracer(&vm, exec);
2744     
2745     if (!butterfly) {
2746         butterfly = Butterfly::create(
2747             vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0);
2748     }
2749     
2750     JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
2751     result->butterfly(); // Ensure that the butterfly is in to-space.
2752     return result;
2753 }
2754
2755 JSCell* JIT_OPERATION operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength(ExecState* exec, Structure* structure, unsigned length, Butterfly* butterfly)
2756 {
2757     VM& vm = exec->vm();
2758     NativeCallFrameTracer tracer(&vm, exec);
2759
2760     IndexingHeader header;
2761     header.setVectorLength(length);
2762     header.setPublicLength(0);
2763     if (butterfly)
2764         *butterfly->indexingHeader() = header;
2765     else {
2766         butterfly = Butterfly::create(
2767             vm, nullptr, 0, structure->outOfLineCapacity(), true, header,
2768             sizeof(EncodedJSValue) * length);
2769     }
2770     
2771     // Paradoxically this may allocate a JSArray. That's totally cool.
2772     JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
2773     result->butterfly(); // Ensure that the butterfly is in to-space.
2774     return result;
2775 }
2776
2777 JSCell* JIT_OPERATION operationNewArrayWithSpreadSlow(ExecState* exec, void* buffer, uint32_t numItems)
2778 {
2779     VM& vm = exec->vm();
2780     NativeCallFrameTracer tracer(&vm, exec);
2781     auto scope = DECLARE_THROW_SCOPE(vm);
2782
2783     EncodedJSValue* values = static_cast<EncodedJSValue*>(buffer);
2784     Checked<unsigned, RecordOverflow> checkedLength = 0;
2785     for (unsigned i = 0; i < numItems; i++) {
2786         JSValue value = JSValue::decode(values[i]);
2787         if (JSFixedArray* array = jsDynamicCast<JSFixedArray*>(vm, value))
2788             checkedLength += array->size();
2789         else
2790             ++checkedLength;
2791     }
2792
2793     if (UNLIKELY(checkedLength.hasOverflowed())) {
2794         throwOutOfMemoryError(exec, scope);
2795         return nullptr;
2796     }
2797
2798     unsigned length = checkedLength.unsafeGet();
2799     if (UNLIKELY(length >= MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)) {
2800         throwOutOfMemoryError(exec, scope);
2801         return nullptr;
2802     }
2803
2804     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
2805     Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
2806
2807     JSArray* result = JSArray::tryCreate(vm, structure, length);
2808     if (UNLIKELY(!result)) {
2809         throwOutOfMemoryError(exec, scope);
2810         return nullptr;
2811     }
2812     RETURN_IF_EXCEPTION(scope, nullptr);
2813
2814     unsigned index = 0;
2815     for (unsigned i = 0; i < numItems; i++) {
2816         JSValue value = JSValue::decode(values[i]);
2817         if (JSFixedArray* array = jsDynamicCast<JSFixedArray*>(vm, value)) {
2818             // We are spreading.
2819             for (unsigned i = 0; i < array->size(); i++) {
2820                 result->putDirectIndex(exec, index, array->get(i));
2821                 RETURN_IF_EXCEPTION(scope, nullptr);
2822                 ++index;
2823             }
2824         } else {
2825             // We are not spreading.
2826             result->putDirectIndex(exec, index, value);
2827             RETURN_IF_EXCEPTION(scope, nullptr);
2828             ++index;
2829         }
2830     }
2831
2832     return result;
2833 }
2834
2835 JSCell* operationCreateFixedArray(ExecState* exec, unsigned length)
2836 {
2837     VM& vm = exec->vm();
2838     NativeCallFrameTracer tracer(&vm, exec);
2839     auto scope = DECLARE_THROW_SCOPE(vm);
2840
2841     if (JSFixedArray* result = JSFixedArray::tryCreate(vm, vm.fixedArrayStructure.get(), length))
2842         return result;
2843
2844     throwOutOfMemoryError(exec, scope);
2845     return nullptr;
2846 }
2847
2848 JSCell* JIT_OPERATION operationSpreadGeneric(ExecState* exec, JSCell* iterable)
2849 {
2850     VM& vm = exec->vm();
2851     NativeCallFrameTracer tracer(&vm, exec);
2852
2853     auto throwScope = DECLARE_THROW_SCOPE(vm);
2854
2855     if (isJSArray(iterable)) {
2856         JSArray* array = jsCast<JSArray*>(iterable);
2857         if (array->isIteratorProtocolFastAndNonObservable())
2858             RELEASE_AND_RETURN(throwScope, JSFixedArray::createFromArray(exec, vm, array));
2859     }
2860
2861     // FIXME: we can probably make this path faster by having our caller JS code call directly into
2862     // the iteration protocol builtin: https://bugs.webkit.org/show_bug.cgi?id=164520
2863
2864     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
2865     JSArray* array;
2866     {
2867         JSFunction* iterationFunction = globalObject->iteratorProtocolFunction();
2868         CallData callData;
2869         CallType callType = JSC::getCallData(vm, iterationFunction, callData);
2870         ASSERT(callType != CallType::None);
2871
2872         MarkedArgumentBuffer arguments;
2873         arguments.append(iterable);
2874         ASSERT(!arguments.hasOverflowed());
2875         JSValue arrayResult = call(exec, iterationFunction, callType, callData, jsNull(), arguments);
2876         RETURN_IF_EXCEPTION(throwScope, nullptr);
2877         array = jsCast<JSArray*>(arrayResult);
2878     }
2879
2880     RELEASE_AND_RETURN(throwScope, JSFixedArray::createFromArray(exec, vm, array));
2881 }
2882
2883 JSCell* JIT_OPERATION operationSpreadFastArray(ExecState* exec, JSCell* cell)
2884 {
2885     VM& vm = exec->vm();
2886     NativeCallFrameTracer tracer(&vm, exec);
2887
2888     ASSERT(isJSArray(cell));
2889     JSArray* array = jsCast<JSArray*>(cell);
2890     ASSERT(array->isIteratorProtocolFastAndNonObservable());
2891
2892     return JSFixedArray::createFromArray(exec, vm, array);
2893 }
2894
2895 void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState* exec) 
2896 {
2897     VM& vm = exec->vm();
2898     NativeCallFrameTracer tracer(&vm, exec);
2899
2900     vm.typeProfilerLog()->processLogEntries(vm, "Log Full, called from inside DFG."_s);
2901 }
2902
2903 EncodedJSValue JIT_OPERATION operationResolveScopeForHoistingFuncDeclInEval(ExecState* exec, JSScope* scope, UniquedStringImpl* impl)
2904 {
2905     VM& vm = exec->vm();
2906     NativeCallFrameTracer tracer(&vm, exec);
2907         
2908     JSValue resolvedScope = JSScope::resolveScopeForHoistingFuncDeclInEval(exec, scope, Identifier::fromUid(exec, impl));
2909     return JSValue::encode(resolvedScope);
2910 }
2911     
2912 JSCell* JIT_OPERATION operationResolveScope(ExecState* exec, JSScope* scope, UniquedStringImpl* impl)
2913 {
2914     VM& vm = exec->vm();
2915     NativeCallFrameTracer tracer(&vm, exec);
2916
2917     JSObject* resolvedScope = JSScope::resolve(exec, scope, Identifier::fromUid(exec, impl));
2918     return resolvedScope;
2919 }
2920
2921 EncodedJSValue JIT_OPERATION operationGetDynamicVar(ExecState* exec, JSObject* scope, UniquedStringImpl* impl, unsigned getPutInfoBits)
2922 {
2923     VM& vm = exec->vm();
2924     NativeCallFrameTracer tracer(&vm, exec);
2925     auto throwScope = DECLARE_THROW_SCOPE(vm);
2926
2927     Identifier ident = Identifier::fromUid(exec, impl);
2928     RELEASE_AND_RETURN(throwScope, JSValue::encode(scope->getPropertySlot(exec, ident, [&] (bool found, PropertySlot& slot) -> JSValue {
2929         if (!found) {
2930             GetPutInfo getPutInfo(getPutInfoBits);
2931             if (getPutInfo.resolveMode() == ThrowIfNotFound)
2932                 throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
2933             return jsUndefined();
2934         }
2935
2936         if (scope->isGlobalLexicalEnvironment()) {
2937             // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
2938             JSValue result = slot.getValue(exec, ident);
2939             if (result == jsTDZValue()) {
2940                 throwException(exec, throwScope, createTDZError(exec));
2941                 return jsUndefined();
2942             }
2943             return result;
2944         }
2945
2946         return slot.getValue(exec, ident);
2947     })));
2948 }
2949
2950 ALWAYS_INLINE static void putDynamicVar(ExecState* exec, VM& vm, JSObject* scope, EncodedJSValue value, UniquedStringImpl* impl, unsigned getPutInfoBits, bool isStrictMode)
2951 {
2952     auto throwScope = DECLARE_THROW_SCOPE(vm);
2953
2954     const Identifier& ident = Identifier::fromUid(exec, impl);
2955     GetPutInfo getPutInfo(getPutInfoBits);
2956     bool hasProperty = scope->hasProperty(exec, ident);
2957     RETURN_IF_EXCEPTION(throwScope, void());
2958     if (hasProperty
2959         && scope->isGlobalLexicalEnvironment()
2960         && !isInitialization(getPutInfo.initializationMode())) {
2961         // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
2962         PropertySlot slot(scope, PropertySlot::InternalMethodType::Get);
2963         JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot);
2964         if (slot.getValue(exec, ident) == jsTDZValue()) {
2965             throwException(exec, throwScope, createTDZError(exec));
2966             return;
2967         }
2968     }
2969
2970     if (getPutInfo.resolveMode() == ThrowIfNotFound && !hasProperty) {
2971         throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
2972         return;
2973     }
2974
2975     PutPropertySlot slot(scope, isStrictMode, PutPropertySlot::UnknownContext, isInitialization(getPutInfo.initializationMode()));
2976     throwScope.release();
2977     scope->methodTable(vm)->put(scope, exec, ident, JSValue::decode(value), slot);
2978 }
2979
2980 void JIT_OPERATION operationPutDynamicVarStrict(ExecState* exec, JSObject* scope, EncodedJSValue value, UniquedStringImpl* impl, unsigned getPutInfoBits)
2981 {
2982     VM& vm = exec->vm();
2983     NativeCallFrameTracer tracer(&vm, exec);
2984     constexpr bool isStrictMode = true;
2985     return putDynamicVar(exec, vm, scope, value, impl, getPutInfoBits, isStrictMode);
2986 }
2987
2988 void JIT_OPERATION operationPutDynamicVarNonStrict(ExecState* exec, JSObject* scope, EncodedJSValue value, UniquedStringImpl* impl, unsigned getPutInfoBits)
2989 {
2990     VM& vm = exec->vm();
2991     NativeCallFrameTracer tracer(&vm, exec);
2992     constexpr bool isStrictMode = false;
2993     return putDynamicVar(exec, vm, scope, value, impl, getPutInfoBits, isStrictMode);
2994 }
2995
2996 int32_t JIT_OPERATION operationMapHash(ExecState* exec, EncodedJSValue input)
2997 {
2998     VM& vm = exec->vm();
2999     NativeCallFrameTracer tracer(&vm, exec);
3000
3001     return jsMapHash(exec, vm, JSValue::decode(input));
3002 }
3003
3004 JSCell* JIT_OPERATION operationJSMapFindBucket(ExecState* exec, JSCell* map, EncodedJSValue key, int32_t hash)
3005 {
3006     VM& vm = exec->vm();
3007     NativeCallFrameTracer tracer(&vm, exec);
3008     JSMap::BucketType** bucket = jsCast<JSMap*>(map)->findBucket(exec, JSValue::decode(key), hash);
3009     if (!bucket)
3010         return vm.sentinelMapBucket();
3011     return *bucket;
3012 }
3013
3014 JSCell* JIT_OPERATION operationJSSetFindBucket(ExecState* exec, JSCell* map, EncodedJSValue key, int32_t hash)
3015 {
3016     VM& vm = exec->vm();
3017     NativeCallFrameTracer tracer(&vm, exec);
3018     JSSet::BucketType** bucket = jsCast<JSSet*>(map)->findBucket(exec, JSValue::decode(key), hash);
3019     if (!bucket)
3020         return vm.sentinelSetBucket();
3021     return *bucket;
3022 }
3023
3024 JSCell* JIT_OPERATION operationSetAdd(ExecState* exec, JSCell* set, EncodedJSValue key, int32_t hash)
3025 {
3026     VM& vm = exec->vm();
3027     NativeCallFrameTracer tracer(&vm, exec);
3028     auto* bucket = jsCast<JSSet*>(set)->addNormalized(exec, JSValue::decode(key), JSValue(), hash);
3029     if (!bucket)
3030         return vm.sentinelSetBucket();
3031     return bucket;
3032 }
3033
3034 JSCell* JIT_OPERATION operationMapSet(ExecState* exec, JSCell* map, EncodedJSValue key, EncodedJSValue value, int32_t hash)
3035 {
3036     VM& vm = exec->vm();
3037     NativeCallFrameTracer tracer(&vm, exec);
3038     auto* bucket = jsCast<JSMap*>(map)->addNormalized(exec, JSValue::decode(key), JSValue::decode(value), hash);
3039     if (!bucket)
3040         return vm.sentinelMapBucket();
3041     return bucket;
3042 }
3043
3044 void JIT_OPERATION operationWeakSetAdd(ExecState* exec, JSCell* set, JSCell* key, int32_t hash)
3045 {
3046     VM& vm = exec->vm();
3047     NativeCallFrameTracer tracer(&vm, exec);
3048     jsCast<JSWeakSet*>(set)->add(vm, asObject(key), JSValue(), hash);
3049 }
3050
3051 void JIT_OPERATION operationWeakMapSet(ExecState* exec, JSCell* map, JSCell* key, EncodedJSValue value, int32_t hash)
3052 {
3053     VM& vm = exec->vm();
3054     NativeCallFrameTracer tracer(&vm, exec);
3055     jsCast<JSWeakMap*>(map)->add(vm, asObject(key), JSValue::decode(value), hash);
3056 }
3057
3058 EncodedJSValue JIT_OPERATION operationGetPrototypeOfObject(ExecState* exec, JSObject* thisObject)
3059 {
3060     VM& vm = exec->vm();
3061     NativeCallFrameTracer tracer(&vm, exec);
3062     return JSValue::encode(thisObject->getPrototype(vm, exec));
3063 }
3064
3065 EncodedJSValue JIT_OPERATION operationGetPrototypeOf(ExecState* exec, EncodedJSValue encodedValue)
3066 {
3067     VM& vm = exec->vm();
3068     NativeCallFrameTracer tracer(&vm, exec);
3069     auto scope = DECLARE_THROW_SCOPE(vm);
3070
3071     JSValue thisValue = JSValue::decode(encodedValue).toThis(exec, StrictMode);
3072     if (thisValue.isUndefinedOrNull())
3073         return throwVMError(exec, scope, createNotAnObjectError(exec, thisValue));
3074
3075     JSObject* thisObject = jsDynamicCast<JSObject*>(vm, thisValue);
3076     if (!thisObject) {
3077         JSObject* prototype = thisValue.synthesizePrototype(exec);
3078         EXCEPTION_ASSERT(!!scope.exception() == !prototype);
3079         if (UNLIKELY(!prototype))
3080             return JSValue::encode(JSValue());
3081         return JSValue::encode(prototype);
3082     }
3083
3084     RELEASE_AND_RETURN(scope, JSValue::encode(thisObject->getPrototype(vm, exec)));
3085 }
3086
3087 void JIT_OPERATION operationThrowDFG(ExecState* exec, EncodedJSValue valueToThrow)
3088 {
3089     VM& vm = exec->vm();
3090     NativeCallFrameTracer tracer(&vm, exec);
3091     auto scope = DECLARE_THROW_SCOPE(vm);
3092     scope.throwException(exec, JSValue::decode(valueToThrow));
3093 }
3094
3095 void JIT_OPERATION operationThrowStaticError(ExecState* exec, JSString* message, uint32_t errorType)
3096 {
3097     VM& vm = exec->vm();
3098     NativeCallFrameTracer tracer(&vm, exec);
3099     auto scope = DECLARE_THROW_SCOPE(vm);
3100     String errorMessage = message->value(exec);
3101     scope.throwException(exec, createError(exec, static_cast<ErrorType>(errorType), errorMessage));
3102 }
3103
3104 extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, CodeBlock* optimizedCodeBlock, OSRExitBase* exit)
3105 {
3106     // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
3107     // really be profitable.
3108     DeferGCForAWhile deferGC(codeBlock->vm()->heap);
3109     
3110     sanitizeStackForVM(codeBlock->vm());
3111
3112     if (Options::verboseOSR())
3113         dataLog(*codeBlock, ": Entered reoptimize\n");
3114     // We must be called with the baseline code block.
3115     ASSERT(JITCode::isBaselineCode(codeBlock->jitType()));
3116
3117     // If I am my own replacement, then reoptimization has already been triggered.
3118     // This can happen in recursive functions.
3119     //
3120     // Note that even if optimizedCodeBlock is an FTLForOSREntry style CodeBlock, this condition is a
3121     // sure bet that we don't have anything else left to do.
3122     CodeBlock* replacement = codeBlock->replacement();
3123     if (!replacement || replacement == codeBlock) {
3124         if (Options::verboseOSR())
3125             dataLog(*codeBlock, ": Not reoptimizing because we've already been jettisoned.\n");
3126         return;
3127     }
3128     
3129     // Otherwise, the replacement must be optimized code. Use this as an opportunity
3130     // to check our logic.
3131     ASSERT(codeBlock->hasOptimizedReplacement());
3132     ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
3133     
3134     bool didTryToEnterIntoInlinedLoops = false;
3135     for (InlineCallFrame* inlineCallFrame = exit->m_codeOrigin.inlineCallFrame(); inlineCallFrame; inlineCallFrame = inlineCallFrame->directCaller.inlineCallFrame()) {
3136         if (inlineCallFrame->baselineCodeBlock->ownerExecutable()->didTryToEnterInLoop()) {
3137             didTryToEnterIntoInlinedLoops = true;
3138             break;
3139         }
3140     }
3141
3142     // In order to trigger reoptimization, one of two things must have happened:
3143     // 1) We exited more than some number of times.
3144     // 2) We exited and got stuck in a loop, and now we're exiting again.
3145     bool didExitABunch = optimizedCodeBlock->shouldReoptimizeNow();
3146     bool didGetStuckInLoop =
3147         (codeBlock->checkIfOptimizationThresholdReached() || didTryToEnterIntoInlinedLoops)
3148         && optimizedCodeBlock->shouldReoptimizeFromLoopNow();
3149     
3150     if (!didExitABunch && !didGetStuckInLoop) {
3151         if (Options::verboseOSR())
3152             dataLog(*codeBlock, ": Not reoptimizing ", *optimizedCodeBlock, " because it either didn't exit enough or didn't loop enough after exit.\n");
3153         codeBlock->optimizeAfterLongWarmUp();
3154         return;
3155     }
3156     
3157     optimizedCodeBlock->jettison(Profiler::JettisonDueToOSRExit, CountReoptimization);
3158 }
3159
3160 #if ENABLE(FTL_JIT)
3161 static bool shouldTriggerFTLCompile(CodeBlock* codeBlock, JITCode* jitCode)
3162 {
3163     if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
3164         CODEBLOCK_LOG_EVENT(codeBlock, "abortFTLCompile", ());
3165         if (Options::verboseOSR())
3166             dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
3167         jitCode->dontOptimizeAnytimeSoon(codeBlock);
3168         return false;
3169     }
3170
3171     if (!codeBlock->hasOptimizedReplacement()
3172         && !jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
3173         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("counter = ", jitCode->tierUpCounter));
3174         if (Options::verboseOSR())
3175             dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
3176         return false;
3177     }
3178     return true;
3179 }
3180
3181 static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
3182 {
3183     if (codeBlock->codeType() == GlobalCode) {
3184         // Global code runs once, so we don't want to do anything. We don't want to defer indefinitely,
3185         // since this may have been spuriously called from tier-up initiated in a loop, and that loop may
3186         // later want to run faster code. Deferring for warm-up seems safest.
3187         jitCode->optimizeAfterWarmUp(codeBlock);
3188         return;
3189     }
3190     
3191     Worklist::State worklistState;
3192     if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
3193         worklistState = worklist->completeAllReadyPlansForVM(
3194             *vm, CompilationKey(codeBlock->baselineVersion(), FTLMode));
3195     } else
3196         worklistState = Worklist::NotKnown;
3197     
3198     if (worklistState == Worklist::Compiling) {
3199         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
3200         jitCode->setOptimizationThresholdBasedOnCompilationResult(
3201             codeBlock, CompilationDeferred);
3202         return;
3203     }
3204     
3205     if (codeBlock->hasOptimizedReplacement()) {
3206         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("has replacement"));
3207         // That's great, we've compiled the code - next time we call this function,
3208         // we'll enter that replacement.
3209         jitCode->optimizeSoon(codeBlock);
3210         return;
3211     }
3212     
3213     if (worklistState == Worklist::Compiled) {
3214         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
3215         // This means that we finished compiling, but failed somehow; in that case the
3216         // thresholds will be set appropriately.
3217         if (Options::verboseOSR())
3218             dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
3219         return;
3220     }
3221
3222     CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLReplacement", ());
3223     // We need to compile the code.
3224     compile(
3225         *vm, codeBlock->newReplacement(), codeBlock, FTLMode, UINT_MAX,
3226         Operands<Optional<JSValue>>(), ToFTLDeferredCompilationCallback::create());
3227
3228     // If we reached here, the counter has not be reset. Do that now.
3229     jitCode->setOptimizationThresholdBasedOnCompilationResult(
3230         codeBlock, CompilationDeferred);
3231 }
3232
3233 void JIT_OPERATION triggerTierUpNow(ExecState* exec)
3234 {
3235     VM* vm = &exec->vm();
3236     NativeCallFrameTracer tracer(vm, exec);
3237     DeferGCForAWhile deferGC(vm->heap);
3238     CodeBlock* codeBlock = exec->codeBlock();
3239     
3240     sanitizeStackForVM(vm);
3241
3242     if (codeBlock->jitType() != JITType::DFGJIT) {
3243         dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
3244         RELEASE_ASSERT_NOT_REACHED();
3245     }
3246     
3247     JITCode* jitCode = codeBlock->jitCode()->dfg();
3248     
3249     if (Options::verboseOSR()) {
3250         dataLog(
3251             *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
3252             jitCode->tierUpCounter, "\n");
3253     }
3254
3255     if (shouldTriggerFTLCompile(codeBlock, jitCode))
3256         triggerFTLReplacementCompile(vm, codeBlock, jitCode);
3257
3258     if (codeBlock->hasOptimizedReplacement()) {
3259         if (jitCode->tierUpEntryTriggers.isEmpty()) {
3260             CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("replacement in place, delaying indefinitely"));
3261             // There is nothing more we can do, the only way this will be entered
3262             // is through the function entry point.
3263             jitCode->dontOptimizeAnytimeSoon(codeBlock);
3264             return;
3265         }
3266         if (jitCode->osrEntryBlock() && jitCode->tierUpEntryTriggers.size() == 1) {
3267             CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("trigger in place, delaying indefinitely"));
3268             // There is only one outer loop and its trigger must have been set
3269             // when the plan completed.
3270             // Exiting the inner loop is useless, we can ignore the counter and leave
3271             // the trigger do its job.
3272             jitCode->dontOptimizeAnytimeSoon(codeBlock);
3273             return;
3274         }
3275     }
3276 }
3277
3278 static char* tierUpCommon(ExecState* exec, unsigned originBytecodeIndex, bool canOSREnterHere)
3279 {
3280     VM* vm = &exec->vm();
3281     CodeBlock* codeBlock = exec->codeBlock();
3282
3283     // Resolve any pending plan for OSR Enter on this function.
3284     Worklist::State worklistState;
3285     if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
3286         worklistState = worklist->completeAllReadyPlansForVM(
3287             *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode));
3288     } else
3289         worklistState = Worklist::NotKnown;
3290
3291     JITCode* jitCode = codeBlock->jitCode()->dfg();
3292     
3293     bool triggeredSlowPathToStartCompilation = false;
3294     auto tierUpEntryTriggers = jitCode->tierUpEntryTriggers.find(originBytecodeIndex);
3295     if (tierUpEntryTriggers != jitCode->tierUpEntryTriggers.end()) {
3296         switch (tierUpEntryTriggers->value) {
3297         case JITCode::TriggerReason::DontTrigger:
3298             // The trigger isn't set, we entered because the counter reached its
3299             // threshold.
3300             break;
3301
3302         case JITCode::TriggerReason::CompilationDone:
3303             // The trigger was set because compilation completed. Don't unset it
3304             // so that further DFG executions OSR enter as well.
3305             break;
3306
3307         case JITCode::TriggerReason::StartCompilation:
3308             // We were asked to enter as soon as possible and start compiling an
3309             // entry for the current bytecode location. Unset this trigger so we
3310             // don't continually enter.
3311             tierUpEntryTriggers->value = JITCode::TriggerReason::DontTrigger;
3312             triggeredSlowPathToStartCompilation = true;
3313             break;
3314         }
3315     }
3316
3317     if (worklistState == Worklist::Compiling) {
3318         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
3319         jitCode->setOptimizationThresholdBasedOnCompilationResult(codeBlock, CompilationDeferred);
3320         return nullptr;
3321     }
3322
3323     // If we can OSR Enter, do it right away.
3324     if (canOSREnterHere) {
3325         auto iter = jitCode->bytecodeIndexToStreamIndex.find(originBytecodeIndex);
3326         if (iter != jitCode->bytecodeIndexToStreamIndex.end()) {
3327             unsigned streamIndex = iter->value;
3328             if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
3329                 if (Options::verboseOSR())
3330                     dataLog("OSR entry: From ", RawPointer(jitCode), " got entry block ", RawPointer(entryBlock), "\n");
3331                 if (void* address = FTL::prepareOSREntry(exec, codeBlock, entryBlock, originBytecodeIndex, streamIndex)) {
3332                     CODEBLOCK_LOG_EVENT(entryBlock, "osrEntry", ("at bc#", originBytecodeIndex));
3333                     return retagCodePtr<char*>(address, JSEntryPtrTag, bitwise_cast<PtrTag>(exec));
3334                 }
3335             }
3336         }
3337     }
3338
3339     if (worklistState == Worklist::Compiled) {
3340         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
3341         // This means that compilation failed and we already set the thresholds.
3342         if (Options::verboseOSR())
3343             dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
3344         return nullptr;
3345     }
3346
3347     // - If we don't have an FTL code block, then try to compile one.
3348     // - If we do have an FTL code block, then try to enter for a while.
3349     // - If we couldn't enter for a while, then trigger OSR entry.
3350
3351     if (!shouldTriggerFTLCompile(codeBlock, jitCode) && !triggeredSlowPathToStartCompilation)
3352         return nullptr;
3353
3354     if (!jitCode->neverExecutedEntry && !triggeredSlowPathToStartCompilation) {
3355         triggerFTLReplacementCompile(vm, codeBlock, jitCode);
3356
3357         if (!codeBlock->hasOptimizedReplacement())
3358             return nullptr;
3359
3360         if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
3361             CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding OSR entry compile"));
3362             jitCode->osrEntryRetry++;
3363             return nullptr;
3364         }
3365     } else
3366         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding replacement compile"));
3367
3368     if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
3369         if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
3370             CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed, OSR entry threshold not met"));
3371             jitCode->osrEntryRetry++;
3372             jitCode->setOptimizationThresholdBasedOnCompilationResult(
3373                 codeBlock, CompilationDeferred);
3374             return nullptr;
3375         }
3376
3377         FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
3378         entryCode->countEntryFailure();
3379         if (entryCode->entryFailureCount() <
3380             Options::ftlOSREntryFailureCountForReoptimization()) {
3381             CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed"));
3382             jitCode->setOptimizationThresholdBasedOnCompilationResult(
3383                 codeBlock, CompilationDeferred);
3384             return nullptr;
3385         }
3386
3387         // OSR entry failed. Oh no! This implies that we need to retry. We retry
3388         // without exponential backoff and we only do this for the entry code block.
3389         CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed too many times"));
3390         jitCode->clearOSREntryBlockAndResetThresholds(codeBlock);
3391         return nullptr;
3392     }
3393
3394     // It's time to try to compile code for OSR entry.
3395
3396     if (!triggeredSlowPathToStartCompilation) {
3397
3398         // An inner loop didn't specifically ask for us to kick off a compilation. This means the counter
3399         // crossed its threshold. We either fall through and kick off a compile for originBytecodeIndex,
3400         // or we flag an outer loop to immediately try to compile itself. If there are outer loops,
3401         // we first try to make them compile themselves. But we will eventually fall back to compiling
3402         // a progressively inner loop if it takes too long for control to reach an outer loop.
3403
3404         auto tryTriggerOuterLoopToCompile = [&] {
3405             auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(originBytecodeIndex);
3406             if (tierUpHierarchyEntry == jitCode->tierUpInLoopHierarchy.end())
3407                 return false;
3408
3409             // This vector is ordered from innermost to outermost loop. Every bytecode entry in this vector is
3410             // allowed to do OSR entry. We start with the outermost loop and make our way inwards (hence why we
3411             // iterate the vector in reverse). Our policy is that we will trigger an outer loop to compile
3412             // immediately when program control reaches it. If program control is taking too long to reach that
3413             // outer loop, we progressively move inwards, meaning, we'll eventually trigger some loop that is
3414             // executing to compile. We start with trying to compile outer loops since we believe outer loop
3415             // compilations reveal the best opportunities for optimizing code.
3416             for (auto iter = tierUpHierarchyEntry->value.rbegin(), end = tierUpHierarchyEntry->value.rend(); iter != end; ++iter) {
3417                 unsigned osrEntryCandidate = *iter;
3418
3419                 if (jitCode->tierUpEntryTriggers.get(osrEntryCandidate) == JITCode::TriggerReason::StartCompilation) {
3420                     // This means that we already asked this loop to compile. If we've reached here, it
3421                     // means program control has not yet reached that loop. So it's taking too long to compile.
3422                     // So we move on to asking the inner loop of this loop to compile itself.
3423                     continue;
3424                 }
3425
3426                 // This is where we ask the outer to loop to immediately compile itself if program
3427                 // control reaches it.
3428                 if (Options::verboseOSR())
3429                     dataLog("Inner-loop bc#", originBytecodeIndex, " in ", *codeBlock, " setting parent loop bc#", osrEntryCandidate, "'s trigger and backing off.\n");
3430                 jitCode->tierUpEntryTriggers.set(osrEntryCandidate, JITCode::TriggerReason::StartCompilation);
3431                 return true;
3432             }
3433
3434             return false;
3435         };
3436
3437         if (tryTriggerOuterLoopToCompile()) {
3438             jitCode->setOptimizationThresholdBasedOnCompilationResult(codeBlock, CompilationDeferred);
3439             return nullptr;
3440         }
3441     }
3442
3443     if (!canOSREnterHere) {
3444         jitCode->setOptimizationThresholdBasedOnCompilationResult(codeBlock, CompilationDeferred);
3445         return nullptr;
3446     }
3447
3448     // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile
3449     // something.
3450
3451     auto triggerIterator = jitCode->tierUpEntryTriggers.find(originBytecodeIndex);
3452     if (triggerIterator == jitCode->tierUpEntryTriggers.end()) {
3453       &nb