blob: b28929c5020a115d23d88fefa2e7db5c5e7df817 [file] [log] [blame]
barraclough@apple.com2302c042011-03-14 23:31:00 +00001/*
keith_miller@apple.com3793b132016-01-11 21:31:04 +00002 * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
barraclough@apple.com2302c042011-03-14 23:31:00 +00003 *
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
keith_miller@apple.com5bed6f62016-06-16 06:01:47 +000029#include "ArrayConstructor.h"
mark.lam@apple.coma4fe7ab2012-11-09 03:03:44 +000030#include "ButterflyInlines.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000031#include "ClonedArguments.h"
barraclough@apple.com2302c042011-03-14 23:31:00 +000032#include "CodeBlock.h"
oliver@apple.comb3e5acb2013-07-25 04:02:53 +000033#include "CommonSlowPaths.h"
mark.lam@apple.coma4fe7ab2012-11-09 03:03:44 +000034#include "CopiedSpaceInlines.h"
fpizlo@apple.com532f1e52013-09-04 06:26:04 +000035#include "DFGDriver.h"
fpizlo@apple.comb426f862014-02-10 02:51:13 +000036#include "DFGJITCode.h"
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000037#include "DFGOSRExit.h"
fpizlo@apple.com5e135772012-07-12 00:12:03 +000038#include "DFGThunks.h"
fpizlo@apple.com532f1e52013-09-04 06:26:04 +000039#include "DFGToFTLDeferredCompilationCallback.h"
40#include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
41#include "DFGWorklist.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000042#include "DirectArguments.h"
fpizlo@apple.com532f1e52013-09-04 06:26:04 +000043#include "FTLForOSREntryJITCode.h"
44#include "FTLOSREntry.h"
fpizlo@apple.comdc03dc52012-01-17 00:53:40 +000045#include "GetterSetter.h"
utatane.tea@gmail.comc2585192016-08-25 22:55:10 +000046#include "HostCallReturnValue.h"
barraclough@apple.com2302c042011-03-14 23:31:00 +000047#include "Interpreter.h"
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +000048#include "JIT.h"
oliver@apple.comc55314a2012-05-30 19:45:20 +000049#include "JITExceptions.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000050#include "JSCInlines.h"
keith_miller@apple.com1ec869c2016-06-21 17:54:33 +000051#include "JSGenericTypedArrayViewConstructorInlines.h"
oliver@apple.coma7dfb4d2014-09-11 18:18:14 +000052#include "JSLexicalEnvironment.h"
sbarati@apple.com21fc86e2016-09-06 23:22:01 +000053#include "JSMap.h"
54#include "JSSet.h"
ggaren@apple.comc862eac2013-01-29 05:48:01 +000055#include "ObjectConstructor.h"
mark.lam@apple.com9df8b832013-09-26 20:27:14 +000056#include "Repatch.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000057#include "ScopedArguments.h"
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +000058#include "StringConstructor.h"
fpizlo@apple.com5e29b762016-03-18 00:53:24 +000059#include "SuperSampler.h"
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +000060#include "Symbol.h"
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +000061#include "TypeProfilerLog.h"
fpizlo@apple.com372fa822013-08-21 19:43:47 +000062#include "TypedArrayInlines.h"
fpizlo@apple.com4a528d02016-05-11 00:08:50 +000063#include "VMInlines.h"
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +000064#include <wtf/InlineASM.h>
barraclough@apple.com2302c042011-03-14 23:31:00 +000065
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +000066#if ENABLE(JIT)
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +000067#if ENABLE(DFG_JIT)
68
barraclough@apple.com2302c042011-03-14 23:31:00 +000069namespace JSC { namespace DFG {
70
oliver@apple.come050d642013-10-19 00:09:28 +000071template<bool strict, bool direct>
weinig@apple.coma96509f2011-06-15 21:57:17 +000072static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000073{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000074 VM& vm = exec->vm();
75 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +000076 ASSERT(isIndex(index));
oliver@apple.come050d642013-10-19 00:09:28 +000077 if (direct) {
78 RELEASE_ASSERT(baseValue.isObject());
79 asObject(baseValue)->putDirectIndex(exec, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
80 return;
81 }
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +000082 if (baseValue.isObject()) {
83 JSObject* object = asObject(baseValue);
84 if (object->canSetIndexQuickly(index)) {
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000085 object->setIndexQuickly(vm, index, value);
weinig@apple.coma96509f2011-06-15 21:57:17 +000086 return;
87 }
88
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +000089 object->methodTable(vm)->putByIndex(object, exec, index, value, strict);
weinig@apple.coma96509f2011-06-15 21:57:17 +000090 return;
91 }
92
barraclough@apple.coma4d51f22012-03-06 01:18:42 +000093 baseValue.putByIndex(exec, index, value, strict);
weinig@apple.coma96509f2011-06-15 21:57:17 +000094}
95
oliver@apple.come050d642013-10-19 00:09:28 +000096template<bool strict, bool direct>
mark.lam@apple.com9df8b832013-09-26 20:27:14 +000097ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
weinig@apple.coma96509f2011-06-15 21:57:17 +000098{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000099 VM* vm = &exec->vm();
mark.lam@apple.com451de992016-09-07 22:10:50 +0000100 auto scope = DECLARE_THROW_SCOPE(*vm);
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000101 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000102
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000103 JSValue baseValue = JSValue::decode(encodedBase);
104 JSValue property = JSValue::decode(encodedProperty);
105 JSValue value = JSValue::decode(encodedValue);
106
107 if (LIKELY(property.isUInt32())) {
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000108 // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
109 ASSERT(isIndex(property.asUInt32()));
commit-queue@webkit.orge3549c62015-01-22 19:34:34 +0000110 putByVal<strict, direct>(exec, baseValue, property.asUInt32(), value);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000111 return;
112 }
113
weinig@apple.coma96509f2011-06-15 21:57:17 +0000114 if (property.isDouble()) {
115 double propertyAsDouble = property.asDouble();
116 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000117 if (propertyAsDouble == propertyAsUInt32 && isIndex(propertyAsUInt32)) {
oliver@apple.come050d642013-10-19 00:09:28 +0000118 putByVal<strict, direct>(exec, baseValue, propertyAsUInt32, value);
weinig@apple.coma96509f2011-06-15 21:57:17 +0000119 return;
120 }
121 }
122
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000123 // Don't put to an object if toString throws an exception.
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000124 auto propertyName = property.toPropertyKey(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000125 if (UNLIKELY(scope.exception()))
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000126 return;
127
128 PutPropertySlot slot(baseValue, strict);
129 if (direct) {
130 RELEASE_ASSERT(baseValue.isObject());
131 if (Optional<uint32_t> index = parseIndex(propertyName))
132 asObject(baseValue)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
133 else
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +0000134 asObject(baseValue)->putDirect(*vm, propertyName, value, slot);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000135 } else
136 baseValue.put(exec, propertyName, value, slot);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000137}
138
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000139template<typename ViewClass>
fpizlo@apple.com30a72582016-09-08 16:47:34 +0000140char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000141{
142 VM& vm = exec->vm();
143 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000144 auto scope = DECLARE_THROW_SCOPE(vm);
145
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000146 if (size < 0) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000147 throwException(exec, scope, createRangeError(exec, ASCIILiteral("Requested length is negative")));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000148 return 0;
149 }
fpizlo@apple.com30a72582016-09-08 16:47:34 +0000150
151 if (vector)
152 return bitwise_cast<char*>(ViewClass::createWithFastVector(exec, structure, size, vector));
153
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000154 return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
155}
156
sbarati@apple.com23315d62016-05-09 20:17:23 +0000157template <bool strict>
158static ALWAYS_INLINE void putWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, const Identifier& ident)
159{
160 JSValue baseValue = JSValue::decode(encodedBase);
161 JSValue thisVal = JSValue::decode(encodedThis);
162 JSValue putValue = JSValue::decode(encodedValue);
163 PutPropertySlot slot(thisVal, strict);
164 baseValue.putInline(exec, ident, putValue, slot);
165}
166
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000167extern "C" {
168
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000169EncodedJSValue JIT_OPERATION operationToThis(ExecState* exec, EncodedJSValue encodedOp)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000170{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000171 VM* vm = &exec->vm();
172 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000173
fpizlo@apple.com018818d2013-09-13 23:18:19 +0000174 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, NotStrictMode));
175}
176
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000177EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState* exec, EncodedJSValue encodedOp)
fpizlo@apple.com018818d2013-09-13 23:18:19 +0000178{
179 VM* vm = &exec->vm();
180 NativeCallFrameTracer tracer(vm, exec);
181
182 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, StrictMode));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000183}
184
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000185JSCell* JIT_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
fpizlo@apple.combb159ec2011-09-21 22:17:06 +0000186{
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000187 VM& vm = exec->vm();
188 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000189 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.come5315aa2016-02-20 23:51:33 +0000190 if (constructor->type() == JSFunctionType)
191 return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->rareData(exec, inlineCapacity)->objectAllocationProfile()->structure());
barraclough@apple.comcef11dc2012-05-10 18:40:29 +0000192
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +0000193 JSValue proto = constructor->get(exec, exec->propertyNames().prototype);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000194 if (UNLIKELY(scope.exception()))
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +0000195 return nullptr;
196 if (proto.isObject())
197 return constructEmptyObject(exec, asObject(proto));
sbarati@apple.come5315aa2016-02-20 23:51:33 +0000198 return constructEmptyObject(exec);
fpizlo@apple.com133c9ac2011-11-08 00:37:33 +0000199}
200
keith_miller@apple.com5bed6f62016-06-16 06:01:47 +0000201JSCell* JIT_OPERATION operationObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget)
202{
203 VM* vm = &exec->vm();
204 NativeCallFrameTracer tracer(vm, exec);
205
206 JSValue value = JSValue::decode(encodedTarget);
207 ASSERT(!value.isObject());
208
209 if (value.isUndefinedOrNull())
210 return constructEmptyObject(exec, globalObject->objectPrototype());
211 return value.toObject(exec, globalObject);
212}
213
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000214EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
215{
216 VM* vm = &exec->vm();
217 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000218 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000219
220 JSValue op1 = JSValue::decode(encodedOp1);
221 JSValue op2 = JSValue::decode(encodedOp2);
222
223 int32_t a = op1.toInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000224 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000225 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000226 int32_t b = op2.toInt32(exec);
227 return JSValue::encode(jsNumber(a & b));
228}
229
230EncodedJSValue JIT_OPERATION operationValueBitOr(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
231{
232 VM* vm = &exec->vm();
233 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000234 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000235
236 JSValue op1 = JSValue::decode(encodedOp1);
237 JSValue op2 = JSValue::decode(encodedOp2);
238
239 int32_t a = op1.toInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000240 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000241 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000242 int32_t b = op2.toInt32(exec);
243 return JSValue::encode(jsNumber(a | b));
244}
245
246EncodedJSValue JIT_OPERATION operationValueBitXor(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
247{
248 VM* vm = &exec->vm();
249 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000250 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000251
252 JSValue op1 = JSValue::decode(encodedOp1);
253 JSValue op2 = JSValue::decode(encodedOp2);
254
255 int32_t a = op1.toInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000256 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000257 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000258 int32_t b = op2.toInt32(exec);
259 return JSValue::encode(jsNumber(a ^ b));
260}
261
262EncodedJSValue JIT_OPERATION operationValueBitLShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
263{
264 VM* vm = &exec->vm();
265 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000266 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000267
268 JSValue op1 = JSValue::decode(encodedOp1);
269 JSValue op2 = JSValue::decode(encodedOp2);
270
271 int32_t a = op1.toInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000272 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000273 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000274 uint32_t b = op2.toUInt32(exec);
275 return JSValue::encode(jsNumber(a << (b & 0x1f)));
276}
277
278EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
279{
280 VM* vm = &exec->vm();
281 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000282 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000283
284 JSValue op1 = JSValue::decode(encodedOp1);
285 JSValue op2 = JSValue::decode(encodedOp2);
286
287 int32_t a = op1.toInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000288 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000289 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000290 uint32_t b = op2.toUInt32(exec);
291 return JSValue::encode(jsNumber(a >> (b & 0x1f)));
292}
293
294EncodedJSValue JIT_OPERATION operationValueBitURShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
295{
296 VM* vm = &exec->vm();
297 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000298 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000299
300 JSValue op1 = JSValue::decode(encodedOp1);
301 JSValue op2 = JSValue::decode(encodedOp2);
302
303 uint32_t a = op1.toUInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000304 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000305 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000306 uint32_t b = op2.toUInt32(exec);
307 return JSValue::encode(jsNumber(static_cast<int32_t>(a >> (b & 0x1f))));
308}
309
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000310EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000311{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000312 VM* vm = &exec->vm();
313 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000314
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000315 JSValue op1 = JSValue::decode(encodedOp1);
316 JSValue op2 = JSValue::decode(encodedOp2);
317
fpizlo@apple.com5df0cd82011-08-19 00:18:49 +0000318 ASSERT(!op1.isNumber() || !op2.isNumber());
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000319
ggaren@apple.com64be5e92012-01-24 07:34:10 +0000320 if (op1.isString() && !op2.isObject())
321 return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000322
323 return JSValue::encode(jsAddSlowCase(exec, op1, op2));
324}
325
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000326EncodedJSValue JIT_OPERATION operationValueDiv(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
327{
328 VM* vm = &exec->vm();
329 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000330 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000331
332 JSValue op1 = JSValue::decode(encodedOp1);
333 JSValue op2 = JSValue::decode(encodedOp2);
334
335 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000336 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000337 return JSValue::encode(JSValue());
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000338 double b = op2.toNumber(exec);
339 return JSValue::encode(jsNumber(a / b));
340}
341
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000342double JIT_OPERATION operationArithAbs(ExecState* exec, EncodedJSValue encodedOp1)
343{
344 VM* vm = &exec->vm();
345 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000346 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000347
348 JSValue op1 = JSValue::decode(encodedOp1);
349 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000350 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000351 return PNaN;
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000352 return fabs(a);
353}
354
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000355int32_t JIT_OPERATION operationArithClz32(ExecState* exec, EncodedJSValue encodedOp1)
356{
357 VM* vm = &exec->vm();
358 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000359 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000360
361 JSValue op1 = JSValue::decode(encodedOp1);
362 uint32_t value = op1.toUInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000363 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000364 return 0;
365 return clz32(value);
366}
367
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000368double JIT_OPERATION operationArithCos(ExecState* exec, EncodedJSValue encodedOp1)
369{
370 VM* vm = &exec->vm();
371 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000372 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000373
374 JSValue op1 = JSValue::decode(encodedOp1);
375 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000376 if (UNLIKELY(scope.exception()))
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000377 return JSValue::encode(JSValue());
378 return cos(a);
379}
380
benjamin@webkit.org87238e92016-08-25 01:21:43 +0000381double JIT_OPERATION operationArithFRound(ExecState* exec, EncodedJSValue encodedOp1)
382{
383 VM* vm = &exec->vm();
384 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000385 auto scope = DECLARE_THROW_SCOPE(*vm);
benjamin@webkit.org87238e92016-08-25 01:21:43 +0000386
387 JSValue op1 = JSValue::decode(encodedOp1);
388 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000389 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000390 return PNaN;
benjamin@webkit.org87238e92016-08-25 01:21:43 +0000391 return static_cast<float>(a);
392}
393
benjamin@webkit.org770c27f2016-08-24 02:36:40 +0000394double JIT_OPERATION operationArithLog(ExecState* exec, EncodedJSValue encodedOp1)
395{
396 VM* vm = &exec->vm();
397 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000398 auto scope = DECLARE_THROW_SCOPE(*vm);
benjamin@webkit.org770c27f2016-08-24 02:36:40 +0000399
400 JSValue op1 = JSValue::decode(encodedOp1);
401 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000402 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000403 return PNaN;
benjamin@webkit.org770c27f2016-08-24 02:36:40 +0000404 return log(a);
405}
406
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000407double JIT_OPERATION operationArithSin(ExecState* exec, EncodedJSValue encodedOp1)
408{
409 VM* vm = &exec->vm();
410 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000411 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000412
413 JSValue op1 = JSValue::decode(encodedOp1);
414 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000415 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000416 return PNaN;
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000417 return sin(a);
418}
419
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000420double JIT_OPERATION operationArithSqrt(ExecState* exec, EncodedJSValue encodedOp1)
421{
422 VM* vm = &exec->vm();
423 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000424 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000425
426 JSValue op1 = JSValue::decode(encodedOp1);
427 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000428 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000429 return PNaN;
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000430 return sqrt(a);
431}
432
akling@apple.com6d3d1812014-04-26 06:00:43 +0000433static ALWAYS_INLINE EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
weinig@apple.coma96509f2011-06-15 21:57:17 +0000434{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000435 VM& vm = exec->vm();
436 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000437
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +0000438 if (base->isObject()) {
439 JSObject* object = asObject(base);
440 if (object->canGetIndexQuickly(index))
441 return JSValue::encode(object->getIndexQuickly(index));
442 }
weinig@apple.coma96509f2011-06-15 21:57:17 +0000443
mhahnenberg@apple.comc58d54d2011-12-16 19:06:44 +0000444 if (isJSString(base) && asString(base)->canGetIndex(index))
weinig@apple.coma96509f2011-06-15 21:57:17 +0000445 return JSValue::encode(asString(base)->getIndex(exec, index));
446
weinig@apple.coma96509f2011-06-15 21:57:17 +0000447 return JSValue::encode(JSValue(base).get(exec, index));
448}
449
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000450EncodedJSValue JIT_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000451{
akling@apple.comb6d91ab2014-02-09 21:33:17 +0000452 VM& vm = exec->vm();
453 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000454 auto scope = DECLARE_THROW_SCOPE(vm);
455
barraclough@apple.com2302c042011-03-14 23:31:00 +0000456 JSValue baseValue = JSValue::decode(encodedBase);
457 JSValue property = JSValue::decode(encodedProperty);
458
459 if (LIKELY(baseValue.isCell())) {
460 JSCell* base = baseValue.asCell();
461
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000462 if (property.isUInt32()) {
weinig@apple.coma96509f2011-06-15 21:57:17 +0000463 return getByVal(exec, base, property.asUInt32());
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000464 } else if (property.isDouble()) {
weinig@apple.coma96509f2011-06-15 21:57:17 +0000465 double propertyAsDouble = property.asDouble();
466 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000467 if (propertyAsUInt32 == propertyAsDouble && isIndex(propertyAsUInt32))
weinig@apple.coma96509f2011-06-15 21:57:17 +0000468 return getByVal(exec, base, propertyAsUInt32);
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000469 } else if (property.isString()) {
akling@apple.combaca5e82014-05-06 00:53:29 +0000470 Structure& structure = *base->structure(vm);
471 if (JSCell::canUseFastGetOwnProperty(structure)) {
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000472 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
473 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
akling@apple.comcad89042014-09-02 22:29:59 +0000474 return JSValue::encode(result);
475 }
akling@apple.combaca5e82014-05-06 00:53:29 +0000476 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000477 }
barraclough@apple.com2302c042011-03-14 23:31:00 +0000478 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000479
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000480 baseValue.requireObjectCoercible(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000481 if (UNLIKELY(scope.exception()))
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000482 return JSValue::encode(jsUndefined());
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000483 auto propertyName = property.toPropertyKey(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000484 if (UNLIKELY(scope.exception()))
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000485 return JSValue::encode(jsUndefined());
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +0000486 return JSValue::encode(baseValue.get(exec, propertyName));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000487}
488
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000489EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000490{
akling@apple.comb6d91ab2014-02-09 21:33:17 +0000491 VM& vm = exec->vm();
492 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000493 auto scope = DECLARE_THROW_SCOPE(vm);
494
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000495 JSValue property = JSValue::decode(encodedProperty);
496
497 if (property.isUInt32())
498 return getByVal(exec, base, property.asUInt32());
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000499 if (property.isDouble()) {
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000500 double propertyAsDouble = property.asDouble();
501 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
502 if (propertyAsUInt32 == propertyAsDouble)
503 return getByVal(exec, base, propertyAsUInt32);
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000504 } else if (property.isString()) {
akling@apple.combaca5e82014-05-06 00:53:29 +0000505 Structure& structure = *base->structure(vm);
506 if (JSCell::canUseFastGetOwnProperty(structure)) {
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000507 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
508 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
akling@apple.comcad89042014-09-02 22:29:59 +0000509 return JSValue::encode(result);
510 }
akling@apple.combaca5e82014-05-06 00:53:29 +0000511 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000512 }
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000513
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000514 auto propertyName = property.toPropertyKey(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000515 if (UNLIKELY(scope.exception()))
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000516 return JSValue::encode(jsUndefined());
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +0000517 return JSValue::encode(JSValue(base).get(exec, propertyName));
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000518}
519
oliver@apple.com211b3be2013-07-25 04:03:39 +0000520ALWAYS_INLINE EncodedJSValue getByValCellInt(ExecState* exec, JSCell* base, int32_t index)
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000521{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000522 VM* vm = &exec->vm();
523 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000524
525 if (index < 0) {
526 // Go the slowest way possible becase negative indices don't use indexed storage.
527 return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
528 }
529
530 // Use this since we know that the value is out of bounds.
sbarati@apple.com575aa2b2016-03-04 02:25:30 +0000531 return JSValue::encode(JSValue(base).get(exec, static_cast<unsigned>(index)));
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000532}
533
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000534EncodedJSValue JIT_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
oliver@apple.com211b3be2013-07-25 04:03:39 +0000535{
536 return getByValCellInt(exec, base, index);
537}
538
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000539EncodedJSValue JIT_OPERATION operationGetByValStringInt(ExecState* exec, JSString* base, int32_t index)
oliver@apple.com211b3be2013-07-25 04:03:39 +0000540{
541 return getByValCellInt(exec, base, index);
542}
543
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000544void JIT_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000545{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000546 VM* vm = &exec->vm();
547 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000548
oliver@apple.come050d642013-10-19 00:09:28 +0000549 operationPutByValInternal<true, false>(exec, encodedBase, encodedProperty, encodedValue);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000550}
551
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000552void JIT_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000553{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000554 VM* vm = &exec->vm();
555 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000556
oliver@apple.come050d642013-10-19 00:09:28 +0000557 operationPutByValInternal<false, false>(exec, encodedBase, encodedProperty, encodedValue);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000558}
559
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000560void JIT_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000561{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000562 VM* vm = &exec->vm();
563 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000564
oliver@apple.come050d642013-10-19 00:09:28 +0000565 operationPutByValInternal<true, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000566}
567
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000568void JIT_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000569{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000570 VM* vm = &exec->vm();
571 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000572
oliver@apple.come050d642013-10-19 00:09:28 +0000573 operationPutByValInternal<false, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000574}
575
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000576void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
barraclough@apple.come2130ff2011-06-07 23:03:32 +0000577{
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000578 VM& vm = exec->vm();
579 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000580
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000581 if (index >= 0) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000582 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000583 return;
584 }
585
oliver@apple.com68848412014-01-02 20:56:20 +0000586 PutPropertySlot slot(array, true);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000587 array->methodTable()->put(
588 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000589}
590
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000591void JIT_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000592{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000593 VM* vm = &exec->vm();
594 NativeCallFrameTracer tracer(vm, exec);
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000595
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000596 if (index >= 0) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000597 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000598 return;
599 }
600
oliver@apple.com68848412014-01-02 20:56:20 +0000601 PutPropertySlot slot(array, false);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000602 array->methodTable()->put(
603 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
barraclough@apple.come2130ff2011-06-07 23:03:32 +0000604}
605
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000606void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000607{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000608 VM* vm = &exec->vm();
609 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000610
611 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
612
613 if (index >= 0) {
614 array->putByIndexInline(exec, index, jsValue, true);
615 return;
616 }
617
oliver@apple.com68848412014-01-02 20:56:20 +0000618 PutPropertySlot slot(array, true);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000619 array->methodTable()->put(
620 array, exec, Identifier::from(exec, index), jsValue, slot);
621}
622
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000623void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000624{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000625 VM* vm = &exec->vm();
626 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000627
628 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
629
630 if (index >= 0) {
631 array->putByIndexInline(exec, index, jsValue, false);
632 return;
633 }
634
oliver@apple.com68848412014-01-02 20:56:20 +0000635 PutPropertySlot slot(array, false);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000636 array->methodTable()->put(
637 array, exec, Identifier::from(exec, index), jsValue, slot);
638}
639
oliver@apple.come050d642013-10-19 00:09:28 +0000640void JIT_OPERATION operationPutByValDirectStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
641{
642 VM* vm = &exec->vm();
643 NativeCallFrameTracer tracer(vm, exec);
644
645 operationPutByValInternal<true, true>(exec, encodedBase, encodedProperty, encodedValue);
646}
647
648void JIT_OPERATION operationPutByValDirectNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
649{
650 VM* vm = &exec->vm();
651 NativeCallFrameTracer tracer(vm, exec);
652
653 operationPutByValInternal<false, true>(exec, encodedBase, encodedProperty, encodedValue);
654}
655
656void JIT_OPERATION operationPutByValDirectCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
657{
658 VM* vm = &exec->vm();
659 NativeCallFrameTracer tracer(vm, exec);
660
661 operationPutByValInternal<true, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
662}
663
664void JIT_OPERATION operationPutByValDirectCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
665{
666 VM* vm = &exec->vm();
667 NativeCallFrameTracer tracer(vm, exec);
668
669 operationPutByValInternal<false, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
670}
671
672void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
673{
674 VM* vm = &exec->vm();
675 NativeCallFrameTracer tracer(vm, exec);
676 if (index >= 0) {
677 array->putDirectIndex(exec, index, JSValue::decode(encodedValue), 0, PutDirectIndexShouldThrow);
678 return;
679 }
680
oliver@apple.com68848412014-01-02 20:56:20 +0000681 PutPropertySlot slot(array, true);
oliver@apple.come050d642013-10-19 00:09:28 +0000682 array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
683}
684
685void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
686{
687 VM* vm = &exec->vm();
688 NativeCallFrameTracer tracer(vm, exec);
689
690 if (index >= 0) {
691 array->putDirectIndex(exec, index, JSValue::decode(encodedValue));
692 return;
693 }
694
oliver@apple.com68848412014-01-02 20:56:20 +0000695 PutPropertySlot slot(array, false);
oliver@apple.come050d642013-10-19 00:09:28 +0000696 array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
697}
698
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000699EncodedJSValue JIT_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
fpizlo@apple.com24d24e52011-10-04 02:55:54 +0000700{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000701 VM* vm = &exec->vm();
702 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000703
fpizlo@apple.com24d24e52011-10-04 02:55:54 +0000704 array->push(exec, JSValue::decode(encodedValue));
705 return JSValue::encode(jsNumber(array->length()));
706}
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000707
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000708EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000709{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000710 VM* vm = &exec->vm();
711 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000712
713 array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
714 return JSValue::encode(jsNumber(array->length()));
715}
716
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000717EncodedJSValue JIT_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000718{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000719 VM* vm = &exec->vm();
720 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000721
722 return JSValue::encode(array->pop(exec));
723}
724
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000725EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000726{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000727 VM* vm = &exec->vm();
728 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000729
730 array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
731
732 return JSValue::encode(array->pop(exec));
733}
734
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000735EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* argument)
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000736{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000737 SuperSamplerScope superSamplerScope(false);
738
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000739 VM& vm = globalObject->vm();
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000740 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000741
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +0000742 return JSValue::encode(regExpObject->execInline(exec, globalObject, argument));
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000743}
744
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000745EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000746{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000747 SuperSamplerScope superSamplerScope(false);
748
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000749 VM& vm = globalObject->vm();
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000750 NativeCallFrameTracer tracer(&vm, exec);
751
752 JSValue argument = JSValue::decode(encodedArgument);
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000753
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000754 JSString* input = argument.toStringOrNull(exec);
755 if (!input)
756 return JSValue::encode(jsUndefined());
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +0000757 return JSValue::encode(regExpObject->execInline(exec, globalObject, input));
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000758}
759
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000760EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000761{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000762 SuperSamplerScope superSamplerScope(false);
763
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000764 VM& vm = globalObject->vm();
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000765 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000766 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000767
768 JSValue base = JSValue::decode(encodedBase);
769 JSValue argument = JSValue::decode(encodedArgument);
770
771 if (!base.inherits(RegExpObject::info()))
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000772 return throwVMTypeError(exec, scope);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000773
774 JSString* input = argument.toStringOrNull(exec);
775 if (!input)
776 return JSValue::encode(jsUndefined());
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000777 return JSValue::encode(asRegExpObject(base)->exec(exec, globalObject, input));
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000778}
779
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000780size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* input)
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000781{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000782 SuperSamplerScope superSamplerScope(false);
783
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000784 VM& vm = globalObject->vm();
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000785 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000786
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +0000787 return regExpObject->testInline(exec, globalObject, input);
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000788}
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000789
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000790size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000791{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000792 SuperSamplerScope superSamplerScope(false);
793
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000794 VM& vm = globalObject->vm();
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000795 NativeCallFrameTracer tracer(&vm, exec);
796
797 JSValue argument = JSValue::decode(encodedArgument);
798
799 JSString* input = argument.toStringOrNull(exec);
800 if (!input)
801 return false;
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +0000802 return regExpObject->testInline(exec, globalObject, input);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000803}
804
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000805size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000806{
fpizlo@apple.com57aea1c2016-04-11 18:20:59 +0000807 SuperSamplerScope superSamplerScope(false);
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000808
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000809 VM& vm = globalObject->vm();
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000810 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000811 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000812
813 JSValue base = JSValue::decode(encodedBase);
814 JSValue argument = JSValue::decode(encodedArgument);
815
816 if (!base.inherits(RegExpObject::info())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000817 throwTypeError(exec, scope);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000818 return false;
819 }
820
821 JSString* input = argument.toStringOrNull(exec);
822 if (!input)
823 return false;
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000824 return asRegExpObject(base)->test(exec, globalObject, input);
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000825}
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000826
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000827size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
commit-queue@webkit.org6efa2ca2011-07-19 00:36:37 +0000828{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000829 VM* vm = &exec->vm();
830 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000831
commit-queue@webkit.org6efa2ca2011-07-19 00:36:37 +0000832 JSValue op1 = JSValue::decode(encodedOp1);
833 JSValue op2 = JSValue::decode(encodedOp2);
834
835 ASSERT(op1.isCell());
836 ASSERT(op2.isCell());
837
838 return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
839}
840
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000841size_t JIT_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000842{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000843 VM* vm = &exec->vm();
844 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com82acbbf2012-02-28 00:37:58 +0000845
846 JSValue src1 = JSValue::decode(encodedOp1);
847 JSValue src2 = JSValue::decode(encodedOp2);
oliver@apple.come07a4592012-01-25 19:43:06 +0000848
fpizlo@apple.com82acbbf2012-02-28 00:37:58 +0000849 return JSValue::strictEqual(exec, src1, src2);
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000850}
851
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000852EncodedJSValue JIT_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
fpizlo@apple.com90e5f0e2011-09-22 22:42:54 +0000853{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000854 VM* vm = &exec->vm();
855 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000856
fpizlo@apple.com90e5f0e2011-09-22 22:42:54 +0000857 return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
858}
859
utatane.tea@gmail.comdb32c542016-06-30 15:26:47 +0000860EncodedJSValue JIT_OPERATION operationToNumber(ExecState* exec, EncodedJSValue value)
861{
862 VM* vm = &exec->vm();
863 NativeCallFrameTracer tracer(vm, exec);
864
865 return JSValue::encode(jsNumber(JSValue::decode(value).toNumber(exec)));
866}
867
sbarati@apple.com23315d62016-05-09 20:17:23 +0000868EncodedJSValue JIT_OPERATION operationGetByIdWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, UniquedStringImpl* impl)
869{
870 VM& vm = exec->vm();
871 NativeCallFrameTracer tracer(&vm, exec);
872
873 JSValue baseValue = JSValue::decode(encodedBase);
874 JSValue thisVal = JSValue::decode(encodedThis);
875 PropertySlot slot(thisVal, PropertySlot::PropertySlot::InternalMethodType::Get);
876 JSValue result = baseValue.get(exec, Identifier::fromUid(exec, impl), slot);
877 return JSValue::encode(result);
878}
879
880EncodedJSValue JIT_OPERATION operationGetByValWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript)
881{
882 VM& vm = exec->vm();
883 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000884 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.com23315d62016-05-09 20:17:23 +0000885
886 JSValue baseValue = JSValue::decode(encodedBase);
887 JSValue thisVal = JSValue::decode(encodedThis);
888 JSValue subscript = JSValue::decode(encodedSubscript);
889
890 if (LIKELY(baseValue.isCell() && subscript.isString())) {
891 Structure& structure = *baseValue.asCell()->structure(vm);
892 if (JSCell::canUseFastGetOwnProperty(structure)) {
893 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
894 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
895 return JSValue::encode(result);
896 }
897 }
898 }
899
900 PropertySlot slot(thisVal, PropertySlot::PropertySlot::InternalMethodType::Get);
901 if (subscript.isUInt32()) {
902 uint32_t i = subscript.asUInt32();
903 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
904 return JSValue::encode(asString(baseValue)->getIndex(exec, i));
905
906 return JSValue::encode(baseValue.get(exec, i, slot));
907 }
908
909 baseValue.requireObjectCoercible(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000910 if (UNLIKELY(scope.exception()))
sbarati@apple.com23315d62016-05-09 20:17:23 +0000911 return JSValue::encode(JSValue());
912
913 auto property = subscript.toPropertyKey(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000914 if (UNLIKELY(scope.exception()))
sbarati@apple.com23315d62016-05-09 20:17:23 +0000915 return JSValue::encode(JSValue());
916 return JSValue::encode(baseValue.get(exec, property, slot));
917}
918
919void JIT_OPERATION operationPutByIdWithThisStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, UniquedStringImpl* impl)
920{
921 VM& vm = exec->vm();
922 NativeCallFrameTracer tracer(&vm, exec);
923
924 putWithThis<true>(exec, encodedBase, encodedThis, encodedValue, Identifier::fromUid(exec, impl));
925}
926
927void JIT_OPERATION operationPutByIdWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, UniquedStringImpl* impl)
928{
929 VM& vm = exec->vm();
930 NativeCallFrameTracer tracer(&vm, exec);
931
932 putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, Identifier::fromUid(exec, impl));
933}
934
935void JIT_OPERATION operationPutByValWithThisStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
936{
937 VM& vm = exec->vm();
938 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000939 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.com23315d62016-05-09 20:17:23 +0000940
941 Identifier property = JSValue::decode(encodedSubscript).toPropertyKey(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000942 if (UNLIKELY(scope.exception()))
sbarati@apple.com23315d62016-05-09 20:17:23 +0000943 return;
944 putWithThis<true>(exec, encodedBase, encodedThis, encodedValue, property);
945}
946
947void JIT_OPERATION operationPutByValWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
948{
949 VM& vm = exec->vm();
950 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000951 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.com23315d62016-05-09 20:17:23 +0000952
953 Identifier property = JSValue::decode(encodedSubscript).toPropertyKey(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000954 if (UNLIKELY(scope.exception()))
sbarati@apple.com23315d62016-05-09 20:17:23 +0000955 return;
956 putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, property);
957}
958
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000959char* JIT_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000960{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000961 VM* vm = &exec->vm();
962 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com1bc68482012-10-13 03:56:09 +0000963
fpizlo@apple.com59d1ddb2013-11-05 00:05:02 +0000964 return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000965}
966
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000967char* JIT_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000968{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000969 VM* vm = &exec->vm();
970 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com1bc68482012-10-13 03:56:09 +0000971
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000972 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000973}
974
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +0000975char* JIT_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size, Butterfly* butterfly)
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000976{
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +0000977 VM& vm = exec->vm();
978 NativeCallFrameTracer tracer(&vm, exec);
979 auto scope = DECLARE_THROW_SCOPE(vm);
msaboff@apple.com51d65f22013-04-10 20:01:14 +0000980
msaboff@apple.com6ebf3b82013-04-11 16:19:35 +0000981 if (UNLIKELY(size < 0))
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000982 return bitwise_cast<char*>(throwException(exec, scope, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
msaboff@apple.com51d65f22013-04-10 20:01:14 +0000983
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +0000984 JSArray* result;
985 if (butterfly)
986 result = JSArray::createWithButterfly(vm, arrayStructure, butterfly);
987 else
988 result = JSArray::create(vm, arrayStructure, size);
fpizlo@apple.com8dde06b2015-10-12 22:41:01 +0000989 return bitwise_cast<char*>(result);
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000990}
991
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000992char* JIT_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000993{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000994 VM& vm = exec->vm();
995 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com59d1ddb2013-11-05 00:05:02 +0000996 return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000997}
998
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000999char* JIT_OPERATION operationNewInt8ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001000 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001001{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001002 return newTypedArrayWithSize<JSInt8Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001003}
1004
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001005char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001006 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1007{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001008 VM& vm = exec->vm();
1009 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001010 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt8Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001011}
1012
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001013char* JIT_OPERATION operationNewInt16ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001014 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001015{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001016 return newTypedArrayWithSize<JSInt16Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001017}
1018
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001019char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001020 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1021{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001022 VM& vm = exec->vm();
1023 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001024 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt16Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001025}
1026
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001027char* JIT_OPERATION operationNewInt32ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001028 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001029{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001030 return newTypedArrayWithSize<JSInt32Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001031}
1032
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001033char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001034 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1035{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001036 VM& vm = exec->vm();
1037 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001038 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt32Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001039}
1040
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001041char* JIT_OPERATION operationNewUint8ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001042 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001043{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001044 return newTypedArrayWithSize<JSUint8Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001045}
1046
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001047char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001048 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1049{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001050 VM& vm = exec->vm();
1051 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001052 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001053}
1054
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001055char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001056 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001057{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001058 return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001059}
1060
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001061char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001062 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1063{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001064 VM& vm = exec->vm();
1065 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001066 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8ClampedArray>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001067}
1068
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001069char* JIT_OPERATION operationNewUint16ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001070 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001071{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001072 return newTypedArrayWithSize<JSUint16Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001073}
1074
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001075char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001076 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1077{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001078 VM& vm = exec->vm();
1079 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001080 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint16Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001081}
1082
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001083char* JIT_OPERATION operationNewUint32ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001084 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001085{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001086 return newTypedArrayWithSize<JSUint32Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001087}
1088
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001089char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001090 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1091{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001092 VM& vm = exec->vm();
1093 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001094 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint32Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001095}
1096
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001097char* JIT_OPERATION operationNewFloat32ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001098 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001099{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001100 return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001101}
1102
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001103char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001104 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1105{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001106 VM& vm = exec->vm();
1107 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001108 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat32Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001109}
1110
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001111char* JIT_OPERATION operationNewFloat64ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001112 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001113{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001114 return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001115}
1116
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001117char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001118 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1119{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001120 VM& vm = exec->vm();
1121 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001122 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat64Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001123}
1124
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00001125JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState* exec, Structure* structure, JSScope* scope, SymbolTable* table, EncodedJSValue initialValueEncoded)
fpizlo@apple.comc6446112012-05-23 20:52:42 +00001126{
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00001127 JSValue initialValue = JSValue::decode(initialValueEncoded);
1128 ASSERT(initialValue == jsUndefined() || initialValue == jsTDZValue());
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001129 VM& vm = exec->vm();
1130 NativeCallFrameTracer tracer(&vm, exec);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00001131 return JSLexicalEnvironment::create(vm, structure, scope, table, initialValue);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001132}
1133
1134JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState* exec, Structure* structure, int32_t length, int32_t minCapacity)
1135{
1136 VM& vm = exec->vm();
1137 NativeCallFrameTracer target(&vm, exec);
1138 DirectArguments* result = DirectArguments::create(
1139 vm, structure, length, std::max(length, minCapacity));
1140 // The caller will store to this object without barriers. Most likely, at this point, this is
1141 // still a young object and so no barriers are needed. But it's good to be careful anyway,
1142 // since the GC should be allowed to do crazy (like pretenuring, for example).
1143 vm.heap.writeBarrier(result);
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001144 return result;
fpizlo@apple.comc6446112012-05-23 20:52:42 +00001145}
1146
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001147JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment* scope)
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001148{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001149 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001150 NativeCallFrameTracer target(&vm, exec);
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001151
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001152 // We could pass the ScopedArgumentsTable* as an argument. We currently don't because I
1153 // didn't feel like changing the max number of arguments for a slow path call from 6 to 7.
1154 ScopedArgumentsTable* table = scope->symbolTable()->arguments();
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001155
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001156 return ScopedArguments::createByCopyingFrom(
1157 vm, structure, argumentStart, length, callee, table, scope);
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001158}
1159
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001160JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee)
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001161{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001162 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001163 NativeCallFrameTracer target(&vm, exec);
1164 return ClonedArguments::createByCopyingFrom(
1165 exec, structure, argumentStart, length, callee);
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001166}
1167
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001168JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001169{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001170 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001171 NativeCallFrameTracer target(&vm, exec);
1172
1173 DeferGCForAWhile deferGC(vm.heap);
1174
1175 CodeBlock* codeBlock;
1176 if (inlineCallFrame)
1177 codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
1178 else
1179 codeBlock = exec->codeBlock();
1180
1181 unsigned length = argumentCount - 1;
1182 unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
1183 DirectArguments* result = DirectArguments::create(
1184 vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
1185
1186 result->callee().set(vm, result, callee);
1187
1188 Register* arguments =
1189 exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
1190 CallFrame::argumentOffset(0);
1191 for (unsigned i = length; i--;)
1192 result->setIndexQuickly(vm, i, arguments[i].jsValue());
1193
1194 return result;
1195}
1196
1197JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
1198{
1199 VM& vm = exec->vm();
1200 NativeCallFrameTracer target(&vm, exec);
1201
1202 DeferGCForAWhile deferGC(vm.heap);
1203
1204 CodeBlock* codeBlock;
1205 if (inlineCallFrame)
1206 codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
1207 else
1208 codeBlock = exec->codeBlock();
1209
1210 unsigned length = argumentCount - 1;
1211 ClonedArguments* result = ClonedArguments::createEmpty(
keith_miller@apple.com26367392016-03-14 20:55:15 +00001212 vm, codeBlock->globalObject()->clonedArgumentsStructure(), callee, length);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001213
1214 Register* arguments =
1215 exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
1216 CallFrame::argumentOffset(0);
1217 for (unsigned i = length; i--;)
keith_miller@apple.com26367392016-03-14 20:55:15 +00001218 result->initializeIndex(vm, i, arguments[i].jsValue());
1219
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001220
1221 return result;
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001222}
1223
sbarati@apple.com6cfefd82016-08-13 02:14:42 +00001224JSCell* JIT_OPERATION operationCreateRest(ExecState* exec, Register* argumentStart, unsigned numberOfParamsToSkip, unsigned arraySize)
sbarati@apple.comc0722da2015-11-20 02:37:47 +00001225{
keith_miller@apple.com1b8b0062016-04-16 01:26:10 +00001226 VM* vm = &exec->vm();
1227 NativeCallFrameTracer tracer(vm, exec);
1228
sbarati@apple.com6cfefd82016-08-13 02:14:42 +00001229 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
1230 Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
1231 static_assert(sizeof(Register) == sizeof(JSValue), "This is a strong assumption here.");
1232 JSValue* argumentsToCopyRegion = bitwise_cast<JSValue*>(argumentStart) + numberOfParamsToSkip;
1233 return constructArray(exec, structure, argumentsToCopyRegion, arraySize);
sbarati@apple.comc0722da2015-11-20 02:37:47 +00001234}
1235
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001236size_t JIT_OPERATION operationObjectIsObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
oliver@apple.come722ad02013-01-09 02:37:29 +00001237{
mark.lam@apple.com87a5b6f2014-02-05 04:22:43 +00001238 VM& vm = exec->vm();
1239 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001240
1241 ASSERT(jsDynamicCast<JSObject*>(object));
1242
1243 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1244 return false;
1245 if (object->type() == JSFunctionType)
1246 return false;
1247 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1248 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001249 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001250 return false;
1251 }
1252
1253 return true;
1254}
1255
1256size_t JIT_OPERATION operationObjectIsFunction(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1257{
1258 VM& vm = exec->vm();
1259 NativeCallFrameTracer tracer(&vm, exec);
1260
1261 ASSERT(jsDynamicCast<JSObject*>(object));
1262
1263 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1264 return false;
1265 if (object->type() == JSFunctionType)
1266 return true;
1267 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1268 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001269 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001270 return true;
1271 }
1272
1273 return false;
1274}
1275
1276JSCell* JIT_OPERATION operationTypeOfObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1277{
1278 VM& vm = exec->vm();
1279 NativeCallFrameTracer tracer(&vm, exec);
1280
1281 ASSERT(jsDynamicCast<JSObject*>(object));
1282
1283 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1284 return vm.smallStrings.undefinedString();
1285 if (object->type() == JSFunctionType)
1286 return vm.smallStrings.functionString();
1287 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1288 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001289 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001290 return vm.smallStrings.functionString();
1291 }
1292
1293 return vm.smallStrings.objectString();
1294}
1295
1296int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1297{
1298 VM& vm = exec->vm();
1299 NativeCallFrameTracer tracer(&vm, exec);
1300
1301 ASSERT(jsDynamicCast<JSObject*>(object));
1302
1303 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1304 return static_cast<int32_t>(TypeofType::Undefined);
1305 if (object->type() == JSFunctionType)
1306 return static_cast<int32_t>(TypeofType::Function);
1307 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1308 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001309 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001310 return static_cast<int32_t>(TypeofType::Function);
1311 }
1312
1313 return static_cast<int32_t>(TypeofType::Object);
oliver@apple.come722ad02013-01-09 02:37:29 +00001314}
1315
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001316char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001317{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001318 VM& vm = exec->vm();
1319 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comc17054c2012-09-18 15:22:29 +00001320
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001321 return reinterpret_cast<char*>(
oliver@apple.coma03796a2013-07-25 04:01:20 +00001322 Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001323}
1324
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001325char* JIT_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001326{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001327 VM& vm = exec->vm();
1328 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comc17054c2012-09-18 15:22:29 +00001329
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001330 return reinterpret_cast<char*>(
oliver@apple.coma03796a2013-07-25 04:01:20 +00001331 Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001332}
1333
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001334char* JIT_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001335{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001336 VM& vm = exec->vm();
1337 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001338
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001339 if (!cell->isObject())
1340 return 0;
1341
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001342 return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001343}
1344
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001345char* JIT_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001346{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001347 VM& vm = exec->vm();
1348 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001349
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001350 if (!cell->isObject())
1351 return 0;
1352
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001353 return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001354}
1355
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001356char* JIT_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001357{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001358 VM& vm = exec->vm();
1359 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001360
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001361 if (!cell->isObject())
1362 return 0;
1363
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001364 return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001365}
1366
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001367char* JIT_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001368{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001369 VM& vm = exec->vm();
1370 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001371
1372 if (!cell->isObject())
1373 return 0;
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001374
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001375 return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001376}
1377
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001378StringImpl* JIT_OPERATION operationResolveRope(ExecState* exec, JSString* string)
fpizlo@apple.com70bb5c52012-12-11 05:22:49 +00001379{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001380 VM& vm = exec->vm();
1381 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com70bb5c52012-12-11 05:22:49 +00001382
1383 return string->value(exec).impl();
1384}
1385
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001386JSString* JIT_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
oliver@apple.com63af2d42013-07-25 04:03:33 +00001387{
1388 VM& vm = exec->vm();
1389 NativeCallFrameTracer tracer(&vm, exec);
1390
1391 return jsSingleCharacterString(exec, static_cast<UChar>(character));
1392}
1393
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001394JSCell* JIT_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001395{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001396 VM& vm = exec->vm();
1397 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001398
akling@apple.com019809c2013-10-06 18:16:48 +00001399 return StringObject::create(vm, structure, string);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001400}
1401
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001402JSCell* JIT_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001403{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001404 VM& vm = exec->vm();
1405 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001406
1407 return JSValue(cell).toString(exec);
1408}
1409
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001410JSCell* JIT_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001411{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001412 VM& vm = exec->vm();
1413 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001414
1415 return JSValue::decode(value).toString(exec);
1416}
1417
utatane.tea@gmail.com153559e2015-04-06 19:07:12 +00001418JSCell* JIT_OPERATION operationCallStringConstructorOnCell(ExecState* exec, JSCell* cell)
1419{
1420 VM& vm = exec->vm();
1421 NativeCallFrameTracer tracer(&vm, exec);
1422
1423 return stringConstructor(exec, cell);
1424}
1425
1426JSCell* JIT_OPERATION operationCallStringConstructor(ExecState* exec, EncodedJSValue value)
1427{
1428 VM& vm = exec->vm();
1429 NativeCallFrameTracer tracer(&vm, exec);
1430
1431 return stringConstructor(exec, JSValue::decode(value));
1432}
1433
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001434JSCell* JIT_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001435{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001436 VM& vm = exec->vm();
1437 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001438 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com24c49992014-04-19 21:13:46 +00001439
1440 if (sumOverflows<int32_t>(left->length(), right->length())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001441 throwOutOfMemoryError(exec, scope);
fpizlo@apple.come28731c2014-04-19 20:36:58 +00001442 return nullptr;
fpizlo@apple.com75104a32014-04-15 23:33:11 +00001443 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001444
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001445 return JSRopeString::create(vm, left, right);
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001446}
1447
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001448JSCell* JIT_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001449{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001450 VM& vm = exec->vm();
1451 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001452 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001453
fpizlo@apple.com24c49992014-04-19 21:13:46 +00001454 if (sumOverflows<int32_t>(a->length(), b->length(), c->length())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001455 throwOutOfMemoryError(exec, scope);
fpizlo@apple.come28731c2014-04-19 20:36:58 +00001456 return nullptr;
fpizlo@apple.com75104a32014-04-15 23:33:11 +00001457 }
1458
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001459 return JSRopeString::create(vm, a, b, c);
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001460}
1461
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001462JSCell* JIT_OPERATION operationStrCat2(ExecState* exec, EncodedJSValue a, EncodedJSValue b)
1463{
1464 VM& vm = exec->vm();
1465 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001466 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001467
1468 JSString* str1 = JSValue::decode(a).toString(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001469 ASSERT(!scope.exception()); // Impossible, since we must have been given primitives.
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001470 JSString* str2 = JSValue::decode(b).toString(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001471 ASSERT(!scope.exception());
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001472
1473 if (sumOverflows<int32_t>(str1->length(), str2->length())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001474 throwOutOfMemoryError(exec, scope);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001475 return nullptr;
1476 }
1477
1478 return JSRopeString::create(vm, str1, str2);
1479}
1480
1481JSCell* JIT_OPERATION operationStrCat3(ExecState* exec, EncodedJSValue a, EncodedJSValue b, EncodedJSValue c)
1482{
1483 VM& vm = exec->vm();
1484 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001485 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001486
1487 JSString* str1 = JSValue::decode(a).toString(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001488 ASSERT(!scope.exception()); // Impossible, since we must have been given primitives.
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001489 JSString* str2 = JSValue::decode(b).toString(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001490 ASSERT(!scope.exception());
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001491 JSString* str3 = JSValue::decode(c).toString(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001492 ASSERT(!scope.exception());
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001493
1494 if (sumOverflows<int32_t>(str1->length(), str2->length(), str3->length())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001495 throwOutOfMemoryError(exec, scope);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001496 return nullptr;
1497 }
1498
1499 return JSRopeString::create(vm, str1, str2, str3);
1500}
1501
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001502char* JIT_OPERATION operationFindSwitchImmTargetForDouble(
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001503 ExecState* exec, EncodedJSValue encodedValue, size_t tableIndex)
1504{
keith_miller@apple.com1b8b0062016-04-16 01:26:10 +00001505 VM& vm = exec->vm();
1506 NativeCallFrameTracer tracer(&vm, exec);
1507
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001508 CodeBlock* codeBlock = exec->codeBlock();
oliver@apple.coma14cea52013-07-25 04:03:23 +00001509 SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001510 JSValue value = JSValue::decode(encodedValue);
1511 ASSERT(value.isDouble());
1512 double asDouble = value.asDouble();
1513 int32_t asInt32 = static_cast<int32_t>(asDouble);
1514 if (asDouble == asInt32)
1515 return static_cast<char*>(table.ctiForValue(asInt32).executableAddress());
1516 return static_cast<char*>(table.ctiDefault.executableAddress());
1517}
1518
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001519char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JSString* string)
oliver@apple.com5c826c02013-07-25 04:03:51 +00001520{
1521 VM& vm = exec->vm();
1522 NativeCallFrameTracer tracer(&vm, exec);
1523
1524 return static_cast<char*>(exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress());
1525}
1526
fpizlo@apple.com5a3036b2015-04-29 03:34:43 +00001527int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)
1528{
1529 VM& vm = exec->vm();
1530 NativeCallFrameTracer tracer(&vm, exec);
1531
1532 return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(string->value(exec).impl(), std::numeric_limits<int32_t>::min());
1533}
1534
commit-queue@webkit.org36c52882016-04-22 05:08:28 +00001535uintptr_t JIT_OPERATION operationCompareStringImplLess(StringImpl* a, StringImpl* b)
1536{
1537 return codePointCompare(a, b) < 0;
1538}
1539
1540uintptr_t JIT_OPERATION operationCompareStringImplLessEq(StringImpl* a, StringImpl* b)
1541{
1542 return codePointCompare(a, b) <= 0;
1543}
1544
1545uintptr_t JIT_OPERATION operationCompareStringImplGreater(StringImpl* a, StringImpl* b)
1546{
1547 return codePointCompare(a, b) > 0;
1548}
1549
1550uintptr_t JIT_OPERATION operationCompareStringImplGreaterEq(StringImpl* a, StringImpl* b)
1551{
1552 return codePointCompare(a, b) >= 0;
1553}
1554
1555uintptr_t JIT_OPERATION operationCompareStringLess(ExecState* exec, JSString* a, JSString* b)
1556{
1557 VM& vm = exec->vm();
1558 NativeCallFrameTracer tracer(&vm, exec);
1559
1560 return codePointCompareLessThan(asString(a)->value(exec), asString(b)->value(exec));
1561}
1562
1563uintptr_t JIT_OPERATION operationCompareStringLessEq(ExecState* exec, JSString* a, JSString* b)
1564{
1565 VM& vm = exec->vm();
1566 NativeCallFrameTracer tracer(&vm, exec);
1567
1568 return !codePointCompareLessThan(asString(b)->value(exec), asString(a)->value(exec));
1569}
1570
1571uintptr_t JIT_OPERATION operationCompareStringGreater(ExecState* exec, JSString* a, JSString* b)
1572{
1573 VM& vm = exec->vm();
1574 NativeCallFrameTracer tracer(&vm, exec);
1575
1576 return codePointCompareLessThan(asString(b)->value(exec), asString(a)->value(exec));
1577}
1578
1579uintptr_t JIT_OPERATION operationCompareStringGreaterEq(ExecState* exec, JSString* a, JSString* b)
1580{
1581 VM& vm = exec->vm();
1582 NativeCallFrameTracer tracer(&vm, exec);
1583
1584 return !codePointCompareLessThan(asString(a)->value(exec), asString(b)->value(exec));
1585}
1586
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +00001587void JIT_OPERATION operationNotifyWrite(ExecState* exec, WatchpointSet* set)
fpizlo@apple.com33961712013-11-20 05:49:05 +00001588{
1589 VM& vm = exec->vm();
1590 NativeCallFrameTracer tracer(&vm, exec);
1591
sbarati@apple.com0c3609d2016-06-28 21:30:20 +00001592 set->touch(vm, "Executed NotifyWrite");
fpizlo@apple.com33961712013-11-20 05:49:05 +00001593}
1594
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001595void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
1596{
1597 VM& vm = exec->vm();
1598 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001599 auto scope = DECLARE_THROW_SCOPE(vm);
1600 throwStackOverflowError(exec, scope);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001601}
1602
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001603int32_t JIT_OPERATION operationSizeOfVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
1604{
1605 VM& vm = exec->vm();
1606 NativeCallFrameTracer tracer(&vm, exec);
1607 JSValue arguments = JSValue::decode(encodedArguments);
1608
1609 return sizeOfVarargs(exec, arguments, firstVarArgOffset);
1610}
1611
1612void JIT_OPERATION operationLoadVarargs(ExecState* exec, int32_t firstElementDest, EncodedJSValue encodedArguments, int32_t offset, int32_t length, int32_t mandatoryMinimum)
1613{
1614 VM& vm = exec->vm();
1615 NativeCallFrameTracer tracer(&vm, exec);
1616 JSValue arguments = JSValue::decode(encodedArguments);
1617
1618 loadVarargs(exec, VirtualRegister(firstElementDest), arguments, offset, length);
1619
1620 for (int32_t i = length; i < mandatoryMinimum; ++i)
1621 exec->r(firstElementDest + i) = jsUndefined();
1622}
1623
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001624double JIT_OPERATION operationFModOnInts(int32_t a, int32_t b)
fpizlo@apple.com2c2536e2012-03-21 01:29:28 +00001625{
1626 return fmod(a, b);
1627}
1628
utatane.tea@gmail.comd2fca0a2015-12-15 03:51:42 +00001629#if USE(JSVALUE32_64)
1630double JIT_OPERATION operationRandom(JSGlobalObject* globalObject)
1631{
1632 return globalObject->weakRandomNumber();
1633}
1634#endif
1635
mark.lam@apple.com03a3e382016-01-08 18:44:36 +00001636JSCell* JIT_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +00001637{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001638 VM* vm = &exec->vm();
1639 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com03a3e382016-01-08 18:44:36 +00001640 return JSC::stringFromCharCode(exec, op1);
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +00001641}
1642
mark.lam@apple.com151fe102016-01-13 23:28:38 +00001643EncodedJSValue JIT_OPERATION operationStringFromCharCodeUntyped(ExecState* exec, EncodedJSValue encodedValue)
1644{
1645 VM* vm = &exec->vm();
1646 NativeCallFrameTracer tracer(vm, exec);
1647 JSValue charValue = JSValue::decode(encodedValue);
1648 int32_t chInt = charValue.toUInt32(exec);
1649 return JSValue::encode(JSC::stringFromCharCode(exec, chInt));
1650}
1651
fpizlo@apple.comf2999932014-07-15 00:41:39 +00001652int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue encodedValue)
1653{
1654 JSValue value = JSValue::decode(encodedValue);
1655 if (!value.isDouble())
1656 return JSValue::notInt52;
1657 return tryConvertToInt52(value.asDouble());
1658}
1659
1660int64_t JIT_OPERATION operationConvertDoubleToInt52(double value)
1661{
1662 return tryConvertToInt52(value);
1663}
1664
sbarati@apple.comfa857522016-03-07 01:00:33 +00001665size_t JIT_OPERATION operationDefaultHasInstance(ExecState* exec, JSCell* value, JSCell* proto) // Returns jsBoolean(True|False) on 64-bit.
1666{
1667 VM* vm = &exec->vm();
1668 NativeCallFrameTracer tracer(vm, exec);
1669 if (JSObject::defaultHasInstance(exec, value, proto))
1670 return 1;
1671 return 0;
1672}
1673
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001674char* JIT_OPERATION operationNewRawObject(ExecState* exec, Structure* structure, int32_t length, Butterfly* butterfly)
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001675{
1676 VM& vm = exec->vm();
1677 NativeCallFrameTracer tracer(&vm, exec);
1678
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001679 if (!butterfly
1680 && (structure->outOfLineCapacity() || hasIndexedProperties(structure->indexingType()))) {
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001681 IndexingHeader header;
1682 header.setVectorLength(length);
1683 header.setPublicLength(0);
1684
1685 butterfly = Butterfly::create(
1686 vm, nullptr, 0, structure->outOfLineCapacity(),
1687 hasIndexedProperties(structure->indexingType()), header,
1688 length * sizeof(EncodedJSValue));
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001689 }
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001690
1691 JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
1692 result->butterfly(); // Ensure that the butterfly is in to-space.
1693 return bitwise_cast<char*>(result);
1694}
1695
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001696JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState* exec, Structure* structure, Butterfly* butterfly)
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001697{
1698 VM& vm = exec->vm();
1699 NativeCallFrameTracer tracer(&vm, exec);
1700
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001701 if (!butterfly) {
1702 butterfly = Butterfly::create(
1703 vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0);
1704 }
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001705
1706 JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
1707 result->butterfly(); // Ensure that the butterfly is in to-space.
1708 return result;
1709}
1710
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001711JSCell* JIT_OPERATION operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength(ExecState* exec, Structure* structure, unsigned length, Butterfly* butterfly)
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001712{
1713 VM& vm = exec->vm();
1714 NativeCallFrameTracer tracer(&vm, exec);
1715
1716 IndexingHeader header;
1717 header.setVectorLength(length);
1718 header.setPublicLength(0);
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001719 if (butterfly)
1720 *butterfly->indexingHeader() = header;
1721 else {
1722 butterfly = Butterfly::create(
1723 vm, nullptr, 0, structure->outOfLineCapacity(), true, header,
1724 sizeof(EncodedJSValue) * length);
1725 }
1726
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001727 // Paradoxically this may allocate a JSArray. That's totally cool.
1728 JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
1729 result->butterfly(); // Ensure that the butterfly is in to-space.
1730 return result;
1731}
1732
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001733void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState* exec)
1734{
sbarati@apple.comc6fb7552016-06-07 20:07:56 +00001735 VM& vm = exec->vm();
1736 NativeCallFrameTracer tracer(&vm, exec);
1737
1738 vm.typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside DFG."));
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001739}
1740
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001741void JIT_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001742{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001743 VM* vm = &exec->vm();
1744 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +00001745
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001746 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
fpizlo@apple.comf2bf0dd2011-09-26 04:05:28 +00001747 CodeBlock* codeBlock = debugInfo->codeBlock;
fpizlo@apple.com47d3b642011-10-05 21:36:23 +00001748 CodeBlock* alternative = codeBlock->alternative();
mark.lam@apple.come7ecf832014-04-02 20:49:27 +00001749 dataLog("Speculation failure in ", *codeBlock);
1750 dataLog(" @ exit #", vm->osrExitIndex, " (bc#", debugInfo->bytecodeOffset, ", ", exitKindToString(debugInfo->kind), ") with ");
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +00001751 if (alternative) {
1752 dataLog(
1753 "executeCounter = ", alternative->jitExecuteCounter(),
1754 ", reoptimizationRetryCounter = ", alternative->reoptimizationRetryCounter(),
1755 ", optimizationDelayCounter = ", alternative->optimizationDelayCounter());
1756 } else
1757 dataLog("no alternative code block (i.e. we've been jettisoned)");
1758 dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
fpizlo@apple.com03e446e2013-01-11 22:18:27 +00001759 dataLog(" GPRs at time of exit:");
1760 char* scratchPointer = static_cast<char*>(scratch);
1761 for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
1762 GPRReg gpr = GPRInfo::toRegister(i);
commit-queue@webkit.org94ea8122013-02-25 13:13:43 +00001763 dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
fpizlo@apple.com03e446e2013-01-11 22:18:27 +00001764 scratchPointer += sizeof(EncodedJSValue);
1765 }
1766 dataLog("\n");
1767 dataLog(" FPRs at time of exit:");
1768 for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
1769 FPRReg fpr = FPRInfo::toRegister(i);
1770 dataLog(" ", FPRInfo::debugName(fpr), ":");
commit-queue@webkit.org94ea8122013-02-25 13:13:43 +00001771 uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
1772 double value = *reinterpret_cast_ptr<double*>(scratchPointer);
ossy@webkit.org71aebd72013-01-12 09:33:01 +00001773 dataLogF("%llx:%lf", static_cast<long long>(bits), value);
fpizlo@apple.com03e446e2013-01-11 22:18:27 +00001774 scratchPointer += sizeof(EncodedJSValue);
1775 }
1776 dataLog("\n");
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001777}
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001778
sbarati@apple.come67fd782016-04-19 01:38:30 +00001779JSCell* JIT_OPERATION operationResolveScope(ExecState* exec, JSScope* scope, UniquedStringImpl* impl)
1780{
1781 VM& vm = exec->vm();
1782 NativeCallFrameTracer tracer(&vm, exec);
1783
1784 JSObject* resolvedScope = JSScope::resolve(exec, scope, Identifier::fromUid(exec, impl));
1785 return resolvedScope;
1786}
1787
1788EncodedJSValue JIT_OPERATION operationGetDynamicVar(ExecState* exec, JSObject* scope, UniquedStringImpl* impl, unsigned getPutInfoBits)
1789{
1790 VM& vm = exec->vm();
1791 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001792 auto throwScope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.come67fd782016-04-19 01:38:30 +00001793
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00001794 Identifier ident = Identifier::fromUid(exec, impl);
1795 return JSValue::encode(scope->getPropertySlot(exec, ident, [&] (bool found, PropertySlot& slot) -> JSValue {
1796 if (!found) {
1797 GetPutInfo getPutInfo(getPutInfoBits);
1798 if (getPutInfo.resolveMode() == ThrowIfNotFound)
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001799 throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00001800 return jsUndefined();
sbarati@apple.come67fd782016-04-19 01:38:30 +00001801 }
sbarati@apple.come67fd782016-04-19 01:38:30 +00001802
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00001803 if (scope->isGlobalLexicalEnvironment()) {
1804 // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
1805 JSValue result = slot.getValue(exec, ident);
1806 if (result == jsTDZValue()) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001807 throwException(exec, throwScope, createTDZError(exec));
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00001808 return jsUndefined();
1809 }
1810 return result;
1811 }
1812
1813 return slot.getValue(exec, ident);
1814 }));
sbarati@apple.come67fd782016-04-19 01:38:30 +00001815}
1816
1817void JIT_OPERATION operationPutDynamicVar(ExecState* exec, JSObject* scope, EncodedJSValue value, UniquedStringImpl* impl, unsigned getPutInfoBits)
1818{
1819 VM& vm = exec->vm();
1820 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001821 auto throwScope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.come67fd782016-04-19 01:38:30 +00001822
1823 const Identifier& ident = Identifier::fromUid(exec, impl);
1824 GetPutInfo getPutInfo(getPutInfoBits);
1825 bool hasProperty = scope->hasProperty(exec, ident);
1826 if (hasProperty
1827 && scope->isGlobalLexicalEnvironment()
1828 && !isInitialization(getPutInfo.initializationMode())) {
1829 // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
1830 PropertySlot slot(scope, PropertySlot::InternalMethodType::Get);
1831 JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot);
1832 if (slot.getValue(exec, ident) == jsTDZValue()) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001833 throwException(exec, throwScope, createTDZError(exec));
sbarati@apple.come67fd782016-04-19 01:38:30 +00001834 return;
1835 }
1836 }
1837
1838 if (getPutInfo.resolveMode() == ThrowIfNotFound && !hasProperty) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001839 throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
sbarati@apple.come67fd782016-04-19 01:38:30 +00001840 return;
1841 }
1842
1843 CodeOrigin origin = exec->codeOrigin();
1844 bool strictMode;
1845 if (origin.inlineCallFrame)
1846 strictMode = origin.inlineCallFrame->baselineCodeBlock->isStrictMode();
1847 else
1848 strictMode = exec->codeBlock()->isStrictMode();
1849 PutPropertySlot slot(scope, strictMode, PutPropertySlot::UnknownContext, isInitialization(getPutInfo.initializationMode()));
1850 scope->methodTable()->put(scope, exec, ident, JSValue::decode(value), slot);
1851}
1852
sbarati@apple.com21fc86e2016-09-06 23:22:01 +00001853int32_t JIT_OPERATION operationMapHash(ExecState* exec, EncodedJSValue input)
1854{
1855 VM& vm = exec->vm();
1856 NativeCallFrameTracer tracer(&vm, exec);
1857
1858 return jsMapHash(exec, vm, normalizeMapKey(JSValue::decode(input)));
1859}
1860
1861JSCell* JIT_OPERATION operationJSMapFindBucket(ExecState* exec, JSCell* map, EncodedJSValue key, int32_t hash)
1862{
1863 VM& vm = exec->vm();
1864 NativeCallFrameTracer tracer(&vm, exec);
1865 JSMap::BucketType** bucket = jsCast<JSMap*>(map)->findBucket(exec, normalizeMapKey(JSValue::decode(key)), hash);
1866 if (!bucket)
1867 return nullptr;
1868 return *bucket;
1869}
1870
1871JSCell* JIT_OPERATION operationJSSetFindBucket(ExecState* exec, JSCell* map, EncodedJSValue key, int32_t hash)
1872{
1873 VM& vm = exec->vm();
1874 NativeCallFrameTracer tracer(&vm, exec);
1875 JSSet::BucketType** bucket = jsCast<JSSet*>(map)->findBucket(exec, normalizeMapKey(JSValue::decode(key)), hash);
1876 if (!bucket)
1877 return nullptr;
1878 return *bucket;
1879}
1880
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001881extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001882{
fpizlo@apple.com98225492013-09-10 18:29:45 +00001883 // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
1884 // really be profitable.
1885 DeferGCForAWhile deferGC(codeBlock->vm()->heap);
1886
oliver@apple.com284cc3d2013-07-25 04:00:33 +00001887 if (Options::verboseOSR())
1888 dataLog(*codeBlock, ": Entered reoptimize\n");
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001889 // We must be called with the baseline code block.
oliver@apple.com5a24fdd2013-07-25 04:00:54 +00001890 ASSERT(JITCode::isBaselineCode(codeBlock->jitType()));
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001891
1892 // If I am my own replacement, then reoptimization has already been triggered.
1893 // This can happen in recursive functions.
oliver@apple.comd2a16382013-07-25 04:04:18 +00001894 if (codeBlock->replacement() == codeBlock) {
1895 if (Options::verboseOSR())
1896 dataLog(*codeBlock, ": Not reoptimizing because we've already been jettisoned.\n");
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001897 return;
oliver@apple.comd2a16382013-07-25 04:04:18 +00001898 }
1899
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001900 // Otherwise, the replacement must be optimized code. Use this as an opportunity
1901 // to check our logic.
1902 ASSERT(codeBlock->hasOptimizedReplacement());
oliver@apple.comd2a16382013-07-25 04:04:18 +00001903 CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1904 ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001905
1906 bool didTryToEnterIntoInlinedLoops = false;
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001907 for (InlineCallFrame* inlineCallFrame = exit->m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->directCaller.inlineCallFrame) {
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001908 if (inlineCallFrame->baselineCodeBlock->ownerScriptExecutable()->didTryToEnterInLoop()) {
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001909 didTryToEnterIntoInlinedLoops = true;
1910 break;
1911 }
1912 }
oliver@apple.comd2a16382013-07-25 04:04:18 +00001913
1914 // In order to trigger reoptimization, one of two things must have happened:
1915 // 1) We exited more than some number of times.
1916 // 2) We exited and got stuck in a loop, and now we're exiting again.
1917 bool didExitABunch = optimizedCodeBlock->shouldReoptimizeNow();
1918 bool didGetStuckInLoop =
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001919 (codeBlock->checkIfOptimizationThresholdReached() || didTryToEnterIntoInlinedLoops)
oliver@apple.comd2a16382013-07-25 04:04:18 +00001920 && optimizedCodeBlock->shouldReoptimizeFromLoopNow();
1921
1922 if (!didExitABunch && !didGetStuckInLoop) {
1923 if (Options::verboseOSR())
1924 dataLog(*codeBlock, ": Not reoptimizing ", *optimizedCodeBlock, " because it either didn't exit enough or didn't loop enough after exit.\n");
1925 codeBlock->optimizeAfterLongWarmUp();
1926 return;
1927 }
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001928
fpizlo@apple.com0dda6d72014-02-02 02:25:13 +00001929 optimizedCodeBlock->jettison(Profiler::JettisonDueToOSRExit, CountReoptimization);
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001930}
1931
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001932#if ENABLE(FTL_JIT)
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001933static bool shouldTriggerFTLCompile(CodeBlock* codeBlock, JITCode* jitCode)
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001934{
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001935 if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001936 CODEBLOCK_LOG_EVENT(codeBlock, "abortFTLCompile", ());
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001937 if (Options::verboseOSR())
1938 dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
1939 jitCode->dontOptimizeAnytimeSoon(codeBlock);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001940 return false;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001941 }
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001942
1943 if (!codeBlock->hasOptimizedReplacement()
1944 && !jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001945 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("counter = ", jitCode->tierUpCounter));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001946 if (Options::verboseOSR())
1947 dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001948 return false;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001949 }
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001950 return true;
1951}
1952
1953static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
1954{
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001955 Worklist::State worklistState;
msaboff@apple.com95894332014-01-29 19:18:54 +00001956 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001957 worklistState = worklist->completeAllReadyPlansForVM(
1958 *vm, CompilationKey(codeBlock->baselineVersion(), FTLMode));
1959 } else
1960 worklistState = Worklist::NotKnown;
1961
1962 if (worklistState == Worklist::Compiling) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001963 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001964 jitCode->setOptimizationThresholdBasedOnCompilationResult(
1965 codeBlock, CompilationDeferred);
1966 return;
1967 }
1968
1969 if (codeBlock->hasOptimizedReplacement()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001970 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("has replacement"));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001971 // That's great, we've compiled the code - next time we call this function,
1972 // we'll enter that replacement.
1973 jitCode->optimizeSoon(codeBlock);
1974 return;
1975 }
1976
1977 if (worklistState == Worklist::Compiled) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001978 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001979 // This means that we finished compiling, but failed somehow; in that case the
1980 // thresholds will be set appropriately.
1981 if (Options::verboseOSR())
1982 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1983 return;
1984 }
1985
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001986 CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLReplacement", ());
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001987 // We need to compile the code.
1988 compile(
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001989 *vm, codeBlock->newReplacement(), codeBlock, FTLMode, UINT_MAX,
1990 Operands<JSValue>(), ToFTLDeferredCompilationCallback::create());
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001991
1992 // If we reached here, the counter has not be reset. Do that now.
1993 jitCode->setOptimizationThresholdBasedOnCompilationResult(
1994 codeBlock, CompilationDeferred);
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001995}
1996
benjamin@webkit.org31527f52016-03-09 17:51:38 +00001997void JIT_OPERATION triggerTierUpNow(ExecState* exec)
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001998{
1999 VM* vm = &exec->vm();
2000 NativeCallFrameTracer tracer(vm, exec);
sbarati@apple.comefcb30a2016-06-23 23:28:50 +00002001 DeferGCForAWhile deferGC(vm->heap);
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002002 CodeBlock* codeBlock = exec->codeBlock();
2003
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +00002004 if (codeBlock->jitType() != JITCode::DFGJIT) {
2005 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2006 RELEASE_ASSERT_NOT_REACHED();
2007 }
2008
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002009 JITCode* jitCode = codeBlock->jitCode()->dfg();
2010
2011 if (Options::verboseOSR()) {
2012 dataLog(
2013 *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
2014 jitCode->tierUpCounter, "\n");
2015 }
benjamin@webkit.org8f625992015-05-18 20:45:34 +00002016
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002017 if (shouldTriggerFTLCompile(codeBlock, jitCode))
2018 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002019
2020 if (codeBlock->hasOptimizedReplacement()) {
2021 if (jitCode->tierUpEntryTriggers.isEmpty()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002022 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("replacement in place, delaying indefinitely"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002023 // There is nothing more we can do, the only way this will be entered
2024 // is through the function entry point.
2025 jitCode->dontOptimizeAnytimeSoon(codeBlock);
2026 return;
2027 }
2028 if (jitCode->osrEntryBlock() && jitCode->tierUpEntryTriggers.size() == 1) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002029 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("trigger in place, delaying indefinitely"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002030 // There is only one outer loop and its trigger must have been set
2031 // when the plan completed.
2032 // Exiting the inner loop is useless, we can ignore the counter and leave
2033 // the trigger do its job.
2034 jitCode->dontOptimizeAnytimeSoon(codeBlock);
2035 return;
2036 }
2037 }
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002038}
2039
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002040static char* tierUpCommon(ExecState* exec, unsigned originBytecodeIndex, unsigned osrEntryBytecodeIndex)
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002041{
2042 VM* vm = &exec->vm();
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002043 CodeBlock* codeBlock = exec->codeBlock();
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002044
2045 // Resolve any pending plan for OSR Enter on this function.
2046 Worklist::State worklistState;
2047 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
2048 worklistState = worklist->completeAllReadyPlansForVM(
2049 *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode));
2050 } else
2051 worklistState = Worklist::NotKnown;
2052
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002053 JITCode* jitCode = codeBlock->jitCode()->dfg();
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002054 if (worklistState == Worklist::Compiling) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002055 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002056 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2057 codeBlock, CompilationDeferred);
2058 return nullptr;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002059 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002060
2061 if (worklistState == Worklist::Compiled) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002062 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002063 // This means that compilation failed and we already set the thresholds.
2064 if (Options::verboseOSR())
2065 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
2066 return nullptr;
2067 }
2068
2069 // If we can OSR Enter, do it right away.
2070 if (originBytecodeIndex == osrEntryBytecodeIndex) {
2071 unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(originBytecodeIndex);
2072 if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002073 if (void* address = FTL::prepareOSREntry(exec, codeBlock, entryBlock, originBytecodeIndex, streamIndex)) {
2074 CODEBLOCK_LOG_EVENT(entryBlock, "osrEntry", ("at bc#", originBytecodeIndex));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002075 return static_cast<char*>(address);
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002076 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002077 }
2078 }
2079
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002080 // - If we don't have an FTL code block, then try to compile one.
2081 // - If we do have an FTL code block, then try to enter for a while.
2082 // - If we couldn't enter for a while, then trigger OSR entry.
msaboff@apple.com95894332014-01-29 19:18:54 +00002083
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002084 if (!shouldTriggerFTLCompile(codeBlock, jitCode))
2085 return nullptr;
2086
2087 if (!jitCode->neverExecutedEntry) {
2088 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2089
2090 if (!codeBlock->hasOptimizedReplacement())
2091 return nullptr;
fpizlo@apple.com239b0782016-03-03 05:58:59 +00002092
2093 if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002094 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding OSR entry compile"));
fpizlo@apple.com239b0782016-03-03 05:58:59 +00002095 jitCode->osrEntryRetry++;
2096 return nullptr;
2097 }
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002098 } else
2099 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding replacement compile"));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002100
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002101 // It's time to try to compile code for OSR entry.
2102 if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002103 if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002104 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed, OSR entry threshold not met"));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002105 jitCode->osrEntryRetry++;
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002106 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2107 codeBlock, CompilationDeferred);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002108 return nullptr;
2109 }
2110
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002111 FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
2112 entryCode->countEntryFailure();
2113 if (entryCode->entryFailureCount() <
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002114 Options::ftlOSREntryFailureCountForReoptimization()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002115 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002116 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2117 codeBlock, CompilationDeferred);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002118 return nullptr;
2119 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002120
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002121 // OSR entry failed. Oh no! This implies that we need to retry. We retry
2122 // without exponential backoff and we only do this for the entry code block.
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002123 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed too many times"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002124 unsigned osrEntryBytecode = entryBlock->jitCode()->ftlForOSREntry()->bytecodeIndex();
ggaren@apple.com81def5f2015-10-09 23:10:16 +00002125 jitCode->clearOSREntryBlock();
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002126 jitCode->osrEntryRetry = 0;
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002127 jitCode->tierUpEntryTriggers.set(osrEntryBytecode, 0);
2128 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2129 codeBlock, CompilationDeferred);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002130 return nullptr;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002131 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002132
2133 unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(osrEntryBytecodeIndex);
2134 auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(osrEntryBytecodeIndex);
2135 if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end()) {
2136 for (unsigned osrEntryCandidate : tierUpHierarchyEntry->value) {
2137 if (jitCode->tierUpEntrySeen.contains(osrEntryCandidate)) {
2138 osrEntryBytecodeIndex = osrEntryCandidate;
2139 streamIndex = jitCode->bytecodeIndexToStreamIndex.get(osrEntryBytecodeIndex);
2140 }
2141 }
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002142 }
2143
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002144 // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile
2145 // something.
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002146 auto triggerIterator = jitCode->tierUpEntryTriggers.find(osrEntryBytecodeIndex);
2147 RELEASE_ASSERT(triggerIterator != jitCode->tierUpEntryTriggers.end());
2148 uint8_t* triggerAddress = &(triggerIterator->value);
2149
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002150 Operands<JSValue> mustHandleValues;
2151 jitCode->reconstruct(
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002152 exec, codeBlock, CodeOrigin(osrEntryBytecodeIndex), streamIndex, mustHandleValues);
ggaren@apple.com81def5f2015-10-09 23:10:16 +00002153 CodeBlock* replacementCodeBlock = codeBlock->newReplacement();
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002154
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002155 CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLOSR", ());
msaboff@apple.com95894332014-01-29 19:18:54 +00002156 CompilationResult forEntryResult = compile(
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002157 *vm, replacementCodeBlock, codeBlock, FTLForOSREntryMode, osrEntryBytecodeIndex,
2158 mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(triggerAddress));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002159
2160 if (jitCode->neverExecutedEntry)
2161 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2162
2163 if (forEntryResult != CompilationSuccessful) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002164 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR ecompilation not successful"));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002165 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2166 codeBlock, CompilationDeferred);
2167 return nullptr;
2168 }
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002169
2170 CODEBLOCK_LOG_EVENT(jitCode->osrEntryBlock(), "osrEntry", ("at bc#", originBytecodeIndex));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002171 // It's possible that the for-entry compile already succeeded. In that case OSR
2172 // entry will succeed unless we ran out of stack. It's not clear what we should do.
2173 // We signal to try again after a while if that happens.
2174 void* address = FTL::prepareOSREntry(
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002175 exec, codeBlock, jitCode->osrEntryBlock(), originBytecodeIndex, streamIndex);
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002176 return static_cast<char*>(address);
2177}
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002178
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002179void JIT_OPERATION triggerTierUpNowInLoop(ExecState* exec, unsigned bytecodeIndex)
2180{
2181 VM* vm = &exec->vm();
2182 NativeCallFrameTracer tracer(vm, exec);
sbarati@apple.comefcb30a2016-06-23 23:28:50 +00002183 DeferGCForAWhile deferGC(vm->heap);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002184 CodeBlock* codeBlock = exec->codeBlock();
2185
2186 if (codeBlock->jitType() != JITCode::DFGJIT) {
2187 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2188 RELEASE_ASSERT_NOT_REACHED();
2189 }
2190
2191 JITCode* jitCode = codeBlock->jitCode()->dfg();
2192
2193 if (Options::verboseOSR()) {
2194 dataLog(
2195 *codeBlock, ": Entered triggerTierUpNowInLoop with executeCounter = ",
2196 jitCode->tierUpCounter, "\n");
2197 }
2198
2199 auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(bytecodeIndex);
2200 if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end()
2201 && !tierUpHierarchyEntry->value.isEmpty()) {
2202 tierUpCommon(exec, bytecodeIndex, tierUpHierarchyEntry->value.first());
2203 } else if (shouldTriggerFTLCompile(codeBlock, jitCode))
2204 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2205
2206 // Since we cannot OSR Enter here, the default "optimizeSoon()" is not useful.
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002207 if (codeBlock->hasOptimizedReplacement()) {
2208 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR in loop failed, deferring"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002209 jitCode->setOptimizationThresholdBasedOnCompilationResult(codeBlock, CompilationDeferred);
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002210 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002211}
2212
2213char* JIT_OPERATION triggerOSREntryNow(ExecState* exec, unsigned bytecodeIndex)
2214{
2215 VM* vm = &exec->vm();
2216 NativeCallFrameTracer tracer(vm, exec);
sbarati@apple.comefcb30a2016-06-23 23:28:50 +00002217 DeferGCForAWhile deferGC(vm->heap);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002218 CodeBlock* codeBlock = exec->codeBlock();
2219
2220 if (codeBlock->jitType() != JITCode::DFGJIT) {
2221 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2222 RELEASE_ASSERT_NOT_REACHED();
2223 }
2224
2225 JITCode* jitCode = codeBlock->jitCode()->dfg();
2226 jitCode->tierUpEntrySeen.add(bytecodeIndex);
2227
2228 if (Options::verboseOSR()) {
2229 dataLog(
2230 *codeBlock, ": Entered triggerOSREntryNow with executeCounter = ",
2231 jitCode->tierUpCounter, "\n");
2232 }
2233
2234 return tierUpCommon(exec, bytecodeIndex, bytecodeIndex);
2235}
2236
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002237#endif // ENABLE(FTL_JIT)
2238
barraclough@apple.comc7af2d32011-05-26 21:37:05 +00002239} // extern "C"
fpizlo@apple.com04659ba2012-02-21 09:49:22 +00002240} } // namespace JSC::DFG
2241
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +00002242#endif // ENABLE(DFG_JIT)
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +00002243
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +00002244#endif // ENABLE(JIT)