]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGOperations.cpp
JavaScriptCore-1097.3.3.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
14957cd0 29#include "CodeBlock.h"
6fe7ccc8
A
30#include "DFGOSRExit.h"
31#include "DFGRepatch.h"
32#include "HostCallReturnValue.h"
33#include "GetterSetter.h"
34#include <wtf/InlineASM.h>
14957cd0 35#include "Interpreter.h"
6fe7ccc8
A
36#include "JITExceptions.h"
37#include "JSActivation.h"
14957cd0 38#include "JSGlobalData.h"
6fe7ccc8 39#include "JSStaticScopeObject.h"
14957cd0
A
40#include "Operations.h"
41
6fe7ccc8
A
42#if ENABLE(DFG_JIT)
43
44#if CPU(X86_64)
45
46#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
47 asm( \
48 ".globl " SYMBOL_STRING(function) "\n" \
49 HIDE_SYMBOL(function) "\n" \
50 SYMBOL_STRING(function) ":" "\n" \
51 "mov (%rsp), %" STRINGIZE(register) "\n" \
52 "jmp " SYMBOL_STRING_RELOCATION(function##WithReturnAddress) "\n" \
53 );
54#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rsi)
55#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
56#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
57#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8)
58
59#elif CPU(X86)
60
61#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset) \
62 asm( \
63 ".text" "\n" \
64 ".globl " SYMBOL_STRING(function) "\n" \
65 HIDE_SYMBOL(function) "\n" \
66 SYMBOL_STRING(function) ":" "\n" \
67 "mov (%esp), %eax\n" \
68 "mov %eax, " STRINGIZE(offset) "(%esp)\n" \
69 "jmp " SYMBOL_STRING_RELOCATION(function##WithReturnAddress) "\n" \
70 );
71#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 8)
72#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 16)
73#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 20)
74#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 24)
75
76#elif COMPILER(GCC) && CPU(ARM_THUMB2)
77
78#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
79 asm ( \
80 ".text" "\n" \
81 ".align 2" "\n" \
82 ".globl " SYMBOL_STRING(function) "\n" \
83 HIDE_SYMBOL(function) "\n" \
84 ".thumb" "\n" \
85 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
86 SYMBOL_STRING(function) ":" "\n" \
87 "mov a2, lr" "\n" \
88 "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
89 );
90
91#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
92 asm ( \
93 ".text" "\n" \
94 ".align 2" "\n" \
95 ".globl " SYMBOL_STRING(function) "\n" \
96 HIDE_SYMBOL(function) "\n" \
97 ".thumb" "\n" \
98 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
99 SYMBOL_STRING(function) ":" "\n" \
100 "mov a4, lr" "\n" \
101 "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
102 );
103
104#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
105 asm ( \
106 ".text" "\n" \
107 ".align 2" "\n" \
108 ".globl " SYMBOL_STRING(function) "\n" \
109 HIDE_SYMBOL(function) "\n" \
110 ".thumb" "\n" \
111 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
112 SYMBOL_STRING(function) ":" "\n" \
113 "str lr, [sp, #0]" "\n" \
114 "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
115 );
116
117#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
118 asm ( \
119 ".text" "\n" \
120 ".align 2" "\n" \
121 ".globl " SYMBOL_STRING(function) "\n" \
122 HIDE_SYMBOL(function) "\n" \
123 ".thumb" "\n" \
124 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
125 SYMBOL_STRING(function) ":" "\n" \
126 "str lr, [sp, #4]" "\n" \
127 "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
128 );
129
130#endif
131
132#define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
133void* DFG_OPERATION function##WithReturnAddress(ExecState*, ReturnAddressPtr); \
134FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)
135
136#define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
137EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, JSCell*, Identifier*, ReturnAddressPtr); \
138FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)
139
140#define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
141EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr); \
142FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)
143
144#define V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
145void DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, JSCell*, Identifier*, ReturnAddressPtr); \
146FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function)
147
14957cd0
A
148namespace JSC { namespace DFG {
149
6fe7ccc8
A
150template<bool strict>
151static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
152{
153 JSGlobalData& globalData = exec->globalData();
154 NativeCallFrameTracer tracer(&globalData, exec);
155
156 if (isJSArray(baseValue)) {
157 JSArray* array = asArray(baseValue);
158 if (array->canSetIndex(index)) {
159 array->setIndex(globalData, index, value);
160 return;
161 }
162
163 JSArray::putByIndex(array, exec, index, value, strict);
164 return;
165 }
166
167 baseValue.putByIndex(exec, index, value, strict);
168}
169
170template<bool strict>
171ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
14957cd0 172{
6fe7ccc8
A
173 JSGlobalData* globalData = &exec->globalData();
174 NativeCallFrameTracer tracer(globalData, exec);
175
176 JSValue baseValue = JSValue::decode(encodedBase);
177 JSValue property = JSValue::decode(encodedProperty);
178 JSValue value = JSValue::decode(encodedValue);
179
180 if (LIKELY(property.isUInt32())) {
181 putByVal<strict>(exec, baseValue, property.asUInt32(), value);
182 return;
183 }
184
185 if (property.isDouble()) {
186 double propertyAsDouble = property.asDouble();
187 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
188 if (propertyAsDouble == propertyAsUInt32) {
189 putByVal<strict>(exec, baseValue, propertyAsUInt32, value);
190 return;
191 }
192 }
193
194
195 // Don't put to an object if toString throws an exception.
196 Identifier ident(exec, property.toString(exec)->value(exec));
197 if (!globalData->exception) {
198 PutPropertySlot slot(strict);
199 baseValue.put(exec, ident, value, slot);
200 }
201}
202
203extern "C" {
204
205EncodedJSValue DFG_OPERATION operationConvertThis(ExecState* exec, EncodedJSValue encodedOp)
206{
207 JSGlobalData* globalData = &exec->globalData();
208 NativeCallFrameTracer tracer(globalData, exec);
209
14957cd0
A
210 return JSValue::encode(JSValue::decode(encodedOp).toThisObject(exec));
211}
212
6fe7ccc8 213inline JSCell* createThis(ExecState* exec, JSCell* prototype, JSFunction* constructor)
14957cd0 214{
6fe7ccc8
A
215#if !ASSERT_DISABLED
216 ConstructData constructData;
217 ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
218#endif
219
220 JSGlobalData& globalData = exec->globalData();
221 NativeCallFrameTracer tracer(&globalData, exec);
222
223 Structure* structure;
224 if (prototype->isObject())
225 structure = asObject(prototype)->inheritorID(globalData);
226 else
227 structure = constructor->scope()->globalObject->emptyObjectStructure();
228
229 return constructEmptyObject(exec, structure);
230}
231
232JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSCell* prototype)
233{
234 JSGlobalData* globalData = &exec->globalData();
235 NativeCallFrameTracer tracer(globalData, exec);
236
237 return createThis(exec, prototype, jsCast<JSFunction*>(exec->callee()));
238}
239
240JSCell* DFG_OPERATION operationCreateThisInlined(ExecState* exec, JSCell* prototype, JSCell* constructor)
241{
242 JSGlobalData* globalData = &exec->globalData();
243 NativeCallFrameTracer tracer(globalData, exec);
244
245 return createThis(exec, prototype, jsCast<JSFunction*>(constructor));
246}
247
248JSCell* DFG_OPERATION operationNewObject(ExecState* exec)
249{
250 JSGlobalData* globalData = &exec->globalData();
251 NativeCallFrameTracer tracer(globalData, exec);
252
253 return constructEmptyObject(exec);
254}
255
256EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
257{
258 JSGlobalData* globalData = &exec->globalData();
259 NativeCallFrameTracer tracer(globalData, exec);
260
14957cd0
A
261 JSValue op1 = JSValue::decode(encodedOp1);
262 JSValue op2 = JSValue::decode(encodedOp2);
6fe7ccc8
A
263
264 return JSValue::encode(jsAdd(exec, op1, op2));
265}
14957cd0 266
6fe7ccc8
A
267EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
268{
269 JSGlobalData* globalData = &exec->globalData();
270 NativeCallFrameTracer tracer(globalData, exec);
14957cd0 271
6fe7ccc8
A
272 JSValue op1 = JSValue::decode(encodedOp1);
273 JSValue op2 = JSValue::decode(encodedOp2);
274
275 ASSERT(!op1.isNumber() || !op2.isNumber());
276
277 if (op1.isString() && !op2.isObject())
278 return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
14957cd0
A
279
280 return JSValue::encode(jsAddSlowCase(exec, op1, op2));
281}
282
6fe7ccc8
A
283static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
284{
285 JSGlobalData& globalData = exec->globalData();
286 NativeCallFrameTracer tracer(&globalData, exec);
287
288 // FIXME: the JIT used to handle these in compiled code!
289 if (isJSArray(base) && asArray(base)->canGetIndex(index))
290 return JSValue::encode(asArray(base)->getIndex(index));
291
292 // FIXME: the JITstub used to relink this to an optimized form!
293 if (isJSString(base) && asString(base)->canGetIndex(index))
294 return JSValue::encode(asString(base)->getIndex(exec, index));
295
296 return JSValue::encode(JSValue(base).get(exec, index));
297}
298
299EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
14957cd0 300{
6fe7ccc8
A
301 JSGlobalData* globalData = &exec->globalData();
302 NativeCallFrameTracer tracer(globalData, exec);
303
14957cd0
A
304 JSValue baseValue = JSValue::decode(encodedBase);
305 JSValue property = JSValue::decode(encodedProperty);
306
307 if (LIKELY(baseValue.isCell())) {
308 JSCell* base = baseValue.asCell();
309
310 if (property.isUInt32()) {
6fe7ccc8
A
311 return getByVal(exec, base, property.asUInt32());
312 } else if (property.isDouble()) {
313 double propertyAsDouble = property.asDouble();
314 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
315 if (propertyAsUInt32 == propertyAsDouble)
316 return getByVal(exec, base, propertyAsUInt32);
317 } else if (property.isString()) {
318 if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
319 return JSValue::encode(result);
320 }
321 }
14957cd0 322
6fe7ccc8
A
323 Identifier ident(exec, property.toString(exec)->value(exec));
324 return JSValue::encode(baseValue.get(exec, ident));
325}
14957cd0 326
6fe7ccc8
A
327EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
328{
329 JSGlobalData* globalData = &exec->globalData();
330 NativeCallFrameTracer tracer(globalData, exec);
331
332 JSValue property = JSValue::decode(encodedProperty);
14957cd0 333
6fe7ccc8
A
334 if (property.isUInt32())
335 return getByVal(exec, base, property.asUInt32());
336 if (property.isDouble()) {
337 double propertyAsDouble = property.asDouble();
338 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
339 if (propertyAsUInt32 == propertyAsDouble)
340 return getByVal(exec, base, propertyAsUInt32);
341 } else if (property.isString()) {
342 if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
343 return JSValue::encode(result);
344 }
14957cd0 345
6fe7ccc8
A
346 Identifier ident(exec, property.toString(exec)->value(exec));
347 return JSValue::encode(JSValue(base).get(exec, ident));
348}
14957cd0 349
6fe7ccc8
A
350EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue base, Identifier* propertyName)
351{
352 JSGlobalData* globalData = &exec->globalData();
353 NativeCallFrameTracer tracer(globalData, exec);
354
355 JSValue baseValue = JSValue::decode(base);
356 PropertySlot slot(baseValue);
357 return JSValue::encode(baseValue.get(exec, *propertyName, slot));
358}
14957cd0 359
6fe7ccc8
A
360J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdBuildList);
361EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
362{
363 JSGlobalData* globalData = &exec->globalData();
364 NativeCallFrameTracer tracer(globalData, exec);
365
366 JSValue baseValue = JSValue::decode(base);
367 PropertySlot slot(baseValue);
368 JSValue result = baseValue.get(exec, *propertyName, slot);
369
370 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
371 dfgBuildGetByIDList(exec, baseValue, *propertyName, slot, stubInfo);
372
373 return JSValue::encode(result);
14957cd0
A
374}
375
6fe7ccc8
A
376J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdProtoBuildList);
377EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 378{
6fe7ccc8
A
379 JSGlobalData* globalData = &exec->globalData();
380 NativeCallFrameTracer tracer(globalData, exec);
381
382 JSValue baseValue = JSValue::decode(base);
14957cd0 383 PropertySlot slot(baseValue);
6fe7ccc8
A
384 JSValue result = baseValue.get(exec, *propertyName, slot);
385
386 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
387 dfgBuildGetByIDProtoList(exec, baseValue, *propertyName, slot, stubInfo);
388
389 return JSValue::encode(result);
14957cd0
A
390}
391
6fe7ccc8
A
392J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdOptimize);
393EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0
A
394{
395 JSGlobalData* globalData = &exec->globalData();
6fe7ccc8
A
396 NativeCallFrameTracer tracer(globalData, exec);
397
398 JSValue baseValue = JSValue::decode(base);
399 PropertySlot slot(baseValue);
400 JSValue result = baseValue.get(exec, *propertyName, slot);
401
402 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
403 if (stubInfo.seen)
404 dfgRepatchGetByID(exec, baseValue, *propertyName, slot, stubInfo);
405 else
406 stubInfo.seen = true;
14957cd0 407
6fe7ccc8
A
408 return JSValue::encode(result);
409}
14957cd0 410
6fe7ccc8
A
411EncodedJSValue DFG_OPERATION operationCallCustomGetter(ExecState* exec, JSCell* base, PropertySlot::GetValueFunc function, Identifier* ident)
412{
413 JSGlobalData* globalData = &exec->globalData();
414 NativeCallFrameTracer tracer(globalData, exec);
415
416 return JSValue::encode(function(exec, asObject(base), *ident));
417}
14957cd0 418
6fe7ccc8
A
419EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base, JSCell* value)
420{
421 JSGlobalData* globalData = &exec->globalData();
422 NativeCallFrameTracer tracer(globalData, exec);
423
424 GetterSetter* getterSetter = asGetterSetter(value);
425 JSObject* getter = getterSetter->getter();
426 if (!getter)
427 return JSValue::encode(jsUndefined());
428 CallData callData;
429 CallType callType = getter->methodTable()->getCallData(getter, callData);
430 return JSValue::encode(call(exec, getter, callType, callData, asObject(base), ArgList()));
431}
14957cd0 432
6fe7ccc8
A
433void DFG_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
434{
435 JSGlobalData* globalData = &exec->globalData();
436 NativeCallFrameTracer tracer(globalData, exec);
437
438 operationPutByValInternal<true>(exec, encodedBase, encodedProperty, encodedValue);
439}
14957cd0 440
6fe7ccc8
A
441void DFG_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
442{
443 JSGlobalData* globalData = &exec->globalData();
444 NativeCallFrameTracer tracer(globalData, exec);
445
446 operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue);
447}
448
449void DFG_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
450{
451 JSGlobalData* globalData = &exec->globalData();
452 NativeCallFrameTracer tracer(globalData, exec);
453
454 operationPutByValInternal<true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
455}
456
457void DFG_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
458{
459 JSGlobalData* globalData = &exec->globalData();
460 NativeCallFrameTracer tracer(globalData, exec);
461
462 operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
463}
464
465void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
466{
467 JSGlobalData* globalData = &exec->globalData();
468 NativeCallFrameTracer tracer(globalData, exec);
469
470 if (index >= 0) {
471 // We should only get here if index is outside the existing vector.
472 ASSERT(!array->canSetIndex(index));
473 JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), true);
474 return;
475 }
476
477 PutPropertySlot slot(true);
478 array->methodTable()->put(
479 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
480}
14957cd0 481
6fe7ccc8
A
482void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
483{
484 JSGlobalData* globalData = &exec->globalData();
485 NativeCallFrameTracer tracer(globalData, exec);
486
487 if (index >= 0) {
488 // We should only get here if index is outside the existing vector.
489 ASSERT(!array->canSetIndex(index));
490 JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), false);
14957cd0
A
491 return;
492 }
6fe7ccc8
A
493
494 PutPropertySlot slot(false);
495 array->methodTable()->put(
496 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
497}
14957cd0 498
6fe7ccc8
A
499EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
500{
501 JSGlobalData* globalData = &exec->globalData();
502 NativeCallFrameTracer tracer(globalData, exec);
503
504 array->push(exec, JSValue::decode(encodedValue));
505 return JSValue::encode(jsNumber(array->length()));
506}
507
508EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
509{
510 JSGlobalData& globalData = exec->globalData();
511 NativeCallFrameTracer tracer(&globalData, exec);
512
513 if (!base->inherits(&RegExpObject::s_info))
514 return throwVMTypeError(exec);
515
516 ASSERT(argument->isString() || argument->isObject());
517 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
518 return JSValue::encode(asRegExpObject(base)->exec(exec, input));
519}
520
521size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
522{
523 JSGlobalData& globalData = exec->globalData();
524 NativeCallFrameTracer tracer(&globalData, exec);
525
526 if (!base->inherits(&RegExpObject::s_info)) {
527 throwTypeError(exec);
528 return false;
14957cd0 529 }
6fe7ccc8
A
530
531 ASSERT(argument->isString() || argument->isObject());
532 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
533 return asRegExpObject(base)->test(exec, input);
534}
535
536EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
537{
538 JSGlobalData* globalData = &exec->globalData();
539 NativeCallFrameTracer tracer(globalData, exec);
540
541 return JSValue::encode(array->pop(exec));
542}
543
544void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
545{
546 JSGlobalData* globalData = &exec->globalData();
547 NativeCallFrameTracer tracer(globalData, exec);
548
549 PutPropertySlot slot(true);
550 base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
14957cd0
A
551}
552
6fe7ccc8 553void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
14957cd0 554{
6fe7ccc8
A
555 JSGlobalData* globalData = &exec->globalData();
556 NativeCallFrameTracer tracer(globalData, exec);
557
558 PutPropertySlot slot(false);
559 base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
14957cd0
A
560}
561
6fe7ccc8 562void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
14957cd0 563{
6fe7ccc8
A
564 JSGlobalData* globalData = &exec->globalData();
565 NativeCallFrameTracer tracer(globalData, exec);
566
567 PutPropertySlot slot(true);
568 ASSERT(base->isObject());
569 asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot);
570}
571
572void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
573{
574 JSGlobalData* globalData = &exec->globalData();
575 NativeCallFrameTracer tracer(globalData, exec);
576
577 PutPropertySlot slot(false);
578 ASSERT(base->isObject());
579 asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot);
580}
581
582V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize);
583void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
584{
585 JSGlobalData* globalData = &exec->globalData();
586 NativeCallFrameTracer tracer(globalData, exec);
587
588 JSValue value = JSValue::decode(encodedValue);
589 JSValue baseValue(base);
590 PutPropertySlot slot(true);
591
592 baseValue.put(exec, *propertyName, value, slot);
593
594 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
595 if (stubInfo.seen)
596 dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
597 else
598 stubInfo.seen = true;
599}
600
601V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictOptimize);
602void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
603{
604 JSGlobalData* globalData = &exec->globalData();
605 NativeCallFrameTracer tracer(globalData, exec);
606
607 JSValue value = JSValue::decode(encodedValue);
608 JSValue baseValue(base);
609 PutPropertySlot slot(false);
610
611 baseValue.put(exec, *propertyName, value, slot);
612
613 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
614 if (stubInfo.seen)
615 dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
616 else
617 stubInfo.seen = true;
618}
619
620V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictOptimize);
621void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
622{
623 JSGlobalData* globalData = &exec->globalData();
624 NativeCallFrameTracer tracer(globalData, exec);
625
626 JSValue value = JSValue::decode(encodedValue);
627 PutPropertySlot slot(true);
628
629 ASSERT(base->isObject());
630 asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
631
632 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
633 if (stubInfo.seen)
634 dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
635 else
636 stubInfo.seen = true;
637}
638
639V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictOptimize);
640void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
641{
642 JSGlobalData* globalData = &exec->globalData();
643 NativeCallFrameTracer tracer(globalData, exec);
644
645 JSValue value = JSValue::decode(encodedValue);
646 PutPropertySlot slot(false);
647
648 ASSERT(base->isObject());
649 asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
650
651 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
652 if (stubInfo.seen)
653 dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
654 else
655 stubInfo.seen = true;
14957cd0
A
656}
657
6fe7ccc8
A
658V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictBuildList);
659void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 660{
6fe7ccc8
A
661 JSGlobalData* globalData = &exec->globalData();
662 NativeCallFrameTracer tracer(globalData, exec);
663
664 JSValue value = JSValue::decode(encodedValue);
665 JSValue baseValue(base);
14957cd0 666 PutPropertySlot slot(true);
6fe7ccc8
A
667
668 baseValue.put(exec, *propertyName, value, slot);
669
670 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
671 dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
14957cd0
A
672}
673
6fe7ccc8
A
674V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictBuildList);
675void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 676{
6fe7ccc8
A
677 JSGlobalData* globalData = &exec->globalData();
678 NativeCallFrameTracer tracer(globalData, exec);
679
680 JSValue value = JSValue::decode(encodedValue);
681 JSValue baseValue(base);
14957cd0 682 PutPropertySlot slot(false);
6fe7ccc8
A
683
684 baseValue.put(exec, *propertyName, value, slot);
685
686 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
687 dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
14957cd0
A
688}
689
6fe7ccc8
A
690V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictBuildList);
691void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 692{
6fe7ccc8
A
693 JSGlobalData* globalData = &exec->globalData();
694 NativeCallFrameTracer tracer(globalData, exec);
695
696 JSValue value = JSValue::decode(encodedValue);
14957cd0 697 PutPropertySlot slot(true);
6fe7ccc8
A
698
699 ASSERT(base->isObject());
700 asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
701
702 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
703 dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
14957cd0
A
704}
705
6fe7ccc8
A
706V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictBuildList);
707void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
14957cd0 708{
6fe7ccc8
A
709 JSGlobalData* globalData = &exec->globalData();
710 NativeCallFrameTracer tracer(globalData, exec);
711
712 JSValue value = JSValue::decode(encodedValue);
14957cd0 713 PutPropertySlot slot(false);
6fe7ccc8
A
714
715 ASSERT(base->isObject());
716 asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
717
718 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
719 dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
14957cd0
A
720}
721
6fe7ccc8 722size_t DFG_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
14957cd0 723{
6fe7ccc8
A
724 JSGlobalData* globalData = &exec->globalData();
725 NativeCallFrameTracer tracer(globalData, exec);
726
727 return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
14957cd0
A
728}
729
6fe7ccc8 730size_t DFG_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
14957cd0 731{
6fe7ccc8
A
732 JSGlobalData* globalData = &exec->globalData();
733 NativeCallFrameTracer tracer(globalData, exec);
734
735 return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
14957cd0
A
736}
737
6fe7ccc8 738size_t DFG_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
14957cd0 739{
6fe7ccc8
A
740 JSGlobalData* globalData = &exec->globalData();
741 NativeCallFrameTracer tracer(globalData, exec);
742
743 return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
14957cd0
A
744}
745
6fe7ccc8 746size_t DFG_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
14957cd0 747{
6fe7ccc8
A
748 JSGlobalData* globalData = &exec->globalData();
749 NativeCallFrameTracer tracer(globalData, exec);
750
751 return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
14957cd0
A
752}
753
6fe7ccc8 754size_t DFG_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
14957cd0 755{
6fe7ccc8
A
756 JSGlobalData* globalData = &exec->globalData();
757 NativeCallFrameTracer tracer(globalData, exec);
758
759 return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
760}
761
762size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
763{
764 JSGlobalData* globalData = &exec->globalData();
765 NativeCallFrameTracer tracer(globalData, exec);
766
767 JSValue op1 = JSValue::decode(encodedOp1);
768 JSValue op2 = JSValue::decode(encodedOp2);
769
770 ASSERT(op1.isCell());
771 ASSERT(op2.isCell());
772
773 return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
774}
775
776size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
777{
778 JSGlobalData* globalData = &exec->globalData();
779 NativeCallFrameTracer tracer(globalData, exec);
780
781 JSValue src1 = JSValue::decode(encodedOp1);
782 JSValue src2 = JSValue::decode(encodedOp2);
783
784 return JSValue::strictEqual(exec, src1, src2);
785}
786
787static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
788{
789 ExecState* exec = execCallee->callerFrame();
790 JSGlobalData* globalData = &exec->globalData();
791
792 execCallee->setScopeChain(exec->scopeChain());
793 execCallee->setCodeBlock(0);
794 execCallee->clearReturnPC();
795
796 if (kind == CodeForCall) {
797 CallData callData;
798 CallType callType = getCallData(callee, callData);
799
800 ASSERT(callType != CallTypeJS);
801
802 if (callType == CallTypeHost) {
803 NativeCallFrameTracer tracer(globalData, execCallee);
804 execCallee->setCallee(asObject(callee));
805 globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
806 if (globalData->exception)
807 return 0;
808
809 return reinterpret_cast<void*>(getHostCallReturnValue);
810 }
811
812 ASSERT(callType == CallTypeNone);
813 exec->globalData().exception = createNotAFunctionError(exec, callee);
814 return 0;
815 }
816
817 ASSERT(kind == CodeForConstruct);
818
819 ConstructData constructData;
820 ConstructType constructType = getConstructData(callee, constructData);
821
822 ASSERT(constructType != ConstructTypeJS);
823
824 if (constructType == ConstructTypeHost) {
825 NativeCallFrameTracer tracer(globalData, execCallee);
826 execCallee->setCallee(asObject(callee));
827 globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
828 if (globalData->exception)
829 return 0;
830
831 return reinterpret_cast<void*>(getHostCallReturnValue);
832 }
833
834 ASSERT(constructType == ConstructTypeNone);
835 exec->globalData().exception = createNotAConstructorError(exec, callee);
836 return 0;
837}
838
839inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, CodeSpecializationKind kind)
840{
841 ExecState* exec = execCallee->callerFrame();
842 JSGlobalData* globalData = &exec->globalData();
843 NativeCallFrameTracer tracer(globalData, exec);
844
845 JSValue calleeAsValue = execCallee->calleeAsValue();
846 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
847 if (!calleeAsFunctionCell)
848 return handleHostCall(execCallee, calleeAsValue, kind);
849
850 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
851 execCallee->setScopeChain(callee->scopeUnchecked());
852 ExecutableBase* executable = callee->executable();
853
854 MacroAssemblerCodePtr codePtr;
855 CodeBlock* codeBlock = 0;
856 if (executable->isHostFunction())
857 codePtr = executable->generatedJITCodeFor(kind).addressForCall();
858 else {
859 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
860 JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
861 if (error) {
862 globalData->exception = createStackOverflowError(exec);
863 return 0;
864 }
865 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
866 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
867 codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
868 else
869 codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
870 }
871 CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress);
872 if (!callLinkInfo.seenOnce())
873 callLinkInfo.setSeen();
874 else
875 dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
876 return codePtr.executableAddress();
877}
878
879P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(operationLinkCall);
880void* DFG_OPERATION operationLinkCallWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
881{
882 return linkFor(execCallee, returnAddress, CodeForCall);
883}
884
885P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(operationLinkConstruct);
886void* DFG_OPERATION operationLinkConstructWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
887{
888 return linkFor(execCallee, returnAddress, CodeForConstruct);
889}
890
891inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
892{
893 ExecState* exec = execCallee->callerFrame();
894 JSGlobalData* globalData = &exec->globalData();
895 NativeCallFrameTracer tracer(globalData, exec);
896
897 JSValue calleeAsValue = execCallee->calleeAsValue();
898 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
899 if (UNLIKELY(!calleeAsFunctionCell))
900 return handleHostCall(execCallee, calleeAsValue, kind);
901
902 JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
903 execCallee->setScopeChain(function->scopeUnchecked());
904 ExecutableBase* executable = function->executable();
905 if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
906 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
907 JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
908 if (error) {
909 exec->globalData().exception = error;
910 return 0;
911 }
912 }
913 return executable->generatedJITCodeWithArityCheckFor(kind).executableAddress();
914}
915
916void* DFG_OPERATION operationVirtualCall(ExecState* execCallee)
917{
918 return virtualFor(execCallee, CodeForCall);
919}
920
921void* DFG_OPERATION operationVirtualConstruct(ExecState* execCallee)
922{
923 return virtualFor(execCallee, CodeForConstruct);
924}
925
926EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* propertyName)
927{
928 JSGlobalData* globalData = &exec->globalData();
929 NativeCallFrameTracer tracer(globalData, exec);
930
931 ScopeChainNode* scopeChain = exec->scopeChain();
932 ScopeChainIterator iter = scopeChain->begin();
933 ScopeChainIterator end = scopeChain->end();
934 ASSERT(iter != end);
935
936 do {
937 JSObject* record = iter->get();
938 PropertySlot slot(record);
939 if (record->getPropertySlot(exec, *propertyName, slot))
940 return JSValue::encode(slot.getValue(exec, *propertyName));
941 } while (++iter != end);
942
943 return throwVMError(exec, createUndefinedVariableError(exec, *propertyName));
944}
945
946EncodedJSValue DFG_OPERATION operationResolveBase(ExecState* exec, Identifier* propertyName)
947{
948 JSGlobalData* globalData = &exec->globalData();
949 NativeCallFrameTracer tracer(globalData, exec);
950
951 return JSValue::encode(resolveBase(exec, *propertyName, exec->scopeChain(), false));
952}
953
954EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Identifier* propertyName)
955{
956 JSGlobalData* globalData = &exec->globalData();
957 NativeCallFrameTracer tracer(globalData, exec);
958
959 JSValue base = resolveBase(exec, *propertyName, exec->scopeChain(), true);
960 if (!base)
961 throwError(exec, createErrorForInvalidGlobalAssignment(exec, propertyName->ustring()));
962 return JSValue::encode(base);
963}
964
965EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, GlobalResolveInfo* resolveInfo, Identifier* propertyName)
966{
967 JSGlobalData* globalData = &exec->globalData();
968 NativeCallFrameTracer tracer(globalData, exec);
969
970 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
971
972 PropertySlot slot(globalObject);
973 if (globalObject->getPropertySlot(exec, *propertyName, slot)) {
974 JSValue result = slot.getValue(exec, *propertyName);
975
976 if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
977 resolveInfo->structure.set(exec->globalData(), exec->codeBlock()->ownerExecutable(), globalObject->structure());
978 resolveInfo->offset = slot.cachedOffset();
979 }
980
981 return JSValue::encode(result);
982 }
983
984 return throwVMError(exec, createUndefinedVariableError(exec, *propertyName));
985}
986
987EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
988{
989 JSGlobalData* globalData = &exec->globalData();
990 NativeCallFrameTracer tracer(globalData, exec);
991
992 return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
993}
994
995EncodedJSValue DFG_OPERATION operationStrCat(ExecState* exec, void* buffer, size_t size)
996{
997 JSGlobalData* globalData = &exec->globalData();
998 NativeCallFrameTracer tracer(globalData, exec);
999
1000 return JSValue::encode(jsString(exec, static_cast<Register*>(buffer), size));
1001}
1002
1003EncodedJSValue DFG_OPERATION operationNewArray(ExecState* exec, void* buffer, size_t size)
1004{
1005 JSGlobalData* globalData = &exec->globalData();
1006 NativeCallFrameTracer tracer(globalData, exec);
1007
1008 return JSValue::encode(constructArray(exec, static_cast<JSValue*>(buffer), size));
1009}
1010
1011EncodedJSValue DFG_OPERATION operationNewArrayBuffer(ExecState* exec, size_t start, size_t size)
1012{
1013 JSGlobalData& globalData = exec->globalData();
1014 NativeCallFrameTracer tracer(&globalData, exec);
1015 return JSValue::encode(constructArray(exec, exec->codeBlock()->constantBuffer(start), size));
1016}
1017
1018EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
1019{
1020 JSGlobalData& globalData = exec->globalData();
1021 NativeCallFrameTracer tracer(&globalData, exec);
1022 RegExp* regexp = static_cast<RegExp*>(regexpPtr);
1023 if (!regexp->isValid()) {
1024 throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
1025 return JSValue::encode(jsUndefined());
1026 }
1027
1028 return JSValue::encode(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
1029}
1030
1031JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec)
1032{
1033 JSGlobalData& globalData = exec->globalData();
1034 NativeCallFrameTracer tracer(&globalData, exec);
1035 JSActivation* activation = JSActivation::create(
1036 globalData, exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
1037 exec->setScopeChain(exec->scopeChain()->push(activation));
1038 return activation;
1039}
1040
1041void DFG_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activation)
1042{
1043 ASSERT(activation);
1044 ASSERT(activation->inherits(&JSActivation::s_info));
1045 JSGlobalData& globalData = exec->globalData();
1046 NativeCallFrameTracer tracer(&globalData, exec);
1047 jsCast<JSActivation*>(activation)->tearOff(exec->globalData());
1048}
1049
1050JSCell* DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
1051{
1052 ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
1053 JSGlobalData& globalData = exec->globalData();
1054 NativeCallFrameTracer tracer(&globalData, exec);
1055 return static_cast<FunctionExecutable*>(functionExecutable)->make(exec, exec->scopeChain());
1056}
1057
1058JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
1059{
1060 ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info));
1061 FunctionExecutable* functionExecutable =
1062 static_cast<FunctionExecutable*>(functionExecutableAsCell);
1063 JSFunction *function = functionExecutable->make(exec, exec->scopeChain());
1064 if (!functionExecutable->name().isNull()) {
1065 JSStaticScopeObject* functionScopeObject =
1066 JSStaticScopeObject::create(
1067 exec, functionExecutable->name(), function, ReadOnly | DontDelete);
1068 function->setScope(exec->globalData(), function->scope()->push(functionScopeObject));
1069 }
1070 return function;
1071}
1072
1073size_t DFG_OPERATION operationIsObject(EncodedJSValue value)
1074{
1075 return jsIsObjectType(JSValue::decode(value));
1076}
1077
1078size_t DFG_OPERATION operationIsFunction(EncodedJSValue value)
1079{
1080 return jsIsFunctionType(JSValue::decode(value));
1081}
1082
1083double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b)
1084{
1085 return fmod(a, b);
1086}
1087
1088DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex)
1089{
1090 JSGlobalData* globalData = &exec->globalData();
1091 NativeCallFrameTracer tracer(globalData, exec);
1092
14957cd0
A
1093 JSValue exceptionValue = exec->exception();
1094 ASSERT(exceptionValue);
6fe7ccc8
A
1095
1096 unsigned vPCIndex = exec->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex);
1097 ExceptionHandler handler = genericThrow(globalData, exec, exceptionValue, vPCIndex);
1098 ASSERT(handler.catchRoutine);
1099 return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
1100}
14957cd0 1101
6fe7ccc8
A
1102DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, StructureStubInfo* stubInfo)
1103{
1104 JSGlobalData* globalData = &exec->globalData();
1105 NativeCallFrameTracer tracer(globalData, exec);
14957cd0 1106
6fe7ccc8
A
1107 JSValue exceptionValue = exec->exception();
1108 ASSERT(exceptionValue);
1109
1110 CodeOrigin codeOrigin = stubInfo->codeOrigin;
1111 while (codeOrigin.inlineCallFrame)
1112 codeOrigin = codeOrigin.inlineCallFrame->caller;
1113
1114 ExceptionHandler handler = genericThrow(globalData, exec, exceptionValue, codeOrigin.bytecodeIndex);
1115 ASSERT(handler.catchRoutine);
1116 return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
14957cd0
A
1117}
1118
6fe7ccc8 1119double DFG_OPERATION dfgConvertJSValueToNumber(ExecState* exec, EncodedJSValue value)
14957cd0 1120{
6fe7ccc8
A
1121 JSGlobalData* globalData = &exec->globalData();
1122 NativeCallFrameTracer tracer(globalData, exec);
1123
14957cd0
A
1124 return JSValue::decode(value).toNumber(exec);
1125}
1126
6fe7ccc8 1127size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
14957cd0 1128{
6fe7ccc8
A
1129 JSGlobalData* globalData = &exec->globalData();
1130 NativeCallFrameTracer tracer(globalData, exec);
1131
1132 // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
1133 return JSValue::decode(value).toUInt32(exec);
14957cd0
A
1134}
1135
6fe7ccc8 1136size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
14957cd0 1137{
6fe7ccc8
A
1138 JSGlobalData* globalData = &exec->globalData();
1139 NativeCallFrameTracer tracer(globalData, exec);
1140
14957cd0
A
1141 return JSValue::decode(encodedOp).toBoolean(exec);
1142}
1143
6fe7ccc8
A
1144#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
1145void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw)
1146{
1147 JSGlobalData* globalData = &exec->globalData();
1148 NativeCallFrameTracer tracer(globalData, exec);
1149
1150 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
1151 CodeBlock* codeBlock = debugInfo->codeBlock;
1152 CodeBlock* alternative = codeBlock->alternative();
1153 dataLog("Speculation failure in %p at @%u with executeCounter = %d, "
1154 "reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, "
1155 "success/fail %u/(%u+%u)\n",
1156 codeBlock,
1157 debugInfo->nodeIndex,
1158 alternative ? alternative->jitExecuteCounter() : 0,
1159 alternative ? alternative->reoptimizationRetryCounter() : 0,
1160 alternative ? alternative->optimizationDelayCounter() : 0,
1161 codeBlock->speculativeSuccessCounter(),
1162 codeBlock->speculativeFailCounter(),
1163 codeBlock->forcedOSRExitCounter());
1164}
1165#endif
1166
1167} // extern "C"
14957cd0
A
1168} } // namespace JSC::DFG
1169
1170#endif
6fe7ccc8
A
1171
1172#if COMPILER(GCC)
1173
1174namespace JSC {
1175
1176#if CPU(X86_64)
1177asm (
1178".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1179HIDE_SYMBOL(getHostCallReturnValue) "\n"
1180SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1181 "mov -40(%r13), %r13\n"
1182 "mov %r13, %rdi\n"
1183 "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
1184);
1185#elif CPU(X86)
1186asm (
1187".text" "\n" \
1188".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1189HIDE_SYMBOL(getHostCallReturnValue) "\n"
1190SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1191 "mov -40(%edi), %edi\n"
1192 "mov %edi, 4(%esp)\n"
1193 "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
1194);
1195#elif CPU(ARM_THUMB2)
1196asm (
1197".text" "\n"
1198".align 2" "\n"
1199".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1200HIDE_SYMBOL(getHostCallReturnValue) "\n"
1201".thumb" "\n"
1202".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
1203SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1204 "ldr r5, [r5, #-40]" "\n"
1205 "mov r0, r5" "\n"
1206 "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
1207);
1208#endif
1209
1210extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
1211{
1212 if (!exec)
1213 return JSValue::encode(JSValue());
1214 return JSValue::encode(exec->globalData().hostCallReturnValue);
1215}
1216
1217} // namespace JSC
1218
1219#endif // COMPILER(GCC)
1220