blob: 624090c29657cd0ca4de24e8cca06bdbdd760d3a [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>
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +0000140char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size)
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 }
150 return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
151}
152
sbarati@apple.com23315d62016-05-09 20:17:23 +0000153template <bool strict>
154static ALWAYS_INLINE void putWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, const Identifier& ident)
155{
156 JSValue baseValue = JSValue::decode(encodedBase);
157 JSValue thisVal = JSValue::decode(encodedThis);
158 JSValue putValue = JSValue::decode(encodedValue);
159 PutPropertySlot slot(thisVal, strict);
160 baseValue.putInline(exec, ident, putValue, slot);
161}
162
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000163extern "C" {
164
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000165EncodedJSValue JIT_OPERATION operationToThis(ExecState* exec, EncodedJSValue encodedOp)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000166{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000167 VM* vm = &exec->vm();
168 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000169
fpizlo@apple.com018818d2013-09-13 23:18:19 +0000170 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, NotStrictMode));
171}
172
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000173EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState* exec, EncodedJSValue encodedOp)
fpizlo@apple.com018818d2013-09-13 23:18:19 +0000174{
175 VM* vm = &exec->vm();
176 NativeCallFrameTracer tracer(vm, exec);
177
178 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, StrictMode));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000179}
180
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000181JSCell* JIT_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
fpizlo@apple.combb159ec2011-09-21 22:17:06 +0000182{
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000183 VM& vm = exec->vm();
184 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000185 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.come5315aa2016-02-20 23:51:33 +0000186 if (constructor->type() == JSFunctionType)
187 return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->rareData(exec, inlineCapacity)->objectAllocationProfile()->structure());
barraclough@apple.comcef11dc2012-05-10 18:40:29 +0000188
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +0000189 JSValue proto = constructor->get(exec, exec->propertyNames().prototype);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000190 if (UNLIKELY(scope.exception()))
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +0000191 return nullptr;
192 if (proto.isObject())
193 return constructEmptyObject(exec, asObject(proto));
sbarati@apple.come5315aa2016-02-20 23:51:33 +0000194 return constructEmptyObject(exec);
fpizlo@apple.com133c9ac2011-11-08 00:37:33 +0000195}
196
keith_miller@apple.com5bed6f62016-06-16 06:01:47 +0000197JSCell* JIT_OPERATION operationObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget)
198{
199 VM* vm = &exec->vm();
200 NativeCallFrameTracer tracer(vm, exec);
201
202 JSValue value = JSValue::decode(encodedTarget);
203 ASSERT(!value.isObject());
204
205 if (value.isUndefinedOrNull())
206 return constructEmptyObject(exec, globalObject->objectPrototype());
207 return value.toObject(exec, globalObject);
208}
209
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000210EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
211{
212 VM* vm = &exec->vm();
213 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000214 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000215
216 JSValue op1 = JSValue::decode(encodedOp1);
217 JSValue op2 = JSValue::decode(encodedOp2);
218
219 int32_t a = op1.toInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000220 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000221 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000222 int32_t b = op2.toInt32(exec);
223 return JSValue::encode(jsNumber(a & b));
224}
225
226EncodedJSValue JIT_OPERATION operationValueBitOr(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
227{
228 VM* vm = &exec->vm();
229 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000230 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000231
232 JSValue op1 = JSValue::decode(encodedOp1);
233 JSValue op2 = JSValue::decode(encodedOp2);
234
235 int32_t a = op1.toInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000236 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000237 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000238 int32_t b = op2.toInt32(exec);
239 return JSValue::encode(jsNumber(a | b));
240}
241
242EncodedJSValue JIT_OPERATION operationValueBitXor(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
243{
244 VM* vm = &exec->vm();
245 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000246 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000247
248 JSValue op1 = JSValue::decode(encodedOp1);
249 JSValue op2 = JSValue::decode(encodedOp2);
250
251 int32_t a = op1.toInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000252 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000253 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000254 int32_t b = op2.toInt32(exec);
255 return JSValue::encode(jsNumber(a ^ b));
256}
257
258EncodedJSValue JIT_OPERATION operationValueBitLShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
259{
260 VM* vm = &exec->vm();
261 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000262 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000263
264 JSValue op1 = JSValue::decode(encodedOp1);
265 JSValue op2 = JSValue::decode(encodedOp2);
266
267 int32_t a = op1.toInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000268 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000269 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000270 uint32_t b = op2.toUInt32(exec);
271 return JSValue::encode(jsNumber(a << (b & 0x1f)));
272}
273
274EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
275{
276 VM* vm = &exec->vm();
277 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000278 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000279
280 JSValue op1 = JSValue::decode(encodedOp1);
281 JSValue op2 = JSValue::decode(encodedOp2);
282
283 int32_t a = op1.toInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000284 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000285 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000286 uint32_t b = op2.toUInt32(exec);
287 return JSValue::encode(jsNumber(a >> (b & 0x1f)));
288}
289
290EncodedJSValue JIT_OPERATION operationValueBitURShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
291{
292 VM* vm = &exec->vm();
293 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000294 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000295
296 JSValue op1 = JSValue::decode(encodedOp1);
297 JSValue op2 = JSValue::decode(encodedOp2);
298
299 uint32_t a = op1.toUInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000300 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000301 return JSValue::encode(JSValue());
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000302 uint32_t b = op2.toUInt32(exec);
303 return JSValue::encode(jsNumber(static_cast<int32_t>(a >> (b & 0x1f))));
304}
305
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000306EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000307{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000308 VM* vm = &exec->vm();
309 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000310
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000311 JSValue op1 = JSValue::decode(encodedOp1);
312 JSValue op2 = JSValue::decode(encodedOp2);
313
fpizlo@apple.com5df0cd82011-08-19 00:18:49 +0000314 ASSERT(!op1.isNumber() || !op2.isNumber());
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000315
ggaren@apple.com64be5e92012-01-24 07:34:10 +0000316 if (op1.isString() && !op2.isObject())
317 return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000318
319 return JSValue::encode(jsAddSlowCase(exec, op1, op2));
320}
321
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000322EncodedJSValue JIT_OPERATION operationValueDiv(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
323{
324 VM* vm = &exec->vm();
325 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000326 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000327
328 JSValue op1 = JSValue::decode(encodedOp1);
329 JSValue op2 = JSValue::decode(encodedOp2);
330
331 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000332 if (UNLIKELY(scope.exception()))
sbarati@apple.combe40c4f2016-08-06 00:46:50 +0000333 return JSValue::encode(JSValue());
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000334 double b = op2.toNumber(exec);
335 return JSValue::encode(jsNumber(a / b));
336}
337
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000338double JIT_OPERATION operationArithAbs(ExecState* exec, EncodedJSValue encodedOp1)
339{
340 VM* vm = &exec->vm();
341 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000342 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000343
344 JSValue op1 = JSValue::decode(encodedOp1);
345 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000346 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000347 return PNaN;
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000348 return fabs(a);
349}
350
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000351int32_t JIT_OPERATION operationArithClz32(ExecState* exec, EncodedJSValue encodedOp1)
352{
353 VM* vm = &exec->vm();
354 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000355 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000356
357 JSValue op1 = JSValue::decode(encodedOp1);
358 uint32_t value = op1.toUInt32(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000359 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000360 return 0;
361 return clz32(value);
362}
363
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000364double JIT_OPERATION operationArithCos(ExecState* exec, EncodedJSValue encodedOp1)
365{
366 VM* vm = &exec->vm();
367 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000368 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000369
370 JSValue op1 = JSValue::decode(encodedOp1);
371 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000372 if (UNLIKELY(scope.exception()))
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000373 return JSValue::encode(JSValue());
374 return cos(a);
375}
376
benjamin@webkit.org87238e92016-08-25 01:21:43 +0000377double JIT_OPERATION operationArithFRound(ExecState* exec, EncodedJSValue encodedOp1)
378{
379 VM* vm = &exec->vm();
380 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000381 auto scope = DECLARE_THROW_SCOPE(*vm);
benjamin@webkit.org87238e92016-08-25 01:21:43 +0000382
383 JSValue op1 = JSValue::decode(encodedOp1);
384 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000385 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000386 return PNaN;
benjamin@webkit.org87238e92016-08-25 01:21:43 +0000387 return static_cast<float>(a);
388}
389
benjamin@webkit.org770c27f2016-08-24 02:36:40 +0000390double JIT_OPERATION operationArithLog(ExecState* exec, EncodedJSValue encodedOp1)
391{
392 VM* vm = &exec->vm();
393 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000394 auto scope = DECLARE_THROW_SCOPE(*vm);
benjamin@webkit.org770c27f2016-08-24 02:36:40 +0000395
396 JSValue op1 = JSValue::decode(encodedOp1);
397 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000398 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000399 return PNaN;
benjamin@webkit.org770c27f2016-08-24 02:36:40 +0000400 return log(a);
401}
402
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000403double JIT_OPERATION operationArithSin(ExecState* exec, EncodedJSValue encodedOp1)
404{
405 VM* vm = &exec->vm();
406 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000407 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000408
409 JSValue op1 = JSValue::decode(encodedOp1);
410 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000411 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000412 return PNaN;
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000413 return sin(a);
414}
415
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000416double JIT_OPERATION operationArithSqrt(ExecState* exec, EncodedJSValue encodedOp1)
417{
418 VM* vm = &exec->vm();
419 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000420 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000421
422 JSValue op1 = JSValue::decode(encodedOp1);
423 double a = op1.toNumber(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000424 if (UNLIKELY(scope.exception()))
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000425 return PNaN;
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000426 return sqrt(a);
427}
428
akling@apple.com6d3d1812014-04-26 06:00:43 +0000429static ALWAYS_INLINE EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
weinig@apple.coma96509f2011-06-15 21:57:17 +0000430{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000431 VM& vm = exec->vm();
432 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000433
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +0000434 if (base->isObject()) {
435 JSObject* object = asObject(base);
436 if (object->canGetIndexQuickly(index))
437 return JSValue::encode(object->getIndexQuickly(index));
438 }
weinig@apple.coma96509f2011-06-15 21:57:17 +0000439
mhahnenberg@apple.comc58d54d2011-12-16 19:06:44 +0000440 if (isJSString(base) && asString(base)->canGetIndex(index))
weinig@apple.coma96509f2011-06-15 21:57:17 +0000441 return JSValue::encode(asString(base)->getIndex(exec, index));
442
weinig@apple.coma96509f2011-06-15 21:57:17 +0000443 return JSValue::encode(JSValue(base).get(exec, index));
444}
445
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000446EncodedJSValue JIT_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000447{
akling@apple.comb6d91ab2014-02-09 21:33:17 +0000448 VM& vm = exec->vm();
449 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000450 auto scope = DECLARE_THROW_SCOPE(vm);
451
barraclough@apple.com2302c042011-03-14 23:31:00 +0000452 JSValue baseValue = JSValue::decode(encodedBase);
453 JSValue property = JSValue::decode(encodedProperty);
454
455 if (LIKELY(baseValue.isCell())) {
456 JSCell* base = baseValue.asCell();
457
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000458 if (property.isUInt32()) {
weinig@apple.coma96509f2011-06-15 21:57:17 +0000459 return getByVal(exec, base, property.asUInt32());
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000460 } else if (property.isDouble()) {
weinig@apple.coma96509f2011-06-15 21:57:17 +0000461 double propertyAsDouble = property.asDouble();
462 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000463 if (propertyAsUInt32 == propertyAsDouble && isIndex(propertyAsUInt32))
weinig@apple.coma96509f2011-06-15 21:57:17 +0000464 return getByVal(exec, base, propertyAsUInt32);
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000465 } else if (property.isString()) {
akling@apple.combaca5e82014-05-06 00:53:29 +0000466 Structure& structure = *base->structure(vm);
467 if (JSCell::canUseFastGetOwnProperty(structure)) {
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000468 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
469 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
akling@apple.comcad89042014-09-02 22:29:59 +0000470 return JSValue::encode(result);
471 }
akling@apple.combaca5e82014-05-06 00:53:29 +0000472 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000473 }
barraclough@apple.com2302c042011-03-14 23:31:00 +0000474 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000475
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000476 baseValue.requireObjectCoercible(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000477 if (UNLIKELY(scope.exception()))
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000478 return JSValue::encode(jsUndefined());
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000479 auto propertyName = property.toPropertyKey(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000480 if (UNLIKELY(scope.exception()))
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000481 return JSValue::encode(jsUndefined());
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +0000482 return JSValue::encode(baseValue.get(exec, propertyName));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000483}
484
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000485EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000486{
akling@apple.comb6d91ab2014-02-09 21:33:17 +0000487 VM& vm = exec->vm();
488 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000489 auto scope = DECLARE_THROW_SCOPE(vm);
490
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000491 JSValue property = JSValue::decode(encodedProperty);
492
493 if (property.isUInt32())
494 return getByVal(exec, base, property.asUInt32());
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000495 if (property.isDouble()) {
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000496 double propertyAsDouble = property.asDouble();
497 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
498 if (propertyAsUInt32 == propertyAsDouble)
499 return getByVal(exec, base, propertyAsUInt32);
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000500 } else if (property.isString()) {
akling@apple.combaca5e82014-05-06 00:53:29 +0000501 Structure& structure = *base->structure(vm);
502 if (JSCell::canUseFastGetOwnProperty(structure)) {
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000503 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
504 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
akling@apple.comcad89042014-09-02 22:29:59 +0000505 return JSValue::encode(result);
506 }
akling@apple.combaca5e82014-05-06 00:53:29 +0000507 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000508 }
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000509
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000510 auto propertyName = property.toPropertyKey(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000511 if (UNLIKELY(scope.exception()))
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000512 return JSValue::encode(jsUndefined());
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +0000513 return JSValue::encode(JSValue(base).get(exec, propertyName));
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000514}
515
oliver@apple.com211b3be2013-07-25 04:03:39 +0000516ALWAYS_INLINE EncodedJSValue getByValCellInt(ExecState* exec, JSCell* base, int32_t index)
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000517{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000518 VM* vm = &exec->vm();
519 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000520
521 if (index < 0) {
522 // Go the slowest way possible becase negative indices don't use indexed storage.
523 return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
524 }
525
526 // Use this since we know that the value is out of bounds.
sbarati@apple.com575aa2b2016-03-04 02:25:30 +0000527 return JSValue::encode(JSValue(base).get(exec, static_cast<unsigned>(index)));
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000528}
529
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000530EncodedJSValue JIT_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
oliver@apple.com211b3be2013-07-25 04:03:39 +0000531{
532 return getByValCellInt(exec, base, index);
533}
534
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000535EncodedJSValue JIT_OPERATION operationGetByValStringInt(ExecState* exec, JSString* base, int32_t index)
oliver@apple.com211b3be2013-07-25 04:03:39 +0000536{
537 return getByValCellInt(exec, base, index);
538}
539
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000540void JIT_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000541{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000542 VM* vm = &exec->vm();
543 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000544
oliver@apple.come050d642013-10-19 00:09:28 +0000545 operationPutByValInternal<true, false>(exec, encodedBase, encodedProperty, encodedValue);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000546}
547
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000548void JIT_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000549{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000550 VM* vm = &exec->vm();
551 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000552
oliver@apple.come050d642013-10-19 00:09:28 +0000553 operationPutByValInternal<false, false>(exec, encodedBase, encodedProperty, encodedValue);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000554}
555
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000556void JIT_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000557{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000558 VM* vm = &exec->vm();
559 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000560
oliver@apple.come050d642013-10-19 00:09:28 +0000561 operationPutByValInternal<true, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000562}
563
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000564void JIT_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000565{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000566 VM* vm = &exec->vm();
567 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000568
oliver@apple.come050d642013-10-19 00:09:28 +0000569 operationPutByValInternal<false, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000570}
571
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000572void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
barraclough@apple.come2130ff2011-06-07 23:03:32 +0000573{
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000574 VM& vm = exec->vm();
575 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000576
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000577 if (index >= 0) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000578 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000579 return;
580 }
581
oliver@apple.com68848412014-01-02 20:56:20 +0000582 PutPropertySlot slot(array, true);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000583 array->methodTable()->put(
584 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000585}
586
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000587void JIT_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000588{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000589 VM* vm = &exec->vm();
590 NativeCallFrameTracer tracer(vm, exec);
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000591
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000592 if (index >= 0) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000593 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000594 return;
595 }
596
oliver@apple.com68848412014-01-02 20:56:20 +0000597 PutPropertySlot slot(array, false);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000598 array->methodTable()->put(
599 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
barraclough@apple.come2130ff2011-06-07 23:03:32 +0000600}
601
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000602void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000603{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000604 VM* vm = &exec->vm();
605 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000606
607 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
608
609 if (index >= 0) {
610 array->putByIndexInline(exec, index, jsValue, true);
611 return;
612 }
613
oliver@apple.com68848412014-01-02 20:56:20 +0000614 PutPropertySlot slot(array, true);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000615 array->methodTable()->put(
616 array, exec, Identifier::from(exec, index), jsValue, slot);
617}
618
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000619void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000620{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000621 VM* vm = &exec->vm();
622 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000623
624 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
625
626 if (index >= 0) {
627 array->putByIndexInline(exec, index, jsValue, false);
628 return;
629 }
630
oliver@apple.com68848412014-01-02 20:56:20 +0000631 PutPropertySlot slot(array, false);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000632 array->methodTable()->put(
633 array, exec, Identifier::from(exec, index), jsValue, slot);
634}
635
oliver@apple.come050d642013-10-19 00:09:28 +0000636void JIT_OPERATION operationPutByValDirectStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
637{
638 VM* vm = &exec->vm();
639 NativeCallFrameTracer tracer(vm, exec);
640
641 operationPutByValInternal<true, true>(exec, encodedBase, encodedProperty, encodedValue);
642}
643
644void JIT_OPERATION operationPutByValDirectNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
645{
646 VM* vm = &exec->vm();
647 NativeCallFrameTracer tracer(vm, exec);
648
649 operationPutByValInternal<false, true>(exec, encodedBase, encodedProperty, encodedValue);
650}
651
652void JIT_OPERATION operationPutByValDirectCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
653{
654 VM* vm = &exec->vm();
655 NativeCallFrameTracer tracer(vm, exec);
656
657 operationPutByValInternal<true, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
658}
659
660void JIT_OPERATION operationPutByValDirectCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
661{
662 VM* vm = &exec->vm();
663 NativeCallFrameTracer tracer(vm, exec);
664
665 operationPutByValInternal<false, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
666}
667
668void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
669{
670 VM* vm = &exec->vm();
671 NativeCallFrameTracer tracer(vm, exec);
672 if (index >= 0) {
673 array->putDirectIndex(exec, index, JSValue::decode(encodedValue), 0, PutDirectIndexShouldThrow);
674 return;
675 }
676
oliver@apple.com68848412014-01-02 20:56:20 +0000677 PutPropertySlot slot(array, true);
oliver@apple.come050d642013-10-19 00:09:28 +0000678 array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
679}
680
681void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
682{
683 VM* vm = &exec->vm();
684 NativeCallFrameTracer tracer(vm, exec);
685
686 if (index >= 0) {
687 array->putDirectIndex(exec, index, JSValue::decode(encodedValue));
688 return;
689 }
690
oliver@apple.com68848412014-01-02 20:56:20 +0000691 PutPropertySlot slot(array, false);
oliver@apple.come050d642013-10-19 00:09:28 +0000692 array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
693}
694
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000695EncodedJSValue JIT_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
fpizlo@apple.com24d24e52011-10-04 02:55:54 +0000696{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000697 VM* vm = &exec->vm();
698 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000699
fpizlo@apple.com24d24e52011-10-04 02:55:54 +0000700 array->push(exec, JSValue::decode(encodedValue));
701 return JSValue::encode(jsNumber(array->length()));
702}
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000703
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000704EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000705{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000706 VM* vm = &exec->vm();
707 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000708
709 array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
710 return JSValue::encode(jsNumber(array->length()));
711}
712
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000713EncodedJSValue JIT_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000714{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000715 VM* vm = &exec->vm();
716 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000717
718 return JSValue::encode(array->pop(exec));
719}
720
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000721EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000722{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000723 VM* vm = &exec->vm();
724 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000725
726 array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
727
728 return JSValue::encode(array->pop(exec));
729}
730
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000731EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* argument)
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000732{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000733 SuperSamplerScope superSamplerScope(false);
734
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000735 VM& vm = globalObject->vm();
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000736 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000737
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +0000738 return JSValue::encode(regExpObject->execInline(exec, globalObject, argument));
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000739}
740
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000741EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000742{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000743 SuperSamplerScope superSamplerScope(false);
744
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000745 VM& vm = globalObject->vm();
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000746 NativeCallFrameTracer tracer(&vm, exec);
747
748 JSValue argument = JSValue::decode(encodedArgument);
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000749
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000750 JSString* input = argument.toStringOrNull(exec);
751 if (!input)
752 return JSValue::encode(jsUndefined());
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +0000753 return JSValue::encode(regExpObject->execInline(exec, globalObject, input));
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000754}
755
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000756EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000757{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000758 SuperSamplerScope superSamplerScope(false);
759
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000760 VM& vm = globalObject->vm();
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000761 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000762 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000763
764 JSValue base = JSValue::decode(encodedBase);
765 JSValue argument = JSValue::decode(encodedArgument);
766
767 if (!base.inherits(RegExpObject::info()))
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000768 return throwVMTypeError(exec, scope);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000769
770 JSString* input = argument.toStringOrNull(exec);
771 if (!input)
772 return JSValue::encode(jsUndefined());
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000773 return JSValue::encode(asRegExpObject(base)->exec(exec, globalObject, input));
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000774}
775
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000776size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* input)
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000777{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000778 SuperSamplerScope superSamplerScope(false);
779
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000780 VM& vm = globalObject->vm();
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000781 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000782
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +0000783 return regExpObject->testInline(exec, globalObject, input);
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000784}
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000785
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000786size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000787{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000788 SuperSamplerScope superSamplerScope(false);
789
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000790 VM& vm = globalObject->vm();
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000791 NativeCallFrameTracer tracer(&vm, exec);
792
793 JSValue argument = JSValue::decode(encodedArgument);
794
795 JSString* input = argument.toStringOrNull(exec);
796 if (!input)
797 return false;
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +0000798 return regExpObject->testInline(exec, globalObject, input);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000799}
800
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000801size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000802{
fpizlo@apple.com57aea1c2016-04-11 18:20:59 +0000803 SuperSamplerScope superSamplerScope(false);
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000804
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000805 VM& vm = globalObject->vm();
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000806 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000807 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000808
809 JSValue base = JSValue::decode(encodedBase);
810 JSValue argument = JSValue::decode(encodedArgument);
811
812 if (!base.inherits(RegExpObject::info())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000813 throwTypeError(exec, scope);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000814 return false;
815 }
816
817 JSString* input = argument.toStringOrNull(exec);
818 if (!input)
819 return false;
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000820 return asRegExpObject(base)->test(exec, globalObject, input);
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000821}
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000822
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000823size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
commit-queue@webkit.org6efa2ca2011-07-19 00:36:37 +0000824{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000825 VM* vm = &exec->vm();
826 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000827
commit-queue@webkit.org6efa2ca2011-07-19 00:36:37 +0000828 JSValue op1 = JSValue::decode(encodedOp1);
829 JSValue op2 = JSValue::decode(encodedOp2);
830
831 ASSERT(op1.isCell());
832 ASSERT(op2.isCell());
833
834 return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
835}
836
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000837size_t JIT_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000838{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000839 VM* vm = &exec->vm();
840 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com82acbbf2012-02-28 00:37:58 +0000841
842 JSValue src1 = JSValue::decode(encodedOp1);
843 JSValue src2 = JSValue::decode(encodedOp2);
oliver@apple.come07a4592012-01-25 19:43:06 +0000844
fpizlo@apple.com82acbbf2012-02-28 00:37:58 +0000845 return JSValue::strictEqual(exec, src1, src2);
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000846}
847
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000848EncodedJSValue JIT_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
fpizlo@apple.com90e5f0e2011-09-22 22:42:54 +0000849{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000850 VM* vm = &exec->vm();
851 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000852
fpizlo@apple.com90e5f0e2011-09-22 22:42:54 +0000853 return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
854}
855
utatane.tea@gmail.comdb32c542016-06-30 15:26:47 +0000856EncodedJSValue JIT_OPERATION operationToNumber(ExecState* exec, EncodedJSValue value)
857{
858 VM* vm = &exec->vm();
859 NativeCallFrameTracer tracer(vm, exec);
860
861 return JSValue::encode(jsNumber(JSValue::decode(value).toNumber(exec)));
862}
863
sbarati@apple.com23315d62016-05-09 20:17:23 +0000864EncodedJSValue JIT_OPERATION operationGetByIdWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, UniquedStringImpl* impl)
865{
866 VM& vm = exec->vm();
867 NativeCallFrameTracer tracer(&vm, exec);
868
869 JSValue baseValue = JSValue::decode(encodedBase);
870 JSValue thisVal = JSValue::decode(encodedThis);
871 PropertySlot slot(thisVal, PropertySlot::PropertySlot::InternalMethodType::Get);
872 JSValue result = baseValue.get(exec, Identifier::fromUid(exec, impl), slot);
873 return JSValue::encode(result);
874}
875
876EncodedJSValue JIT_OPERATION operationGetByValWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript)
877{
878 VM& vm = exec->vm();
879 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000880 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.com23315d62016-05-09 20:17:23 +0000881
882 JSValue baseValue = JSValue::decode(encodedBase);
883 JSValue thisVal = JSValue::decode(encodedThis);
884 JSValue subscript = JSValue::decode(encodedSubscript);
885
886 if (LIKELY(baseValue.isCell() && subscript.isString())) {
887 Structure& structure = *baseValue.asCell()->structure(vm);
888 if (JSCell::canUseFastGetOwnProperty(structure)) {
889 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
890 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
891 return JSValue::encode(result);
892 }
893 }
894 }
895
896 PropertySlot slot(thisVal, PropertySlot::PropertySlot::InternalMethodType::Get);
897 if (subscript.isUInt32()) {
898 uint32_t i = subscript.asUInt32();
899 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
900 return JSValue::encode(asString(baseValue)->getIndex(exec, i));
901
902 return JSValue::encode(baseValue.get(exec, i, slot));
903 }
904
905 baseValue.requireObjectCoercible(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000906 if (UNLIKELY(scope.exception()))
sbarati@apple.com23315d62016-05-09 20:17:23 +0000907 return JSValue::encode(JSValue());
908
909 auto property = subscript.toPropertyKey(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 return JSValue::encode(baseValue.get(exec, property, slot));
913}
914
915void JIT_OPERATION operationPutByIdWithThisStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, UniquedStringImpl* impl)
916{
917 VM& vm = exec->vm();
918 NativeCallFrameTracer tracer(&vm, exec);
919
920 putWithThis<true>(exec, encodedBase, encodedThis, encodedValue, Identifier::fromUid(exec, impl));
921}
922
923void JIT_OPERATION operationPutByIdWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, UniquedStringImpl* impl)
924{
925 VM& vm = exec->vm();
926 NativeCallFrameTracer tracer(&vm, exec);
927
928 putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, Identifier::fromUid(exec, impl));
929}
930
931void JIT_OPERATION operationPutByValWithThisStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
932{
933 VM& vm = exec->vm();
934 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000935 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.com23315d62016-05-09 20:17:23 +0000936
937 Identifier property = JSValue::decode(encodedSubscript).toPropertyKey(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000938 if (UNLIKELY(scope.exception()))
sbarati@apple.com23315d62016-05-09 20:17:23 +0000939 return;
940 putWithThis<true>(exec, encodedBase, encodedThis, encodedValue, property);
941}
942
943void JIT_OPERATION operationPutByValWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
944{
945 VM& vm = exec->vm();
946 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000947 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.com23315d62016-05-09 20:17:23 +0000948
949 Identifier property = JSValue::decode(encodedSubscript).toPropertyKey(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000950 if (UNLIKELY(scope.exception()))
sbarati@apple.com23315d62016-05-09 20:17:23 +0000951 return;
952 putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, property);
953}
954
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000955char* JIT_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000956{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000957 VM* vm = &exec->vm();
958 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com1bc68482012-10-13 03:56:09 +0000959
fpizlo@apple.com59d1ddb2013-11-05 00:05:02 +0000960 return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000961}
962
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000963char* JIT_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000964{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000965 VM* vm = &exec->vm();
966 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com1bc68482012-10-13 03:56:09 +0000967
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000968 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000969}
970
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +0000971char* JIT_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size, Butterfly* butterfly)
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000972{
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +0000973 VM& vm = exec->vm();
974 NativeCallFrameTracer tracer(&vm, exec);
975 auto scope = DECLARE_THROW_SCOPE(vm);
msaboff@apple.com51d65f22013-04-10 20:01:14 +0000976
msaboff@apple.com6ebf3b82013-04-11 16:19:35 +0000977 if (UNLIKELY(size < 0))
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000978 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 +0000979
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +0000980 JSArray* result;
981 if (butterfly)
982 result = JSArray::createWithButterfly(vm, arrayStructure, butterfly);
983 else
984 result = JSArray::create(vm, arrayStructure, size);
fpizlo@apple.com8dde06b2015-10-12 22:41:01 +0000985 return bitwise_cast<char*>(result);
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000986}
987
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000988char* JIT_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000989{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000990 VM& vm = exec->vm();
991 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com59d1ddb2013-11-05 00:05:02 +0000992 return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000993}
994
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000995char* JIT_OPERATION operationNewInt8ArrayWithSize(
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +0000996 ExecState* exec, Structure* structure, int32_t length)
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000997{
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +0000998 return newTypedArrayWithSize<JSInt8Array>(exec, structure, length);
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000999}
1000
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001001char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001002 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1003{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001004 VM& vm = exec->vm();
1005 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001006 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt8Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001007}
1008
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001009char* JIT_OPERATION operationNewInt16ArrayWithSize(
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001010 ExecState* exec, Structure* structure, int32_t length)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001011{
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001012 return newTypedArrayWithSize<JSInt16Array>(exec, structure, length);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001013}
1014
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001015char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001016 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1017{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001018 VM& vm = exec->vm();
1019 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001020 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt16Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001021}
1022
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001023char* JIT_OPERATION operationNewInt32ArrayWithSize(
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001024 ExecState* exec, Structure* structure, int32_t length)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001025{
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001026 return newTypedArrayWithSize<JSInt32Array>(exec, structure, length);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001027}
1028
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001029char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001030 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1031{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001032 VM& vm = exec->vm();
1033 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001034 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt32Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001035}
1036
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001037char* JIT_OPERATION operationNewUint8ArrayWithSize(
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001038 ExecState* exec, Structure* structure, int32_t length)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001039{
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001040 return newTypedArrayWithSize<JSUint8Array>(exec, structure, length);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001041}
1042
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001043char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001044 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1045{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001046 VM& vm = exec->vm();
1047 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001048 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001049}
1050
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001051char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001052 ExecState* exec, Structure* structure, int32_t length)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001053{
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001054 return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001055}
1056
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001057char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001058 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1059{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001060 VM& vm = exec->vm();
1061 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001062 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8ClampedArray>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001063}
1064
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001065char* JIT_OPERATION operationNewUint16ArrayWithSize(
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001066 ExecState* exec, Structure* structure, int32_t length)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001067{
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001068 return newTypedArrayWithSize<JSUint16Array>(exec, structure, length);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001069}
1070
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001071char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001072 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1073{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001074 VM& vm = exec->vm();
1075 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001076 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint16Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001077}
1078
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001079char* JIT_OPERATION operationNewUint32ArrayWithSize(
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001080 ExecState* exec, Structure* structure, int32_t length)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001081{
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001082 return newTypedArrayWithSize<JSUint32Array>(exec, structure, length);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001083}
1084
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001085char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001086 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1087{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001088 VM& vm = exec->vm();
1089 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001090 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint32Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001091}
1092
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001093char* JIT_OPERATION operationNewFloat32ArrayWithSize(
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001094 ExecState* exec, Structure* structure, int32_t length)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001095{
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001096 return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001097}
1098
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001099char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001100 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1101{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001102 VM& vm = exec->vm();
1103 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001104 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat32Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001105}
1106
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001107char* JIT_OPERATION operationNewFloat64ArrayWithSize(
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001108 ExecState* exec, Structure* structure, int32_t length)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001109{
ryanhaddad@apple.com4a64b142016-09-06 21:43:08 +00001110 return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001111}
1112
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001113char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001114 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1115{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001116 VM& vm = exec->vm();
1117 NativeCallFrameTracer tracer(&vm, exec);
keith_miller@apple.coma646a262015-10-16 21:40:21 +00001118 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat64Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001119}
1120
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00001121JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState* exec, Structure* structure, JSScope* scope, SymbolTable* table, EncodedJSValue initialValueEncoded)
fpizlo@apple.comc6446112012-05-23 20:52:42 +00001122{
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00001123 JSValue initialValue = JSValue::decode(initialValueEncoded);
1124 ASSERT(initialValue == jsUndefined() || initialValue == jsTDZValue());
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001125 VM& vm = exec->vm();
1126 NativeCallFrameTracer tracer(&vm, exec);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00001127 return JSLexicalEnvironment::create(vm, structure, scope, table, initialValue);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001128}
1129
1130JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState* exec, Structure* structure, int32_t length, int32_t minCapacity)
1131{
1132 VM& vm = exec->vm();
1133 NativeCallFrameTracer target(&vm, exec);
1134 DirectArguments* result = DirectArguments::create(
1135 vm, structure, length, std::max(length, minCapacity));
1136 // The caller will store to this object without barriers. Most likely, at this point, this is
1137 // still a young object and so no barriers are needed. But it's good to be careful anyway,
1138 // since the GC should be allowed to do crazy (like pretenuring, for example).
1139 vm.heap.writeBarrier(result);
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001140 return result;
fpizlo@apple.comc6446112012-05-23 20:52:42 +00001141}
1142
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001143JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment* scope)
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001144{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001145 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001146 NativeCallFrameTracer target(&vm, exec);
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001147
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001148 // We could pass the ScopedArgumentsTable* as an argument. We currently don't because I
1149 // didn't feel like changing the max number of arguments for a slow path call from 6 to 7.
1150 ScopedArgumentsTable* table = scope->symbolTable()->arguments();
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001151
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001152 return ScopedArguments::createByCopyingFrom(
1153 vm, structure, argumentStart, length, callee, table, scope);
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001154}
1155
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001156JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee)
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001157{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001158 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001159 NativeCallFrameTracer target(&vm, exec);
1160 return ClonedArguments::createByCopyingFrom(
1161 exec, structure, argumentStart, length, callee);
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001162}
1163
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001164JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001165{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001166 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001167 NativeCallFrameTracer target(&vm, exec);
1168
1169 DeferGCForAWhile deferGC(vm.heap);
1170
1171 CodeBlock* codeBlock;
1172 if (inlineCallFrame)
1173 codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
1174 else
1175 codeBlock = exec->codeBlock();
1176
1177 unsigned length = argumentCount - 1;
1178 unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
1179 DirectArguments* result = DirectArguments::create(
1180 vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
1181
1182 result->callee().set(vm, result, callee);
1183
1184 Register* arguments =
1185 exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
1186 CallFrame::argumentOffset(0);
1187 for (unsigned i = length; i--;)
1188 result->setIndexQuickly(vm, i, arguments[i].jsValue());
1189
1190 return result;
1191}
1192
1193JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
1194{
1195 VM& vm = exec->vm();
1196 NativeCallFrameTracer target(&vm, exec);
1197
1198 DeferGCForAWhile deferGC(vm.heap);
1199
1200 CodeBlock* codeBlock;
1201 if (inlineCallFrame)
1202 codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
1203 else
1204 codeBlock = exec->codeBlock();
1205
1206 unsigned length = argumentCount - 1;
1207 ClonedArguments* result = ClonedArguments::createEmpty(
keith_miller@apple.com26367392016-03-14 20:55:15 +00001208 vm, codeBlock->globalObject()->clonedArgumentsStructure(), callee, length);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001209
1210 Register* arguments =
1211 exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
1212 CallFrame::argumentOffset(0);
1213 for (unsigned i = length; i--;)
keith_miller@apple.com26367392016-03-14 20:55:15 +00001214 result->initializeIndex(vm, i, arguments[i].jsValue());
1215
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001216
1217 return result;
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001218}
1219
sbarati@apple.com6cfefd82016-08-13 02:14:42 +00001220JSCell* JIT_OPERATION operationCreateRest(ExecState* exec, Register* argumentStart, unsigned numberOfParamsToSkip, unsigned arraySize)
sbarati@apple.comc0722da2015-11-20 02:37:47 +00001221{
keith_miller@apple.com1b8b0062016-04-16 01:26:10 +00001222 VM* vm = &exec->vm();
1223 NativeCallFrameTracer tracer(vm, exec);
1224
sbarati@apple.com6cfefd82016-08-13 02:14:42 +00001225 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
1226 Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
1227 static_assert(sizeof(Register) == sizeof(JSValue), "This is a strong assumption here.");
1228 JSValue* argumentsToCopyRegion = bitwise_cast<JSValue*>(argumentStart) + numberOfParamsToSkip;
1229 return constructArray(exec, structure, argumentsToCopyRegion, arraySize);
sbarati@apple.comc0722da2015-11-20 02:37:47 +00001230}
1231
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001232size_t JIT_OPERATION operationObjectIsObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
oliver@apple.come722ad02013-01-09 02:37:29 +00001233{
mark.lam@apple.com87a5b6f2014-02-05 04:22:43 +00001234 VM& vm = exec->vm();
1235 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001236
1237 ASSERT(jsDynamicCast<JSObject*>(object));
1238
1239 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1240 return false;
1241 if (object->type() == JSFunctionType)
1242 return false;
1243 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1244 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001245 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001246 return false;
1247 }
1248
1249 return true;
1250}
1251
1252size_t JIT_OPERATION operationObjectIsFunction(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1253{
1254 VM& vm = exec->vm();
1255 NativeCallFrameTracer tracer(&vm, exec);
1256
1257 ASSERT(jsDynamicCast<JSObject*>(object));
1258
1259 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1260 return false;
1261 if (object->type() == JSFunctionType)
1262 return true;
1263 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1264 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001265 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001266 return true;
1267 }
1268
1269 return false;
1270}
1271
1272JSCell* JIT_OPERATION operationTypeOfObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1273{
1274 VM& vm = exec->vm();
1275 NativeCallFrameTracer tracer(&vm, exec);
1276
1277 ASSERT(jsDynamicCast<JSObject*>(object));
1278
1279 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1280 return vm.smallStrings.undefinedString();
1281 if (object->type() == JSFunctionType)
1282 return vm.smallStrings.functionString();
1283 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1284 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001285 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001286 return vm.smallStrings.functionString();
1287 }
1288
1289 return vm.smallStrings.objectString();
1290}
1291
1292int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1293{
1294 VM& vm = exec->vm();
1295 NativeCallFrameTracer tracer(&vm, exec);
1296
1297 ASSERT(jsDynamicCast<JSObject*>(object));
1298
1299 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1300 return static_cast<int32_t>(TypeofType::Undefined);
1301 if (object->type() == JSFunctionType)
1302 return static_cast<int32_t>(TypeofType::Function);
1303 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1304 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001305 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001306 return static_cast<int32_t>(TypeofType::Function);
1307 }
1308
1309 return static_cast<int32_t>(TypeofType::Object);
oliver@apple.come722ad02013-01-09 02:37:29 +00001310}
1311
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001312char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001313{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001314 VM& vm = exec->vm();
1315 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comc17054c2012-09-18 15:22:29 +00001316
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001317 return reinterpret_cast<char*>(
oliver@apple.coma03796a2013-07-25 04:01:20 +00001318 Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001319}
1320
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001321char* JIT_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001322{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001323 VM& vm = exec->vm();
1324 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comc17054c2012-09-18 15:22:29 +00001325
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001326 return reinterpret_cast<char*>(
oliver@apple.coma03796a2013-07-25 04:01:20 +00001327 Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001328}
1329
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001330char* JIT_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001331{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001332 VM& vm = exec->vm();
1333 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001334
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001335 if (!cell->isObject())
1336 return 0;
1337
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001338 return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001339}
1340
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001341char* JIT_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001342{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001343 VM& vm = exec->vm();
1344 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001345
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001346 if (!cell->isObject())
1347 return 0;
1348
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001349 return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001350}
1351
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001352char* JIT_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001353{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001354 VM& vm = exec->vm();
1355 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001356
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001357 if (!cell->isObject())
1358 return 0;
1359
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001360 return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001361}
1362
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001363char* JIT_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001364{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001365 VM& vm = exec->vm();
1366 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001367
1368 if (!cell->isObject())
1369 return 0;
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001370
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001371 return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001372}
1373
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001374StringImpl* JIT_OPERATION operationResolveRope(ExecState* exec, JSString* string)
fpizlo@apple.com70bb5c52012-12-11 05:22:49 +00001375{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001376 VM& vm = exec->vm();
1377 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com70bb5c52012-12-11 05:22:49 +00001378
1379 return string->value(exec).impl();
1380}
1381
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001382JSString* JIT_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
oliver@apple.com63af2d42013-07-25 04:03:33 +00001383{
1384 VM& vm = exec->vm();
1385 NativeCallFrameTracer tracer(&vm, exec);
1386
1387 return jsSingleCharacterString(exec, static_cast<UChar>(character));
1388}
1389
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001390JSCell* JIT_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001391{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001392 VM& vm = exec->vm();
1393 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001394
akling@apple.com019809c2013-10-06 18:16:48 +00001395 return StringObject::create(vm, structure, string);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001396}
1397
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001398JSCell* JIT_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001399{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001400 VM& vm = exec->vm();
1401 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001402
1403 return JSValue(cell).toString(exec);
1404}
1405
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001406JSCell* JIT_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001407{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001408 VM& vm = exec->vm();
1409 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001410
1411 return JSValue::decode(value).toString(exec);
1412}
1413
utatane.tea@gmail.com153559e2015-04-06 19:07:12 +00001414JSCell* JIT_OPERATION operationCallStringConstructorOnCell(ExecState* exec, JSCell* cell)
1415{
1416 VM& vm = exec->vm();
1417 NativeCallFrameTracer tracer(&vm, exec);
1418
1419 return stringConstructor(exec, cell);
1420}
1421
1422JSCell* JIT_OPERATION operationCallStringConstructor(ExecState* exec, EncodedJSValue value)
1423{
1424 VM& vm = exec->vm();
1425 NativeCallFrameTracer tracer(&vm, exec);
1426
1427 return stringConstructor(exec, JSValue::decode(value));
1428}
1429
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001430JSCell* JIT_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001431{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001432 VM& vm = exec->vm();
1433 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001434 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com24c49992014-04-19 21:13:46 +00001435
1436 if (sumOverflows<int32_t>(left->length(), right->length())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001437 throwOutOfMemoryError(exec, scope);
fpizlo@apple.come28731c2014-04-19 20:36:58 +00001438 return nullptr;
fpizlo@apple.com75104a32014-04-15 23:33:11 +00001439 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001440
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001441 return JSRopeString::create(vm, left, right);
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001442}
1443
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001444JSCell* JIT_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001445{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001446 VM& vm = exec->vm();
1447 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001448 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001449
fpizlo@apple.com24c49992014-04-19 21:13:46 +00001450 if (sumOverflows<int32_t>(a->length(), b->length(), c->length())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001451 throwOutOfMemoryError(exec, scope);
fpizlo@apple.come28731c2014-04-19 20:36:58 +00001452 return nullptr;
fpizlo@apple.com75104a32014-04-15 23:33:11 +00001453 }
1454
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001455 return JSRopeString::create(vm, a, b, c);
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001456}
1457
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001458JSCell* JIT_OPERATION operationStrCat2(ExecState* exec, EncodedJSValue a, EncodedJSValue b)
1459{
1460 VM& vm = exec->vm();
1461 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001462 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001463
1464 JSString* str1 = JSValue::decode(a).toString(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001465 ASSERT(!scope.exception()); // Impossible, since we must have been given primitives.
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001466 JSString* str2 = JSValue::decode(b).toString(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001467 ASSERT(!scope.exception());
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001468
1469 if (sumOverflows<int32_t>(str1->length(), str2->length())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001470 throwOutOfMemoryError(exec, scope);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001471 return nullptr;
1472 }
1473
1474 return JSRopeString::create(vm, str1, str2);
1475}
1476
1477JSCell* JIT_OPERATION operationStrCat3(ExecState* exec, EncodedJSValue a, EncodedJSValue b, EncodedJSValue c)
1478{
1479 VM& vm = exec->vm();
1480 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001481 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001482
1483 JSString* str1 = JSValue::decode(a).toString(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001484 ASSERT(!scope.exception()); // Impossible, since we must have been given primitives.
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001485 JSString* str2 = JSValue::decode(b).toString(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001486 ASSERT(!scope.exception());
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001487 JSString* str3 = JSValue::decode(c).toString(exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001488 ASSERT(!scope.exception());
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001489
1490 if (sumOverflows<int32_t>(str1->length(), str2->length(), str3->length())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001491 throwOutOfMemoryError(exec, scope);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001492 return nullptr;
1493 }
1494
1495 return JSRopeString::create(vm, str1, str2, str3);
1496}
1497
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001498char* JIT_OPERATION operationFindSwitchImmTargetForDouble(
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001499 ExecState* exec, EncodedJSValue encodedValue, size_t tableIndex)
1500{
keith_miller@apple.com1b8b0062016-04-16 01:26:10 +00001501 VM& vm = exec->vm();
1502 NativeCallFrameTracer tracer(&vm, exec);
1503
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001504 CodeBlock* codeBlock = exec->codeBlock();
oliver@apple.coma14cea52013-07-25 04:03:23 +00001505 SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001506 JSValue value = JSValue::decode(encodedValue);
1507 ASSERT(value.isDouble());
1508 double asDouble = value.asDouble();
1509 int32_t asInt32 = static_cast<int32_t>(asDouble);
1510 if (asDouble == asInt32)
1511 return static_cast<char*>(table.ctiForValue(asInt32).executableAddress());
1512 return static_cast<char*>(table.ctiDefault.executableAddress());
1513}
1514
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001515char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JSString* string)
oliver@apple.com5c826c02013-07-25 04:03:51 +00001516{
1517 VM& vm = exec->vm();
1518 NativeCallFrameTracer tracer(&vm, exec);
1519
1520 return static_cast<char*>(exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress());
1521}
1522
fpizlo@apple.com5a3036b2015-04-29 03:34:43 +00001523int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)
1524{
1525 VM& vm = exec->vm();
1526 NativeCallFrameTracer tracer(&vm, exec);
1527
1528 return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(string->value(exec).impl(), std::numeric_limits<int32_t>::min());
1529}
1530
commit-queue@webkit.org36c52882016-04-22 05:08:28 +00001531uintptr_t JIT_OPERATION operationCompareStringImplLess(StringImpl* a, StringImpl* b)
1532{
1533 return codePointCompare(a, b) < 0;
1534}
1535
1536uintptr_t JIT_OPERATION operationCompareStringImplLessEq(StringImpl* a, StringImpl* b)
1537{
1538 return codePointCompare(a, b) <= 0;
1539}
1540
1541uintptr_t JIT_OPERATION operationCompareStringImplGreater(StringImpl* a, StringImpl* b)
1542{
1543 return codePointCompare(a, b) > 0;
1544}
1545
1546uintptr_t JIT_OPERATION operationCompareStringImplGreaterEq(StringImpl* a, StringImpl* b)
1547{
1548 return codePointCompare(a, b) >= 0;
1549}
1550
1551uintptr_t JIT_OPERATION operationCompareStringLess(ExecState* exec, JSString* a, JSString* b)
1552{
1553 VM& vm = exec->vm();
1554 NativeCallFrameTracer tracer(&vm, exec);
1555
1556 return codePointCompareLessThan(asString(a)->value(exec), asString(b)->value(exec));
1557}
1558
1559uintptr_t JIT_OPERATION operationCompareStringLessEq(ExecState* exec, JSString* a, JSString* b)
1560{
1561 VM& vm = exec->vm();
1562 NativeCallFrameTracer tracer(&vm, exec);
1563
1564 return !codePointCompareLessThan(asString(b)->value(exec), asString(a)->value(exec));
1565}
1566
1567uintptr_t JIT_OPERATION operationCompareStringGreater(ExecState* exec, JSString* a, JSString* b)
1568{
1569 VM& vm = exec->vm();
1570 NativeCallFrameTracer tracer(&vm, exec);
1571
1572 return codePointCompareLessThan(asString(b)->value(exec), asString(a)->value(exec));
1573}
1574
1575uintptr_t JIT_OPERATION operationCompareStringGreaterEq(ExecState* exec, JSString* a, JSString* b)
1576{
1577 VM& vm = exec->vm();
1578 NativeCallFrameTracer tracer(&vm, exec);
1579
1580 return !codePointCompareLessThan(asString(a)->value(exec), asString(b)->value(exec));
1581}
1582
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +00001583void JIT_OPERATION operationNotifyWrite(ExecState* exec, WatchpointSet* set)
fpizlo@apple.com33961712013-11-20 05:49:05 +00001584{
1585 VM& vm = exec->vm();
1586 NativeCallFrameTracer tracer(&vm, exec);
1587
sbarati@apple.com0c3609d2016-06-28 21:30:20 +00001588 set->touch(vm, "Executed NotifyWrite");
fpizlo@apple.com33961712013-11-20 05:49:05 +00001589}
1590
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001591void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
1592{
1593 VM& vm = exec->vm();
1594 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001595 auto scope = DECLARE_THROW_SCOPE(vm);
1596 throwStackOverflowError(exec, scope);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001597}
1598
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001599int32_t JIT_OPERATION operationSizeOfVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
1600{
1601 VM& vm = exec->vm();
1602 NativeCallFrameTracer tracer(&vm, exec);
1603 JSValue arguments = JSValue::decode(encodedArguments);
1604
1605 return sizeOfVarargs(exec, arguments, firstVarArgOffset);
1606}
1607
1608void JIT_OPERATION operationLoadVarargs(ExecState* exec, int32_t firstElementDest, EncodedJSValue encodedArguments, int32_t offset, int32_t length, int32_t mandatoryMinimum)
1609{
1610 VM& vm = exec->vm();
1611 NativeCallFrameTracer tracer(&vm, exec);
1612 JSValue arguments = JSValue::decode(encodedArguments);
1613
1614 loadVarargs(exec, VirtualRegister(firstElementDest), arguments, offset, length);
1615
1616 for (int32_t i = length; i < mandatoryMinimum; ++i)
1617 exec->r(firstElementDest + i) = jsUndefined();
1618}
1619
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001620double JIT_OPERATION operationFModOnInts(int32_t a, int32_t b)
fpizlo@apple.com2c2536e2012-03-21 01:29:28 +00001621{
1622 return fmod(a, b);
1623}
1624
utatane.tea@gmail.comd2fca0a2015-12-15 03:51:42 +00001625#if USE(JSVALUE32_64)
1626double JIT_OPERATION operationRandom(JSGlobalObject* globalObject)
1627{
1628 return globalObject->weakRandomNumber();
1629}
1630#endif
1631
mark.lam@apple.com03a3e382016-01-08 18:44:36 +00001632JSCell* JIT_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +00001633{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001634 VM* vm = &exec->vm();
1635 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com03a3e382016-01-08 18:44:36 +00001636 return JSC::stringFromCharCode(exec, op1);
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +00001637}
1638
mark.lam@apple.com151fe102016-01-13 23:28:38 +00001639EncodedJSValue JIT_OPERATION operationStringFromCharCodeUntyped(ExecState* exec, EncodedJSValue encodedValue)
1640{
1641 VM* vm = &exec->vm();
1642 NativeCallFrameTracer tracer(vm, exec);
1643 JSValue charValue = JSValue::decode(encodedValue);
1644 int32_t chInt = charValue.toUInt32(exec);
1645 return JSValue::encode(JSC::stringFromCharCode(exec, chInt));
1646}
1647
fpizlo@apple.comf2999932014-07-15 00:41:39 +00001648int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue encodedValue)
1649{
1650 JSValue value = JSValue::decode(encodedValue);
1651 if (!value.isDouble())
1652 return JSValue::notInt52;
1653 return tryConvertToInt52(value.asDouble());
1654}
1655
1656int64_t JIT_OPERATION operationConvertDoubleToInt52(double value)
1657{
1658 return tryConvertToInt52(value);
1659}
1660
sbarati@apple.comfa857522016-03-07 01:00:33 +00001661size_t JIT_OPERATION operationDefaultHasInstance(ExecState* exec, JSCell* value, JSCell* proto) // Returns jsBoolean(True|False) on 64-bit.
1662{
1663 VM* vm = &exec->vm();
1664 NativeCallFrameTracer tracer(vm, exec);
1665 if (JSObject::defaultHasInstance(exec, value, proto))
1666 return 1;
1667 return 0;
1668}
1669
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001670char* JIT_OPERATION operationNewRawObject(ExecState* exec, Structure* structure, int32_t length, Butterfly* butterfly)
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001671{
1672 VM& vm = exec->vm();
1673 NativeCallFrameTracer tracer(&vm, exec);
1674
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001675 if (!butterfly
1676 && (structure->outOfLineCapacity() || hasIndexedProperties(structure->indexingType()))) {
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001677 IndexingHeader header;
1678 header.setVectorLength(length);
1679 header.setPublicLength(0);
1680
1681 butterfly = Butterfly::create(
1682 vm, nullptr, 0, structure->outOfLineCapacity(),
1683 hasIndexedProperties(structure->indexingType()), header,
1684 length * sizeof(EncodedJSValue));
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001685 }
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001686
1687 JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
1688 result->butterfly(); // Ensure that the butterfly is in to-space.
1689 return bitwise_cast<char*>(result);
1690}
1691
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001692JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState* exec, Structure* structure, Butterfly* butterfly)
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001693{
1694 VM& vm = exec->vm();
1695 NativeCallFrameTracer tracer(&vm, exec);
1696
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001697 if (!butterfly) {
1698 butterfly = Butterfly::create(
1699 vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0);
1700 }
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001701
1702 JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
1703 result->butterfly(); // Ensure that the butterfly is in to-space.
1704 return result;
1705}
1706
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001707JSCell* JIT_OPERATION operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength(ExecState* exec, Structure* structure, unsigned length, Butterfly* butterfly)
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001708{
1709 VM& vm = exec->vm();
1710 NativeCallFrameTracer tracer(&vm, exec);
1711
1712 IndexingHeader header;
1713 header.setVectorLength(length);
1714 header.setPublicLength(0);
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001715 if (butterfly)
1716 *butterfly->indexingHeader() = header;
1717 else {
1718 butterfly = Butterfly::create(
1719 vm, nullptr, 0, structure->outOfLineCapacity(), true, header,
1720 sizeof(EncodedJSValue) * length);
1721 }
1722
fpizlo@apple.com280ef002016-04-05 22:13:16 +00001723 // Paradoxically this may allocate a JSArray. That's totally cool.
1724 JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
1725 result->butterfly(); // Ensure that the butterfly is in to-space.
1726 return result;
1727}
1728
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001729void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState* exec)
1730{
sbarati@apple.comc6fb7552016-06-07 20:07:56 +00001731 VM& vm = exec->vm();
1732 NativeCallFrameTracer tracer(&vm, exec);
1733
1734 vm.typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside DFG."));
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001735}
1736
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001737void JIT_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001738{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001739 VM* vm = &exec->vm();
1740 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +00001741
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001742 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
fpizlo@apple.comf2bf0dd2011-09-26 04:05:28 +00001743 CodeBlock* codeBlock = debugInfo->codeBlock;
fpizlo@apple.com47d3b642011-10-05 21:36:23 +00001744 CodeBlock* alternative = codeBlock->alternative();
mark.lam@apple.come7ecf832014-04-02 20:49:27 +00001745 dataLog("Speculation failure in ", *codeBlock);
1746 dataLog(" @ exit #", vm->osrExitIndex, " (bc#", debugInfo->bytecodeOffset, ", ", exitKindToString(debugInfo->kind), ") with ");
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +00001747 if (alternative) {
1748 dataLog(
1749 "executeCounter = ", alternative->jitExecuteCounter(),
1750 ", reoptimizationRetryCounter = ", alternative->reoptimizationRetryCounter(),
1751 ", optimizationDelayCounter = ", alternative->optimizationDelayCounter());
1752 } else
1753 dataLog("no alternative code block (i.e. we've been jettisoned)");
1754 dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
fpizlo@apple.com03e446e2013-01-11 22:18:27 +00001755 dataLog(" GPRs at time of exit:");
1756 char* scratchPointer = static_cast<char*>(scratch);
1757 for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
1758 GPRReg gpr = GPRInfo::toRegister(i);
commit-queue@webkit.org94ea8122013-02-25 13:13:43 +00001759 dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
fpizlo@apple.com03e446e2013-01-11 22:18:27 +00001760 scratchPointer += sizeof(EncodedJSValue);
1761 }
1762 dataLog("\n");
1763 dataLog(" FPRs at time of exit:");
1764 for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
1765 FPRReg fpr = FPRInfo::toRegister(i);
1766 dataLog(" ", FPRInfo::debugName(fpr), ":");
commit-queue@webkit.org94ea8122013-02-25 13:13:43 +00001767 uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
1768 double value = *reinterpret_cast_ptr<double*>(scratchPointer);
ossy@webkit.org71aebd72013-01-12 09:33:01 +00001769 dataLogF("%llx:%lf", static_cast<long long>(bits), value);
fpizlo@apple.com03e446e2013-01-11 22:18:27 +00001770 scratchPointer += sizeof(EncodedJSValue);
1771 }
1772 dataLog("\n");
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001773}
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001774
sbarati@apple.come67fd782016-04-19 01:38:30 +00001775JSCell* JIT_OPERATION operationResolveScope(ExecState* exec, JSScope* scope, UniquedStringImpl* impl)
1776{
1777 VM& vm = exec->vm();
1778 NativeCallFrameTracer tracer(&vm, exec);
1779
1780 JSObject* resolvedScope = JSScope::resolve(exec, scope, Identifier::fromUid(exec, impl));
1781 return resolvedScope;
1782}
1783
1784EncodedJSValue JIT_OPERATION operationGetDynamicVar(ExecState* exec, JSObject* scope, UniquedStringImpl* impl, unsigned getPutInfoBits)
1785{
1786 VM& vm = exec->vm();
1787 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001788 auto throwScope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.come67fd782016-04-19 01:38:30 +00001789
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00001790 Identifier ident = Identifier::fromUid(exec, impl);
1791 return JSValue::encode(scope->getPropertySlot(exec, ident, [&] (bool found, PropertySlot& slot) -> JSValue {
1792 if (!found) {
1793 GetPutInfo getPutInfo(getPutInfoBits);
1794 if (getPutInfo.resolveMode() == ThrowIfNotFound)
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001795 throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00001796 return jsUndefined();
sbarati@apple.come67fd782016-04-19 01:38:30 +00001797 }
sbarati@apple.come67fd782016-04-19 01:38:30 +00001798
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00001799 if (scope->isGlobalLexicalEnvironment()) {
1800 // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
1801 JSValue result = slot.getValue(exec, ident);
1802 if (result == jsTDZValue()) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001803 throwException(exec, throwScope, createTDZError(exec));
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00001804 return jsUndefined();
1805 }
1806 return result;
1807 }
1808
1809 return slot.getValue(exec, ident);
1810 }));
sbarati@apple.come67fd782016-04-19 01:38:30 +00001811}
1812
1813void JIT_OPERATION operationPutDynamicVar(ExecState* exec, JSObject* scope, EncodedJSValue value, UniquedStringImpl* impl, unsigned getPutInfoBits)
1814{
1815 VM& vm = exec->vm();
1816 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001817 auto throwScope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.come67fd782016-04-19 01:38:30 +00001818
1819 const Identifier& ident = Identifier::fromUid(exec, impl);
1820 GetPutInfo getPutInfo(getPutInfoBits);
1821 bool hasProperty = scope->hasProperty(exec, ident);
1822 if (hasProperty
1823 && scope->isGlobalLexicalEnvironment()
1824 && !isInitialization(getPutInfo.initializationMode())) {
1825 // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
1826 PropertySlot slot(scope, PropertySlot::InternalMethodType::Get);
1827 JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot);
1828 if (slot.getValue(exec, ident) == jsTDZValue()) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001829 throwException(exec, throwScope, createTDZError(exec));
sbarati@apple.come67fd782016-04-19 01:38:30 +00001830 return;
1831 }
1832 }
1833
1834 if (getPutInfo.resolveMode() == ThrowIfNotFound && !hasProperty) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001835 throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
sbarati@apple.come67fd782016-04-19 01:38:30 +00001836 return;
1837 }
1838
1839 CodeOrigin origin = exec->codeOrigin();
1840 bool strictMode;
1841 if (origin.inlineCallFrame)
1842 strictMode = origin.inlineCallFrame->baselineCodeBlock->isStrictMode();
1843 else
1844 strictMode = exec->codeBlock()->isStrictMode();
1845 PutPropertySlot slot(scope, strictMode, PutPropertySlot::UnknownContext, isInitialization(getPutInfo.initializationMode()));
1846 scope->methodTable()->put(scope, exec, ident, JSValue::decode(value), slot);
1847}
1848
sbarati@apple.com21fc86e2016-09-06 23:22:01 +00001849int32_t JIT_OPERATION operationMapHash(ExecState* exec, EncodedJSValue input)
1850{
1851 VM& vm = exec->vm();
1852 NativeCallFrameTracer tracer(&vm, exec);
1853
1854 return jsMapHash(exec, vm, normalizeMapKey(JSValue::decode(input)));
1855}
1856
1857JSCell* JIT_OPERATION operationJSMapFindBucket(ExecState* exec, JSCell* map, EncodedJSValue key, int32_t hash)
1858{
1859 VM& vm = exec->vm();
1860 NativeCallFrameTracer tracer(&vm, exec);
1861 JSMap::BucketType** bucket = jsCast<JSMap*>(map)->findBucket(exec, normalizeMapKey(JSValue::decode(key)), hash);
1862 if (!bucket)
1863 return nullptr;
1864 return *bucket;
1865}
1866
1867JSCell* JIT_OPERATION operationJSSetFindBucket(ExecState* exec, JSCell* map, EncodedJSValue key, int32_t hash)
1868{
1869 VM& vm = exec->vm();
1870 NativeCallFrameTracer tracer(&vm, exec);
1871 JSSet::BucketType** bucket = jsCast<JSSet*>(map)->findBucket(exec, normalizeMapKey(JSValue::decode(key)), hash);
1872 if (!bucket)
1873 return nullptr;
1874 return *bucket;
1875}
1876
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001877extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001878{
fpizlo@apple.com98225492013-09-10 18:29:45 +00001879 // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
1880 // really be profitable.
1881 DeferGCForAWhile deferGC(codeBlock->vm()->heap);
1882
oliver@apple.com284cc3d2013-07-25 04:00:33 +00001883 if (Options::verboseOSR())
1884 dataLog(*codeBlock, ": Entered reoptimize\n");
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001885 // We must be called with the baseline code block.
oliver@apple.com5a24fdd2013-07-25 04:00:54 +00001886 ASSERT(JITCode::isBaselineCode(codeBlock->jitType()));
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001887
1888 // If I am my own replacement, then reoptimization has already been triggered.
1889 // This can happen in recursive functions.
oliver@apple.comd2a16382013-07-25 04:04:18 +00001890 if (codeBlock->replacement() == codeBlock) {
1891 if (Options::verboseOSR())
1892 dataLog(*codeBlock, ": Not reoptimizing because we've already been jettisoned.\n");
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001893 return;
oliver@apple.comd2a16382013-07-25 04:04:18 +00001894 }
1895
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001896 // Otherwise, the replacement must be optimized code. Use this as an opportunity
1897 // to check our logic.
1898 ASSERT(codeBlock->hasOptimizedReplacement());
oliver@apple.comd2a16382013-07-25 04:04:18 +00001899 CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1900 ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001901
1902 bool didTryToEnterIntoInlinedLoops = false;
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001903 for (InlineCallFrame* inlineCallFrame = exit->m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->directCaller.inlineCallFrame) {
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001904 if (inlineCallFrame->baselineCodeBlock->ownerScriptExecutable()->didTryToEnterInLoop()) {
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001905 didTryToEnterIntoInlinedLoops = true;
1906 break;
1907 }
1908 }
oliver@apple.comd2a16382013-07-25 04:04:18 +00001909
1910 // In order to trigger reoptimization, one of two things must have happened:
1911 // 1) We exited more than some number of times.
1912 // 2) We exited and got stuck in a loop, and now we're exiting again.
1913 bool didExitABunch = optimizedCodeBlock->shouldReoptimizeNow();
1914 bool didGetStuckInLoop =
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001915 (codeBlock->checkIfOptimizationThresholdReached() || didTryToEnterIntoInlinedLoops)
oliver@apple.comd2a16382013-07-25 04:04:18 +00001916 && optimizedCodeBlock->shouldReoptimizeFromLoopNow();
1917
1918 if (!didExitABunch && !didGetStuckInLoop) {
1919 if (Options::verboseOSR())
1920 dataLog(*codeBlock, ": Not reoptimizing ", *optimizedCodeBlock, " because it either didn't exit enough or didn't loop enough after exit.\n");
1921 codeBlock->optimizeAfterLongWarmUp();
1922 return;
1923 }
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001924
fpizlo@apple.com0dda6d72014-02-02 02:25:13 +00001925 optimizedCodeBlock->jettison(Profiler::JettisonDueToOSRExit, CountReoptimization);
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001926}
1927
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001928#if ENABLE(FTL_JIT)
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001929static bool shouldTriggerFTLCompile(CodeBlock* codeBlock, JITCode* jitCode)
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001930{
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001931 if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001932 CODEBLOCK_LOG_EVENT(codeBlock, "abortFTLCompile", ());
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001933 if (Options::verboseOSR())
1934 dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
1935 jitCode->dontOptimizeAnytimeSoon(codeBlock);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001936 return false;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001937 }
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001938
1939 if (!codeBlock->hasOptimizedReplacement()
1940 && !jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001941 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("counter = ", jitCode->tierUpCounter));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001942 if (Options::verboseOSR())
1943 dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001944 return false;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001945 }
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001946 return true;
1947}
1948
1949static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
1950{
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001951 Worklist::State worklistState;
msaboff@apple.com95894332014-01-29 19:18:54 +00001952 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001953 worklistState = worklist->completeAllReadyPlansForVM(
1954 *vm, CompilationKey(codeBlock->baselineVersion(), FTLMode));
1955 } else
1956 worklistState = Worklist::NotKnown;
1957
1958 if (worklistState == Worklist::Compiling) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001959 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001960 jitCode->setOptimizationThresholdBasedOnCompilationResult(
1961 codeBlock, CompilationDeferred);
1962 return;
1963 }
1964
1965 if (codeBlock->hasOptimizedReplacement()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001966 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("has replacement"));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001967 // That's great, we've compiled the code - next time we call this function,
1968 // we'll enter that replacement.
1969 jitCode->optimizeSoon(codeBlock);
1970 return;
1971 }
1972
1973 if (worklistState == Worklist::Compiled) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001974 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001975 // This means that we finished compiling, but failed somehow; in that case the
1976 // thresholds will be set appropriately.
1977 if (Options::verboseOSR())
1978 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1979 return;
1980 }
1981
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00001982 CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLReplacement", ());
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001983 // We need to compile the code.
1984 compile(
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001985 *vm, codeBlock->newReplacement(), codeBlock, FTLMode, UINT_MAX,
1986 Operands<JSValue>(), ToFTLDeferredCompilationCallback::create());
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001987
1988 // If we reached here, the counter has not be reset. Do that now.
1989 jitCode->setOptimizationThresholdBasedOnCompilationResult(
1990 codeBlock, CompilationDeferred);
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001991}
1992
benjamin@webkit.org31527f52016-03-09 17:51:38 +00001993void JIT_OPERATION triggerTierUpNow(ExecState* exec)
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001994{
1995 VM* vm = &exec->vm();
1996 NativeCallFrameTracer tracer(vm, exec);
sbarati@apple.comefcb30a2016-06-23 23:28:50 +00001997 DeferGCForAWhile deferGC(vm->heap);
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001998 CodeBlock* codeBlock = exec->codeBlock();
1999
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +00002000 if (codeBlock->jitType() != JITCode::DFGJIT) {
2001 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2002 RELEASE_ASSERT_NOT_REACHED();
2003 }
2004
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002005 JITCode* jitCode = codeBlock->jitCode()->dfg();
2006
2007 if (Options::verboseOSR()) {
2008 dataLog(
2009 *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
2010 jitCode->tierUpCounter, "\n");
2011 }
benjamin@webkit.org8f625992015-05-18 20:45:34 +00002012
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002013 if (shouldTriggerFTLCompile(codeBlock, jitCode))
2014 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002015
2016 if (codeBlock->hasOptimizedReplacement()) {
2017 if (jitCode->tierUpEntryTriggers.isEmpty()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002018 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("replacement in place, delaying indefinitely"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002019 // There is nothing more we can do, the only way this will be entered
2020 // is through the function entry point.
2021 jitCode->dontOptimizeAnytimeSoon(codeBlock);
2022 return;
2023 }
2024 if (jitCode->osrEntryBlock() && jitCode->tierUpEntryTriggers.size() == 1) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002025 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("trigger in place, delaying indefinitely"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002026 // There is only one outer loop and its trigger must have been set
2027 // when the plan completed.
2028 // Exiting the inner loop is useless, we can ignore the counter and leave
2029 // the trigger do its job.
2030 jitCode->dontOptimizeAnytimeSoon(codeBlock);
2031 return;
2032 }
2033 }
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002034}
2035
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002036static char* tierUpCommon(ExecState* exec, unsigned originBytecodeIndex, unsigned osrEntryBytecodeIndex)
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002037{
2038 VM* vm = &exec->vm();
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002039 CodeBlock* codeBlock = exec->codeBlock();
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002040
2041 // Resolve any pending plan for OSR Enter on this function.
2042 Worklist::State worklistState;
2043 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
2044 worklistState = worklist->completeAllReadyPlansForVM(
2045 *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode));
2046 } else
2047 worklistState = Worklist::NotKnown;
2048
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002049 JITCode* jitCode = codeBlock->jitCode()->dfg();
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002050 if (worklistState == Worklist::Compiling) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002051 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002052 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2053 codeBlock, CompilationDeferred);
2054 return nullptr;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002055 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002056
2057 if (worklistState == Worklist::Compiled) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002058 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002059 // This means that compilation failed and we already set the thresholds.
2060 if (Options::verboseOSR())
2061 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
2062 return nullptr;
2063 }
2064
2065 // If we can OSR Enter, do it right away.
2066 if (originBytecodeIndex == osrEntryBytecodeIndex) {
2067 unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(originBytecodeIndex);
2068 if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002069 if (void* address = FTL::prepareOSREntry(exec, codeBlock, entryBlock, originBytecodeIndex, streamIndex)) {
2070 CODEBLOCK_LOG_EVENT(entryBlock, "osrEntry", ("at bc#", originBytecodeIndex));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002071 return static_cast<char*>(address);
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002072 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002073 }
2074 }
2075
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002076 // - If we don't have an FTL code block, then try to compile one.
2077 // - If we do have an FTL code block, then try to enter for a while.
2078 // - If we couldn't enter for a while, then trigger OSR entry.
msaboff@apple.com95894332014-01-29 19:18:54 +00002079
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002080 if (!shouldTriggerFTLCompile(codeBlock, jitCode))
2081 return nullptr;
2082
2083 if (!jitCode->neverExecutedEntry) {
2084 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2085
2086 if (!codeBlock->hasOptimizedReplacement())
2087 return nullptr;
fpizlo@apple.com239b0782016-03-03 05:58:59 +00002088
2089 if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002090 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding OSR entry compile"));
fpizlo@apple.com239b0782016-03-03 05:58:59 +00002091 jitCode->osrEntryRetry++;
2092 return nullptr;
2093 }
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002094 } else
2095 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding replacement compile"));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002096
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002097 // It's time to try to compile code for OSR entry.
2098 if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002099 if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002100 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed, OSR entry threshold not met"));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002101 jitCode->osrEntryRetry++;
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002102 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2103 codeBlock, CompilationDeferred);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002104 return nullptr;
2105 }
2106
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002107 FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
2108 entryCode->countEntryFailure();
2109 if (entryCode->entryFailureCount() <
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002110 Options::ftlOSREntryFailureCountForReoptimization()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002111 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002112 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2113 codeBlock, CompilationDeferred);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002114 return nullptr;
2115 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002116
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002117 // OSR entry failed. Oh no! This implies that we need to retry. We retry
2118 // without exponential backoff and we only do this for the entry code block.
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002119 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed too many times"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002120 unsigned osrEntryBytecode = entryBlock->jitCode()->ftlForOSREntry()->bytecodeIndex();
ggaren@apple.com81def5f2015-10-09 23:10:16 +00002121 jitCode->clearOSREntryBlock();
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002122 jitCode->osrEntryRetry = 0;
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002123 jitCode->tierUpEntryTriggers.set(osrEntryBytecode, 0);
2124 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2125 codeBlock, CompilationDeferred);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002126 return nullptr;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002127 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002128
2129 unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(osrEntryBytecodeIndex);
2130 auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(osrEntryBytecodeIndex);
2131 if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end()) {
2132 for (unsigned osrEntryCandidate : tierUpHierarchyEntry->value) {
2133 if (jitCode->tierUpEntrySeen.contains(osrEntryCandidate)) {
2134 osrEntryBytecodeIndex = osrEntryCandidate;
2135 streamIndex = jitCode->bytecodeIndexToStreamIndex.get(osrEntryBytecodeIndex);
2136 }
2137 }
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002138 }
2139
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002140 // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile
2141 // something.
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002142 auto triggerIterator = jitCode->tierUpEntryTriggers.find(osrEntryBytecodeIndex);
2143 RELEASE_ASSERT(triggerIterator != jitCode->tierUpEntryTriggers.end());
2144 uint8_t* triggerAddress = &(triggerIterator->value);
2145
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002146 Operands<JSValue> mustHandleValues;
2147 jitCode->reconstruct(
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002148 exec, codeBlock, CodeOrigin(osrEntryBytecodeIndex), streamIndex, mustHandleValues);
ggaren@apple.com81def5f2015-10-09 23:10:16 +00002149 CodeBlock* replacementCodeBlock = codeBlock->newReplacement();
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002150
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002151 CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLOSR", ());
msaboff@apple.com95894332014-01-29 19:18:54 +00002152 CompilationResult forEntryResult = compile(
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002153 *vm, replacementCodeBlock, codeBlock, FTLForOSREntryMode, osrEntryBytecodeIndex,
2154 mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(triggerAddress));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002155
2156 if (jitCode->neverExecutedEntry)
2157 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2158
2159 if (forEntryResult != CompilationSuccessful) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002160 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR ecompilation not successful"));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002161 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2162 codeBlock, CompilationDeferred);
2163 return nullptr;
2164 }
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002165
2166 CODEBLOCK_LOG_EVENT(jitCode->osrEntryBlock(), "osrEntry", ("at bc#", originBytecodeIndex));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002167 // It's possible that the for-entry compile already succeeded. In that case OSR
2168 // entry will succeed unless we ran out of stack. It's not clear what we should do.
2169 // We signal to try again after a while if that happens.
2170 void* address = FTL::prepareOSREntry(
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002171 exec, codeBlock, jitCode->osrEntryBlock(), originBytecodeIndex, streamIndex);
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002172 return static_cast<char*>(address);
2173}
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002174
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002175void JIT_OPERATION triggerTierUpNowInLoop(ExecState* exec, unsigned bytecodeIndex)
2176{
2177 VM* vm = &exec->vm();
2178 NativeCallFrameTracer tracer(vm, exec);
sbarati@apple.comefcb30a2016-06-23 23:28:50 +00002179 DeferGCForAWhile deferGC(vm->heap);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002180 CodeBlock* codeBlock = exec->codeBlock();
2181
2182 if (codeBlock->jitType() != JITCode::DFGJIT) {
2183 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2184 RELEASE_ASSERT_NOT_REACHED();
2185 }
2186
2187 JITCode* jitCode = codeBlock->jitCode()->dfg();
2188
2189 if (Options::verboseOSR()) {
2190 dataLog(
2191 *codeBlock, ": Entered triggerTierUpNowInLoop with executeCounter = ",
2192 jitCode->tierUpCounter, "\n");
2193 }
2194
2195 auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(bytecodeIndex);
2196 if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end()
2197 && !tierUpHierarchyEntry->value.isEmpty()) {
2198 tierUpCommon(exec, bytecodeIndex, tierUpHierarchyEntry->value.first());
2199 } else if (shouldTriggerFTLCompile(codeBlock, jitCode))
2200 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2201
2202 // Since we cannot OSR Enter here, the default "optimizeSoon()" is not useful.
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002203 if (codeBlock->hasOptimizedReplacement()) {
2204 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR in loop failed, deferring"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002205 jitCode->setOptimizationThresholdBasedOnCompilationResult(codeBlock, CompilationDeferred);
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002206 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002207}
2208
2209char* JIT_OPERATION triggerOSREntryNow(ExecState* exec, unsigned bytecodeIndex)
2210{
2211 VM* vm = &exec->vm();
2212 NativeCallFrameTracer tracer(vm, exec);
sbarati@apple.comefcb30a2016-06-23 23:28:50 +00002213 DeferGCForAWhile deferGC(vm->heap);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002214 CodeBlock* codeBlock = exec->codeBlock();
2215
2216 if (codeBlock->jitType() != JITCode::DFGJIT) {
2217 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2218 RELEASE_ASSERT_NOT_REACHED();
2219 }
2220
2221 JITCode* jitCode = codeBlock->jitCode()->dfg();
2222 jitCode->tierUpEntrySeen.add(bytecodeIndex);
2223
2224 if (Options::verboseOSR()) {
2225 dataLog(
2226 *codeBlock, ": Entered triggerOSREntryNow with executeCounter = ",
2227 jitCode->tierUpCounter, "\n");
2228 }
2229
2230 return tierUpCommon(exec, bytecodeIndex, bytecodeIndex);
2231}
2232
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002233#endif // ENABLE(FTL_JIT)
2234
barraclough@apple.comc7af2d32011-05-26 21:37:05 +00002235} // extern "C"
fpizlo@apple.com04659ba2012-02-21 09:49:22 +00002236} } // namespace JSC::DFG
2237
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +00002238#endif // ENABLE(DFG_JIT)
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +00002239
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +00002240#endif // ENABLE(JIT)