blob: 19ac6ccb67092eb41b303129e60fd660912a57ad [file] [log] [blame]
barraclough@apple.com2302c042011-03-14 23:31:00 +00001/*
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
29#if ENABLE(DFG_JIT)
30
31#include "CodeBlock.h"
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000032#include "DFGRepatch.h"
barraclough@apple.com2302c042011-03-14 23:31:00 +000033#include "Interpreter.h"
34#include "JSByteArray.h"
35#include "JSGlobalData.h"
36#include "Operations.h"
37
barraclough@apple.com2decbec2011-09-28 01:09:33 +000038
39#if OS(DARWIN) || (OS(WINDOWS) && CPU(X86))
40#define SYMBOL_STRING(name) "_" #name
41#else
42#define SYMBOL_STRING(name) #name
43#endif
44
barraclough@apple.comd910c0d2011-09-24 05:04:08 +000045#if CPU(X86_64)
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000046#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
47 asm( \
barraclough@apple.com2decbec2011-09-28 01:09:33 +000048 ".globl " SYMBOL_STRING(function) "\n" \
49 SYMBOL_STRING(function) ":" "\n" \
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000050 "mov (%rsp), %" STRINGIZE(register) "\n" \
barraclough@apple.com2decbec2011-09-28 01:09:33 +000051 "jmp " SYMBOL_STRING(function) "WithReturnAddress" "\n" \
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000052 );
barraclough@apple.comd910c0d2011-09-24 05:04:08 +000053#elif CPU(X86)
54#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
55 asm( \
barraclough@apple.com2decbec2011-09-28 01:09:33 +000056 ".globl " SYMBOL_STRING(function) "\n" \
57 SYMBOL_STRING(function) ":" "\n" \
barraclough@apple.comd910c0d2011-09-24 05:04:08 +000058 "push (%esp)\n" \
barraclough@apple.com2decbec2011-09-28 01:09:33 +000059 "jmp " SYMBOL_STRING(function) "WithReturnAddress" "\n" \
barraclough@apple.comd910c0d2011-09-24 05:04:08 +000060 );
61#endif
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +000062#define FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rsi)
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000063#define FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
commit-queue@webkit.org0df040e2011-06-27 21:38:09 +000064#define FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8)
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000065
barraclough@apple.com2302c042011-03-14 23:31:00 +000066namespace JSC { namespace DFG {
67
weinig@apple.coma96509f2011-06-15 21:57:17 +000068static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000069{
70 JSGlobalData* globalData = &exec->globalData();
71
weinig@apple.coma96509f2011-06-15 21:57:17 +000072 if (isJSArray(globalData, baseValue)) {
73 JSArray* array = asArray(baseValue);
74 if (array->canSetIndex(index)) {
75 array->setIndex(*globalData, index, value);
76 return;
77 }
78
79 array->JSArray::put(exec, index, value);
80 return;
81 }
82
83 if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(index)) {
84 JSByteArray* byteArray = asByteArray(baseValue);
85 // FIXME: the JITstub used to relink this to an optimized form!
86 if (value.isInt32()) {
87 byteArray->setIndex(index, value.asInt32());
88 return;
89 }
90
91 double dValue = 0;
92 if (value.getNumber(dValue)) {
93 byteArray->setIndex(index, dValue);
94 return;
95 }
96 }
97
98 baseValue.put(exec, index, value);
99}
100
101template<bool strict>
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000102ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
weinig@apple.coma96509f2011-06-15 21:57:17 +0000103{
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000104 JSValue baseValue = JSValue::decode(encodedBase);
105 JSValue property = JSValue::decode(encodedProperty);
106 JSValue value = JSValue::decode(encodedValue);
107
108 if (LIKELY(property.isUInt32())) {
weinig@apple.coma96509f2011-06-15 21:57:17 +0000109 putByVal(exec, baseValue, property.asUInt32(), value);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000110 return;
111 }
112
weinig@apple.coma96509f2011-06-15 21:57:17 +0000113 if (property.isDouble()) {
114 double propertyAsDouble = property.asDouble();
115 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
116 if (propertyAsDouble == propertyAsUInt32) {
117 putByVal(exec, baseValue, propertyAsUInt32, value);
118 return;
119 }
120 }
121
122 JSGlobalData* globalData = &exec->globalData();
123
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000124 // Don't put to an object if toString throws an exception.
125 Identifier ident(exec, property.toString(exec));
126 if (!globalData->exception) {
127 PutPropertySlot slot(strict);
128 baseValue.put(exec, ident, value, slot);
129 }
130}
131
132extern "C" {
133
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000134EncodedJSValue DFG_OPERATION operationConvertThis(ExecState* exec, EncodedJSValue encodedOp)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000135{
barraclough@apple.comd9976842011-03-17 23:11:47 +0000136 return JSValue::encode(JSValue::decode(encodedOp).toThisObject(exec));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000137}
138
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000139EncodedJSValue DFG_OPERATION operationCreateThis(ExecState* exec, EncodedJSValue encodedOp)
fpizlo@apple.combb159ec2011-09-21 22:17:06 +0000140{
141 JSFunction* constructor = asFunction(exec->callee());
142
143#if !ASSERT_DISABLED
144 ConstructData constructData;
145 ASSERT(constructor->getConstructData(constructData) == ConstructTypeJS);
146#endif
147
148 JSGlobalData& globalData = exec->globalData();
149
150 Structure* structure;
151 JSValue proto = JSValue::decode(encodedOp);
152 if (proto.isObject())
153 structure = asObject(proto)->inheritorID(globalData);
154 else
155 structure = constructor->scope()->globalObject->emptyObjectStructure();
156
157 return JSValue::encode(constructEmptyObject(exec, structure));
158}
159
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000160EncodedJSValue DFG_OPERATION operationNewObject(ExecState* exec)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000161{
162 return JSValue::encode(constructEmptyObject(exec));
163}
164
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000165EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000166{
167 JSValue op1 = JSValue::decode(encodedOp1);
168 JSValue op2 = JSValue::decode(encodedOp2);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000169
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000170 return JSValue::encode(jsAdd(exec, op1, op2));
171}
172
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000173EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000174{
175 JSValue op1 = JSValue::decode(encodedOp1);
176 JSValue op2 = JSValue::decode(encodedOp2);
177
fpizlo@apple.com5df0cd82011-08-19 00:18:49 +0000178 ASSERT(!op1.isNumber() || !op2.isNumber());
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000179
180 if (op1.isString()) {
181 if (op2.isString())
182 return JSValue::encode(jsString(exec, asString(op1), asString(op2)));
183 return JSValue::encode(jsString(exec, asString(op1), op2.toPrimitiveString(exec)));
184 }
barraclough@apple.com2302c042011-03-14 23:31:00 +0000185
186 return JSValue::encode(jsAddSlowCase(exec, op1, op2));
187}
188
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000189EncodedJSValue DFG_OPERATION operationArithAdd(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
commit-queue@webkit.orgb873a812011-06-26 19:30:56 +0000190{
191 double num1 = JSValue::decode(encodedOp1).uncheckedGetNumber();
192 double num2 = JSValue::decode(encodedOp2).uncheckedGetNumber();
193 return JSValue::encode(jsNumber(num1 + num2));
194}
195
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000196EncodedJSValue DFG_OPERATION operationArithSub(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
commit-queue@webkit.orgb873a812011-06-26 19:30:56 +0000197{
198 double num1 = JSValue::decode(encodedOp1).uncheckedGetNumber();
199 double num2 = JSValue::decode(encodedOp2).uncheckedGetNumber();
200 return JSValue::encode(jsNumber(num1 - num2));
201}
202
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000203EncodedJSValue DFG_OPERATION operationArithMul(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
commit-queue@webkit.orgb873a812011-06-26 19:30:56 +0000204{
205 double num1 = JSValue::decode(encodedOp1).uncheckedGetNumber();
206 double num2 = JSValue::decode(encodedOp2).uncheckedGetNumber();
207 return JSValue::encode(jsNumber(num1 * num2));
208}
209
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000210EncodedJSValue DFG_OPERATION operationArithDiv(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
commit-queue@webkit.orgb873a812011-06-26 19:30:56 +0000211{
212 double num1 = JSValue::decode(encodedOp1).uncheckedGetNumber();
213 double num2 = JSValue::decode(encodedOp2).uncheckedGetNumber();
214 return JSValue::encode(jsNumber(num1 / num2));
215}
216
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000217EncodedJSValue DFG_OPERATION operationArithMod(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
commit-queue@webkit.orgb873a812011-06-26 19:30:56 +0000218{
219 double num1 = JSValue::decode(encodedOp1).uncheckedGetNumber();
220 double num2 = JSValue::decode(encodedOp2).uncheckedGetNumber();
221 return JSValue::encode(jsNumber(fmod(num1, num2)));
222}
223
weinig@apple.coma96509f2011-06-15 21:57:17 +0000224static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
225{
226 JSGlobalData* globalData = &exec->globalData();
227
228 // FIXME: the JIT used to handle these in compiled code!
229 if (isJSArray(globalData, base) && asArray(base)->canGetIndex(index))
230 return JSValue::encode(asArray(base)->getIndex(index));
231
232 // FIXME: the JITstub used to relink this to an optimized form!
233 if (isJSString(globalData, base) && asString(base)->canGetIndex(index))
234 return JSValue::encode(asString(base)->getIndex(exec, index));
235
236 // FIXME: the JITstub used to relink this to an optimized form!
237 if (isJSByteArray(globalData, base) && asByteArray(base)->canAccessIndex(index))
238 return JSValue::encode(asByteArray(base)->getIndex(exec, index));
239
240 return JSValue::encode(JSValue(base).get(exec, index));
241}
242
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000243EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000244{
245 JSValue baseValue = JSValue::decode(encodedBase);
246 JSValue property = JSValue::decode(encodedProperty);
247
248 if (LIKELY(baseValue.isCell())) {
249 JSCell* base = baseValue.asCell();
250
251 if (property.isUInt32()) {
weinig@apple.coma96509f2011-06-15 21:57:17 +0000252 return getByVal(exec, base, property.asUInt32());
253 } else if (property.isDouble()) {
254 double propertyAsDouble = property.asDouble();
255 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
256 if (propertyAsUInt32 == propertyAsDouble)
257 return getByVal(exec, base, propertyAsUInt32);
258 } else if (property.isString()) {
barraclough@apple.com5d959c72011-08-07 03:44:45 +0000259 if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
260 return JSValue::encode(result);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000261 }
262 }
263
264 Identifier ident(exec, property.toString(exec));
265 return JSValue::encode(baseValue.get(exec, ident));
266}
267
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000268EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000269{
270 JSValue baseValue = JSValue::decode(encodedBase);
271 PropertySlot slot(baseValue);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000272 return JSValue::encode(baseValue.get(exec, *propertyName, slot));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000273}
274
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000275#if CPU(X86_64)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000276EncodedJSValue DFG_OPERATION operationGetMethodOptimizeWithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr);
commit-queue@webkit.orgc0f5cb02011-07-07 03:42:02 +0000277FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetMethodOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000278EncodedJSValue DFG_OPERATION operationGetMethodOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000279#elif CPU(X86)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000280EncodedJSValue DFG_OPERATION operationGetMethodOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000281FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetMethodOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000282EncodedJSValue DFG_OPERATION operationGetMethodOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000283#endif
barraclough@apple.com2302c042011-03-14 23:31:00 +0000284{
barraclough@apple.com2302c042011-03-14 23:31:00 +0000285 JSValue baseValue = JSValue::decode(encodedBase);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000286 PropertySlot slot(baseValue);
287 JSValue result = baseValue.get(exec, *propertyName, slot);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000288
commit-queue@webkit.orgc0f5cb02011-07-07 03:42:02 +0000289 MethodCallLinkInfo& methodInfo = exec->codeBlock()->getMethodCallLinkInfo(returnAddress);
290 if (methodInfo.seenOnce())
291 dfgRepatchGetMethod(exec, baseValue, *propertyName, slot, methodInfo);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000292 else
commit-queue@webkit.orgc0f5cb02011-07-07 03:42:02 +0000293 methodInfo.setSeen();
barraclough@apple.com2302c042011-03-14 23:31:00 +0000294
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000295 return JSValue::encode(result);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000296}
297
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000298#if CPU(X86_64)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000299EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr);
commit-queue@webkit.orge3cb7792011-06-29 19:46:28 +0000300FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetByIdBuildList);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000301EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000302#elif CPU(X86)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000303EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000304FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetByIdBuildList);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000305EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000306#endif
commit-queue@webkit.orge3cb7792011-06-29 19:46:28 +0000307{
308 JSValue baseValue = JSValue::decode(encodedBase);
309 PropertySlot slot(baseValue);
310 JSValue result = baseValue.get(exec, *propertyName, slot);
311
312 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
313 dfgBuildGetByIDList(exec, baseValue, *propertyName, slot, stubInfo);
314
315 return JSValue::encode(result);
316}
317
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000318#if CPU(X86_64)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000319EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr);
commit-queue@webkit.org5f595752011-07-13 21:44:42 +0000320FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetByIdProtoBuildList);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000321EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000322#elif CPU(X86)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000323EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000324FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetByIdProtoBuildList);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000325EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000326#endif
commit-queue@webkit.org5f595752011-07-13 21:44:42 +0000327{
328 JSValue baseValue = JSValue::decode(encodedBase);
329 PropertySlot slot(baseValue);
330 JSValue result = baseValue.get(exec, *propertyName, slot);
331
332 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
333 dfgBuildGetByIDProtoList(exec, baseValue, *propertyName, slot, stubInfo);
334
335 return JSValue::encode(result);
336}
337
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000338#if CPU(X86_64)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000339EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr);
commit-queue@webkit.orgc0f5cb02011-07-07 03:42:02 +0000340FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetByIdOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000341EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000342#elif CPU(X86)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000343EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000344FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetByIdOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000345EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000346#endif
commit-queue@webkit.orgc0f5cb02011-07-07 03:42:02 +0000347{
348 JSValue baseValue = JSValue::decode(encodedBase);
349 PropertySlot slot(baseValue);
350 JSValue result = baseValue.get(exec, *propertyName, slot);
351
352 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
353 if (stubInfo.seen)
354 dfgRepatchGetByID(exec, baseValue, *propertyName, slot, stubInfo);
355 else
356 stubInfo.seen = true;
357
358 return JSValue::encode(result);
359}
360
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000361void DFG_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000362{
363 operationPutByValInternal<true>(exec, encodedBase, encodedProperty, encodedValue);
364}
365
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000366void DFG_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000367{
368 operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue);
369}
370
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000371void DFG_OPERATION operationPutByValBeyondArrayBounds(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
barraclough@apple.come2130ff2011-06-07 23:03:32 +0000372{
373 // We should only get here if index is outside the existing vector.
374 ASSERT(!array->canSetIndex(index));
375 array->JSArray::put(exec, index, JSValue::decode(encodedValue));
376}
377
fpizlo@apple.com24d24e52011-10-04 02:55:54 +0000378EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, JSArray* array, EncodedJSValue encodedValue)
379{
380 array->push(exec, JSValue::decode(encodedValue));
381 return JSValue::encode(jsNumber(array->length()));
382}
383
384EncodedJSValue DFG_OPERATION operationArrayPop(ExecState*, JSArray* array)
385{
386 return JSValue::encode(array->pop());
387}
388
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000389void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000390{
391 PutPropertySlot slot(true);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000392 JSValue::decode(encodedBase).put(exec, *propertyName, JSValue::decode(encodedValue), slot);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000393}
394
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000395void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000396{
397 PutPropertySlot slot(false);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000398 JSValue::decode(encodedBase).put(exec, *propertyName, JSValue::decode(encodedValue), slot);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000399}
400
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000401void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000402{
403 PutPropertySlot slot(true);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000404 JSValue::decode(encodedBase).putDirect(exec, *propertyName, JSValue::decode(encodedValue), slot);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000405}
406
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000407void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000408{
409 PutPropertySlot slot(false);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000410 JSValue::decode(encodedBase).putDirect(exec, *propertyName, JSValue::decode(encodedValue), slot);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000411}
412
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000413#if CPU(X86_64)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000414void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState*, EncodedJSValue, EncodedJSValue, Identifier*, ReturnAddressPtr);
commit-queue@webkit.org0df040e2011-06-27 21:38:09 +0000415FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdStrictOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000416void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000417#elif CPU(X86)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000418void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000419FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdStrictOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000420void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000421#endif
commit-queue@webkit.org0df040e2011-06-27 21:38:09 +0000422{
423 JSValue value = JSValue::decode(encodedValue);
424 JSValue base = JSValue::decode(encodedBase);
425 PutPropertySlot slot(true);
426
427 base.put(exec, *propertyName, value, slot);
428
429 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
430 if (stubInfo.seen)
431 dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, NotDirect);
432 else
433 stubInfo.seen = true;
434}
435
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000436#if CPU(X86_64)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000437void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState*, EncodedJSValue, EncodedJSValue, Identifier*, ReturnAddressPtr);
commit-queue@webkit.org0df040e2011-06-27 21:38:09 +0000438FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdNonStrictOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000439void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000440#elif CPU(X86)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000441void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000442FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdNonStrictOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000443void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000444#endif
commit-queue@webkit.org0df040e2011-06-27 21:38:09 +0000445{
446 JSValue value = JSValue::decode(encodedValue);
447 JSValue base = JSValue::decode(encodedBase);
448 PutPropertySlot slot(false);
449
450 base.put(exec, *propertyName, value, slot);
451
452 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
453 if (stubInfo.seen)
454 dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, NotDirect);
455 else
456 stubInfo.seen = true;
457}
458
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000459#if CPU(X86_64)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000460void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState*, EncodedJSValue, EncodedJSValue, Identifier*, ReturnAddressPtr);
commit-queue@webkit.org0df040e2011-06-27 21:38:09 +0000461FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdDirectStrictOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000462void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000463#elif CPU(X86)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000464void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000465FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdDirectStrictOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000466void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000467#endif
commit-queue@webkit.org0df040e2011-06-27 21:38:09 +0000468{
469 JSValue value = JSValue::decode(encodedValue);
470 JSValue base = JSValue::decode(encodedBase);
471 PutPropertySlot slot(true);
472
473 base.putDirect(exec, *propertyName, value, slot);
474
475 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
476 if (stubInfo.seen)
477 dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
478 else
479 stubInfo.seen = true;
480}
481
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000482#if CPU(X86_64)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000483void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState*, EncodedJSValue, EncodedJSValue, Identifier*, ReturnAddressPtr);
commit-queue@webkit.org0df040e2011-06-27 21:38:09 +0000484FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdDirectNonStrictOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000485void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000486#elif CPU(X86)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000487void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000488FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdDirectNonStrictOptimize);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000489void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000490#endif
commit-queue@webkit.org0df040e2011-06-27 21:38:09 +0000491{
492 JSValue value = JSValue::decode(encodedValue);
493 JSValue base = JSValue::decode(encodedBase);
494 PutPropertySlot slot(false);
495
496 base.putDirect(exec, *propertyName, value, slot);
497
498 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
499 if (stubInfo.seen)
500 dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
501 else
502 stubInfo.seen = true;
503}
504
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000505RegisterSizedBoolean DFG_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000506{
barraclough@apple.com8a8aab62011-07-05 19:01:41 +0000507 return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000508}
509
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000510RegisterSizedBoolean DFG_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000511{
barraclough@apple.com8a8aab62011-07-05 19:01:41 +0000512 return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000513}
514
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000515RegisterSizedBoolean DFG_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com57b4bdb82011-07-04 19:26:05 +0000516{
barraclough@apple.com8a8aab62011-07-05 19:01:41 +0000517 return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
barraclough@apple.com57b4bdb82011-07-04 19:26:05 +0000518}
519
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000520RegisterSizedBoolean DFG_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com57b4bdb82011-07-04 19:26:05 +0000521{
barraclough@apple.com8a8aab62011-07-05 19:01:41 +0000522 return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
barraclough@apple.com57b4bdb82011-07-04 19:26:05 +0000523}
524
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000525RegisterSizedBoolean DFG_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000526{
commit-queue@webkit.org10d804a2011-07-17 09:02:26 +0000527 return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000528}
529
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000530RegisterSizedBoolean DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
commit-queue@webkit.org6efa2ca2011-07-19 00:36:37 +0000531{
532 JSValue op1 = JSValue::decode(encodedOp1);
533 JSValue op2 = JSValue::decode(encodedOp2);
534
535 ASSERT(op1.isCell());
536 ASSERT(op2.isCell());
537
538 return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
539}
540
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000541RegisterSizedBoolean DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000542{
543 return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
544}
545
commit-queue@webkit.orgecf81e62011-09-30 20:36:08 +0000546EncodedJSValue DFG_OPERATION getHostCallReturnValue();
547EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState*);
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000548
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000549#if CPU(X86_64)
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000550asm (
barraclough@apple.com2decbec2011-09-28 01:09:33 +0000551".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
552SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000553 "mov -40(%r13), %r13\n"
554 "mov %r13, %rdi\n"
barraclough@apple.com2decbec2011-09-28 01:09:33 +0000555 "jmp " SYMBOL_STRING(getHostCallReturnValueWithExecState) "\n"
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000556);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000557#elif CPU(X86)
558asm (
barraclough@apple.com2decbec2011-09-28 01:09:33 +0000559".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
560SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000561 "mov -40(%edi), %edi\n"
commit-queue@webkit.orgecf81e62011-09-30 20:36:08 +0000562 "mov (%esp), %ecx\n"
563 "mov %edi, (%esp)\n"
564 "lea -4(%esp), %esp\n"
565 "mov %ecx, (%esp)\n"
barraclough@apple.com2decbec2011-09-28 01:09:33 +0000566 "jmp " SYMBOL_STRING(getHostCallReturnValueWithExecState) "\n"
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000567);
568#endif
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000569
commit-queue@webkit.orgecf81e62011-09-30 20:36:08 +0000570EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState* exec)
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000571{
572 return JSValue::encode(exec->globalData().hostCallReturnValue);
573}
574
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000575static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000576{
577 ExecState* exec = execCallee->callerFrame();
578 JSGlobalData* globalData = &exec->globalData();
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000579 if (kind == CodeForCall) {
580 CallData callData;
581 CallType callType = getCallData(callee, callData);
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000582
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000583 ASSERT(callType != CallTypeJS);
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000584
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000585 if (callType == CallTypeHost) {
586 if (!globalData->interpreter->registerFile().grow(execCallee->registers())) {
587 globalData->exception = createStackOverflowError(exec);
588 return 0;
589 }
590
591 execCallee->setScopeChain(exec->scopeChain());
592
593 globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
594
595 if (globalData->exception)
596 return 0;
597 return reinterpret_cast<void*>(getHostCallReturnValue);
598 }
599
600 ASSERT(callType == CallTypeNone);
barraclough@apple.com085e4ef2011-07-21 18:57:57 +0000601 exec->globalData().exception = createNotAFunctionError(exec, callee);
602 return 0;
603 }
604
605 ASSERT(kind == CodeForConstruct);
606
607 ConstructData constructData;
608 ConstructType constructType = getConstructData(callee, constructData);
609
610 ASSERT(constructType != ConstructTypeJS);
611
612 if (constructType == ConstructTypeHost) {
613 if (!globalData->interpreter->registerFile().grow(execCallee->registers())) {
614 globalData->exception = createStackOverflowError(exec);
615 return 0;
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000616 }
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000617
barraclough@apple.com085e4ef2011-07-21 18:57:57 +0000618 execCallee->setScopeChain(exec->scopeChain());
619
620 globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
621
622 if (globalData->exception)
623 return 0;
624 return reinterpret_cast<void*>(getHostCallReturnValue);
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000625 }
barraclough@apple.com085e4ef2011-07-21 18:57:57 +0000626
627 ASSERT(constructType == ConstructTypeNone);
628 exec->globalData().exception = createNotAConstructorError(exec, callee);
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000629 return 0;
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000630}
631
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000632inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, CodeSpecializationKind kind)
commit-queue@webkit.orgd4e53d62011-07-07 23:54:57 +0000633{
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000634 ExecState* exec = execCallee->callerFrame();
635 JSGlobalData* globalData = &exec->globalData();
636 JSValue calleeAsValue = execCallee->calleeAsValue();
barraclough@apple.comb38285c2011-09-21 19:59:39 +0000637 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000638 if (!calleeAsFunctionCell)
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000639 return handleHostCall(execCallee, calleeAsValue, kind);
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000640 JSFunction* callee = asFunction(calleeAsFunctionCell);
641 ExecutableBase* executable = callee->executable();
642
643 MacroAssemblerCodePtr codePtr;
644 CodeBlock* codeBlock = 0;
645 if (executable->isHostFunction())
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000646 codePtr = executable->generatedJITCodeFor(kind).addressForCall();
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000647 else {
barraclough@apple.com79fe3982011-07-27 23:48:56 +0000648 execCallee->setScopeChain(callee->scope());
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000649 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
barraclough@apple.com79fe3982011-07-27 23:48:56 +0000650 JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000651 if (error) {
652 globalData->exception = createStackOverflowError(exec);
653 return 0;
654 }
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000655 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000656 if (execCallee->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000657 codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000658 else
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000659 codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000660 }
661 CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress);
662 if (!callLinkInfo.seenOnce())
663 callLinkInfo.setSeen();
664 else
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000665 dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
barraclough@apple.com86d1dfa2011-07-08 23:40:39 +0000666 return codePtr.executableAddress();
commit-queue@webkit.orgd4e53d62011-07-07 23:54:57 +0000667}
668
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000669#if CPU(X86_64)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000670void* DFG_OPERATION operationLinkCallWithReturnAddress(ExecState*, ReturnAddressPtr);
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000671FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkCall);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000672void* DFG_OPERATION operationLinkCallWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000673#elif CPU(X86)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000674void* DFG_OPERATION operationLinkCallWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* execCallee);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000675FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkCall);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000676void* DFG_OPERATION operationLinkCallWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* execCallee)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000677#endif
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000678{
679 return linkFor(execCallee, returnAddress, CodeForCall);
680}
681
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000682#if CPU(X86_64)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000683void* DFG_OPERATION operationLinkConstructWithReturnAddress(ExecState*, ReturnAddressPtr);
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000684FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkConstruct);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000685void* DFG_OPERATION operationLinkConstructWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000686#elif CPU(X86)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000687void* DFG_OPERATION operationLinkConstructWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* execCallee);
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000688FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkConstruct);
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000689void* DFG_OPERATION operationLinkConstructWithReturnAddress(ReturnAddressPtr returnAddress, ExecState* execCallee)
barraclough@apple.comd910c0d2011-09-24 05:04:08 +0000690#endif
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000691{
692 return linkFor(execCallee, returnAddress, CodeForConstruct);
693}
694
695inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000696{
697 ExecState* exec = execCallee->callerFrame();
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000698 JSValue calleeAsValue = execCallee->calleeAsValue();
barraclough@apple.comb38285c2011-09-21 19:59:39 +0000699 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
commit-queue@webkit.orgacf52bf2011-07-06 06:35:44 +0000700 if (UNLIKELY(!calleeAsFunctionCell))
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000701 return handleHostCall(execCallee, calleeAsValue, kind);
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000702
703 JSFunction* function = asFunction(calleeAsFunctionCell);
barraclough@apple.com79fe3982011-07-27 23:48:56 +0000704 execCallee->setScopeChain(function->scopeUnchecked());
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000705 ExecutableBase* executable = function->executable();
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000706 if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
commit-queue@webkit.orgacf52bf2011-07-06 06:35:44 +0000707 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
barraclough@apple.com79fe3982011-07-27 23:48:56 +0000708 JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
commit-queue@webkit.orgacf52bf2011-07-06 06:35:44 +0000709 if (error) {
710 exec->globalData().exception = error;
711 return 0;
712 }
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000713 }
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000714 return executable->generatedJITCodeWithArityCheckFor(kind).executableAddress();
715}
716
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000717void* DFG_OPERATION operationVirtualCall(ExecState* execCallee)
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000718{
719 return virtualFor(execCallee, CodeForCall);
720}
721
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000722void* DFG_OPERATION operationVirtualConstruct(ExecState* execCallee)
commit-queue@webkit.org63ac9002011-07-13 01:46:09 +0000723{
724 return virtualFor(execCallee, CodeForConstruct);
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000725}
726
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000727EncodedJSValue DFG_OPERATION operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, EncodedJSValue encodedPrototype)
barraclough@apple.com691cb222011-07-02 23:08:23 +0000728{
729 JSValue value = JSValue::decode(encodedValue);
730 JSValue base = JSValue::decode(encodedBase);
731 JSValue prototype = JSValue::decode(encodedPrototype);
732
733 // Otherwise CheckHasInstance should have failed.
734 ASSERT(base.isCell());
735 // At least one of these checks must have failed to get to the slow case.
736 ASSERT(!value.isCell()
737 || !prototype.isCell()
weinig@apple.com00c765a2011-09-17 00:22:50 +0000738 || !prototype.isObject()
739 || !base.asCell()->structure()->typeInfo().implementsDefaultHasInstance());
barraclough@apple.com691cb222011-07-02 23:08:23 +0000740
741
742 // ECMA-262 15.3.5.3:
743 // Throw an exception either if base is not an object, or if it does not implement 'HasInstance' (i.e. is a function).
744 TypeInfo typeInfo(UnspecifiedType);
745 if (!base.isObject() || !(typeInfo = asObject(base)->structure()->typeInfo()).implementsHasInstance()) {
746 throwError(exec, createInvalidParamError(exec, "instanceof", base));
747 return JSValue::encode(jsUndefined());
748 }
749
750 return JSValue::encode(jsBoolean(asObject(base)->hasInstance(exec, value, prototype)));
751}
752
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000753EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* propertyName)
barraclough@apple.come0764432011-07-22 22:08:52 +0000754{
755 ScopeChainNode* scopeChain = exec->scopeChain();
756 ScopeChainIterator iter = scopeChain->begin();
757 ScopeChainIterator end = scopeChain->end();
758 ASSERT(iter != end);
759
760 do {
761 JSObject* record = iter->get();
762 PropertySlot slot(record);
763 if (record->getPropertySlot(exec, *propertyName, slot))
764 return JSValue::encode(slot.getValue(exec, *propertyName));
765 } while (++iter != end);
766
767 return throwVMError(exec, createUndefinedVariableError(exec, *propertyName));
768}
769
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000770EncodedJSValue DFG_OPERATION operationResolveBase(ExecState* exec, Identifier* propertyName)
barraclough@apple.come0764432011-07-22 22:08:52 +0000771{
772 return JSValue::encode(resolveBase(exec, *propertyName, exec->scopeChain(), false));
773}
774
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000775EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Identifier* propertyName)
barraclough@apple.come0764432011-07-22 22:08:52 +0000776{
777 JSValue base = resolveBase(exec, *propertyName, exec->scopeChain(), true);
778 if (!base)
779 throwError(exec, createErrorForInvalidGlobalAssignment(exec, propertyName->ustring()));
780 return JSValue::encode(base);
781}
782
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000783EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, GlobalResolveInfo* resolveInfo, Identifier* propertyName)
barraclough@apple.com014d4be2011-09-23 18:52:19 +0000784{
785 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
786
787 PropertySlot slot(globalObject);
788 if (globalObject->getPropertySlot(exec, *propertyName, slot)) {
789 JSValue result = slot.getValue(exec, *propertyName);
790
791 if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
792 resolveInfo->structure.set(exec->globalData(), exec->codeBlock()->ownerExecutable(), globalObject->structure());
793 resolveInfo->offset = slot.cachedOffset();
794 }
795
796 return JSValue::encode(result);
797 }
798
799 return throwVMError(exec, createUndefinedVariableError(exec, *propertyName));
800}
801
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000802EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
fpizlo@apple.com90e5f0e2011-09-22 22:42:54 +0000803{
804 return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
805}
806
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000807EncodedJSValue DFG_OPERATION operationStrCat(ExecState* exec, void* start, size_t size)
fpizlo@apple.com90e5f0e2011-09-22 22:42:54 +0000808{
809 return JSValue::encode(jsString(exec, static_cast<Register*>(start), size));
810}
811
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000812EncodedJSValue DFG_OPERATION operationNewArray(ExecState* exec, void* start, size_t size)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000813{
814 ArgList argList(static_cast<Register*>(start), size);
815 return JSValue::encode(constructArray(exec, argList));
816}
817
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000818EncodedJSValue DFG_OPERATION operationNewArrayBuffer(ExecState* exec, size_t start, size_t size)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000819{
820 ArgList argList(exec->codeBlock()->constantBuffer(start), size);
821 return JSValue::encode(constructArray(exec, argList));
822}
823
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000824EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000825{
826 RegExp* regexp = static_cast<RegExp*>(regexpPtr);
827 if (!regexp->isValid()) {
828 throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
829 return JSValue::encode(jsUndefined());
830 }
831
barraclough@apple.com5922d252011-09-28 19:53:09 +0000832 return JSValue::encode(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000833}
834
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000835void DFG_OPERATION operationThrowHasInstanceError(ExecState* exec, EncodedJSValue encodedBase)
barraclough@apple.com691cb222011-07-02 23:08:23 +0000836{
837 JSValue base = JSValue::decode(encodedBase);
838
barraclough@apple.com691cb222011-07-02 23:08:23 +0000839 // We should only call this function if base is not an object, or if it does not implement 'HasInstance'.
barraclough@apple.come0764432011-07-22 22:08:52 +0000840 ASSERT(!base.isObject() || !asObject(base)->structure()->typeInfo().implementsHasInstance());
barraclough@apple.com691cb222011-07-02 23:08:23 +0000841
842 throwError(exec, createInvalidParamError(exec, "instanceof", base));
843}
844
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000845DFGHandler DFG_OPERATION lookupExceptionHandler(ExecState* exec, ReturnAddressPtr faultLocation)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000846{
847 JSValue exceptionValue = exec->exception();
848 ASSERT(exceptionValue);
849
850 unsigned vPCIndex = exec->codeBlock()->bytecodeOffset(faultLocation);
851 HandlerInfo* handler = exec->globalData().interpreter->throwException(exec, exceptionValue, vPCIndex);
852
853 void* catchRoutine = handler ? handler->nativeCode.executableAddress() : (void*)ctiOpThrowNotCaught;
854 ASSERT(catchRoutine);
855 return DFGHandler(exec, catchRoutine);
856}
857
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000858double DFG_OPERATION dfgConvertJSValueToNumber(ExecState* exec, EncodedJSValue value)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000859{
860 return JSValue::decode(value).toNumber(exec);
861}
862
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000863int32_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000864{
865 return JSValue::decode(value).toInt32(exec);
866}
867
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000868RegisterSizedBoolean DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000869{
870 return JSValue::decode(encodedOp).toBoolean(exec);
871}
872
fpizlo@apple.com6d314862011-09-12 03:42:39 +0000873#if ENABLE(DFG_VERBOSE_SPECULATION_FAILURE)
barraclough@apple.com52e88de2011-09-29 01:36:00 +0000874void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState*, void* debugInfoRaw)
fpizlo@apple.com746c6d072011-09-07 02:47:51 +0000875{
876 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
fpizlo@apple.comf2bf0dd2011-09-26 04:05:28 +0000877 CodeBlock* codeBlock = debugInfo->codeBlock;
878 printf("Speculation failure in %p at 0x%x with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, success/fail %u/%u\n", codeBlock, debugInfo->debugOffset, codeBlock->alternative()->executeCounter(), codeBlock->alternative()->reoptimizationRetryCounter(), codeBlock->alternative()->optimizationDelayCounter(), codeBlock->speculativeSuccessCounter(), codeBlock->speculativeFailCounter());
fpizlo@apple.com746c6d072011-09-07 02:47:51 +0000879}
880#endif
881
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000882} // extern "C"
barraclough@apple.com2302c042011-03-14 23:31:00 +0000883} } // namespace JSC::DFG
884
885#endif