Simplify call linking
[WebKit-https.git] / Source / JavaScriptCore / jit / JITOperations.cpp
1 /*
2  * Copyright (C) 2013-2015 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 "JITOperations.h"
28
29 #if ENABLE(JIT)
30
31 #include "ArrayConstructor.h"
32 #include "DFGCompilationMode.h"
33 #include "DFGDriver.h"
34 #include "DFGOSREntry.h"
35 #include "DFGThunks.h"
36 #include "DFGWorklist.h"
37 #include "Debugger.h"
38 #include "DirectArguments.h"
39 #include "Error.h"
40 #include "ErrorHandlingScope.h"
41 #include "ExceptionFuzz.h"
42 #include "GetterSetter.h"
43 #include "HostCallReturnValue.h"
44 #include "JIT.h"
45 #include "JITToDFGDeferredCompilationCallback.h"
46 #include "JSCInlines.h"
47 #include "JSCatchScope.h"
48 #include "JSFunctionNameScope.h"
49 #include "JSGlobalObjectFunctions.h"
50 #include "JSLexicalEnvironment.h"
51 #include "JSNameScope.h"
52 #include "JSPropertyNameEnumerator.h"
53 #include "JSStackInlines.h"
54 #include "JSWithScope.h"
55 #include "LegacyProfiler.h"
56 #include "ObjectConstructor.h"
57 #include "PropertyName.h"
58 #include "Repatch.h"
59 #include "RepatchBuffer.h"
60 #include "ScopedArguments.h"
61 #include "TestRunnerUtils.h"
62 #include "TypeProfilerLog.h"
63 #include <wtf/InlineASM.h>
64
65 namespace JSC {
66
67 template<typename ScopeType>
68 void pushNameScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
69 {
70     VM& vm = exec->vm();
71     NativeCallFrameTracer tracer(&vm, exec);
72     
73     ASSERT(!JITCode::isOptimizingJIT(exec->codeBlock()->jitType()));
74
75     // FIXME: This won't work if this operation is called from the DFG or FTL.
76     // This should be changed to pass in the new scope.
77     JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
78     JSNameScope* scope = ScopeType::create(vm, exec->lexicalGlobalObject(), currentScope, symbolTable, JSValue::decode(encodedValue));
79
80     // FIXME: This won't work if this operation is called from the DFG or FTL.
81     // This should be changed to return the new scope.
82     exec->uncheckedR(dst) = scope;
83 }
84
85 extern "C" {
86
87 #if COMPILER(MSVC)
88 void * _ReturnAddress(void);
89 #pragma intrinsic(_ReturnAddress)
90
91 #define OUR_RETURN_ADDRESS _ReturnAddress()
92 #else
93 #define OUR_RETURN_ADDRESS __builtin_return_address(0)
94 #endif
95
96 #if ENABLE(OPCODE_SAMPLING)
97 #define CTI_SAMPLER vm->interpreter->sampler()
98 #else
99 #define CTI_SAMPLER 0
100 #endif
101
102
103 void JIT_OPERATION operationThrowStackOverflowError(ExecState* exec, CodeBlock* codeBlock)
104 {
105     // We pass in our own code block, because the callframe hasn't been populated.
106     VM* vm = codeBlock->vm();
107
108     VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
109     CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
110     if (!callerFrame)
111         callerFrame = exec;
112
113     NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
114     ErrorHandlingScope errorScope(*vm);
115     vm->throwException(callerFrame, createStackOverflowError(callerFrame));
116 }
117
118 int32_t JIT_OPERATION operationCallArityCheck(ExecState* exec)
119 {
120     VM* vm = &exec->vm();
121     VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
122     CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
123
124     JSStack& stack = vm->interpreter->stack();
125
126     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForCall);
127     if (missingArgCount < 0) {
128         NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
129         throwStackOverflowError(callerFrame);
130     }
131
132     return missingArgCount;
133 }
134
135 int32_t JIT_OPERATION operationConstructArityCheck(ExecState* exec)
136 {
137     VM* vm = &exec->vm();
138     VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
139     CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
140
141     JSStack& stack = vm->interpreter->stack();
142
143     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForConstruct);
144     if (missingArgCount < 0) {
145         NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
146         throwStackOverflowError(callerFrame);
147     }
148
149     return missingArgCount;
150 }
151
152 EncodedJSValue JIT_OPERATION operationGetById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
153 {
154     VM* vm = &exec->vm();
155     NativeCallFrameTracer tracer(vm, exec);
156     
157     stubInfo->tookSlowPath = true;
158     
159     JSValue baseValue = JSValue::decode(base);
160     PropertySlot slot(baseValue);
161     Identifier ident = Identifier::fromUid(vm, uid);
162     return JSValue::encode(baseValue.get(exec, ident, slot));
163 }
164
165 EncodedJSValue JIT_OPERATION operationGetByIdGeneric(ExecState* exec, EncodedJSValue base, UniquedStringImpl* uid)
166 {
167     VM* vm = &exec->vm();
168     NativeCallFrameTracer tracer(vm, exec);
169     
170     JSValue baseValue = JSValue::decode(base);
171     PropertySlot slot(baseValue);
172     Identifier ident = Identifier::fromUid(vm, uid);
173     return JSValue::encode(baseValue.get(exec, ident, slot));
174 }
175
176 EncodedJSValue JIT_OPERATION operationGetByIdBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
177 {
178     VM* vm = &exec->vm();
179     NativeCallFrameTracer tracer(vm, exec);
180
181     Identifier ident = Identifier::fromUid(vm, uid);
182     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
183
184     JSValue baseValue = JSValue::decode(base);
185     PropertySlot slot(baseValue);
186     bool hasResult = baseValue.getPropertySlot(exec, ident, slot);
187     
188     if (accessType == static_cast<AccessType>(stubInfo->accessType))
189         buildGetByIDList(exec, baseValue, ident, slot, *stubInfo);
190
191     return JSValue::encode(hasResult? slot.getValue(exec, ident) : jsUndefined());
192 }
193
194 EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
195 {
196     VM* vm = &exec->vm();
197     NativeCallFrameTracer tracer(vm, exec);
198     Identifier ident = Identifier::fromUid(vm, uid);
199
200     JSValue baseValue = JSValue::decode(base);
201     PropertySlot slot(baseValue);
202     
203     bool hasResult = baseValue.getPropertySlot(exec, ident, slot);
204     if (stubInfo->seen)
205         repatchGetByID(exec, baseValue, ident, slot, *stubInfo);
206     else
207         stubInfo->seen = true;
208     
209     return JSValue::encode(hasResult? slot.getValue(exec, ident) : jsUndefined());
210
211 }
212
213 EncodedJSValue JIT_OPERATION operationInOptimize(ExecState* exec, StructureStubInfo* stubInfo, JSCell* base, UniquedStringImpl* key)
214 {
215     VM* vm = &exec->vm();
216     NativeCallFrameTracer tracer(vm, exec);
217     
218     if (!base->isObject()) {
219         vm->throwException(exec, createInvalidInParameterError(exec, base));
220         return JSValue::encode(jsUndefined());
221     }
222     
223     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
224
225     Identifier ident = Identifier::fromUid(vm, key);
226     PropertySlot slot(base);
227     bool result = asObject(base)->getPropertySlot(exec, ident, slot);
228     
229     RELEASE_ASSERT(accessType == stubInfo->accessType);
230     
231     if (stubInfo->seen)
232         repatchIn(exec, base, ident, result, slot, *stubInfo);
233     else
234         stubInfo->seen = true;
235     
236     return JSValue::encode(jsBoolean(result));
237 }
238
239 EncodedJSValue JIT_OPERATION operationIn(ExecState* exec, StructureStubInfo* stubInfo, JSCell* base, UniquedStringImpl* key)
240 {
241     VM* vm = &exec->vm();
242     NativeCallFrameTracer tracer(vm, exec);
243     
244     stubInfo->tookSlowPath = true;
245
246     if (!base->isObject()) {
247         vm->throwException(exec, createInvalidInParameterError(exec, base));
248         return JSValue::encode(jsUndefined());
249     }
250
251     Identifier ident = Identifier::fromUid(vm, key);
252     return JSValue::encode(jsBoolean(asObject(base)->hasProperty(exec, ident)));
253 }
254
255 EncodedJSValue JIT_OPERATION operationGenericIn(ExecState* exec, JSCell* base, EncodedJSValue key)
256 {
257     VM* vm = &exec->vm();
258     NativeCallFrameTracer tracer(vm, exec);
259
260     return JSValue::encode(jsBoolean(CommonSlowPaths::opIn(exec, JSValue::decode(key), base)));
261 }
262
263 void JIT_OPERATION operationPutByIdStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
264 {
265     VM* vm = &exec->vm();
266     NativeCallFrameTracer tracer(vm, exec);
267     
268     stubInfo->tookSlowPath = true;
269     
270     Identifier ident = Identifier::fromUid(vm, uid);
271     PutPropertySlot slot(JSValue::decode(encodedBase), true, exec->codeBlock()->putByIdContext());
272     JSValue::decode(encodedBase).put(exec, ident, JSValue::decode(encodedValue), slot);
273 }
274
275 void JIT_OPERATION operationPutByIdNonStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
276 {
277     VM* vm = &exec->vm();
278     NativeCallFrameTracer tracer(vm, exec);
279     
280     stubInfo->tookSlowPath = true;
281     
282     Identifier ident = Identifier::fromUid(vm, uid);
283     PutPropertySlot slot(JSValue::decode(encodedBase), false, exec->codeBlock()->putByIdContext());
284     JSValue::decode(encodedBase).put(exec, ident, JSValue::decode(encodedValue), slot);
285 }
286
287 void JIT_OPERATION operationPutByIdDirectStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
288 {
289     VM* vm = &exec->vm();
290     NativeCallFrameTracer tracer(vm, exec);
291     
292     stubInfo->tookSlowPath = true;
293     
294     Identifier ident = Identifier::fromUid(vm, uid);
295     PutPropertySlot slot(JSValue::decode(encodedBase), true, exec->codeBlock()->putByIdContext());
296     asObject(JSValue::decode(encodedBase))->putDirect(exec->vm(), ident, JSValue::decode(encodedValue), slot);
297 }
298
299 void JIT_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
300 {
301     VM* vm = &exec->vm();
302     NativeCallFrameTracer tracer(vm, exec);
303     
304     stubInfo->tookSlowPath = true;
305     
306     Identifier ident = Identifier::fromUid(vm, uid);
307     PutPropertySlot slot(JSValue::decode(encodedBase), false, exec->codeBlock()->putByIdContext());
308     asObject(JSValue::decode(encodedBase))->putDirect(exec->vm(), ident, JSValue::decode(encodedValue), slot);
309 }
310
311 void JIT_OPERATION operationPutByIdStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
312 {
313     VM* vm = &exec->vm();
314     NativeCallFrameTracer tracer(vm, exec);
315     
316     Identifier ident = Identifier::fromUid(vm, uid);
317     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
318
319     JSValue value = JSValue::decode(encodedValue);
320     JSValue baseValue = JSValue::decode(encodedBase);
321     PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
322
323     Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;
324     baseValue.put(exec, ident, value, slot);
325     
326     if (accessType != static_cast<AccessType>(stubInfo->accessType))
327         return;
328     
329     if (stubInfo->seen)
330         repatchPutByID(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
331     else
332         stubInfo->seen = true;
333 }
334
335 void JIT_OPERATION operationPutByIdNonStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
336 {
337     VM* vm = &exec->vm();
338     NativeCallFrameTracer tracer(vm, exec);
339     
340     Identifier ident = Identifier::fromUid(vm, uid);
341     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
342
343     JSValue value = JSValue::decode(encodedValue);
344     JSValue baseValue = JSValue::decode(encodedBase);
345     PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
346
347     Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;    
348     baseValue.put(exec, ident, value, slot);
349     
350     if (accessType != static_cast<AccessType>(stubInfo->accessType))
351         return;
352     
353     if (stubInfo->seen)
354         repatchPutByID(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
355     else
356         stubInfo->seen = true;
357 }
358
359 void JIT_OPERATION operationPutByIdDirectStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
360 {
361     VM* vm = &exec->vm();
362     NativeCallFrameTracer tracer(vm, exec);
363     
364     Identifier ident = Identifier::fromUid(vm, uid);
365     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
366
367     JSValue value = JSValue::decode(encodedValue);
368     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
369     PutPropertySlot slot(baseObject, true, exec->codeBlock()->putByIdContext());
370     
371     Structure* structure = baseObject->structure(*vm);
372     baseObject->putDirect(exec->vm(), ident, value, slot);
373     
374     if (accessType != static_cast<AccessType>(stubInfo->accessType))
375         return;
376     
377     if (stubInfo->seen)
378         repatchPutByID(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
379     else
380         stubInfo->seen = true;
381 }
382
383 void JIT_OPERATION operationPutByIdDirectNonStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
384 {
385     VM* vm = &exec->vm();
386     NativeCallFrameTracer tracer(vm, exec);
387     
388     Identifier ident = Identifier::fromUid(vm, uid);
389     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
390
391     JSValue value = JSValue::decode(encodedValue);
392     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
393     PutPropertySlot slot(baseObject, false, exec->codeBlock()->putByIdContext());
394     
395     Structure* structure = baseObject->structure(*vm);
396     baseObject->putDirect(exec->vm(), ident, value, slot);
397     
398     if (accessType != static_cast<AccessType>(stubInfo->accessType))
399         return;
400     
401     if (stubInfo->seen)
402         repatchPutByID(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
403     else
404         stubInfo->seen = true;
405 }
406
407 void JIT_OPERATION operationPutByIdStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
408 {
409     VM* vm = &exec->vm();
410     NativeCallFrameTracer tracer(vm, exec);
411     
412     Identifier ident = Identifier::fromUid(vm, uid);
413     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
414
415     JSValue value = JSValue::decode(encodedValue);
416     JSValue baseValue = JSValue::decode(encodedBase);
417     PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
418     
419     Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr; 
420     baseValue.put(exec, ident, value, slot);
421
422     if (accessType != static_cast<AccessType>(stubInfo->accessType))
423         return;
424
425     buildPutByIdList(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
426 }
427
428 void JIT_OPERATION operationPutByIdNonStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
429 {
430     VM* vm = &exec->vm();
431     NativeCallFrameTracer tracer(vm, exec);
432     
433     Identifier ident = Identifier::fromUid(vm, uid);
434     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
435
436     JSValue value = JSValue::decode(encodedValue);
437     JSValue baseValue = JSValue::decode(encodedBase);
438     PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
439
440     Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;
441     baseValue.put(exec, ident, value, slot);
442     
443     if (accessType != static_cast<AccessType>(stubInfo->accessType))
444         return;
445     
446     buildPutByIdList(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
447 }
448
449 void JIT_OPERATION operationPutByIdDirectStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
450 {
451     VM* vm = &exec->vm();
452     NativeCallFrameTracer tracer(vm, exec);
453     
454     Identifier ident = Identifier::fromUid(vm, uid);
455     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
456     
457     JSValue value = JSValue::decode(encodedValue);
458     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
459     PutPropertySlot slot(baseObject, true, exec->codeBlock()->putByIdContext());
460
461     Structure* structure = baseObject->structure(*vm);    
462     baseObject->putDirect(*vm, ident, value, slot);
463     
464     if (accessType != static_cast<AccessType>(stubInfo->accessType))
465         return;
466     
467     buildPutByIdList(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
468 }
469
470 void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
471 {
472     VM* vm = &exec->vm();
473     NativeCallFrameTracer tracer(vm, exec);
474     
475     Identifier ident = Identifier::fromUid(vm, uid);
476     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
477
478     JSValue value = JSValue::decode(encodedValue);
479     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
480     PutPropertySlot slot(baseObject, false, exec->codeBlock()->putByIdContext());
481
482     Structure* structure = baseObject->structure(*vm);    
483     baseObject->putDirect(*vm, ident, value, slot);
484
485     if (accessType != static_cast<AccessType>(stubInfo->accessType))
486         return;
487     
488     buildPutByIdList(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
489 }
490
491 void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value)
492 {
493     VM& vm = exec->vm();
494     NativeCallFrameTracer tracer(&vm, exec);
495
496     ASSERT(structure->outOfLineCapacity() > base->structure(vm)->outOfLineCapacity());
497     ASSERT(!vm.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue)));
498     base->setStructureAndReallocateStorageIfNecessary(vm, structure);
499     base->putDirect(vm, offset, JSValue::decode(value));
500 }
501
502 static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript, JSValue value, ArrayProfile* arrayProfile)
503 {
504     VM& vm = callFrame->vm();
505     if (LIKELY(subscript.isUInt32())) {
506         uint32_t i = subscript.asUInt32();
507         if (baseValue.isObject()) {
508             JSObject* object = asObject(baseValue);
509             if (object->canSetIndexQuickly(i))
510                 object->setIndexQuickly(callFrame->vm(), i, value);
511             else {
512                 arrayProfile->setOutOfBounds();
513                 object->methodTable(vm)->putByIndex(object, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
514             }
515         } else
516             baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
517     } else {
518         auto property = subscript.toPropertyKey(callFrame);
519         if (!callFrame->vm().exception()) { // Don't put to an object if toString threw an exception.
520             PutPropertySlot slot(baseValue, callFrame->codeBlock()->isStrictMode());
521             baseValue.put(callFrame, property, value, slot);
522         }
523     }
524 }
525
526 static void directPutByVal(CallFrame* callFrame, JSObject* baseObject, JSValue subscript, JSValue value, ArrayProfile* arrayProfile)
527 {
528     bool isStrictMode = callFrame->codeBlock()->isStrictMode();
529     if (LIKELY(subscript.isUInt32())) {
530         // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
531         uint32_t index = subscript.asUInt32();
532         ASSERT(isIndex(index));
533         if (baseObject->canSetIndexQuicklyForPutDirect(index)) {
534             baseObject->setIndexQuickly(callFrame->vm(), index, value);
535             return;
536         }
537
538         arrayProfile->setOutOfBounds();
539         baseObject->putDirectIndex(callFrame, index, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
540         return;
541     }
542
543     if (subscript.isDouble()) {
544         double subscriptAsDouble = subscript.asDouble();
545         uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble);
546         if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) {
547             baseObject->putDirectIndex(callFrame, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
548             return;
549         }
550     }
551
552     // Don't put to an object if toString threw an exception.
553     auto property = subscript.toPropertyKey(callFrame);
554     if (callFrame->vm().exception())
555         return;
556
557     if (Optional<uint32_t> index = parseIndex(property))
558         baseObject->putDirectIndex(callFrame, index.value(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
559     else {
560         PutPropertySlot slot(baseObject, isStrictMode);
561         baseObject->putDirect(callFrame->vm(), property, value, slot);
562     }
563 }
564 void JIT_OPERATION operationPutByVal(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
565 {
566     VM& vm = exec->vm();
567     NativeCallFrameTracer tracer(&vm, exec);
568
569     JSValue baseValue = JSValue::decode(encodedBaseValue);
570     JSValue subscript = JSValue::decode(encodedSubscript);
571     JSValue value = JSValue::decode(encodedValue);
572
573     if (baseValue.isObject() && subscript.isInt32()) {
574         // See if it's worth optimizing at all.
575         JSObject* object = asObject(baseValue);
576         bool didOptimize = false;
577
578         unsigned bytecodeOffset = exec->locationAsBytecodeOffset();
579         ASSERT(bytecodeOffset);
580         ByValInfo& byValInfo = exec->codeBlock()->getByValInfo(bytecodeOffset - 1);
581         ASSERT(!byValInfo.stubRoutine);
582
583         Structure* structure = object->structure(vm);
584         if (hasOptimizableIndexing(structure)) {
585             // Attempt to optimize.
586             JITArrayMode arrayMode = jitArrayModeForStructure(structure);
587             if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
588                 CodeBlock* codeBlock = exec->codeBlock();
589                 ConcurrentJITLocker locker(codeBlock->m_lock);
590                 arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
591
592                 JIT::compilePutByVal(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
593                 didOptimize = true;
594             }
595         }
596
597         if (!didOptimize) {
598             // If we take slow path more than 10 times without patching then make sure we
599             // never make that mistake again. Or, if we failed to patch and we have some object
600             // that intercepts indexed get, then don't even wait until 10 times. For cases
601             // where we see non-index-intercepting objects, this gives 10 iterations worth of
602             // opportunity for us to observe that the get_by_val may be polymorphic.
603             if (++byValInfo.slowPathCount >= 10
604                 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
605                 // Don't ever try to optimize.
606                 ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationPutByValGeneric));
607             }
608         }
609     }
610
611     putByVal(exec, baseValue, subscript, value, arrayProfile);
612 }
613
614 void JIT_OPERATION operationDirectPutByVal(ExecState* callFrame, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
615 {
616     VM& vm = callFrame->vm();
617     NativeCallFrameTracer tracer(&vm, callFrame);
618     
619     JSValue baseValue = JSValue::decode(encodedBaseValue);
620     JSValue subscript = JSValue::decode(encodedSubscript);
621     JSValue value = JSValue::decode(encodedValue);
622     RELEASE_ASSERT(baseValue.isObject());
623     JSObject* object = asObject(baseValue);
624     if (subscript.isInt32()) {
625         // See if it's worth optimizing at all.
626         bool didOptimize = false;
627         
628         unsigned bytecodeOffset = callFrame->locationAsBytecodeOffset();
629         ASSERT(bytecodeOffset);
630         ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1);
631         ASSERT(!byValInfo.stubRoutine);
632
633         Structure* structure = object->structure(vm);
634         if (hasOptimizableIndexing(structure)) {
635             // Attempt to optimize.
636             JITArrayMode arrayMode = jitArrayModeForStructure(structure);
637             if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
638                 CodeBlock* codeBlock = callFrame->codeBlock();
639                 ConcurrentJITLocker locker(codeBlock->m_lock);
640                 arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
641
642                 JIT::compileDirectPutByVal(&vm, callFrame->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
643                 didOptimize = true;
644             }
645         }
646         
647         if (!didOptimize) {
648             // If we take slow path more than 10 times without patching then make sure we
649             // never make that mistake again. Or, if we failed to patch and we have some object
650             // that intercepts indexed get, then don't even wait until 10 times. For cases
651             // where we see non-index-intercepting objects, this gives 10 iterations worth of
652             // opportunity for us to observe that the get_by_val may be polymorphic.
653             if (++byValInfo.slowPathCount >= 10
654                 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
655                 // Don't ever try to optimize.
656                 ctiPatchCallByReturnAddress(callFrame->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationDirectPutByValGeneric));
657             }
658         }
659     }
660     directPutByVal(callFrame, object, subscript, value, arrayProfile);
661 }
662
663 void JIT_OPERATION operationPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
664 {
665     VM& vm = exec->vm();
666     NativeCallFrameTracer tracer(&vm, exec);
667     
668     JSValue baseValue = JSValue::decode(encodedBaseValue);
669     JSValue subscript = JSValue::decode(encodedSubscript);
670     JSValue value = JSValue::decode(encodedValue);
671
672     putByVal(exec, baseValue, subscript, value, arrayProfile);
673 }
674
675
676 void JIT_OPERATION operationDirectPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
677 {
678     VM& vm = exec->vm();
679     NativeCallFrameTracer tracer(&vm, exec);
680     
681     JSValue baseValue = JSValue::decode(encodedBaseValue);
682     JSValue subscript = JSValue::decode(encodedSubscript);
683     JSValue value = JSValue::decode(encodedValue);
684     RELEASE_ASSERT(baseValue.isObject());
685     directPutByVal(exec, asObject(baseValue), subscript, value, arrayProfile);
686 }
687
688 EncodedJSValue JIT_OPERATION operationCallEval(ExecState* exec, ExecState* execCallee)
689 {
690     UNUSED_PARAM(exec);
691
692     execCallee->setCodeBlock(0);
693
694     if (!isHostFunction(execCallee->calleeAsValue(), globalFuncEval))
695         return JSValue::encode(JSValue());
696
697     VM* vm = &execCallee->vm();
698     JSValue result = eval(execCallee);
699     if (vm->exception())
700         return EncodedJSValue();
701     
702     return JSValue::encode(result);
703 }
704
705 static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
706 {
707     ExecState* exec = execCallee->callerFrame();
708     VM* vm = &exec->vm();
709
710     execCallee->setCodeBlock(0);
711
712     if (kind == CodeForCall) {
713         CallData callData;
714         CallType callType = getCallData(callee, callData);
715     
716         ASSERT(callType != CallTypeJS);
717     
718         if (callType == CallTypeHost) {
719             NativeCallFrameTracer tracer(vm, execCallee);
720             execCallee->setCallee(asObject(callee));
721             vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
722             if (vm->exception())
723                 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
724
725             return reinterpret_cast<void*>(getHostCallReturnValue);
726         }
727     
728         ASSERT(callType == CallTypeNone);
729         exec->vm().throwException(exec, createNotAFunctionError(exec, callee));
730         return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
731     }
732
733     ASSERT(kind == CodeForConstruct);
734     
735     ConstructData constructData;
736     ConstructType constructType = getConstructData(callee, constructData);
737     
738     ASSERT(constructType != ConstructTypeJS);
739     
740     if (constructType == ConstructTypeHost) {
741         NativeCallFrameTracer tracer(vm, execCallee);
742         execCallee->setCallee(asObject(callee));
743         vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
744         if (vm->exception())
745             return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
746
747         return reinterpret_cast<void*>(getHostCallReturnValue);
748     }
749     
750     ASSERT(constructType == ConstructTypeNone);
751     exec->vm().throwException(exec, createNotAConstructorError(exec, callee));
752     return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
753 }
754
755 char* JIT_OPERATION operationLinkCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
756 {
757     ExecState* exec = execCallee->callerFrame();
758     VM* vm = &exec->vm();
759     CodeSpecializationKind kind = callLinkInfo->specializationKind();
760     NativeCallFrameTracer tracer(vm, exec);
761     
762     JSValue calleeAsValue = execCallee->calleeAsValue();
763     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
764     if (!calleeAsFunctionCell) {
765         // FIXME: We should cache these kinds of calls. They can be common and currently they are
766         // expensive.
767         // https://bugs.webkit.org/show_bug.cgi?id=144458
768         return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
769     }
770
771     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
772     JSScope* scope = callee->scopeUnchecked();
773     ExecutableBase* executable = callee->executable();
774
775     MacroAssemblerCodePtr codePtr;
776     CodeBlock* codeBlock = 0;
777     if (executable->isHostFunction())
778         codePtr = executable->entrypointFor(*vm, kind, MustCheckArity, callLinkInfo->registerPreservationMode());
779     else {
780         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
781
782         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct) {
783             exec->vm().throwException(exec, createNotAConstructorError(exec, callee));
784             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
785         }
786
787         JSObject* error = functionExecutable->prepareForExecution(execCallee, callee, scope, kind);
788         if (error) {
789             exec->vm().throwException(exec, error);
790             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
791         }
792         codeBlock = functionExecutable->codeBlockFor(kind);
793         ArityCheckMode arity;
794         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo->callType() == CallLinkInfo::CallVarargs || callLinkInfo->callType() == CallLinkInfo::ConstructVarargs)
795             arity = MustCheckArity;
796         else
797             arity = ArityCheckNotRequired;
798         codePtr = functionExecutable->entrypointFor(*vm, kind, arity, callLinkInfo->registerPreservationMode());
799     }
800     if (!callLinkInfo->seenOnce())
801         callLinkInfo->setSeen();
802     else
803         linkFor(execCallee, *callLinkInfo, codeBlock, callee, codePtr);
804     
805     return reinterpret_cast<char*>(codePtr.executableAddress());
806 }
807
808 inline char* virtualForWithFunction(
809     ExecState* execCallee, CallLinkInfo* callLinkInfo, JSCell*& calleeAsFunctionCell)
810 {
811     ExecState* exec = execCallee->callerFrame();
812     VM* vm = &exec->vm();
813     CodeSpecializationKind kind = callLinkInfo->specializationKind();
814     NativeCallFrameTracer tracer(vm, exec);
815
816     JSValue calleeAsValue = execCallee->calleeAsValue();
817     calleeAsFunctionCell = getJSFunction(calleeAsValue);
818     if (UNLIKELY(!calleeAsFunctionCell))
819         return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
820     
821     JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
822     JSScope* scope = function->scopeUnchecked();
823     ExecutableBase* executable = function->executable();
824     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
825         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
826
827         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct) {
828             exec->vm().throwException(exec, createNotAConstructorError(exec, function));
829             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
830         }
831
832         JSObject* error = functionExecutable->prepareForExecution(execCallee, function, scope, kind);
833         if (error) {
834             exec->vm().throwException(exec, error);
835             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
836         }
837     }
838     return reinterpret_cast<char*>(executable->entrypointFor(
839         *vm, kind, MustCheckArity, callLinkInfo->registerPreservationMode()).executableAddress());
840 }
841
842 char* JIT_OPERATION operationLinkPolymorphicCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
843 {
844     ASSERT(callLinkInfo->specializationKind() == CodeForCall);
845     JSCell* calleeAsFunctionCell;
846     char* result = virtualForWithFunction(execCallee, callLinkInfo, calleeAsFunctionCell);
847
848     linkPolymorphicCall(execCallee, *callLinkInfo, CallVariant(calleeAsFunctionCell));
849     
850     return result;
851 }
852
853 char* JIT_OPERATION operationVirtualCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
854 {
855     JSCell* calleeAsFunctionCellIgnored;
856     return virtualForWithFunction(execCallee, callLinkInfo, calleeAsFunctionCellIgnored);
857 }
858
859 size_t JIT_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
860 {
861     VM* vm = &exec->vm();
862     NativeCallFrameTracer tracer(vm, exec);
863     
864     return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
865 }
866
867 size_t JIT_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
868 {
869     VM* vm = &exec->vm();
870     NativeCallFrameTracer tracer(vm, exec);
871
872     return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
873 }
874
875 size_t JIT_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
876 {
877     VM* vm = &exec->vm();
878     NativeCallFrameTracer tracer(vm, exec);
879
880     return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
881 }
882
883 size_t JIT_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
884 {
885     VM* vm = &exec->vm();
886     NativeCallFrameTracer tracer(vm, exec);
887
888     return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
889 }
890
891 size_t JIT_OPERATION operationConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
892 {
893     VM* vm = &exec->vm();
894     NativeCallFrameTracer tracer(vm, exec);
895     
896     return JSValue::decode(encodedOp).toBoolean(exec);
897 }
898
899 size_t JIT_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
900 {
901     VM* vm = &exec->vm();
902     NativeCallFrameTracer tracer(vm, exec);
903
904     return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
905 }
906
907 #if USE(JSVALUE64)
908 EncodedJSValue JIT_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
909 #else
910 size_t JIT_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
911 #endif
912 {
913     VM* vm = &exec->vm();
914     NativeCallFrameTracer tracer(vm, exec);
915
916     bool result = WTF::equal(*asString(left)->value(exec).impl(), *asString(right)->value(exec).impl());
917 #if USE(JSVALUE64)
918     return JSValue::encode(jsBoolean(result));
919 #else
920     return result;
921 #endif
922 }
923
924 size_t JIT_OPERATION operationHasProperty(ExecState* exec, JSObject* base, JSString* property)
925 {
926     int result = base->hasProperty(exec, property->toIdentifier(exec));
927     return result;
928 }
929     
930
931 EncodedJSValue JIT_OPERATION operationNewArrayWithProfile(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, int size)
932 {
933     VM* vm = &exec->vm();
934     NativeCallFrameTracer tracer(vm, exec);
935     return JSValue::encode(constructArrayNegativeIndexed(exec, profile, values, size));
936 }
937
938 EncodedJSValue JIT_OPERATION operationNewArrayBufferWithProfile(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, int size)
939 {
940     VM* vm = &exec->vm();
941     NativeCallFrameTracer tracer(vm, exec);
942     return JSValue::encode(constructArray(exec, profile, values, size));
943 }
944
945 EncodedJSValue JIT_OPERATION operationNewArrayWithSizeAndProfile(ExecState* exec, ArrayAllocationProfile* profile, EncodedJSValue size)
946 {
947     VM* vm = &exec->vm();
948     NativeCallFrameTracer tracer(vm, exec);
949     JSValue sizeValue = JSValue::decode(size);
950     return JSValue::encode(constructArrayWithSizeQuirk(exec, profile, exec->lexicalGlobalObject(), sizeValue));
951 }
952
953 EncodedJSValue JIT_OPERATION operationNewFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
954 {
955     ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
956     VM& vm = exec->vm();
957     NativeCallFrameTracer tracer(&vm, exec);
958     return JSValue::encode(JSFunction::create(vm, static_cast<FunctionExecutable*>(functionExecutable), scope));
959 }
960
961 EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
962 {
963     ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
964     VM& vm = exec->vm();
965     NativeCallFrameTracer tracer(&vm, exec);
966     return JSValue::encode(JSFunction::createWithInvalidatedReallocationWatchpoint(vm, static_cast<FunctionExecutable*>(functionExecutable), scope));
967 }
968
969 JSCell* JIT_OPERATION operationNewObject(ExecState* exec, Structure* structure)
970 {
971     VM* vm = &exec->vm();
972     NativeCallFrameTracer tracer(vm, exec);
973     
974     return constructEmptyObject(exec, structure);
975 }
976
977 EncodedJSValue JIT_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
978 {
979     VM& vm = exec->vm();
980     NativeCallFrameTracer tracer(&vm, exec);
981     RegExp* regexp = static_cast<RegExp*>(regexpPtr);
982     if (!regexp->isValid()) {
983         vm.throwException(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor.")));
984         return JSValue::encode(jsUndefined());
985     }
986
987     return JSValue::encode(RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regexp));
988 }
989
990 void JIT_OPERATION operationHandleWatchdogTimer(ExecState* exec)
991 {
992     VM& vm = exec->vm();
993     NativeCallFrameTracer tracer(&vm, exec);
994
995     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(exec)))
996         vm.throwException(exec, createTerminatedExecutionException(&vm));
997 }
998
999 void JIT_OPERATION operationThrowStaticError(ExecState* exec, EncodedJSValue encodedValue, int32_t referenceErrorFlag)
1000 {
1001     VM& vm = exec->vm();
1002     NativeCallFrameTracer tracer(&vm, exec);
1003     JSValue errorMessageValue = JSValue::decode(encodedValue);
1004     RELEASE_ASSERT(errorMessageValue.isString());
1005     String errorMessage = asString(errorMessageValue)->value(exec);
1006     if (referenceErrorFlag)
1007         vm.throwException(exec, createReferenceError(exec, errorMessage));
1008     else
1009         vm.throwException(exec, createTypeError(exec, errorMessage));
1010 }
1011
1012 void JIT_OPERATION operationDebug(ExecState* exec, int32_t debugHookID)
1013 {
1014     VM& vm = exec->vm();
1015     NativeCallFrameTracer tracer(&vm, exec);
1016
1017     vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID));
1018 }
1019
1020 #if ENABLE(DFG_JIT)
1021 static void updateAllPredictionsAndOptimizeAfterWarmUp(CodeBlock* codeBlock)
1022 {
1023     codeBlock->updateAllPredictions();
1024     codeBlock->optimizeAfterWarmUp();
1025 }
1026
1027 SlowPathReturnType JIT_OPERATION operationOptimize(ExecState* exec, int32_t bytecodeIndex)
1028 {
1029     VM& vm = exec->vm();
1030     NativeCallFrameTracer tracer(&vm, exec);
1031
1032     // Defer GC for a while so that it doesn't run between when we enter into this
1033     // slow path and when we figure out the state of our code block. This prevents
1034     // a number of awkward reentrancy scenarios, including:
1035     //
1036     // - The optimized version of our code block being jettisoned by GC right after
1037     //   we concluded that we wanted to use it, but have not planted it into the JS
1038     //   stack yet.
1039     //
1040     // - An optimized version of our code block being installed just as we decided
1041     //   that it wasn't ready yet.
1042     //
1043     // Note that jettisoning won't happen if we already initiated OSR, because in
1044     // that case we would have already planted the optimized code block into the JS
1045     // stack.
1046     DeferGCForAWhile deferGC(vm.heap);
1047     
1048     CodeBlock* codeBlock = exec->codeBlock();
1049     if (codeBlock->jitType() != JITCode::BaselineJIT) {
1050         dataLog("Unexpected code block in Baseline->DFG tier-up: ", *codeBlock, "\n");
1051         RELEASE_ASSERT_NOT_REACHED();
1052     }
1053     
1054     if (bytecodeIndex) {
1055         // If we're attempting to OSR from a loop, assume that this should be
1056         // separately optimized.
1057         codeBlock->m_shouldAlwaysBeInlined = false;
1058     }
1059
1060     if (Options::verboseOSR()) {
1061         dataLog(
1062             *codeBlock, ": Entered optimize with bytecodeIndex = ", bytecodeIndex,
1063             ", executeCounter = ", codeBlock->jitExecuteCounter(),
1064             ", optimizationDelayCounter = ", codeBlock->reoptimizationRetryCounter(),
1065             ", exitCounter = ");
1066         if (codeBlock->hasOptimizedReplacement())
1067             dataLog(codeBlock->replacement()->osrExitCounter());
1068         else
1069             dataLog("N/A");
1070         dataLog("\n");
1071     }
1072
1073     if (!codeBlock->checkIfOptimizationThresholdReached()) {
1074         codeBlock->updateAllPredictions();
1075         if (Options::verboseOSR())
1076             dataLog("Choosing not to optimize ", *codeBlock, " yet, because the threshold hasn't been reached.\n");
1077         return encodeResult(0, 0);
1078     }
1079     
1080     if (vm.enabledProfiler()) {
1081         updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
1082         return encodeResult(0, 0);
1083     }
1084
1085     Debugger* debugger = codeBlock->globalObject()->debugger();
1086     if (debugger && (debugger->isStepping() || codeBlock->baselineAlternative()->hasDebuggerRequests())) {
1087         updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
1088         return encodeResult(0, 0);
1089     }
1090
1091     if (codeBlock->m_shouldAlwaysBeInlined) {
1092         updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
1093         if (Options::verboseOSR())
1094             dataLog("Choosing not to optimize ", *codeBlock, " yet, because m_shouldAlwaysBeInlined == true.\n");
1095         return encodeResult(0, 0);
1096     }
1097
1098     // We cannot be in the process of asynchronous compilation and also have an optimized
1099     // replacement.
1100     DFG::Worklist* worklist = DFG::existingGlobalDFGWorklistOrNull();
1101     ASSERT(
1102         !worklist
1103         || !(worklist->compilationState(DFG::CompilationKey(codeBlock, DFG::DFGMode)) != DFG::Worklist::NotKnown
1104         && codeBlock->hasOptimizedReplacement()));
1105
1106     DFG::Worklist::State worklistState;
1107     if (worklist) {
1108         // The call to DFG::Worklist::completeAllReadyPlansForVM() will complete all ready
1109         // (i.e. compiled) code blocks. But if it completes ours, we also need to know
1110         // what the result was so that we don't plow ahead and attempt OSR or immediate
1111         // reoptimization. This will have already also set the appropriate JIT execution
1112         // count threshold depending on what happened, so if the compilation was anything
1113         // but successful we just want to return early. See the case for worklistState ==
1114         // DFG::Worklist::Compiled, below.
1115         
1116         // Note that we could have alternatively just called Worklist::compilationState()
1117         // here, and if it returned Compiled, we could have then called
1118         // completeAndScheduleOSR() below. But that would have meant that it could take
1119         // longer for code blocks to be completed: they would only complete when *their*
1120         // execution count trigger fired; but that could take a while since the firing is
1121         // racy. It could also mean that code blocks that never run again after being
1122         // compiled would sit on the worklist until next GC. That's fine, but it's
1123         // probably a waste of memory. Our goal here is to complete code blocks as soon as
1124         // possible in order to minimize the chances of us executing baseline code after
1125         // optimized code is already available.
1126         worklistState = worklist->completeAllReadyPlansForVM(
1127             vm, DFG::CompilationKey(codeBlock, DFG::DFGMode));
1128     } else
1129         worklistState = DFG::Worklist::NotKnown;
1130
1131     if (worklistState == DFG::Worklist::Compiling) {
1132         // We cannot be in the process of asynchronous compilation and also have an optimized
1133         // replacement.
1134         RELEASE_ASSERT(!codeBlock->hasOptimizedReplacement());
1135         codeBlock->setOptimizationThresholdBasedOnCompilationResult(CompilationDeferred);
1136         return encodeResult(0, 0);
1137     }
1138
1139     if (worklistState == DFG::Worklist::Compiled) {
1140         // If we don't have an optimized replacement but we did just get compiled, then
1141         // the compilation failed or was invalidated, in which case the execution count
1142         // thresholds have already been set appropriately by
1143         // CodeBlock::setOptimizationThresholdBasedOnCompilationResult() and we have
1144         // nothing left to do.
1145         if (!codeBlock->hasOptimizedReplacement()) {
1146             codeBlock->updateAllPredictions();
1147             if (Options::verboseOSR())
1148                 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1149             return encodeResult(0, 0);
1150         }
1151     } else if (codeBlock->hasOptimizedReplacement()) {
1152         if (Options::verboseOSR())
1153             dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
1154         // If we have an optimized replacement, then it must be the case that we entered
1155         // cti_optimize from a loop. That's because if there's an optimized replacement,
1156         // then all calls to this function will be relinked to the replacement and so
1157         // the prologue OSR will never fire.
1158         
1159         // This is an interesting threshold check. Consider that a function OSR exits
1160         // in the middle of a loop, while having a relatively low exit count. The exit
1161         // will reset the execution counter to some target threshold, meaning that this
1162         // code won't be reached until that loop heats up for >=1000 executions. But then
1163         // we do a second check here, to see if we should either reoptimize, or just
1164         // attempt OSR entry. Hence it might even be correct for
1165         // shouldReoptimizeFromLoopNow() to always return true. But we make it do some
1166         // additional checking anyway, to reduce the amount of recompilation thrashing.
1167         if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
1168             if (Options::verboseOSR()) {
1169                 dataLog(
1170                     "Triggering reoptimization of ", *codeBlock,
1171                     "(", *codeBlock->replacement(), ") (in loop).\n");
1172             }
1173             codeBlock->replacement()->jettison(Profiler::JettisonDueToBaselineLoopReoptimizationTrigger, CountReoptimization);
1174             return encodeResult(0, 0);
1175         }
1176     } else {
1177         if (!codeBlock->shouldOptimizeNow()) {
1178             if (Options::verboseOSR()) {
1179                 dataLog(
1180                     "Delaying optimization for ", *codeBlock,
1181                     " because of insufficient profiling.\n");
1182             }
1183             return encodeResult(0, 0);
1184         }
1185
1186         if (Options::verboseOSR())
1187             dataLog("Triggering optimized compilation of ", *codeBlock, "\n");
1188
1189         unsigned numVarsWithValues;
1190         if (bytecodeIndex)
1191             numVarsWithValues = codeBlock->m_numVars;
1192         else
1193             numVarsWithValues = 0;
1194         Operands<JSValue> mustHandleValues(codeBlock->numParameters(), numVarsWithValues);
1195         for (size_t i = 0; i < mustHandleValues.size(); ++i) {
1196             int operand = mustHandleValues.operandForIndex(i);
1197             mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
1198         }
1199
1200         RefPtr<CodeBlock> replacementCodeBlock = codeBlock->newReplacement();
1201         CompilationResult result = DFG::compile(
1202             vm, replacementCodeBlock.get(), 0, DFG::DFGMode, bytecodeIndex,
1203             mustHandleValues, JITToDFGDeferredCompilationCallback::create());
1204         
1205         if (result != CompilationSuccessful) {
1206             ASSERT(result == CompilationDeferred || replacementCodeBlock->hasOneRef());
1207             return encodeResult(0, 0);
1208         }
1209     }
1210     
1211     CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1212     ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
1213     
1214     if (void* dataBuffer = DFG::prepareOSREntry(exec, optimizedCodeBlock, bytecodeIndex)) {
1215         if (Options::verboseOSR()) {
1216             dataLog(
1217                 "Performing OSR ", *codeBlock, " -> ", *optimizedCodeBlock, ".\n");
1218         }
1219
1220         codeBlock->optimizeSoon();
1221         return encodeResult(vm.getCTIStub(DFG::osrEntryThunkGenerator).code().executableAddress(), dataBuffer);
1222     }
1223
1224     if (Options::verboseOSR()) {
1225         dataLog(
1226             "Optimizing ", *codeBlock, " -> ", *codeBlock->replacement(),
1227             " succeeded, OSR failed, after a delay of ",
1228             codeBlock->optimizationDelayCounter(), ".\n");
1229     }
1230
1231     // Count the OSR failure as a speculation failure. If this happens a lot, then
1232     // reoptimize.
1233     optimizedCodeBlock->countOSRExit();
1234
1235     // We are a lot more conservative about triggering reoptimization after OSR failure than
1236     // before it. If we enter the optimize_from_loop trigger with a bucket full of fail
1237     // already, then we really would like to reoptimize immediately. But this case covers
1238     // something else: there weren't many (or any) speculation failures before, but we just
1239     // failed to enter the speculative code because some variable had the wrong value or
1240     // because the OSR code decided for any spurious reason that it did not want to OSR
1241     // right now. So, we only trigger reoptimization only upon the more conservative (non-loop)
1242     // reoptimization trigger.
1243     if (optimizedCodeBlock->shouldReoptimizeNow()) {
1244         if (Options::verboseOSR()) {
1245             dataLog(
1246                 "Triggering reoptimization of ", *codeBlock, " -> ",
1247                 *codeBlock->replacement(), " (after OSR fail).\n");
1248         }
1249         optimizedCodeBlock->jettison(Profiler::JettisonDueToBaselineLoopReoptimizationTriggerOnOSREntryFail, CountReoptimization);
1250         return encodeResult(0, 0);
1251     }
1252
1253     // OSR failed this time, but it might succeed next time! Let the code run a bit
1254     // longer and then try again.
1255     codeBlock->optimizeAfterWarmUp();
1256     
1257     return encodeResult(0, 0);
1258 }
1259 #endif
1260
1261 void JIT_OPERATION operationPutByIndex(ExecState* exec, EncodedJSValue encodedArrayValue, int32_t index, EncodedJSValue encodedValue)
1262 {
1263     VM& vm = exec->vm();
1264     NativeCallFrameTracer tracer(&vm, exec);
1265
1266     JSValue arrayValue = JSValue::decode(encodedArrayValue);
1267     ASSERT(isJSArray(arrayValue));
1268     asArray(arrayValue)->putDirectIndex(exec, index, JSValue::decode(encodedValue));
1269 }
1270
1271 #if USE(JSVALUE64)
1272 void JIT_OPERATION operationPutGetterById(ExecState* exec, EncodedJSValue encodedObjectValue, Identifier* identifier, EncodedJSValue encodedGetterValue)
1273 {
1274     VM& vm = exec->vm();
1275     NativeCallFrameTracer tracer(&vm, exec);
1276
1277     ASSERT(JSValue::decode(encodedObjectValue).isObject());
1278     JSObject* baseObj = asObject(JSValue::decode(encodedObjectValue));
1279
1280     JSValue getter = JSValue::decode(encodedGetterValue);
1281     ASSERT(getter.isObject());
1282     baseObj->putGetter(exec, *identifier, asObject(getter));
1283 }
1284
1285 void JIT_OPERATION operationPutSetterById(ExecState* exec, EncodedJSValue encodedObjectValue, Identifier* identifier, EncodedJSValue encodedSetterValue)
1286 {
1287     VM& vm = exec->vm();
1288     NativeCallFrameTracer tracer(&vm, exec);
1289
1290     ASSERT(JSValue::decode(encodedObjectValue).isObject());
1291     JSObject* baseObj = asObject(JSValue::decode(encodedObjectValue));
1292
1293     JSValue setter = JSValue::decode(encodedSetterValue);
1294     ASSERT(setter.isObject());
1295     baseObj->putSetter(exec, *identifier, asObject(setter));
1296 }
1297
1298 void JIT_OPERATION operationPutGetterSetter(ExecState* exec, EncodedJSValue encodedObjectValue, Identifier* identifier, EncodedJSValue encodedGetterValue, EncodedJSValue encodedSetterValue)
1299 {
1300     VM& vm = exec->vm();
1301     NativeCallFrameTracer tracer(&vm, exec);
1302
1303     ASSERT(JSValue::decode(encodedObjectValue).isObject());
1304     JSObject* baseObj = asObject(JSValue::decode(encodedObjectValue));
1305
1306     GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
1307
1308     JSValue getter = JSValue::decode(encodedGetterValue);
1309     JSValue setter = JSValue::decode(encodedSetterValue);
1310     ASSERT(getter.isObject() || getter.isUndefined());
1311     ASSERT(setter.isObject() || setter.isUndefined());
1312     ASSERT(getter.isObject() || setter.isObject());
1313
1314     if (!getter.isUndefined())
1315         accessor->setGetter(vm, exec->lexicalGlobalObject(), asObject(getter));
1316     if (!setter.isUndefined())
1317         accessor->setSetter(vm, exec->lexicalGlobalObject(), asObject(setter));
1318     baseObj->putDirectAccessor(exec, *identifier, accessor, Accessor);
1319 }
1320 #else
1321 void JIT_OPERATION operationPutGetterById(ExecState* exec, JSCell* object, Identifier* identifier, JSCell* getter)
1322 {
1323     VM& vm = exec->vm();
1324     NativeCallFrameTracer tracer(&vm, exec);
1325
1326     ASSERT(object && object->isObject());
1327     JSObject* baseObj = object->getObject();
1328
1329     ASSERT(getter->isObject());
1330     baseObj->putGetter(exec, *identifier, getter);
1331 }
1332
1333 void JIT_OPERATION operationPutSetterById(ExecState* exec, JSCell* object, Identifier* identifier, JSCell* setter)
1334 {
1335     VM& vm = exec->vm();
1336     NativeCallFrameTracer tracer(&vm, exec);
1337
1338     ASSERT(object && object->isObject());
1339     JSObject* baseObj = object->getObject();
1340
1341     ASSERT(setter->isObject());
1342     baseObj->putSetter(exec, *identifier, setter);
1343 }
1344
1345 void JIT_OPERATION operationPutGetterSetter(ExecState* exec, JSCell* object, Identifier* identifier, JSCell* getter, JSCell* setter)
1346 {
1347     VM& vm = exec->vm();
1348     NativeCallFrameTracer tracer(&vm, exec);
1349
1350     ASSERT(object && object->isObject());
1351     JSObject* baseObj = object->getObject();
1352
1353     GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
1354
1355     ASSERT(!getter || getter->isObject());
1356     ASSERT(!setter || setter->isObject());
1357     ASSERT(getter || setter);
1358
1359     if (getter)
1360         accessor->setGetter(vm, exec->lexicalGlobalObject(), getter->getObject());
1361     if (setter)
1362         accessor->setSetter(vm, exec->lexicalGlobalObject(), setter->getObject());
1363     baseObj->putDirectAccessor(exec, *identifier, accessor, Accessor);
1364 }
1365 #endif
1366
1367 void JIT_OPERATION operationPushCatchScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
1368 {
1369     pushNameScope<JSCatchScope>(exec, dst, symbolTable, encodedValue);
1370 }
1371
1372 void JIT_OPERATION operationPushFunctionNameScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
1373 {
1374     pushNameScope<JSFunctionNameScope>(exec, dst, symbolTable, encodedValue);
1375 }
1376
1377 void JIT_OPERATION operationPushWithScope(ExecState* exec, int32_t dst, EncodedJSValue encodedValue)
1378 {
1379     VM& vm = exec->vm();
1380     NativeCallFrameTracer tracer(&vm, exec);
1381
1382     JSObject* o = JSValue::decode(encodedValue).toObject(exec);
1383     if (vm.exception())
1384         return;
1385
1386     // FIXME: This won't work if this operation is called from the DFG or FTL.
1387     // This should be changed to pass in the old scope and return the new scope.
1388     JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
1389     exec->uncheckedR(dst) = JSWithScope::create(exec, o, currentScope);
1390 }
1391
1392 void JIT_OPERATION operationPopScope(ExecState* exec, int32_t scopeReg)
1393 {
1394     VM& vm = exec->vm();
1395     NativeCallFrameTracer tracer(&vm, exec);
1396
1397     JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
1398     exec->uncheckedR(scopeReg) = scope->next();
1399 }
1400
1401 void JIT_OPERATION operationProfileDidCall(ExecState* exec, EncodedJSValue encodedValue)
1402 {
1403     VM& vm = exec->vm();
1404     NativeCallFrameTracer tracer(&vm, exec);
1405
1406     if (LegacyProfiler* profiler = vm.enabledProfiler())
1407         profiler->didExecute(exec, JSValue::decode(encodedValue));
1408 }
1409
1410 void JIT_OPERATION operationProfileWillCall(ExecState* exec, EncodedJSValue encodedValue)
1411 {
1412     VM& vm = exec->vm();
1413     NativeCallFrameTracer tracer(&vm, exec);
1414
1415     if (LegacyProfiler* profiler = vm.enabledProfiler())
1416         profiler->willExecute(exec, JSValue::decode(encodedValue));
1417 }
1418
1419 EncodedJSValue JIT_OPERATION operationCheckHasInstance(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBaseVal)
1420 {
1421     VM& vm = exec->vm();
1422     NativeCallFrameTracer tracer(&vm, exec);
1423
1424     JSValue value = JSValue::decode(encodedValue);
1425     JSValue baseVal = JSValue::decode(encodedBaseVal);
1426
1427     if (baseVal.isObject()) {
1428         JSObject* baseObject = asObject(baseVal);
1429         ASSERT(!baseObject->structure(vm)->typeInfo().implementsDefaultHasInstance());
1430         if (baseObject->structure(vm)->typeInfo().implementsHasInstance()) {
1431             bool result = baseObject->methodTable(vm)->customHasInstance(baseObject, exec, value);
1432             return JSValue::encode(jsBoolean(result));
1433         }
1434     }
1435
1436     vm.throwException(exec, createInvalidInstanceofParameterError(exec, baseVal));
1437     return JSValue::encode(JSValue());
1438 }
1439
1440 }
1441
1442 static bool canAccessArgumentIndexQuickly(JSObject& object, uint32_t index)
1443 {
1444     switch (object.structure()->typeInfo().type()) {
1445     case DirectArgumentsType: {
1446         DirectArguments* directArguments = jsCast<DirectArguments*>(&object);
1447         if (directArguments->canAccessArgumentIndexQuicklyInDFG(index))
1448             return true;
1449         break;
1450     }
1451     case ScopedArgumentsType: {
1452         ScopedArguments* scopedArguments = jsCast<ScopedArguments*>(&object);
1453         if (scopedArguments->canAccessArgumentIndexQuicklyInDFG(index))
1454             return true;
1455         break;
1456     }
1457     default:
1458         break;
1459     }
1460     return false;
1461 }
1462
1463 static JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript, ArrayProfile* arrayProfile, ReturnAddressPtr returnAddress)
1464 {
1465     if (LIKELY(baseValue.isCell() && subscript.isString())) {
1466         VM& vm = exec->vm();
1467         Structure& structure = *baseValue.asCell()->structure(vm);
1468         if (JSCell::canUseFastGetOwnProperty(structure)) {
1469             if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
1470                 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
1471                     return result;
1472             }
1473         }
1474     }
1475
1476     if (subscript.isUInt32()) {
1477         uint32_t i = subscript.asUInt32();
1478         if (isJSString(baseValue)) {
1479             if (asString(baseValue)->canGetIndex(i)) {
1480                 ctiPatchCallByReturnAddress(exec->codeBlock(), returnAddress, FunctionPtr(operationGetByValString));
1481                 return asString(baseValue)->getIndex(exec, i);
1482             }
1483             arrayProfile->setOutOfBounds();
1484         } else if (baseValue.isObject()) {
1485             JSObject* object = asObject(baseValue);
1486             if (object->canGetIndexQuickly(i))
1487                 return object->getIndexQuickly(i);
1488
1489             if (!canAccessArgumentIndexQuickly(*object, i))
1490                 arrayProfile->setOutOfBounds();
1491         }
1492
1493         return baseValue.get(exec, i);
1494     }
1495
1496     baseValue.requireObjectCoercible(exec);
1497     if (exec->hadException())
1498         return jsUndefined();
1499     auto property = subscript.toPropertyKey(exec);
1500     if (exec->hadException())
1501         return jsUndefined();
1502     return baseValue.get(exec, property);
1503 }
1504
1505 extern "C" {
1506     
1507 EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
1508 {
1509     VM& vm = exec->vm();
1510     NativeCallFrameTracer tracer(&vm, exec);
1511     JSValue baseValue = JSValue::decode(encodedBase);
1512     JSValue subscript = JSValue::decode(encodedSubscript);
1513
1514     JSValue result = getByVal(exec, baseValue, subscript, arrayProfile, ReturnAddressPtr(OUR_RETURN_ADDRESS));
1515     return JSValue::encode(result);
1516 }
1517
1518 EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
1519 {
1520     VM& vm = exec->vm();
1521     NativeCallFrameTracer tracer(&vm, exec);
1522     JSValue baseValue = JSValue::decode(encodedBase);
1523     JSValue subscript = JSValue::decode(encodedSubscript);
1524     
1525     if (baseValue.isObject() && subscript.isInt32()) {
1526         // See if it's worth optimizing this at all.
1527         JSObject* object = asObject(baseValue);
1528         bool didOptimize = false;
1529
1530         unsigned bytecodeOffset = exec->locationAsBytecodeOffset();
1531         ASSERT(bytecodeOffset);
1532         ByValInfo& byValInfo = exec->codeBlock()->getByValInfo(bytecodeOffset - 1);
1533         ASSERT(!byValInfo.stubRoutine);
1534         
1535         if (hasOptimizableIndexing(object->structure(vm))) {
1536             // Attempt to optimize.
1537             Structure* structure = object->structure(vm);
1538             JITArrayMode arrayMode = jitArrayModeForStructure(structure);
1539             if (arrayMode != byValInfo.arrayMode) {
1540                 // If we reached this case, we got an interesting array mode we did not expect when we compiled.
1541                 // Let's update the profile to do better next time.
1542                 CodeBlock* codeBlock = exec->codeBlock();
1543                 ConcurrentJITLocker locker(codeBlock->m_lock);
1544                 arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
1545
1546                 JIT::compileGetByVal(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
1547                 didOptimize = true;
1548             }
1549         }
1550         
1551         if (!didOptimize) {
1552             // If we take slow path more than 10 times without patching then make sure we
1553             // never make that mistake again. Or, if we failed to patch and we have some object
1554             // that intercepts indexed get, then don't even wait until 10 times. For cases
1555             // where we see non-index-intercepting objects, this gives 10 iterations worth of
1556             // opportunity for us to observe that the get_by_val may be polymorphic.
1557             if (++byValInfo.slowPathCount >= 10
1558                 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
1559                 // Don't ever try to optimize.
1560                 ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationGetByValGeneric));
1561             }
1562         }
1563     }
1564     
1565     JSValue result = getByVal(exec, baseValue, subscript, arrayProfile, ReturnAddressPtr(OUR_RETURN_ADDRESS));
1566     return JSValue::encode(result);
1567 }
1568     
1569 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
1570 {
1571     VM& vm = exec->vm();
1572     NativeCallFrameTracer tracer(&vm, exec);
1573     JSValue baseValue = JSValue::decode(encodedBase);
1574     JSValue subscript = JSValue::decode(encodedSubscript);
1575     
1576     ASSERT(baseValue.isObject());
1577     ASSERT(subscript.isUInt32());
1578
1579     JSObject* object = asObject(baseValue);
1580     bool didOptimize = false;
1581
1582     unsigned bytecodeOffset = exec->locationAsBytecodeOffset();
1583     ASSERT(bytecodeOffset);
1584     ByValInfo& byValInfo = exec->codeBlock()->getByValInfo(bytecodeOffset - 1);
1585     ASSERT(!byValInfo.stubRoutine);
1586     
1587     if (hasOptimizableIndexing(object->structure(vm))) {
1588         // Attempt to optimize.
1589         JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
1590         if (arrayMode != byValInfo.arrayMode) {
1591             JIT::compileHasIndexedProperty(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
1592             didOptimize = true;
1593         }
1594     }
1595     
1596     if (!didOptimize) {
1597         // If we take slow path more than 10 times without patching then make sure we
1598         // never make that mistake again. Or, if we failed to patch and we have some object
1599         // that intercepts indexed get, then don't even wait until 10 times. For cases
1600         // where we see non-index-intercepting objects, this gives 10 iterations worth of
1601         // opportunity for us to observe that the get_by_val may be polymorphic.
1602         if (++byValInfo.slowPathCount >= 10
1603             || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
1604             // Don't ever try to optimize.
1605             ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationHasIndexedPropertyGeneric)); 
1606         }
1607     }
1608
1609     uint32_t index = subscript.asUInt32();
1610     if (object->canGetIndexQuickly(index))
1611         return JSValue::encode(JSValue(JSValue::JSTrue));
1612
1613     if (!canAccessArgumentIndexQuickly(*object, index))
1614         arrayProfile->setOutOfBounds();
1615     return JSValue::encode(jsBoolean(object->hasProperty(exec, index)));
1616 }
1617     
1618 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
1619 {
1620     VM& vm = exec->vm();
1621     NativeCallFrameTracer tracer(&vm, exec);
1622     JSValue baseValue = JSValue::decode(encodedBase);
1623     JSValue subscript = JSValue::decode(encodedSubscript);
1624     
1625     ASSERT(baseValue.isObject());
1626     ASSERT(subscript.isUInt32());
1627
1628     JSObject* object = asObject(baseValue);
1629     uint32_t index = subscript.asUInt32();
1630     if (object->canGetIndexQuickly(index))
1631         return JSValue::encode(JSValue(JSValue::JSTrue));
1632
1633     if (!canAccessArgumentIndexQuickly(*object, index))
1634         arrayProfile->setOutOfBounds();
1635     return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript.asUInt32())));
1636 }
1637     
1638 EncodedJSValue JIT_OPERATION operationGetByValString(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript)
1639 {
1640     VM& vm = exec->vm();
1641     NativeCallFrameTracer tracer(&vm, exec);
1642     JSValue baseValue = JSValue::decode(encodedBase);
1643     JSValue subscript = JSValue::decode(encodedSubscript);
1644     
1645     JSValue result;
1646     if (LIKELY(subscript.isUInt32())) {
1647         uint32_t i = subscript.asUInt32();
1648         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
1649             result = asString(baseValue)->getIndex(exec, i);
1650         else {
1651             result = baseValue.get(exec, i);
1652             if (!isJSString(baseValue))
1653                 ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationGetByValDefault));
1654         }
1655     } else {
1656         baseValue.requireObjectCoercible(exec);
1657         if (exec->hadException())
1658             return JSValue::encode(jsUndefined());
1659         auto property = subscript.toPropertyKey(exec);
1660         if (exec->hadException())
1661             return JSValue::encode(jsUndefined());
1662         result = baseValue.get(exec, property);
1663     }
1664
1665     return JSValue::encode(result);
1666 }
1667
1668 EncodedJSValue JIT_OPERATION operationDeleteById(ExecState* exec, EncodedJSValue encodedBase, const Identifier* identifier)
1669 {
1670     VM& vm = exec->vm();
1671     NativeCallFrameTracer tracer(&vm, exec);
1672
1673     JSObject* baseObj = JSValue::decode(encodedBase).toObject(exec);
1674     bool couldDelete = baseObj->methodTable(vm)->deleteProperty(baseObj, exec, *identifier);
1675     JSValue result = jsBoolean(couldDelete);
1676     if (!couldDelete && exec->codeBlock()->isStrictMode())
1677         vm.throwException(exec, createTypeError(exec, ASCIILiteral("Unable to delete property.")));
1678     return JSValue::encode(result);
1679 }
1680
1681 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedProto)
1682 {
1683     VM& vm = exec->vm();
1684     NativeCallFrameTracer tracer(&vm, exec);
1685     JSValue value = JSValue::decode(encodedValue);
1686     JSValue proto = JSValue::decode(encodedProto);
1687     
1688     ASSERT(!value.isObject() || !proto.isObject());
1689
1690     bool result = JSObject::defaultHasInstance(exec, value, proto);
1691     return JSValue::encode(jsBoolean(result));
1692 }
1693
1694 int32_t JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset)
1695 {
1696     VM& vm = exec->vm();
1697     NativeCallFrameTracer tracer(&vm, exec);
1698     JSStack* stack = &exec->interpreter()->stack();
1699     JSValue arguments = JSValue::decode(encodedArguments);
1700     return sizeFrameForVarargs(exec, stack, arguments, numUsedStackSlots, firstVarArgOffset);
1701 }
1702
1703 CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedArguments, int32_t firstVarArgOffset, int32_t length)
1704 {
1705     VM& vm = exec->vm();
1706     NativeCallFrameTracer tracer(&vm, exec);
1707     JSValue arguments = JSValue::decode(encodedArguments);
1708     setupVarargsFrame(exec, newCallFrame, arguments, firstVarArgOffset, length);
1709     return newCallFrame;
1710 }
1711
1712 EncodedJSValue JIT_OPERATION operationToObject(ExecState* exec, EncodedJSValue value)
1713 {
1714     VM& vm = exec->vm();
1715     NativeCallFrameTracer tracer(&vm, exec);
1716     return JSValue::encode(JSValue::decode(value).toObject(exec));
1717 }
1718
1719 char* JIT_OPERATION operationSwitchCharWithUnknownKeyType(ExecState* exec, EncodedJSValue encodedKey, size_t tableIndex)
1720 {
1721     VM& vm = exec->vm();
1722     NativeCallFrameTracer tracer(&vm, exec);
1723     JSValue key = JSValue::decode(encodedKey);
1724     CodeBlock* codeBlock = exec->codeBlock();
1725
1726     SimpleJumpTable& jumpTable = codeBlock->switchJumpTable(tableIndex);
1727     void* result = jumpTable.ctiDefault.executableAddress();
1728
1729     if (key.isString()) {
1730         StringImpl* value = asString(key)->value(exec).impl();
1731         if (value->length() == 1)
1732             result = jumpTable.ctiForValue((*value)[0]).executableAddress();
1733     }
1734
1735     return reinterpret_cast<char*>(result);
1736 }
1737
1738 char* JIT_OPERATION operationSwitchImmWithUnknownKeyType(ExecState* exec, EncodedJSValue encodedKey, size_t tableIndex)
1739 {
1740     VM& vm = exec->vm();
1741     NativeCallFrameTracer tracer(&vm, exec);
1742     JSValue key = JSValue::decode(encodedKey);
1743     CodeBlock* codeBlock = exec->codeBlock();
1744
1745     SimpleJumpTable& jumpTable = codeBlock->switchJumpTable(tableIndex);
1746     void* result;
1747     if (key.isInt32())
1748         result = jumpTable.ctiForValue(key.asInt32()).executableAddress();
1749     else if (key.isDouble() && key.asDouble() == static_cast<int32_t>(key.asDouble()))
1750         result = jumpTable.ctiForValue(static_cast<int32_t>(key.asDouble())).executableAddress();
1751     else
1752         result = jumpTable.ctiDefault.executableAddress();
1753     return reinterpret_cast<char*>(result);
1754 }
1755
1756 char* JIT_OPERATION operationSwitchStringWithUnknownKeyType(ExecState* exec, EncodedJSValue encodedKey, size_t tableIndex)
1757 {
1758     VM& vm = exec->vm();
1759     NativeCallFrameTracer tracer(&vm, exec);
1760     JSValue key = JSValue::decode(encodedKey);
1761     CodeBlock* codeBlock = exec->codeBlock();
1762
1763     void* result;
1764     StringJumpTable& jumpTable = codeBlock->stringSwitchJumpTable(tableIndex);
1765
1766     if (key.isString()) {
1767         StringImpl* value = asString(key)->value(exec).impl();
1768         result = jumpTable.ctiForValue(value).executableAddress();
1769     } else
1770         result = jumpTable.ctiDefault.executableAddress();
1771
1772     return reinterpret_cast<char*>(result);
1773 }
1774
1775 EncodedJSValue JIT_OPERATION operationResolveScope(ExecState* exec, int32_t scopeReg, int32_t identifierIndex)
1776 {
1777     VM& vm = exec->vm();
1778     NativeCallFrameTracer tracer(&vm, exec);
1779     const Identifier& ident = exec->codeBlock()->identifier(identifierIndex);
1780     JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
1781     return JSValue::encode(JSScope::resolve(exec, scope, ident));
1782 }
1783
1784 EncodedJSValue JIT_OPERATION operationGetFromScope(ExecState* exec, Instruction* bytecodePC)
1785 {
1786     VM& vm = exec->vm();
1787     NativeCallFrameTracer tracer(&vm, exec);
1788     CodeBlock* codeBlock = exec->codeBlock();
1789     Instruction* pc = bytecodePC;
1790
1791     const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
1792     JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(pc[2].u.operand).jsValue());
1793     ResolveModeAndType modeAndType(pc[4].u.operand);
1794
1795     PropertySlot slot(scope);
1796     if (!scope->getPropertySlot(exec, ident, slot)) {
1797         if (modeAndType.mode() == ThrowIfNotFound)
1798             vm.throwException(exec, createUndefinedVariableError(exec, ident));
1799         return JSValue::encode(jsUndefined());
1800     }
1801
1802     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1803     if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure(vm)->propertyAccessesAreCacheable()) {
1804         if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1805             Structure* structure = scope->structure(vm);
1806             {
1807                 ConcurrentJITLocker locker(codeBlock->m_lock);
1808                 pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
1809                 pc[6].u.operand = slot.cachedOffset();
1810             }
1811             structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
1812         }
1813     }
1814
1815     return JSValue::encode(slot.getValue(exec, ident));
1816 }
1817
1818 void JIT_OPERATION operationPutToScope(ExecState* exec, Instruction* bytecodePC)
1819 {
1820     VM& vm = exec->vm();
1821     NativeCallFrameTracer tracer(&vm, exec);
1822     Instruction* pc = bytecodePC;
1823
1824     CodeBlock* codeBlock = exec->codeBlock();
1825     const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
1826     JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(pc[1].u.operand).jsValue());
1827     JSValue value = exec->r(pc[3].u.operand).jsValue();
1828     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
1829     if (modeAndType.type() == LocalClosureVar) {
1830         JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
1831         environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
1832         if (WatchpointSet* set = pc[5].u.watchpointSet)
1833             set->touch("Executed op_put_scope<LocalClosureVar>");
1834         return;
1835     }
1836     if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident)) {
1837         exec->vm().throwException(exec, createUndefinedVariableError(exec, ident));
1838         return;
1839     }
1840
1841     PutPropertySlot slot(scope, codeBlock->isStrictMode());
1842     scope->methodTable()->put(scope, exec, ident, value, slot);
1843     
1844     if (exec->vm().exception())
1845         return;
1846
1847     CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
1848 }
1849
1850 void JIT_OPERATION operationThrow(ExecState* exec, EncodedJSValue encodedExceptionValue)
1851 {
1852     VM* vm = &exec->vm();
1853     NativeCallFrameTracer tracer(vm, exec);
1854
1855     JSValue exceptionValue = JSValue::decode(encodedExceptionValue);
1856     vm->throwException(exec, exceptionValue);
1857
1858     // Results stored out-of-band in vm.targetMachinePCForThrow, vm.callFrameForThrow & vm.vmEntryFrameForThrow
1859     genericUnwind(vm, exec);
1860 }
1861
1862 void JIT_OPERATION operationFlushWriteBarrierBuffer(ExecState* exec, JSCell* cell)
1863 {
1864     VM* vm = &exec->vm();
1865     NativeCallFrameTracer tracer(vm, exec);
1866     vm->heap.flushWriteBarrierBuffer(cell);
1867 }
1868
1869 void JIT_OPERATION operationOSRWriteBarrier(ExecState* exec, JSCell* cell)
1870 {
1871     VM* vm = &exec->vm();
1872     NativeCallFrameTracer tracer(vm, exec);
1873     vm->heap.writeBarrier(cell);
1874 }
1875
1876 // NB: We don't include the value as part of the barrier because the write barrier elision
1877 // phase in the DFG only tracks whether the object being stored to has been barriered. It 
1878 // would be much more complicated to try to model the value being stored as well.
1879 void JIT_OPERATION operationUnconditionalWriteBarrier(ExecState* exec, JSCell* cell)
1880 {
1881     VM* vm = &exec->vm();
1882     NativeCallFrameTracer tracer(vm, exec);
1883     vm->heap.writeBarrier(cell);
1884 }
1885
1886 void JIT_OPERATION operationInitGlobalConst(ExecState* exec, Instruction* pc)
1887 {
1888     VM* vm = &exec->vm();
1889     NativeCallFrameTracer tracer(vm, exec);
1890
1891     JSValue value = exec->r(pc[2].u.operand).jsValue();
1892     pc[1].u.variablePointer->set(*vm, exec->codeBlock()->globalObject(), value);
1893 }
1894
1895 void JIT_OPERATION lookupExceptionHandler(VM* vm, ExecState* exec)
1896 {
1897     NativeCallFrameTracer tracer(vm, exec);
1898     genericUnwind(vm, exec);
1899     ASSERT(vm->targetMachinePCForThrow);
1900 }
1901
1902 void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM* vm, ExecState* exec)
1903 {
1904     VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
1905     CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
1906     ASSERT(callerFrame);
1907
1908     NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
1909     genericUnwind(vm, callerFrame);
1910     ASSERT(vm->targetMachinePCForThrow);
1911 }
1912
1913 void JIT_OPERATION operationVMHandleException(ExecState* exec)
1914 {
1915     VM* vm = &exec->vm();
1916     NativeCallFrameTracer tracer(vm, exec);
1917     genericUnwind(vm, exec);
1918 }
1919
1920 // This function "should" just take the ExecState*, but doing so would make it more difficult
1921 // to call from exception check sites. So, unlike all of our other functions, we allow
1922 // ourselves to play some gnarly ABI tricks just to simplify the calling convention. This is
1923 // particularly safe here since this is never called on the critical path - it's only for
1924 // testing.
1925 void JIT_OPERATION operationExceptionFuzz()
1926 {
1927 #if COMPILER(GCC)
1928     ExecState* exec = static_cast<ExecState*>(__builtin_frame_address(1));
1929     void* returnPC = __builtin_return_address(0);
1930     doExceptionFuzzing(exec, "JITOperations", returnPC);
1931 #endif // COMPILER(GCC)
1932 }
1933
1934 EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState* exec, EncodedJSValue encodedBaseValue, JSCell* propertyName)
1935 {
1936     VM& vm = exec->vm();
1937     NativeCallFrameTracer tracer(&vm, exec);
1938     JSValue baseValue = JSValue::decode(encodedBaseValue);
1939     if (baseValue.isUndefinedOrNull())
1940         return JSValue::encode(jsBoolean(false));
1941
1942     JSObject* base = baseValue.toObject(exec);
1943     return JSValue::encode(jsBoolean(base->hasProperty(exec, asString(propertyName)->toIdentifier(exec))));
1944 }
1945
1946 EncodedJSValue JIT_OPERATION operationHasIndexedProperty(ExecState* exec, JSCell* baseCell, int32_t subscript)
1947 {
1948     VM& vm = exec->vm();
1949     NativeCallFrameTracer tracer(&vm, exec);
1950     JSObject* object = baseCell->toObject(exec, exec->lexicalGlobalObject());
1951     return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript)));
1952 }
1953     
1954 JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState* exec, JSCell* cell)
1955 {
1956     VM& vm = exec->vm();
1957     NativeCallFrameTracer tracer(&vm, exec);
1958
1959     JSObject* base = cell->toObject(exec, exec->lexicalGlobalObject());
1960
1961     return propertyNameEnumerator(exec, base);
1962 }
1963
1964 EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState* exec, JSCell* enumeratorCell, int32_t index)
1965 {
1966     VM& vm = exec->vm();
1967     NativeCallFrameTracer tracer(&vm, exec);
1968     JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(enumeratorCell);
1969     JSString* propertyName = enumerator->propertyNameAtIndex(index);
1970     return JSValue::encode(propertyName ? propertyName : jsNull());
1971 }
1972
1973 JSCell* JIT_OPERATION operationToIndexString(ExecState* exec, int32_t index)
1974 {
1975     VM& vm = exec->vm();
1976     NativeCallFrameTracer tracer(&vm, exec);
1977     return jsString(exec, Identifier::from(exec, index).string());
1978 }
1979
1980 void JIT_OPERATION operationProcessTypeProfilerLog(ExecState* exec)
1981 {
1982     exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside baseline JIT"));
1983 }
1984
1985 } // extern "C"
1986
1987 // Note: getHostCallReturnValueWithExecState() needs to be placed before the
1988 // definition of getHostCallReturnValue() below because the Windows build
1989 // requires it.
1990 extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
1991 {
1992     if (!exec)
1993         return JSValue::encode(JSValue());
1994     return JSValue::encode(exec->vm().hostCallReturnValue);
1995 }
1996
1997 #if COMPILER(GCC) && CPU(X86_64)
1998 asm (
1999 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2000 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2001 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2002     "mov %rbp, %rdi\n"
2003     "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2004 );
2005
2006 #elif COMPILER(GCC) && CPU(X86)
2007 asm (
2008 ".text" "\n" \
2009 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2010 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2011 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2012     "push %ebp\n"
2013     "leal -4(%esp), %esp\n"
2014     "push %ebp\n"
2015     "call " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2016     "leal 8(%esp), %esp\n"
2017     "pop %ebp\n"
2018     "ret\n"
2019 );
2020
2021 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
2022 asm (
2023 ".text" "\n"
2024 ".align 2" "\n"
2025 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2026 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2027 ".thumb" "\n"
2028 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
2029 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2030     "mov r0, r7" "\n"
2031     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2032 );
2033
2034 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
2035 asm (
2036 ".text" "\n"
2037 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2038 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2039 INLINE_ARM_FUNCTION(getHostCallReturnValue)
2040 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2041     "mov r0, r11" "\n"
2042     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2043 );
2044
2045 #elif CPU(ARM64)
2046 asm (
2047 ".text" "\n"
2048 ".align 2" "\n"
2049 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2050 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2051 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2052      "mov x0, x29" "\n"
2053      "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2054 );
2055
2056 #elif COMPILER(GCC) && CPU(MIPS)
2057
2058 #if WTF_MIPS_PIC
2059 #define LOAD_FUNCTION_TO_T9(function) \
2060         ".set noreorder" "\n" \
2061         ".cpload $25" "\n" \
2062         ".set reorder" "\n" \
2063         "la $t9, " LOCAL_REFERENCE(function) "\n"
2064 #else
2065 #define LOAD_FUNCTION_TO_T9(function) "" "\n"
2066 #endif
2067
2068 asm (
2069 ".text" "\n"
2070 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2071 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2072 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2073     LOAD_FUNCTION_TO_T9(getHostCallReturnValueWithExecState)
2074     "move $a0, $fp" "\n"
2075     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2076 );
2077
2078 #elif COMPILER(GCC) && CPU(SH4)
2079
2080 #define SH4_SCRATCH_REGISTER "r11"
2081
2082 asm (
2083 ".text" "\n"
2084 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2085 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2086 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2087     "mov r14, r4" "\n"
2088     "mov.l 2f, " SH4_SCRATCH_REGISTER "\n"
2089     "braf " SH4_SCRATCH_REGISTER "\n"
2090     "nop" "\n"
2091     "1: .balign 4" "\n"
2092     "2: .long " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "-1b\n"
2093 );
2094
2095 #elif COMPILER(MSVC) && CPU(X86)
2096 extern "C" {
2097     __declspec(naked) EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue()
2098     {
2099         __asm mov [esp + 4], ebp;
2100         __asm jmp getHostCallReturnValueWithExecState
2101     }
2102 }
2103 #endif
2104
2105 } // namespace JSC
2106
2107 #endif // ENABLE(JIT)