]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGOperations.cpp
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / dfg / DFGOperations.cpp
CommitLineData
14957cd0
A
1/*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "DFGOperations.h"
28
93a37866
A
29#include "Arguments.h"
30#include "ButterflyInlines.h"
14957cd0 31#include "CodeBlock.h"
93a37866 32#include "CopiedSpaceInlines.h"
6fe7ccc8
A
33#include "DFGOSRExit.h"
34#include "DFGRepatch.h"
93a37866 35#include "DFGThunks.h"
6fe7ccc8
A
36#include "HostCallReturnValue.h"
37#include "GetterSetter.h"
14957cd0 38#include "Interpreter.h"
93a37866 39#include "JIT.h"
6fe7ccc8
A
40#include "JITExceptions.h"
41#include "JSActivation.h"
93a37866
A
42#include "VM.h"
43#include "JSNameScope.h"
44#include "NameInstance.h"
45#include "ObjectConstructor.h"
14957cd0 46#include "Operations.h"
93a37866
A
47#include "StringConstructor.h"
48#include <wtf/InlineASM.h>
49
50#if ENABLE(JIT)
51
52#if CPU(MIPS)
53#if WTF_MIPS_PIC
54#define LOAD_FUNCTION_TO_T9(function) \
55 ".set noreorder" "\n" \
56 ".cpload $25" "\n" \
57 ".set reorder" "\n" \
58 "la $t9, " LOCAL_REFERENCE(function) "\n"
59#else
60#define LOAD_FUNCTION_TO_T9(function) "" "\n"
61#endif
62#endif
14957cd0 63
6fe7ccc8
A
64#if ENABLE(DFG_JIT)
65
93a37866 66#if COMPILER(GCC) && CPU(X86_64)
6fe7ccc8
A
67
68#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
69 asm( \
70 ".globl " SYMBOL_STRING(function) "\n" \
71 HIDE_SYMBOL(function) "\n" \
72 SYMBOL_STRING(function) ":" "\n" \
73 "mov (%rsp), %" STRINGIZE(register) "\n" \
93a37866 74 "jmp " LOCAL_REFERENCE(function##WithReturnAddress) "\n" \
6fe7ccc8
A
75 );
76#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rsi)
77#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
78#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
79#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8)
80
93a37866 81#elif COMPILER(GCC) && CPU(X86)
6fe7ccc8
A
82
83#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset) \
84 asm( \
85 ".text" "\n" \
86 ".globl " SYMBOL_STRING(function) "\n" \
87 HIDE_SYMBOL(function) "\n" \
88 SYMBOL_STRING(function) ":" "\n" \
89 "mov (%esp), %eax\n" \
90 "mov %eax, " STRINGIZE(offset) "(%esp)\n" \
93a37866 91 "jmp " LOCAL_REFERENCE(function##WithReturnAddress) "\n" \
6fe7ccc8
A
92 );
93#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 8)
94#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 16)
95#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 20)
96#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 24)
97
93a37866
A
98#elif CPU(ARM64)
99
100#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
101 asm ( \
102 ".text" "\n" \
103 ".align 2" "\n" \
104 ".globl " SYMBOL_STRING(function) "\n" \
105 HIDE_SYMBOL(function) "\n" \
106 SYMBOL_STRING(function) ":" "\n" \
107 "mov x1, lr" "\n" \
108 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
109 );
110
111#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
112 asm ( \
113 ".text" "\n" \
114 ".align 2" "\n" \
115 ".globl " SYMBOL_STRING(function) "\n" \
116 HIDE_SYMBOL(function) "\n" \
117 SYMBOL_STRING(function) ":" "\n" \
118 "mov x3, lr" "\n" \
119 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
120 );
121
122#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
123 asm ( \
124 ".text" "\n" \
125 ".align 2" "\n" \
126 ".globl " SYMBOL_STRING(function) "\n" \
127 HIDE_SYMBOL(function) "\n" \
128 SYMBOL_STRING(function) ":" "\n" \
129 "mov x3, lr" "\n" \
130 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
131 );
132
133#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
134 asm ( \
135 ".text" "\n" \
136 ".align 2" "\n" \
137 ".globl " SYMBOL_STRING(function) "\n" \
138 HIDE_SYMBOL(function) "\n" \
139 SYMBOL_STRING(function) ":" "\n" \
140 "mov x4, lr" "\n" \
141 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
142 );
143
6fe7ccc8
A
144#elif COMPILER(GCC) && CPU(ARM_THUMB2)
145
146#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
147 asm ( \
148 ".text" "\n" \
149 ".align 2" "\n" \
150 ".globl " SYMBOL_STRING(function) "\n" \
151 HIDE_SYMBOL(function) "\n" \
152 ".thumb" "\n" \
153 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
154 SYMBOL_STRING(function) ":" "\n" \
155 "mov a2, lr" "\n" \
93a37866 156 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
6fe7ccc8
A
157 );
158
159#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
160 asm ( \
161 ".text" "\n" \
162 ".align 2" "\n" \
163 ".globl " SYMBOL_STRING(function) "\n" \
164 HIDE_SYMBOL(function) "\n" \
165 ".thumb" "\n" \
166 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
167 SYMBOL_STRING(function) ":" "\n" \
168 "mov a4, lr" "\n" \
93a37866 169 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
6fe7ccc8
A
170 );
171
93a37866
A
172// EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
173// As a result, return address will be at a 4-byte further location in the following cases.
174#if COMPILER_SUPPORTS(EABI) && CPU(ARM)
175#define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
176#define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
177#else
178#define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
179#define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
180#endif
181
6fe7ccc8
A
182#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
183 asm ( \
184 ".text" "\n" \
185 ".align 2" "\n" \
186 ".globl " SYMBOL_STRING(function) "\n" \
187 HIDE_SYMBOL(function) "\n" \
188 ".thumb" "\n" \
189 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
190 SYMBOL_STRING(function) ":" "\n" \
93a37866
A
191 INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
192 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
6fe7ccc8
A
193 );
194
195#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
196 asm ( \
197 ".text" "\n" \
198 ".align 2" "\n" \
199 ".globl " SYMBOL_STRING(function) "\n" \
200 HIDE_SYMBOL(function) "\n" \
201 ".thumb" "\n" \
202 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
203 SYMBOL_STRING(function) ":" "\n" \
93a37866
A
204 INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
205 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
206 );
207
208#elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
209
210#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
211 asm ( \
212 ".text" "\n" \
213 ".globl " SYMBOL_STRING(function) "\n" \
214 HIDE_SYMBOL(function) "\n" \
215 INLINE_ARM_FUNCTION(function) \
216 SYMBOL_STRING(function) ":" "\n" \
217 "mov a2, lr" "\n" \
218 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
219 );
220
221#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
222 asm ( \
223 ".text" "\n" \
224 ".globl " SYMBOL_STRING(function) "\n" \
225 HIDE_SYMBOL(function) "\n" \
226 INLINE_ARM_FUNCTION(function) \
227 SYMBOL_STRING(function) ":" "\n" \
228 "mov a4, lr" "\n" \
229 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
230 );
231
232// EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
233// As a result, return address will be at a 4-byte further location in the following cases.
234#if COMPILER_SUPPORTS(EABI) && CPU(ARM)
235#define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
236#define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
237#else
238#define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
239#define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
240#endif
241
242#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
243 asm ( \
244 ".text" "\n" \
245 ".globl " SYMBOL_STRING(function) "\n" \
246 HIDE_SYMBOL(function) "\n" \
247 INLINE_ARM_FUNCTION(function) \
248 SYMBOL_STRING(function) ":" "\n" \
249 INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
250 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
251 );
252
253#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
254 asm ( \
255 ".text" "\n" \
256 ".globl " SYMBOL_STRING(function) "\n" \
257 HIDE_SYMBOL(function) "\n" \
258 INLINE_ARM_FUNCTION(function) \
259 SYMBOL_STRING(function) ":" "\n" \
260 INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
261 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
262 );
263
264#elif COMPILER(GCC) && CPU(MIPS)
265
266#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
267 asm( \
268 ".text" "\n" \
269 ".globl " SYMBOL_STRING(function) "\n" \
270 HIDE_SYMBOL(function) "\n" \
271 SYMBOL_STRING(function) ":" "\n" \
272 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
273 "move $a1, $ra" "\n" \
274 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
275 );
276
277#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
278 asm( \
279 ".text" "\n" \
280 ".globl " SYMBOL_STRING(function) "\n" \
281 HIDE_SYMBOL(function) "\n" \
282 SYMBOL_STRING(function) ":" "\n" \
283 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
284 "move $a3, $ra" "\n" \
285 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
286 );
287
288#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
289 asm( \
290 ".text" "\n" \
291 ".globl " SYMBOL_STRING(function) "\n" \
292 HIDE_SYMBOL(function) "\n" \
293 SYMBOL_STRING(function) ":" "\n" \
294 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
295 "sw $ra, 20($sp)" "\n" \
296 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
297 );
298
299#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
300 asm( \
301 ".text" "\n" \
302 ".globl " SYMBOL_STRING(function) "\n" \
303 HIDE_SYMBOL(function) "\n" \
304 SYMBOL_STRING(function) ":" "\n" \
305 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
306 "sw $ra, 24($sp)" "\n" \
307 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
6fe7ccc8
A
308 );
309
310#endif
311
312#define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
93a37866 313void* DFG_OPERATION function##WithReturnAddress(ExecState*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
6fe7ccc8
A
314FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)
315
316#define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
93a37866 317EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, JSCell*, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
6fe7ccc8
A
318FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)
319
320#define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
93a37866 321EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
6fe7ccc8
A
322FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)
323
324#define V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
93a37866 325void DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, JSCell*, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
6fe7ccc8
A
326FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function)
327
14957cd0
A
328namespace JSC { namespace DFG {
329
6fe7ccc8
A
330template<bool strict>
331static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
332{
93a37866
A
333 VM& vm = exec->vm();
334 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8 335
93a37866
A
336 if (baseValue.isObject()) {
337 JSObject* object = asObject(baseValue);
338 if (object->canSetIndexQuickly(index)) {
339 object->setIndexQuickly(vm, index, value);
6fe7ccc8
A
340 return;
341 }
342
93a37866 343 object->methodTable()->putByIndex(object, exec, index, value, strict);
6fe7ccc8
A
344 return;
345 }
346
347 baseValue.putByIndex(exec, index, value, strict);
348}
349
350template<bool strict>
351ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
14957cd0 352{
93a37866
A
353 VM* vm = &exec->vm();
354 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
355
356 JSValue baseValue = JSValue::decode(encodedBase);
357 JSValue property = JSValue::decode(encodedProperty);
358 JSValue value = JSValue::decode(encodedValue);
359
360 if (LIKELY(property.isUInt32())) {
361 putByVal<strict>(exec, baseValue, property.asUInt32(), value);
362 return;
363 }
364
365 if (property.isDouble()) {
366 double propertyAsDouble = property.asDouble();
367 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
368 if (propertyAsDouble == propertyAsUInt32) {
369 putByVal<strict>(exec, baseValue, propertyAsUInt32, value);
370 return;
371 }
372 }
373
93a37866
A
374 if (isName(property)) {
375 PutPropertySlot slot(strict);
376 baseValue.put(exec, jsCast<NameInstance*>(property.asCell())->privateName(), value, slot);
377 return;
378 }
6fe7ccc8
A
379
380 // Don't put to an object if toString throws an exception.
381 Identifier ident(exec, property.toString(exec)->value(exec));
93a37866 382 if (!vm->exception) {
6fe7ccc8
A
383 PutPropertySlot slot(strict);
384 baseValue.put(exec, ident, value, slot);
385 }
386}
387
388extern "C" {
389
390EncodedJSValue DFG_OPERATION operationConvertThis(ExecState* exec, EncodedJSValue encodedOp)
391{
93a37866
A
392 VM* vm = &exec->vm();
393 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 394
14957cd0
A
395 return JSValue::encode(JSValue::decode(encodedOp).toThisObject(exec));
396}
397
93a37866 398JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
14957cd0 399{
93a37866
A
400 VM* vm = &exec->vm();
401 NativeCallFrameTracer tracer(vm, exec);
402
6fe7ccc8
A
403#if !ASSERT_DISABLED
404 ConstructData constructData;
93a37866 405 ASSERT(jsCast<JSFunction*>(constructor)->methodTable()->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS);
6fe7ccc8
A
406#endif
407
93a37866 408 return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->allocationProfile(exec, inlineCapacity)->structure());
6fe7ccc8
A
409}
410
93a37866 411JSCell* DFG_OPERATION operationNewObject(ExecState* exec, Structure* structure)
6fe7ccc8 412{
93a37866
A
413 VM* vm = &exec->vm();
414 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 415
93a37866 416 return constructEmptyObject(exec, structure);
6fe7ccc8
A
417}
418
419EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
420{
93a37866
A
421 VM* vm = &exec->vm();
422 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 423
14957cd0
A
424 JSValue op1 = JSValue::decode(encodedOp1);
425 JSValue op2 = JSValue::decode(encodedOp2);
6fe7ccc8
A
426
427 return JSValue::encode(jsAdd(exec, op1, op2));
428}
14957cd0 429
6fe7ccc8
A
430EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
431{
93a37866
A
432 VM* vm = &exec->vm();
433 NativeCallFrameTracer tracer(vm, exec);
14957cd0 434
6fe7ccc8
A
435 JSValue op1 = JSValue::decode(encodedOp1);
436 JSValue op2 = JSValue::decode(encodedOp2);
437
438 ASSERT(!op1.isNumber() || !op2.isNumber());
439
440 if (op1.isString() && !op2.isObject())
441 return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
14957cd0
A
442
443 return JSValue::encode(jsAddSlowCase(exec, op1, op2));
444}
445
6fe7ccc8
A
446static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
447{
93a37866
A
448 VM& vm = exec->vm();
449 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8 450
93a37866
A
451 if (base->isObject()) {
452 JSObject* object = asObject(base);
453 if (object->canGetIndexQuickly(index))
454 return JSValue::encode(object->getIndexQuickly(index));
455 }
6fe7ccc8 456
6fe7ccc8
A
457 if (isJSString(base) && asString(base)->canGetIndex(index))
458 return JSValue::encode(asString(base)->getIndex(exec, index));
459
460 return JSValue::encode(JSValue(base).get(exec, index));
461}
462
463EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
14957cd0 464{
93a37866
A
465 VM* vm = &exec->vm();
466 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 467
14957cd0
A
468 JSValue baseValue = JSValue::decode(encodedBase);
469 JSValue property = JSValue::decode(encodedProperty);
470
471 if (LIKELY(baseValue.isCell())) {
472 JSCell* base = baseValue.asCell();
473
474 if (property.isUInt32()) {
6fe7ccc8
A
475 return getByVal(exec, base, property.asUInt32());
476 } else if (property.isDouble()) {
477 double propertyAsDouble = property.asDouble();
478 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
479 if (propertyAsUInt32 == propertyAsDouble)
480 return getByVal(exec, base, propertyAsUInt32);
481 } else if (property.isString()) {
482 if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
483 return JSValue::encode(result);
484 }
485 }
14957cd0 486
93a37866
A
487 if (isName(property))
488 return JSValue::encode(baseValue.get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
489
6fe7ccc8
A
490 Identifier ident(exec, property.toString(exec)->value(exec));
491 return JSValue::encode(baseValue.get(exec, ident));
492}
14957cd0 493
6fe7ccc8
A
494EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
495{
93a37866
A
496 VM* vm = &exec->vm();
497 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
498
499 JSValue property = JSValue::decode(encodedProperty);
14957cd0 500
6fe7ccc8
A
501 if (property.isUInt32())
502 return getByVal(exec, base, property.asUInt32());
503 if (property.isDouble()) {
504 double propertyAsDouble = property.asDouble();
505 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
506 if (propertyAsUInt32 == propertyAsDouble)
507 return getByVal(exec, base, propertyAsUInt32);
508 } else if (property.isString()) {
509 if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
510 return JSValue::encode(result);
511 }
14957cd0 512
93a37866
A
513 if (isName(property))
514 return JSValue::encode(JSValue(base).get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
515
6fe7ccc8
A
516 Identifier ident(exec, property.toString(exec)->value(exec));
517 return JSValue::encode(JSValue(base).get(exec, ident));
518}
14957cd0 519
93a37866
A
520EncodedJSValue DFG_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
521{
522 VM* vm = &exec->vm();
523 NativeCallFrameTracer tracer(vm, exec);
524
525 if (index < 0) {
526 // Go the slowest way possible becase negative indices don't use indexed storage.
527 return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
528 }
529
530 // Use this since we know that the value is out of bounds.
531 return JSValue::encode(JSValue(base).get(exec, index));
532}
533
6fe7ccc8
A
534EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue base, Identifier* propertyName)
535{
93a37866
A
536 VM* vm = &exec->vm();
537 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
538
539 JSValue baseValue = JSValue::decode(base);
540 PropertySlot slot(baseValue);
541 return JSValue::encode(baseValue.get(exec, *propertyName, slot));
542}
14957cd0 543
6fe7ccc8
A
544J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdBuildList);
545EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
546{
93a37866
A
547 VM* vm = &exec->vm();
548 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 549
93a37866
A
550 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
551 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
552
6fe7ccc8
A
553 JSValue baseValue = JSValue::decode(base);
554 PropertySlot slot(baseValue);
555 JSValue result = baseValue.get(exec, *propertyName, slot);
556
93a37866
A
557 if (accessType == static_cast<AccessType>(stubInfo.accessType))
558 dfgBuildGetByIDList(exec, baseValue, *propertyName, slot, stubInfo);
6fe7ccc8
A
559
560 return JSValue::encode(result);
14957cd0
A
561}
562
6fe7ccc8
A
563J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdProtoBuildList);
564EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 565{
93a37866
A
566 VM* vm = &exec->vm();
567 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 568
93a37866
A
569 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
570 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
571
6fe7ccc8 572 JSValue baseValue = JSValue::decode(base);
14957cd0 573 PropertySlot slot(baseValue);
6fe7ccc8 574 JSValue result = baseValue.get(exec, *propertyName, slot);
93a37866
A
575
576 if (accessType == static_cast<AccessType>(stubInfo.accessType))
577 dfgBuildGetByIDProtoList(exec, baseValue, *propertyName, slot, stubInfo);
6fe7ccc8
A
578
579 return JSValue::encode(result);
14957cd0
A
580}
581
6fe7ccc8
A
582J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdOptimize);
583EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 584{
93a37866
A
585 VM* vm = &exec->vm();
586 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 587
93a37866
A
588 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
589 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
590
6fe7ccc8
A
591 JSValue baseValue = JSValue::decode(base);
592 PropertySlot slot(baseValue);
593 JSValue result = baseValue.get(exec, *propertyName, slot);
594
93a37866
A
595 if (accessType == static_cast<AccessType>(stubInfo.accessType)) {
596 if (stubInfo.seen)
597 dfgRepatchGetByID(exec, baseValue, *propertyName, slot, stubInfo);
598 else
599 stubInfo.seen = true;
600 }
14957cd0 601
6fe7ccc8
A
602 return JSValue::encode(result);
603}
14957cd0 604
6fe7ccc8
A
605EncodedJSValue DFG_OPERATION operationCallCustomGetter(ExecState* exec, JSCell* base, PropertySlot::GetValueFunc function, Identifier* ident)
606{
93a37866
A
607 VM* vm = &exec->vm();
608 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
609
610 return JSValue::encode(function(exec, asObject(base), *ident));
611}
14957cd0 612
6fe7ccc8
A
613EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base, JSCell* value)
614{
93a37866
A
615 VM* vm = &exec->vm();
616 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
617
618 GetterSetter* getterSetter = asGetterSetter(value);
619 JSObject* getter = getterSetter->getter();
620 if (!getter)
621 return JSValue::encode(jsUndefined());
622 CallData callData;
623 CallType callType = getter->methodTable()->getCallData(getter, callData);
624 return JSValue::encode(call(exec, getter, callType, callData, asObject(base), ArgList()));
625}
14957cd0 626
6fe7ccc8
A
627void DFG_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
628{
93a37866
A
629 VM* vm = &exec->vm();
630 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
631
632 operationPutByValInternal<true>(exec, encodedBase, encodedProperty, encodedValue);
633}
14957cd0 634
6fe7ccc8
A
635void DFG_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
636{
93a37866
A
637 VM* vm = &exec->vm();
638 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
639
640 operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue);
641}
642
643void DFG_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
644{
93a37866
A
645 VM* vm = &exec->vm();
646 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
647
648 operationPutByValInternal<true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
649}
650
651void DFG_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
652{
93a37866
A
653 VM* vm = &exec->vm();
654 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
655
656 operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
657}
658
93a37866 659void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
6fe7ccc8 660{
93a37866
A
661 VM* vm = &exec->vm();
662 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
663
664 if (index >= 0) {
93a37866 665 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
6fe7ccc8
A
666 return;
667 }
668
669 PutPropertySlot slot(true);
670 array->methodTable()->put(
671 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
672}
14957cd0 673
93a37866 674void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
6fe7ccc8 675{
93a37866
A
676 VM* vm = &exec->vm();
677 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
678
679 if (index >= 0) {
93a37866 680 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
14957cd0
A
681 return;
682 }
6fe7ccc8
A
683
684 PutPropertySlot slot(false);
685 array->methodTable()->put(
686 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
687}
14957cd0 688
93a37866
A
689void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
690{
691 VM* vm = &exec->vm();
692 NativeCallFrameTracer tracer(vm, exec);
693
694 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
695
696 if (index >= 0) {
697 array->putByIndexInline(exec, index, jsValue, true);
698 return;
699 }
700
701 PutPropertySlot slot(true);
702 array->methodTable()->put(
703 array, exec, Identifier::from(exec, index), jsValue, slot);
704}
705
706void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
707{
708 VM* vm = &exec->vm();
709 NativeCallFrameTracer tracer(vm, exec);
710
711 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
712
713 if (index >= 0) {
714 array->putByIndexInline(exec, index, jsValue, false);
715 return;
716 }
717
718 PutPropertySlot slot(false);
719 array->methodTable()->put(
720 array, exec, Identifier::from(exec, index), jsValue, slot);
721}
722
6fe7ccc8
A
723EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
724{
93a37866
A
725 VM* vm = &exec->vm();
726 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
727
728 array->push(exec, JSValue::decode(encodedValue));
729 return JSValue::encode(jsNumber(array->length()));
730}
731
93a37866
A
732EncodedJSValue DFG_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
733{
734 VM* vm = &exec->vm();
735 NativeCallFrameTracer tracer(vm, exec);
736
737 array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
738 return JSValue::encode(jsNumber(array->length()));
739}
740
741EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
742{
743 VM* vm = &exec->vm();
744 NativeCallFrameTracer tracer(vm, exec);
745
746 return JSValue::encode(array->pop(exec));
747}
748
749EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
750{
751 VM* vm = &exec->vm();
752 NativeCallFrameTracer tracer(vm, exec);
753
754 array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
755
756 return JSValue::encode(array->pop(exec));
757}
758
6fe7ccc8
A
759EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
760{
93a37866
A
761 VM& vm = exec->vm();
762 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8
A
763
764 if (!base->inherits(&RegExpObject::s_info))
765 return throwVMTypeError(exec);
766
767 ASSERT(argument->isString() || argument->isObject());
768 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
769 return JSValue::encode(asRegExpObject(base)->exec(exec, input));
770}
771
772size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
773{
93a37866
A
774 VM& vm = exec->vm();
775 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8
A
776
777 if (!base->inherits(&RegExpObject::s_info)) {
778 throwTypeError(exec);
779 return false;
14957cd0 780 }
6fe7ccc8
A
781
782 ASSERT(argument->isString() || argument->isObject());
783 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
784 return asRegExpObject(base)->test(exec, input);
785}
786
6fe7ccc8
A
787void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
788{
93a37866
A
789 VM* vm = &exec->vm();
790 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
791
792 PutPropertySlot slot(true);
793 base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
14957cd0
A
794}
795
6fe7ccc8 796void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
14957cd0 797{
93a37866
A
798 VM* vm = &exec->vm();
799 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
800
801 PutPropertySlot slot(false);
802 base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
14957cd0
A
803}
804
6fe7ccc8 805void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
14957cd0 806{
93a37866
A
807 VM* vm = &exec->vm();
808 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
809
810 PutPropertySlot slot(true);
811 ASSERT(base->isObject());
93a37866 812 asObject(base)->putDirect(exec->vm(), *propertyName, JSValue::decode(encodedValue), slot);
6fe7ccc8
A
813}
814
815void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
816{
93a37866
A
817 VM* vm = &exec->vm();
818 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
819
820 PutPropertySlot slot(false);
821 ASSERT(base->isObject());
93a37866 822 asObject(base)->putDirect(exec->vm(), *propertyName, JSValue::decode(encodedValue), slot);
6fe7ccc8
A
823}
824
825V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize);
826void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
827{
93a37866
A
828 VM* vm = &exec->vm();
829 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 830
93a37866
A
831 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
832 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
833
6fe7ccc8
A
834 JSValue value = JSValue::decode(encodedValue);
835 JSValue baseValue(base);
836 PutPropertySlot slot(true);
837
838 baseValue.put(exec, *propertyName, value, slot);
839
93a37866
A
840 if (accessType != static_cast<AccessType>(stubInfo.accessType))
841 return;
842
6fe7ccc8
A
843 if (stubInfo.seen)
844 dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
845 else
846 stubInfo.seen = true;
847}
848
849V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictOptimize);
850void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
851{
93a37866
A
852 VM* vm = &exec->vm();
853 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 854
93a37866
A
855 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
856 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
857
6fe7ccc8
A
858 JSValue value = JSValue::decode(encodedValue);
859 JSValue baseValue(base);
860 PutPropertySlot slot(false);
861
862 baseValue.put(exec, *propertyName, value, slot);
863
93a37866
A
864 if (accessType != static_cast<AccessType>(stubInfo.accessType))
865 return;
866
6fe7ccc8
A
867 if (stubInfo.seen)
868 dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
869 else
870 stubInfo.seen = true;
871}
872
873V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictOptimize);
874void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
875{
93a37866
A
876 VM* vm = &exec->vm();
877 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 878
93a37866
A
879 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
880 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
881
6fe7ccc8
A
882 JSValue value = JSValue::decode(encodedValue);
883 PutPropertySlot slot(true);
884
885 ASSERT(base->isObject());
93a37866
A
886 asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
887
888 if (accessType != static_cast<AccessType>(stubInfo.accessType))
889 return;
6fe7ccc8 890
6fe7ccc8
A
891 if (stubInfo.seen)
892 dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
893 else
894 stubInfo.seen = true;
895}
896
897V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictOptimize);
898void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
899{
93a37866
A
900 VM* vm = &exec->vm();
901 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 902
93a37866
A
903 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
904 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
905
6fe7ccc8
A
906 JSValue value = JSValue::decode(encodedValue);
907 PutPropertySlot slot(false);
908
909 ASSERT(base->isObject());
93a37866
A
910 asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
911
912 if (accessType != static_cast<AccessType>(stubInfo.accessType))
913 return;
6fe7ccc8 914
6fe7ccc8
A
915 if (stubInfo.seen)
916 dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
917 else
918 stubInfo.seen = true;
14957cd0
A
919}
920
6fe7ccc8
A
921V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictBuildList);
922void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 923{
93a37866
A
924 VM* vm = &exec->vm();
925 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 926
93a37866
A
927 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
928 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
929
6fe7ccc8
A
930 JSValue value = JSValue::decode(encodedValue);
931 JSValue baseValue(base);
14957cd0 932 PutPropertySlot slot(true);
6fe7ccc8
A
933
934 baseValue.put(exec, *propertyName, value, slot);
935
93a37866
A
936 if (accessType != static_cast<AccessType>(stubInfo.accessType))
937 return;
938
6fe7ccc8 939 dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
14957cd0
A
940}
941
6fe7ccc8
A
942V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictBuildList);
943void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 944{
93a37866
A
945 VM* vm = &exec->vm();
946 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 947
93a37866
A
948 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
949 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
950
6fe7ccc8
A
951 JSValue value = JSValue::decode(encodedValue);
952 JSValue baseValue(base);
14957cd0 953 PutPropertySlot slot(false);
6fe7ccc8
A
954
955 baseValue.put(exec, *propertyName, value, slot);
956
93a37866
A
957 if (accessType != static_cast<AccessType>(stubInfo.accessType))
958 return;
959
6fe7ccc8 960 dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
14957cd0
A
961}
962
6fe7ccc8
A
963V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictBuildList);
964void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 965{
93a37866
A
966 VM* vm = &exec->vm();
967 NativeCallFrameTracer tracer(vm, exec);
968
969 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
970 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
6fe7ccc8
A
971
972 JSValue value = JSValue::decode(encodedValue);
14957cd0 973 PutPropertySlot slot(true);
6fe7ccc8
A
974
975 ASSERT(base->isObject());
93a37866
A
976 asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
977
978 if (accessType != static_cast<AccessType>(stubInfo.accessType))
979 return;
6fe7ccc8 980
6fe7ccc8 981 dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
14957cd0
A
982}
983
6fe7ccc8
A
984V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictBuildList);
985void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 986{
93a37866
A
987 VM* vm = &exec->vm();
988 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 989
93a37866
A
990 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
991 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
992
6fe7ccc8 993 JSValue value = JSValue::decode(encodedValue);
14957cd0 994 PutPropertySlot slot(false);
6fe7ccc8
A
995
996 ASSERT(base->isObject());
93a37866
A
997 asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
998
999 if (accessType != static_cast<AccessType>(stubInfo.accessType))
1000 return;
6fe7ccc8 1001
6fe7ccc8 1002 dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
14957cd0
A
1003}
1004
6fe7ccc8 1005size_t DFG_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
14957cd0 1006{
93a37866
A
1007 VM* vm = &exec->vm();
1008 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1009
1010 return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
14957cd0
A
1011}
1012
6fe7ccc8 1013size_t DFG_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
14957cd0 1014{
93a37866
A
1015 VM* vm = &exec->vm();
1016 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1017
1018 return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
14957cd0
A
1019}
1020
6fe7ccc8 1021size_t DFG_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
14957cd0 1022{
93a37866
A
1023 VM* vm = &exec->vm();
1024 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1025
1026 return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
14957cd0
A
1027}
1028
6fe7ccc8 1029size_t DFG_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
14957cd0 1030{
93a37866
A
1031 VM* vm = &exec->vm();
1032 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1033
1034 return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
14957cd0
A
1035}
1036
6fe7ccc8 1037size_t DFG_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
14957cd0 1038{
93a37866
A
1039 VM* vm = &exec->vm();
1040 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1041
1042 return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
1043}
1044
93a37866
A
1045#if USE(JSVALUE64)
1046EncodedJSValue DFG_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
1047#else
1048size_t DFG_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
1049#endif
1050{
1051 VM* vm = &exec->vm();
1052 NativeCallFrameTracer tracer(vm, exec);
1053
1054 bool result = asString(left)->value(exec) == asString(right)->value(exec);
1055#if USE(JSVALUE64)
1056 return JSValue::encode(jsBoolean(result));
1057#else
1058 return result;
1059#endif
1060}
1061
6fe7ccc8
A
1062size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1063{
93a37866
A
1064 VM* vm = &exec->vm();
1065 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1066
1067 JSValue op1 = JSValue::decode(encodedOp1);
1068 JSValue op2 = JSValue::decode(encodedOp2);
1069
1070 ASSERT(op1.isCell());
1071 ASSERT(op2.isCell());
1072
1073 return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
1074}
1075
1076size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1077{
93a37866
A
1078 VM* vm = &exec->vm();
1079 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1080
1081 JSValue src1 = JSValue::decode(encodedOp1);
1082 JSValue src2 = JSValue::decode(encodedOp2);
1083
1084 return JSValue::strictEqual(exec, src1, src2);
1085}
1086
1087static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
1088{
1089 ExecState* exec = execCallee->callerFrame();
93a37866 1090 VM* vm = &exec->vm();
6fe7ccc8 1091
93a37866 1092 execCallee->setScope(exec->scope());
6fe7ccc8 1093 execCallee->setCodeBlock(0);
6fe7ccc8
A
1094
1095 if (kind == CodeForCall) {
1096 CallData callData;
1097 CallType callType = getCallData(callee, callData);
1098
1099 ASSERT(callType != CallTypeJS);
1100
1101 if (callType == CallTypeHost) {
93a37866 1102 NativeCallFrameTracer tracer(vm, execCallee);
6fe7ccc8 1103 execCallee->setCallee(asObject(callee));
93a37866
A
1104 vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1105 if (vm->exception)
1106 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
6fe7ccc8
A
1107
1108 return reinterpret_cast<void*>(getHostCallReturnValue);
1109 }
1110
1111 ASSERT(callType == CallTypeNone);
93a37866
A
1112 exec->vm().exception = createNotAFunctionError(exec, callee);
1113 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
6fe7ccc8
A
1114 }
1115
1116 ASSERT(kind == CodeForConstruct);
1117
1118 ConstructData constructData;
1119 ConstructType constructType = getConstructData(callee, constructData);
1120
1121 ASSERT(constructType != ConstructTypeJS);
1122
1123 if (constructType == ConstructTypeHost) {
93a37866 1124 NativeCallFrameTracer tracer(vm, execCallee);
6fe7ccc8 1125 execCallee->setCallee(asObject(callee));
93a37866
A
1126 vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1127 if (vm->exception)
1128 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
6fe7ccc8
A
1129
1130 return reinterpret_cast<void*>(getHostCallReturnValue);
1131 }
1132
1133 ASSERT(constructType == ConstructTypeNone);
93a37866
A
1134 exec->vm().exception = createNotAConstructorError(exec, callee);
1135 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
6fe7ccc8
A
1136}
1137
93a37866 1138inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
6fe7ccc8
A
1139{
1140 ExecState* exec = execCallee->callerFrame();
93a37866
A
1141 VM* vm = &exec->vm();
1142 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1143
1144 JSValue calleeAsValue = execCallee->calleeAsValue();
1145 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1146 if (!calleeAsFunctionCell)
93a37866 1147 return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
6fe7ccc8
A
1148
1149 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
93a37866 1150 execCallee->setScope(callee->scopeUnchecked());
6fe7ccc8
A
1151 ExecutableBase* executable = callee->executable();
1152
1153 MacroAssemblerCodePtr codePtr;
1154 CodeBlock* codeBlock = 0;
1155 if (executable->isHostFunction())
1156 codePtr = executable->generatedJITCodeFor(kind).addressForCall();
1157 else {
1158 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1159 JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
1160 if (error) {
93a37866
A
1161 vm->exception = createStackOverflowError(exec);
1162 return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
6fe7ccc8
A
1163 }
1164 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1165 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1166 codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
1167 else
1168 codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
1169 }
93a37866 1170 CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(execCallee->returnPC());
6fe7ccc8
A
1171 if (!callLinkInfo.seenOnce())
1172 callLinkInfo.setSeen();
1173 else
1174 dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
93a37866 1175 return reinterpret_cast<char*>(codePtr.executableAddress());
6fe7ccc8
A
1176}
1177
93a37866 1178char* DFG_OPERATION operationLinkCall(ExecState* execCallee)
6fe7ccc8 1179{
93a37866 1180 return linkFor(execCallee, CodeForCall);
6fe7ccc8
A
1181}
1182
93a37866 1183char* DFG_OPERATION operationLinkConstruct(ExecState* execCallee)
6fe7ccc8 1184{
93a37866 1185 return linkFor(execCallee, CodeForConstruct);
6fe7ccc8
A
1186}
1187
93a37866 1188inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKind kind, JSCell*& calleeAsFunctionCell)
6fe7ccc8
A
1189{
1190 ExecState* exec = execCallee->callerFrame();
93a37866
A
1191 VM* vm = &exec->vm();
1192 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1193
1194 JSValue calleeAsValue = execCallee->calleeAsValue();
93a37866 1195 calleeAsFunctionCell = getJSFunction(calleeAsValue);
6fe7ccc8 1196 if (UNLIKELY(!calleeAsFunctionCell))
93a37866 1197 return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
6fe7ccc8
A
1198
1199 JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
93a37866 1200 execCallee->setScope(function->scopeUnchecked());
6fe7ccc8
A
1201 ExecutableBase* executable = function->executable();
1202 if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
1203 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1204 JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
1205 if (error) {
93a37866
A
1206 exec->vm().exception = error;
1207 return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
6fe7ccc8
A
1208 }
1209 }
93a37866 1210 return reinterpret_cast<char*>(executable->generatedJITCodeWithArityCheckFor(kind).executableAddress());
6fe7ccc8
A
1211}
1212
93a37866
A
1213inline char* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
1214{
1215 JSCell* calleeAsFunctionCellIgnored;
1216 return virtualForWithFunction(execCallee, kind, calleeAsFunctionCellIgnored);
6fe7ccc8
A
1217}
1218
93a37866 1219static bool attemptToOptimizeClosureCall(ExecState* execCallee, JSCell* calleeAsFunctionCell, CallLinkInfo& callLinkInfo)
6fe7ccc8 1220{
93a37866
A
1221 if (!calleeAsFunctionCell)
1222 return false;
1223
1224 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1225 JSFunction* oldCallee = callLinkInfo.callee.get();
1226
1227 if (!oldCallee
1228 || oldCallee->structure() != callee->structure()
1229 || oldCallee->executable() != callee->executable())
1230 return false;
1231
1232 ASSERT(callee->executable()->hasJITCodeForCall());
1233 MacroAssemblerCodePtr codePtr = callee->executable()->generatedJITCodeForCall().addressForCall();
1234
1235 CodeBlock* codeBlock;
1236 if (callee->executable()->isHostFunction())
1237 codeBlock = 0;
1238 else {
1239 codeBlock = &jsCast<FunctionExecutable*>(callee->executable())->generatedBytecodeForCall();
1240 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1241 return false;
1242 }
1243
1244 dfgLinkClosureCall(
1245 execCallee, callLinkInfo, codeBlock,
1246 callee->structure(), callee->executable(), codePtr);
1247
1248 return true;
6fe7ccc8
A
1249}
1250
93a37866 1251char* DFG_OPERATION operationLinkClosureCall(ExecState* execCallee)
6fe7ccc8 1252{
93a37866
A
1253 JSCell* calleeAsFunctionCell;
1254 char* result = virtualForWithFunction(execCallee, CodeForCall, calleeAsFunctionCell);
1255 CallLinkInfo& callLinkInfo = execCallee->callerFrame()->codeBlock()->getCallLinkInfo(execCallee->returnPC());
1256
1257 if (!attemptToOptimizeClosureCall(execCallee, calleeAsFunctionCell, callLinkInfo))
1258 dfgLinkSlowFor(execCallee, callLinkInfo, CodeForCall);
6fe7ccc8 1259
93a37866
A
1260 return result;
1261}
6fe7ccc8 1262
93a37866
A
1263char* DFG_OPERATION operationVirtualCall(ExecState* execCallee)
1264{
1265 return virtualFor(execCallee, CodeForCall);
1266}
6fe7ccc8 1267
93a37866
A
1268char* DFG_OPERATION operationVirtualConstruct(ExecState* execCallee)
1269{
1270 return virtualFor(execCallee, CodeForConstruct);
6fe7ccc8
A
1271}
1272
93a37866 1273void DFG_OPERATION operationNotifyGlobalVarWrite(WatchpointSet* watchpointSet)
6fe7ccc8 1274{
93a37866 1275 watchpointSet->notifyWrite();
6fe7ccc8
A
1276}
1277
93a37866 1278EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* propertyName, ResolveOperations* operations)
6fe7ccc8 1279{
93a37866
A
1280 VM* vm = &exec->vm();
1281 NativeCallFrameTracer tracer(vm, exec);
1282 return JSValue::encode(JSScope::resolve(exec, *propertyName, operations));
6fe7ccc8
A
1283}
1284
93a37866 1285EncodedJSValue DFG_OPERATION operationResolveBase(ExecState* exec, Identifier* propertyName, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
6fe7ccc8 1286{
93a37866
A
1287 VM* vm = &exec->vm();
1288 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 1289
93a37866
A
1290 return JSValue::encode(JSScope::resolveBase(exec, *propertyName, false, operations, putToBaseOperations));
1291}
6fe7ccc8 1292
93a37866
A
1293EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Identifier* propertyName, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
1294{
1295 VM* vm = &exec->vm();
1296 NativeCallFrameTracer tracer(vm, exec);
1297
1298 return JSValue::encode(JSScope::resolveBase(exec, *propertyName, true, operations, putToBaseOperations));
1299}
6fe7ccc8 1300
93a37866
A
1301EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, ResolveOperation* resolveOperation, JSGlobalObject* globalObject, Identifier* propertyName)
1302{
1303 VM* vm = &exec->vm();
1304 NativeCallFrameTracer tracer(vm, exec);
1305 ASSERT(globalObject);
1306 UNUSED_PARAM(resolveOperation);
1307 UNUSED_PARAM(globalObject);
1308 ASSERT(resolveOperation->m_operation == ResolveOperation::GetAndReturnGlobalProperty);
1309 return JSValue::encode(JSScope::resolveGlobal(exec, *propertyName, globalObject, resolveOperation));
6fe7ccc8
A
1310}
1311
1312EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
1313{
93a37866
A
1314 VM* vm = &exec->vm();
1315 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1316
1317 return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
1318}
1319
93a37866 1320char* DFG_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
6fe7ccc8 1321{
93a37866
A
1322 VM* vm = &exec->vm();
1323 NativeCallFrameTracer tracer(vm, exec);
1324
1325 return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
1326}
6fe7ccc8 1327
93a37866
A
1328char* DFG_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
1329{
1330 VM* vm = &exec->vm();
1331 NativeCallFrameTracer tracer(vm, exec);
1332
1333 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
6fe7ccc8
A
1334}
1335
93a37866 1336char* DFG_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size)
6fe7ccc8 1337{
93a37866
A
1338 VM* vm = &exec->vm();
1339 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 1340
93a37866
A
1341 if (UNLIKELY(size < 0))
1342 return bitwise_cast<char*>(throwError(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
1343
1344 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure, size));
6fe7ccc8
A
1345}
1346
93a37866 1347char* DFG_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
6fe7ccc8 1348{
93a37866
A
1349 VM& vm = exec->vm();
1350 NativeCallFrameTracer tracer(&vm, exec);
1351 return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
6fe7ccc8
A
1352}
1353
1354EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
1355{
93a37866
A
1356 VM& vm = exec->vm();
1357 NativeCallFrameTracer tracer(&vm, exec);
6fe7ccc8
A
1358 RegExp* regexp = static_cast<RegExp*>(regexpPtr);
1359 if (!regexp->isValid()) {
1360 throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
1361 return JSValue::encode(jsUndefined());
1362 }
1363
93a37866 1364 return JSValue::encode(RegExpObject::create(exec->vm(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
6fe7ccc8
A
1365}
1366
1367JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec)
1368{
93a37866
A
1369 VM& vm = exec->vm();
1370 NativeCallFrameTracer tracer(&vm, exec);
1371 JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
1372 exec->setScope(activation);
6fe7ccc8
A
1373 return activation;
1374}
1375
93a37866
A
1376JSCell* DFG_OPERATION operationCreateArguments(ExecState* exec)
1377{
1378 VM& vm = exec->vm();
1379 NativeCallFrameTracer tracer(&vm, exec);
1380 // NB: This needs to be exceedingly careful with top call frame tracking, since it
1381 // may be called from OSR exit, while the state of the call stack is bizarre.
1382 Arguments* result = Arguments::create(vm, exec);
1383 ASSERT(!vm.exception);
1384 return result;
1385}
1386
1387JSCell* DFG_OPERATION operationCreateInlinedArguments(
1388 ExecState* exec, InlineCallFrame* inlineCallFrame)
1389{
1390 VM& vm = exec->vm();
1391 NativeCallFrameTracer tracer(&vm, exec);
1392 // NB: This needs to be exceedingly careful with top call frame tracking, since it
1393 // may be called from OSR exit, while the state of the call stack is bizarre.
1394 Arguments* result = Arguments::create(vm, exec, inlineCallFrame);
1395 ASSERT(!vm.exception);
1396 return result;
1397}
1398
1399void DFG_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell* activationCell)
1400{
1401 ASSERT(exec->codeBlock()->usesArguments());
1402 if (activationCell) {
1403 jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec, jsCast<JSActivation*>(activationCell));
1404 return;
1405 }
1406 jsCast<Arguments*>(argumentsCell)->tearOff(exec);
1407}
1408
1409void DFG_OPERATION operationTearOffInlinedArguments(
1410 ExecState* exec, JSCell* argumentsCell, JSCell* activationCell, InlineCallFrame* inlineCallFrame)
1411{
1412 ASSERT_UNUSED(activationCell, !activationCell); // Currently, we don't inline functions with activations.
1413 jsCast<Arguments*>(argumentsCell)->tearOff(exec, inlineCallFrame);
1414}
1415
1416EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState* exec, int32_t argumentsRegister)
1417{
1418 VM& vm = exec->vm();
1419 NativeCallFrameTracer tracer(&vm, exec);
1420 // Here we can assume that the argumernts were created. Because otherwise the JIT code would
1421 // have not made this call.
1422 Identifier ident(&vm, "length");
1423 JSValue baseValue = exec->uncheckedR(argumentsRegister).jsValue();
1424 PropertySlot slot(baseValue);
1425 return JSValue::encode(baseValue.get(exec, ident, slot));
1426}
1427
1428EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index)
6fe7ccc8 1429{
93a37866
A
1430 VM& vm = exec->vm();
1431 NativeCallFrameTracer tracer(&vm, exec);
1432
1433 JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
1434
1435 // If there are no arguments, and we're accessing out of bounds, then we have to create the
1436 // arguments in case someone has installed a getter on a numeric property.
1437 if (!argumentsValue)
1438 exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec);
1439
1440 return JSValue::encode(argumentsValue.get(exec, index));
1441}
1442
1443EncodedJSValue DFG_OPERATION operationGetInlinedArgumentByVal(
1444 ExecState* exec, int32_t argumentsRegister, InlineCallFrame* inlineCallFrame, int32_t index)
1445{
1446 VM& vm = exec->vm();
1447 NativeCallFrameTracer tracer(&vm, exec);
1448
1449 JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
1450
1451 // If there are no arguments, and we're accessing out of bounds, then we have to create the
1452 // arguments in case someone has installed a getter on a numeric property.
1453 if (!argumentsValue) {
1454 exec->uncheckedR(argumentsRegister) = argumentsValue =
1455 Arguments::create(exec->vm(), exec, inlineCallFrame);
1456 }
1457
1458 return JSValue::encode(argumentsValue.get(exec, index));
1459}
1460
1461JSCell* DFG_OPERATION operationNewFunctionNoCheck(ExecState* exec, JSCell* functionExecutable)
1462{
1463 ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
1464 VM& vm = exec->vm();
1465 NativeCallFrameTracer tracer(&vm, exec);
1466 return JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope());
6fe7ccc8
A
1467}
1468
93a37866 1469EncodedJSValue DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
6fe7ccc8
A
1470{
1471 ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
93a37866
A
1472 VM& vm = exec->vm();
1473 NativeCallFrameTracer tracer(&vm, exec);
1474 return JSValue::encode(JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope()));
6fe7ccc8
A
1475}
1476
1477JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
1478{
1479 ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info));
93a37866
A
1480
1481 VM& vm = exec->vm();
1482 NativeCallFrameTracer tracer(&vm, exec);
1483
6fe7ccc8
A
1484 FunctionExecutable* functionExecutable =
1485 static_cast<FunctionExecutable*>(functionExecutableAsCell);
93a37866 1486 return JSFunction::create(exec, functionExecutable, exec->scope());
6fe7ccc8
A
1487}
1488
93a37866 1489size_t DFG_OPERATION operationIsObject(ExecState* exec, EncodedJSValue value)
6fe7ccc8 1490{
93a37866 1491 return jsIsObjectType(exec, JSValue::decode(value));
6fe7ccc8
A
1492}
1493
1494size_t DFG_OPERATION operationIsFunction(EncodedJSValue value)
1495{
1496 return jsIsFunctionType(JSValue::decode(value));
1497}
1498
93a37866
A
1499JSCell* DFG_OPERATION operationTypeOf(ExecState* exec, JSCell* value)
1500{
1501 return jsTypeStringForValue(exec, JSValue(value)).asCell();
1502}
1503
1504void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value)
1505{
1506 VM& vm = exec->vm();
1507 NativeCallFrameTracer tracer(&vm, exec);
1508
1509 ASSERT(structure->outOfLineCapacity() > base->structure()->outOfLineCapacity());
1510 ASSERT(!vm.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue)));
1511 base->setStructureAndReallocateStorageIfNecessary(vm, structure);
1512 base->putDirect(vm, offset, JSValue::decode(value));
1513}
1514
1515char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
1516{
1517 VM& vm = exec->vm();
1518 NativeCallFrameTracer tracer(&vm, exec);
1519
1520 return reinterpret_cast<char*>(
1521 Butterfly::createUninitialized(vm, 0, initialOutOfLineCapacity, false, 0));
1522}
1523
1524char* DFG_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
1525{
1526 VM& vm = exec->vm();
1527 NativeCallFrameTracer tracer(&vm, exec);
1528
1529 return reinterpret_cast<char*>(
1530 Butterfly::createUninitialized(vm, 0, newSize, false, 0));
1531}
1532
1533char* DFG_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
1534{
1535 VM& vm = exec->vm();
1536 NativeCallFrameTracer tracer(&vm, exec);
1537
1538 ASSERT(!object->structure()->outOfLineCapacity());
1539 Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
1540 object->setButterflyWithoutChangingStructure(result);
1541 return reinterpret_cast<char*>(result);
1542}
1543
1544char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
1545{
1546 VM& vm = exec->vm();
1547 NativeCallFrameTracer tracer(&vm, exec);
1548
1549 Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize);
1550 object->setButterflyWithoutChangingStructure(result);
1551 return reinterpret_cast<char*>(result);
1552}
1553
1554char* DFG_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
1555{
1556 VM& vm = exec->vm();
1557 NativeCallFrameTracer tracer(&vm, exec);
1558
1559 if (!cell->isObject())
1560 return 0;
1561
1562 return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
1563}
1564
1565char* DFG_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
1566{
1567 VM& vm = exec->vm();
1568 NativeCallFrameTracer tracer(&vm, exec);
1569
1570 if (!cell->isObject())
1571 return 0;
1572
1573 return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
1574}
1575
1576char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
1577{
1578 VM& vm = exec->vm();
1579 NativeCallFrameTracer tracer(&vm, exec);
1580
1581 if (!cell->isObject())
1582 return 0;
1583
1584 return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
1585}
1586
1587char* DFG_OPERATION operationRageEnsureContiguous(ExecState* exec, JSCell* cell)
1588{
1589 VM& vm = exec->vm();
1590 NativeCallFrameTracer tracer(&vm, exec);
1591
1592 if (!cell->isObject())
1593 return 0;
1594
1595 return reinterpret_cast<char*>(asObject(cell)->rageEnsureContiguous(vm).data());
1596}
1597
1598char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
1599{
1600 VM& vm = exec->vm();
1601 NativeCallFrameTracer tracer(&vm, exec);
1602
1603 if (!cell->isObject())
1604 return 0;
1605
1606 return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
1607}
1608
1609StringImpl* DFG_OPERATION operationResolveRope(ExecState* exec, JSString* string)
1610{
1611 VM& vm = exec->vm();
1612 NativeCallFrameTracer tracer(&vm, exec);
1613
1614 return string->value(exec).impl();
1615}
1616
1617JSCell* DFG_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
1618{
1619 VM& vm = exec->vm();
1620 NativeCallFrameTracer tracer(&vm, exec);
1621
1622 return StringObject::create(exec, structure, string);
1623}
1624
1625JSCell* DFG_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
1626{
1627 VM& vm = exec->vm();
1628 NativeCallFrameTracer tracer(&vm, exec);
1629
1630 return JSValue(cell).toString(exec);
1631}
1632
1633JSCell* DFG_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
1634{
1635 VM& vm = exec->vm();
1636 NativeCallFrameTracer tracer(&vm, exec);
1637
1638 return JSValue::decode(value).toString(exec);
1639}
1640
1641JSCell* DFG_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
1642{
1643 VM& vm = exec->vm();
1644 NativeCallFrameTracer tracer(&vm, exec);
1645
1646 return JSRopeString::create(vm, left, right);
1647}
1648
1649JSCell* DFG_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
1650{
1651 VM& vm = exec->vm();
1652 NativeCallFrameTracer tracer(&vm, exec);
1653
1654 return JSRopeString::create(vm, a, b, c);
1655}
1656
6fe7ccc8
A
1657double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b)
1658{
1659 return fmod(a, b);
1660}
1661
93a37866
A
1662JSCell* DFG_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
1663{
1664 VM* vm = &exec->vm();
1665 NativeCallFrameTracer tracer(vm, exec);
1666 return JSC::stringFromCharCode(exec, op1);
1667}
1668
6fe7ccc8
A
1669DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex)
1670{
93a37866
A
1671 VM* vm = &exec->vm();
1672 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 1673
14957cd0
A
1674 JSValue exceptionValue = exec->exception();
1675 ASSERT(exceptionValue);
6fe7ccc8
A
1676
1677 unsigned vPCIndex = exec->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex);
93a37866 1678 ExceptionHandler handler = genericThrow(vm, exec, exceptionValue, vPCIndex);
6fe7ccc8
A
1679 ASSERT(handler.catchRoutine);
1680 return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
1681}
14957cd0 1682
6fe7ccc8
A
1683DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, StructureStubInfo* stubInfo)
1684{
93a37866
A
1685 VM* vm = &exec->vm();
1686 NativeCallFrameTracer tracer(vm, exec);
14957cd0 1687
6fe7ccc8
A
1688 JSValue exceptionValue = exec->exception();
1689 ASSERT(exceptionValue);
1690
1691 CodeOrigin codeOrigin = stubInfo->codeOrigin;
1692 while (codeOrigin.inlineCallFrame)
1693 codeOrigin = codeOrigin.inlineCallFrame->caller;
1694
93a37866 1695 ExceptionHandler handler = genericThrow(vm, exec, exceptionValue, codeOrigin.bytecodeIndex);
6fe7ccc8
A
1696 ASSERT(handler.catchRoutine);
1697 return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
14957cd0
A
1698}
1699
6fe7ccc8 1700size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
14957cd0 1701{
93a37866
A
1702 VM* vm = &exec->vm();
1703 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1704
1705 // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
1706 return JSValue::decode(value).toUInt32(exec);
14957cd0
A
1707}
1708
6fe7ccc8 1709size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
14957cd0 1710{
93a37866
A
1711 VM* vm = &exec->vm();
1712 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8 1713
14957cd0
A
1714 return JSValue::decode(encodedOp).toBoolean(exec);
1715}
1716
93a37866 1717void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
6fe7ccc8 1718{
93a37866
A
1719 VM* vm = &exec->vm();
1720 NativeCallFrameTracer tracer(vm, exec);
6fe7ccc8
A
1721
1722 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
1723 CodeBlock* codeBlock = debugInfo->codeBlock;
1724 CodeBlock* alternative = codeBlock->alternative();
93a37866
A
1725 dataLog(
1726 "Speculation failure in ", *codeBlock, " with ");
1727 if (alternative) {
1728 dataLog(
1729 "executeCounter = ", alternative->jitExecuteCounter(),
1730 ", reoptimizationRetryCounter = ", alternative->reoptimizationRetryCounter(),
1731 ", optimizationDelayCounter = ", alternative->optimizationDelayCounter());
1732 } else
1733 dataLog("no alternative code block (i.e. we've been jettisoned)");
1734 dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
1735 dataLog(" GPRs at time of exit:");
1736 char* scratchPointer = static_cast<char*>(scratch);
1737 for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
1738 GPRReg gpr = GPRInfo::toRegister(i);
1739 dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
1740 scratchPointer += sizeof(EncodedJSValue);
1741 }
1742 dataLog("\n");
1743 dataLog(" FPRs at time of exit:");
1744 for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
1745 FPRReg fpr = FPRInfo::toRegister(i);
1746 dataLog(" ", FPRInfo::debugName(fpr), ":");
1747 uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
1748 double value = *reinterpret_cast_ptr<double*>(scratchPointer);
1749 dataLogF("%llx:%lf", static_cast<long long>(bits), value);
1750 scratchPointer += sizeof(EncodedJSValue);
1751 }
1752 dataLog("\n");
6fe7ccc8 1753}
93a37866
A
1754
1755extern "C" void DFG_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock)
1756{
1757#if ENABLE(JIT_VERBOSE_OSR)
1758 dataLog(*codeBlock, ": Entered reoptimize\n");
6fe7ccc8 1759#endif
93a37866
A
1760 // We must be called with the baseline code block.
1761 ASSERT(JITCode::isBaselineCode(codeBlock->getJITType()));
1762
1763 // If I am my own replacement, then reoptimization has already been triggered.
1764 // This can happen in recursive functions.
1765 if (codeBlock->replacement() == codeBlock)
1766 return;
1767
1768 // Otherwise, the replacement must be optimized code. Use this as an opportunity
1769 // to check our logic.
1770 ASSERT(codeBlock->hasOptimizedReplacement());
1771 ASSERT(codeBlock->replacement()->getJITType() == JITCode::DFGJIT);
1772
1773 codeBlock->reoptimize();
1774}
6fe7ccc8
A
1775
1776} // extern "C"
14957cd0
A
1777} } // namespace JSC::DFG
1778
93a37866 1779#endif // ENABLE(DFG_JIT)
6fe7ccc8
A
1780
1781namespace JSC {
1782
93a37866 1783#if COMPILER(GCC) && CPU(X86_64)
6fe7ccc8
A
1784asm (
1785".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1786HIDE_SYMBOL(getHostCallReturnValue) "\n"
1787SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1788 "mov -40(%r13), %r13\n"
1789 "mov %r13, %rdi\n"
93a37866 1790 "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
6fe7ccc8 1791);
93a37866 1792#elif COMPILER(GCC) && CPU(X86)
6fe7ccc8
A
1793asm (
1794".text" "\n" \
1795".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1796HIDE_SYMBOL(getHostCallReturnValue) "\n"
1797SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1798 "mov -40(%edi), %edi\n"
1799 "mov %edi, 4(%esp)\n"
93a37866 1800 "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
6fe7ccc8 1801);
93a37866 1802#elif COMPILER(GCC) && CPU(ARM_THUMB2)
6fe7ccc8
A
1803asm (
1804".text" "\n"
1805".align 2" "\n"
1806".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1807HIDE_SYMBOL(getHostCallReturnValue) "\n"
1808".thumb" "\n"
1809".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
1810SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1811 "ldr r5, [r5, #-40]" "\n"
1812 "mov r0, r5" "\n"
93a37866
A
1813 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1814);
1815#elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
1816asm (
1817".text" "\n"
1818".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1819HIDE_SYMBOL(getHostCallReturnValue) "\n"
1820INLINE_ARM_FUNCTION(getHostCallReturnValue)
1821SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1822 "ldr r5, [r5, #-40]" "\n"
1823 "mov r0, r5" "\n"
1824 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1825);
1826#elif CPU(ARM64)
1827asm (
1828".text" "\n"
1829".align 2" "\n"
1830".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1831HIDE_SYMBOL(getHostCallReturnValue) "\n"
1832SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1833 "ldur x25, [x25, #-40]" "\n"
1834 "mov x0, x25" "\n"
1835 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1836);
1837#elif COMPILER(GCC) && CPU(MIPS)
1838asm(
1839".text" "\n"
1840".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1841HIDE_SYMBOL(getHostCallReturnValue) "\n"
1842SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1843 LOAD_FUNCTION_TO_T9(getHostCallReturnValueWithExecState)
1844 "lw $s0, -40($s0)" "\n"
1845 "move $a0, $s0" "\n"
1846 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1847);
1848#elif COMPILER(GCC) && CPU(SH4)
1849asm(
1850".text" "\n"
1851".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1852HIDE_SYMBOL(getHostCallReturnValue) "\n"
1853SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1854 "add #-40, r14" "\n"
1855 "mov.l @r14, r14" "\n"
1856 "mov r14, r4" "\n"
1857 "bra " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1858 "nop" "\n"
6fe7ccc8
A
1859);
1860#endif
1861
1862extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
1863{
1864 if (!exec)
1865 return JSValue::encode(JSValue());
93a37866 1866 return JSValue::encode(exec->vm().hostCallReturnValue);
6fe7ccc8
A
1867}
1868
1869} // namespace JSC
1870
93a37866 1871#endif // ENABLE(JIT)