blob: 0217ea89b388f7f444c2d201542ed53ae84a0f23 [file] [log] [blame]
barraclough@apple.com2302c042011-03-14 23:31:00 +00001/*
mark.lam@apple.com61dbb712017-03-16 21:53:33 +00002 * Copyright (C) 2011-2017 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"
fpizlo@apple.com532f1e52013-09-04 06:26:04 +000034#include "DFGDriver.h"
fpizlo@apple.comb426f862014-02-10 02:51:13 +000035#include "DFGJITCode.h"
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000036#include "DFGOSRExit.h"
fpizlo@apple.com5e135772012-07-12 00:12:03 +000037#include "DFGThunks.h"
fpizlo@apple.com532f1e52013-09-04 06:26:04 +000038#include "DFGToFTLDeferredCompilationCallback.h"
39#include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
40#include "DFGWorklist.h"
utatane.tea@gmail.comf7db5592016-10-04 19:31:24 +000041#include "DefinePropertyAttributes.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"
annulen@yandex.ru6712c2d2017-06-25 17:40:30 +000045#include "FrameTracers.h"
sbarati@apple.coma3db4652016-09-20 01:05:50 +000046#include "HasOwnPropertyCache.h"
utatane.tea@gmail.comc2585192016-08-25 22:55:10 +000047#include "HostCallReturnValue.h"
barraclough@apple.com2302c042011-03-14 23:31:00 +000048#include "Interpreter.h"
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +000049#include "JIT.h"
oliver@apple.comc55314a2012-05-30 19:45:20 +000050#include "JITExceptions.h"
sbarati@apple.com5b8aea12017-01-24 00:15:21 +000051#include "JSArrayInlines.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000052#include "JSCInlines.h"
sbarati@apple.com99ed4792016-11-12 02:58:11 +000053#include "JSFixedArray.h"
keith_miller@apple.com1ec869c2016-06-21 17:54:33 +000054#include "JSGenericTypedArrayViewConstructorInlines.h"
oliver@apple.coma7dfb4d2014-09-11 18:18:14 +000055#include "JSLexicalEnvironment.h"
sbarati@apple.com21fc86e2016-09-06 23:22:01 +000056#include "JSMap.h"
57#include "JSSet.h"
utatane.tea@gmail.com288e68f2017-09-13 07:02:13 +000058#include "JSWeakMap.h"
ggaren@apple.comc862eac2013-01-29 05:48:01 +000059#include "ObjectConstructor.h"
mark.lam@apple.com581437a2016-09-22 23:41:56 +000060#include "Operations.h"
sbarati@apple.com0c3eb932017-02-24 04:07:30 +000061#include "ParseInt.h"
joepeck@webkit.org7e07f392016-09-22 18:59:47 +000062#include "RegExpObject.h"
mark.lam@apple.com9df8b832013-09-26 20:27:14 +000063#include "Repatch.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000064#include "ScopedArguments.h"
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +000065#include "StringConstructor.h"
fpizlo@apple.com5e29b762016-03-18 00:53:24 +000066#include "SuperSampler.h"
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +000067#include "Symbol.h"
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +000068#include "TypeProfilerLog.h"
fpizlo@apple.com372fa822013-08-21 19:43:47 +000069#include "TypedArrayInlines.h"
fpizlo@apple.com4a528d02016-05-11 00:08:50 +000070#include "VMInlines.h"
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +000071#include <wtf/InlineASM.h>
barraclough@apple.com2302c042011-03-14 23:31:00 +000072
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +000073#if ENABLE(JIT)
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +000074#if ENABLE(DFG_JIT)
75
barraclough@apple.com2302c042011-03-14 23:31:00 +000076namespace JSC { namespace DFG {
77
oliver@apple.come050d642013-10-19 00:09:28 +000078template<bool strict, bool direct>
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +000079static inline void putByVal(ExecState* exec, VM& vm, JSValue baseValue, uint32_t index, JSValue value)
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000080{
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +000081 ASSERT(isIndex(index));
oliver@apple.come050d642013-10-19 00:09:28 +000082 if (direct) {
83 RELEASE_ASSERT(baseValue.isObject());
84 asObject(baseValue)->putDirectIndex(exec, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
85 return;
86 }
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +000087 if (baseValue.isObject()) {
88 JSObject* object = asObject(baseValue);
89 if (object->canSetIndexQuickly(index)) {
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000090 object->setIndexQuickly(vm, index, value);
weinig@apple.coma96509f2011-06-15 21:57:17 +000091 return;
92 }
93
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +000094 object->methodTable(vm)->putByIndex(object, exec, index, value, strict);
weinig@apple.coma96509f2011-06-15 21:57:17 +000095 return;
96 }
97
barraclough@apple.coma4d51f22012-03-06 01:18:42 +000098 baseValue.putByIndex(exec, index, value, strict);
weinig@apple.coma96509f2011-06-15 21:57:17 +000099}
100
oliver@apple.come050d642013-10-19 00:09:28 +0000101template<bool strict, bool direct>
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000102ALWAYS_INLINE static void putByValInternal(ExecState* exec, VM& vm, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
weinig@apple.coma96509f2011-06-15 21:57:17 +0000103{
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000104 auto scope = DECLARE_THROW_SCOPE(vm);
oliver@apple.come07a4592012-01-25 19:43:06 +0000105
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000106 JSValue baseValue = JSValue::decode(encodedBase);
107 JSValue property = JSValue::decode(encodedProperty);
108 JSValue value = JSValue::decode(encodedValue);
109
110 if (LIKELY(property.isUInt32())) {
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000111 // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
112 ASSERT(isIndex(property.asUInt32()));
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000113 scope.release();
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000114 putByVal<strict, direct>(exec, vm, baseValue, property.asUInt32(), value);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000115 return;
116 }
117
weinig@apple.coma96509f2011-06-15 21:57:17 +0000118 if (property.isDouble()) {
119 double propertyAsDouble = property.asDouble();
120 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000121 if (propertyAsDouble == propertyAsUInt32 && isIndex(propertyAsUInt32)) {
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000122 scope.release();
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000123 putByVal<strict, direct>(exec, vm, baseValue, propertyAsUInt32, value);
weinig@apple.coma96509f2011-06-15 21:57:17 +0000124 return;
125 }
126 }
127
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000128 // Don't put to an object if toString throws an exception.
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000129 auto propertyName = property.toPropertyKey(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000130 RETURN_IF_EXCEPTION(scope, void());
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000131
132 PutPropertySlot slot(baseValue, strict);
133 if (direct) {
134 RELEASE_ASSERT(baseValue.isObject());
utatane.tea@gmail.com43926962016-11-27 06:08:16 +0000135 if (std::optional<uint32_t> index = parseIndex(propertyName)) {
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000136 scope.release();
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000137 asObject(baseValue)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000138 return;
139 }
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000140 asObject(baseValue)->putDirect(vm, propertyName, value, slot);
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000141 return;
142 }
143 scope.release();
144 baseValue.put(exec, propertyName, value, slot);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000145}
146
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000147template<bool strict, bool direct>
148ALWAYS_INLINE static void putByValCellInternal(ExecState* exec, VM& vm, JSCell* base, PropertyName propertyName, JSValue value)
149{
150 PutPropertySlot slot(base, strict);
151 if (direct) {
152 RELEASE_ASSERT(base->isObject());
153 if (std::optional<uint32_t> index = parseIndex(propertyName))
154 asObject(base)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
155 else
156 asObject(base)->putDirect(vm, propertyName, value, slot);
157 return;
158 }
159 base->putInline(exec, propertyName, value, slot);
160}
161
162template<bool strict, bool direct>
163ALWAYS_INLINE static void putByValCellStringInternal(ExecState* exec, VM& vm, JSCell* base, JSString* property, JSValue value)
164{
165 auto scope = DECLARE_THROW_SCOPE(vm);
166
167 auto propertyName = property->toIdentifier(exec);
168 RETURN_IF_EXCEPTION(scope, void());
169
170 scope.release();
171 putByValCellInternal<strict, direct>(exec, vm, base, propertyName, value);
172}
173
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000174template<typename ViewClass>
fpizlo@apple.com30a72582016-09-08 16:47:34 +0000175char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000176{
177 VM& vm = exec->vm();
178 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000179 auto scope = DECLARE_THROW_SCOPE(vm);
180
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000181 if (size < 0) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000182 throwException(exec, scope, createRangeError(exec, ASCIILiteral("Requested length is negative")));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000183 return 0;
184 }
fpizlo@apple.com30a72582016-09-08 16:47:34 +0000185
186 if (vector)
187 return bitwise_cast<char*>(ViewClass::createWithFastVector(exec, structure, size, vector));
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000188
189 scope.release();
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000190 return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
191}
192
sbarati@apple.com23315d62016-05-09 20:17:23 +0000193template <bool strict>
194static ALWAYS_INLINE void putWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, const Identifier& ident)
195{
196 JSValue baseValue = JSValue::decode(encodedBase);
197 JSValue thisVal = JSValue::decode(encodedThis);
198 JSValue putValue = JSValue::decode(encodedValue);
199 PutPropertySlot slot(thisVal, strict);
200 baseValue.putInline(exec, ident, putValue, slot);
201}
202
sbarati@apple.com0c3eb932017-02-24 04:07:30 +0000203static ALWAYS_INLINE EncodedJSValue parseIntResult(double input)
204{
205 int asInt = static_cast<int>(input);
206 if (static_cast<double>(asInt) == input)
207 return JSValue::encode(jsNumber(asInt));
208 return JSValue::encode(jsNumber(input));
209}
210
utatane.tea@gmail.coma12d84b2017-09-08 15:36:05 +0000211ALWAYS_INLINE static JSValue getByValObject(ExecState* exec, VM& vm, JSObject* base, PropertyName propertyName)
212{
213 Structure& structure = *base->structure(vm);
214 if (JSCell::canUseFastGetOwnProperty(structure)) {
215 if (JSValue result = base->fastGetOwnProperty(vm, structure, propertyName))
216 return result;
217 }
218 return base->get(exec, propertyName);
219}
220
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000221extern "C" {
222
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000223EncodedJSValue JIT_OPERATION operationToThis(ExecState* exec, EncodedJSValue encodedOp)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000224{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000225 VM* vm = &exec->vm();
226 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000227
fpizlo@apple.com018818d2013-09-13 23:18:19 +0000228 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, NotStrictMode));
229}
230
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000231EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState* exec, EncodedJSValue encodedOp)
fpizlo@apple.com018818d2013-09-13 23:18:19 +0000232{
233 VM* vm = &exec->vm();
234 NativeCallFrameTracer tracer(vm, exec);
235
236 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, StrictMode));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000237}
238
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000239JSCell* JIT_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
fpizlo@apple.combb159ec2011-09-21 22:17:06 +0000240{
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000241 VM& vm = exec->vm();
242 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000243 auto scope = DECLARE_THROW_SCOPE(vm);
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000244 if (constructor->type() == JSFunctionType) {
245 auto rareData = jsCast<JSFunction*>(constructor)->rareData(exec, inlineCapacity);
246 RETURN_IF_EXCEPTION(scope, nullptr);
sbarati@apple.com8ebc61d2017-10-04 01:53:18 +0000247 Structure* structure = rareData->objectAllocationProfile()->structure();
248 JSObject* result = constructEmptyObject(exec, structure);
sbarati@apple.com648f4012017-10-05 07:38:00 +0000249 if (structure->hasPolyProto()) {
250 JSObject* prototype = jsCast<JSFunction*>(constructor)->prototypeForConstruction(vm, exec);
251 result->putDirect(vm, structure->polyProtoOffset(), prototype);
fpizlo@apple.comf0b92ac2017-10-08 03:15:56 +0000252 prototype->didBecomePrototype();
sbarati@apple.comdd0cf032017-10-10 07:58:27 +0000253 ASSERT_WITH_MESSAGE(!hasIndexedProperties(result->indexingType()), "We rely on JSFinalObject not starting out with an indexing type otherwise we would potentially need to convert to slow put storage");
sbarati@apple.com648f4012017-10-05 07:38:00 +0000254 }
sbarati@apple.com8ebc61d2017-10-04 01:53:18 +0000255 return result;
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000256 }
barraclough@apple.comcef11dc2012-05-10 18:40:29 +0000257
mark.lam@apple.com23e96242017-09-09 16:21:45 +0000258 JSValue proto = constructor->get(exec, vm.propertyNames->prototype);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000259 RETURN_IF_EXCEPTION(scope, nullptr);
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +0000260 if (proto.isObject())
261 return constructEmptyObject(exec, asObject(proto));
sbarati@apple.come5315aa2016-02-20 23:51:33 +0000262 return constructEmptyObject(exec);
fpizlo@apple.com133c9ac2011-11-08 00:37:33 +0000263}
264
keith_miller@apple.com5bed6f62016-06-16 06:01:47 +0000265JSCell* JIT_OPERATION operationObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget)
266{
267 VM* vm = &exec->vm();
268 NativeCallFrameTracer tracer(vm, exec);
269
270 JSValue value = JSValue::decode(encodedTarget);
271 ASSERT(!value.isObject());
272
273 if (value.isUndefinedOrNull())
274 return constructEmptyObject(exec, globalObject->objectPrototype());
275 return value.toObject(exec, globalObject);
276}
277
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000278EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
279{
280 VM* vm = &exec->vm();
281 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000282 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000283
284 JSValue op1 = JSValue::decode(encodedOp1);
285 JSValue op2 = JSValue::decode(encodedOp2);
286
287 int32_t a = op1.toInt32(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000288 RETURN_IF_EXCEPTION(scope, encodedJSValue());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000289 scope.release();
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000290 int32_t b = op2.toInt32(exec);
291 return JSValue::encode(jsNumber(a & b));
292}
293
294EncodedJSValue JIT_OPERATION operationValueBitOr(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
295{
296 VM* vm = &exec->vm();
297 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000298 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000299
300 JSValue op1 = JSValue::decode(encodedOp1);
301 JSValue op2 = JSValue::decode(encodedOp2);
302
303 int32_t a = op1.toInt32(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000304 RETURN_IF_EXCEPTION(scope, encodedJSValue());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000305 scope.release();
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000306 int32_t b = op2.toInt32(exec);
307 return JSValue::encode(jsNumber(a | b));
308}
309
310EncodedJSValue JIT_OPERATION operationValueBitXor(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
311{
312 VM* vm = &exec->vm();
313 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000314 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000315
316 JSValue op1 = JSValue::decode(encodedOp1);
317 JSValue op2 = JSValue::decode(encodedOp2);
318
319 int32_t a = op1.toInt32(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000320 RETURN_IF_EXCEPTION(scope, encodedJSValue());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000321 scope.release();
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000322 int32_t b = op2.toInt32(exec);
323 return JSValue::encode(jsNumber(a ^ b));
324}
325
326EncodedJSValue JIT_OPERATION operationValueBitLShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
327{
328 VM* vm = &exec->vm();
329 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000330 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000331
332 JSValue op1 = JSValue::decode(encodedOp1);
333 JSValue op2 = JSValue::decode(encodedOp2);
334
335 int32_t a = op1.toInt32(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000336 RETURN_IF_EXCEPTION(scope, encodedJSValue());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000337 scope.release();
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000338 uint32_t b = op2.toUInt32(exec);
339 return JSValue::encode(jsNumber(a << (b & 0x1f)));
340}
341
342EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
343{
344 VM* vm = &exec->vm();
345 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000346 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000347
348 JSValue op1 = JSValue::decode(encodedOp1);
349 JSValue op2 = JSValue::decode(encodedOp2);
350
351 int32_t a = op1.toInt32(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000352 RETURN_IF_EXCEPTION(scope, encodedJSValue());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000353 scope.release();
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000354 uint32_t b = op2.toUInt32(exec);
355 return JSValue::encode(jsNumber(a >> (b & 0x1f)));
356}
357
358EncodedJSValue JIT_OPERATION operationValueBitURShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
359{
360 VM* vm = &exec->vm();
361 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000362 auto scope = DECLARE_THROW_SCOPE(*vm);
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000363
364 JSValue op1 = JSValue::decode(encodedOp1);
365 JSValue op2 = JSValue::decode(encodedOp2);
366
367 uint32_t a = op1.toUInt32(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000368 RETURN_IF_EXCEPTION(scope, encodedJSValue());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000369 scope.release();
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000370 uint32_t b = op2.toUInt32(exec);
371 return JSValue::encode(jsNumber(static_cast<int32_t>(a >> (b & 0x1f))));
372}
373
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000374EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000375{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000376 VM* vm = &exec->vm();
377 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000378
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000379 JSValue op1 = JSValue::decode(encodedOp1);
380 JSValue op2 = JSValue::decode(encodedOp2);
381
fpizlo@apple.com5df0cd82011-08-19 00:18:49 +0000382 ASSERT(!op1.isNumber() || !op2.isNumber());
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000383
ggaren@apple.com64be5e92012-01-24 07:34:10 +0000384 if (op1.isString() && !op2.isObject())
385 return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000386
387 return JSValue::encode(jsAddSlowCase(exec, op1, op2));
388}
389
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000390EncodedJSValue JIT_OPERATION operationValueDiv(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
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);
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000395
396 JSValue op1 = JSValue::decode(encodedOp1);
397 JSValue op2 = JSValue::decode(encodedOp2);
398
399 double a = op1.toNumber(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000400 RETURN_IF_EXCEPTION(scope, encodedJSValue());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000401 scope.release();
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000402 double b = op2.toNumber(exec);
403 return JSValue::encode(jsNumber(a / b));
404}
405
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000406double JIT_OPERATION operationArithAbs(ExecState* exec, EncodedJSValue encodedOp1)
407{
408 VM* vm = &exec->vm();
409 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000410 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000411
412 JSValue op1 = JSValue::decode(encodedOp1);
413 double a = op1.toNumber(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000414 RETURN_IF_EXCEPTION(scope, PNaN);
commit-queue@webkit.org0ec71072016-08-29 07:21:04 +0000415 return fabs(a);
416}
417
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000418int32_t JIT_OPERATION operationArithClz32(ExecState* exec, EncodedJSValue encodedOp1)
419{
420 VM* vm = &exec->vm();
421 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000422 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000423
424 JSValue op1 = JSValue::decode(encodedOp1);
425 uint32_t value = op1.toUInt32(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000426 RETURN_IF_EXCEPTION(scope, 0);
commit-queue@webkit.org95f28be2016-09-06 21:54:11 +0000427 return clz32(value);
428}
429
benjamin@webkit.org87238e92016-08-25 01:21:43 +0000430double JIT_OPERATION operationArithFRound(ExecState* exec, EncodedJSValue encodedOp1)
431{
432 VM* vm = &exec->vm();
433 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000434 auto scope = DECLARE_THROW_SCOPE(*vm);
benjamin@webkit.org87238e92016-08-25 01:21:43 +0000435
436 JSValue op1 = JSValue::decode(encodedOp1);
437 double a = op1.toNumber(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000438 RETURN_IF_EXCEPTION(scope, PNaN);
benjamin@webkit.org87238e92016-08-25 01:21:43 +0000439 return static_cast<float>(a);
440}
441
utatane.tea@gmail.comccb74992017-05-04 11:40:46 +0000442#define DFG_ARITH_UNARY(capitalizedName, lowerName) \
443double JIT_OPERATION operationArith##capitalizedName(ExecState* exec, EncodedJSValue encodedOp1) \
444{ \
445 VM* vm = &exec->vm(); \
446 NativeCallFrameTracer tracer(vm, exec); \
447 auto scope = DECLARE_THROW_SCOPE(*vm); \
448 JSValue op1 = JSValue::decode(encodedOp1); \
449 double result = op1.toNumber(exec); \
450 RETURN_IF_EXCEPTION(scope, PNaN); \
451 return JSC::Math::lowerName(result); \
benjamin@webkit.org770c27f2016-08-24 02:36:40 +0000452}
utatane.tea@gmail.comccb74992017-05-04 11:40:46 +0000453 FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
454#undef DFG_ARITH_UNARY
commit-queue@webkit.orgee8d5482016-08-23 19:09:50 +0000455
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000456double JIT_OPERATION operationArithSqrt(ExecState* exec, EncodedJSValue encodedOp1)
457{
458 VM* vm = &exec->vm();
459 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000460 auto scope = DECLARE_THROW_SCOPE(*vm);
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000461
462 JSValue op1 = JSValue::decode(encodedOp1);
463 double a = op1.toNumber(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000464 RETURN_IF_EXCEPTION(scope, PNaN);
commit-queue@webkit.org91b902c2016-08-20 02:00:44 +0000465 return sqrt(a);
466}
467
commit-queue@webkit.org2e9df642016-09-20 00:48:39 +0000468EncodedJSValue JIT_OPERATION operationArithRound(ExecState* exec, EncodedJSValue encodedArgument)
469{
470 VM* vm = &exec->vm();
471 NativeCallFrameTracer tracer(vm, exec);
472 auto scope = DECLARE_THROW_SCOPE(*vm);
473
474 JSValue argument = JSValue::decode(encodedArgument);
475 double valueOfArgument = argument.toNumber(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000476 RETURN_IF_EXCEPTION(scope, encodedJSValue());
commit-queue@webkit.org2e9df642016-09-20 00:48:39 +0000477 return JSValue::encode(jsNumber(jsRound(valueOfArgument)));
478}
479
480EncodedJSValue JIT_OPERATION operationArithFloor(ExecState* exec, EncodedJSValue encodedArgument)
481{
482 VM* vm = &exec->vm();
483 NativeCallFrameTracer tracer(vm, exec);
484 auto scope = DECLARE_THROW_SCOPE(*vm);
485
486 JSValue argument = JSValue::decode(encodedArgument);
487 double valueOfArgument = argument.toNumber(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000488 RETURN_IF_EXCEPTION(scope, encodedJSValue());
commit-queue@webkit.org2e9df642016-09-20 00:48:39 +0000489 return JSValue::encode(jsNumber(floor(valueOfArgument)));
490}
491
492EncodedJSValue JIT_OPERATION operationArithCeil(ExecState* exec, EncodedJSValue encodedArgument)
493{
494 VM* vm = &exec->vm();
495 NativeCallFrameTracer tracer(vm, exec);
496 auto scope = DECLARE_THROW_SCOPE(*vm);
497
498 JSValue argument = JSValue::decode(encodedArgument);
499 double valueOfArgument = argument.toNumber(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000500 RETURN_IF_EXCEPTION(scope, encodedJSValue());
commit-queue@webkit.org2e9df642016-09-20 00:48:39 +0000501 return JSValue::encode(jsNumber(ceil(valueOfArgument)));
502}
503
504EncodedJSValue JIT_OPERATION operationArithTrunc(ExecState* exec, EncodedJSValue encodedArgument)
505{
506 VM* vm = &exec->vm();
507 NativeCallFrameTracer tracer(vm, exec);
508 auto scope = DECLARE_THROW_SCOPE(*vm);
509
510 JSValue argument = JSValue::decode(encodedArgument);
511 double truncatedValueOfArgument = argument.toIntegerPreserveNaN(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000512 RETURN_IF_EXCEPTION(scope, encodedJSValue());
commit-queue@webkit.org2e9df642016-09-20 00:48:39 +0000513 return JSValue::encode(jsNumber(truncatedValueOfArgument));
514}
515
akling@apple.com6d3d1812014-04-26 06:00:43 +0000516static ALWAYS_INLINE EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
weinig@apple.coma96509f2011-06-15 21:57:17 +0000517{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000518 VM& vm = exec->vm();
519 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000520
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +0000521 if (base->isObject()) {
522 JSObject* object = asObject(base);
523 if (object->canGetIndexQuickly(index))
524 return JSValue::encode(object->getIndexQuickly(index));
525 }
weinig@apple.coma96509f2011-06-15 21:57:17 +0000526
mhahnenberg@apple.comc58d54d2011-12-16 19:06:44 +0000527 if (isJSString(base) && asString(base)->canGetIndex(index))
weinig@apple.coma96509f2011-06-15 21:57:17 +0000528 return JSValue::encode(asString(base)->getIndex(exec, index));
529
weinig@apple.coma96509f2011-06-15 21:57:17 +0000530 return JSValue::encode(JSValue(base).get(exec, index));
531}
532
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000533EncodedJSValue JIT_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000534{
akling@apple.comb6d91ab2014-02-09 21:33:17 +0000535 VM& vm = exec->vm();
536 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000537 auto scope = DECLARE_THROW_SCOPE(vm);
538
barraclough@apple.com2302c042011-03-14 23:31:00 +0000539 JSValue baseValue = JSValue::decode(encodedBase);
540 JSValue property = JSValue::decode(encodedProperty);
541
542 if (LIKELY(baseValue.isCell())) {
543 JSCell* base = baseValue.asCell();
544
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000545 if (property.isUInt32()) {
546 scope.release();
weinig@apple.coma96509f2011-06-15 21:57:17 +0000547 return getByVal(exec, base, property.asUInt32());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000548 }
549 if (property.isDouble()) {
weinig@apple.coma96509f2011-06-15 21:57:17 +0000550 double propertyAsDouble = property.asDouble();
551 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000552 if (propertyAsUInt32 == propertyAsDouble && isIndex(propertyAsUInt32)) {
553 scope.release();
weinig@apple.coma96509f2011-06-15 21:57:17 +0000554 return getByVal(exec, base, propertyAsUInt32);
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000555 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000556 } else if (property.isString()) {
akling@apple.combaca5e82014-05-06 00:53:29 +0000557 Structure& structure = *base->structure(vm);
558 if (JSCell::canUseFastGetOwnProperty(structure)) {
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000559 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
560 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
akling@apple.comcad89042014-09-02 22:29:59 +0000561 return JSValue::encode(result);
562 }
akling@apple.combaca5e82014-05-06 00:53:29 +0000563 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000564 }
barraclough@apple.com2302c042011-03-14 23:31:00 +0000565 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000566
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000567 baseValue.requireObjectCoercible(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000568 RETURN_IF_EXCEPTION(scope, encodedJSValue());
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000569 auto propertyName = property.toPropertyKey(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000570 RETURN_IF_EXCEPTION(scope, encodedJSValue());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +0000571 scope.release();
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +0000572 return JSValue::encode(baseValue.get(exec, propertyName));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000573}
574
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000575EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000576{
akling@apple.comb6d91ab2014-02-09 21:33:17 +0000577 VM& vm = exec->vm();
578 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +0000579 auto scope = DECLARE_THROW_SCOPE(vm);
580
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000581 JSValue property = JSValue::decode(encodedProperty);
582
mark.lam@apple.comf626f162017-09-11 22:16:38 +0000583 if (property.isUInt32()) {
584 scope.release();
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000585 return getByVal(exec, base, property.asUInt32());
mark.lam@apple.comf626f162017-09-11 22:16:38 +0000586 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000587 if (property.isDouble()) {
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000588 double propertyAsDouble = property.asDouble();
589 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
mark.lam@apple.comf626f162017-09-11 22:16:38 +0000590 if (propertyAsUInt32 == propertyAsDouble) {
591 scope.release();
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000592 return getByVal(exec, base, propertyAsUInt32);
mark.lam@apple.comf626f162017-09-11 22:16:38 +0000593 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000594 } else if (property.isString()) {
akling@apple.combaca5e82014-05-06 00:53:29 +0000595 Structure& structure = *base->structure(vm);
596 if (JSCell::canUseFastGetOwnProperty(structure)) {
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000597 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
598 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
akling@apple.comcad89042014-09-02 22:29:59 +0000599 return JSValue::encode(result);
600 }
akling@apple.combaca5e82014-05-06 00:53:29 +0000601 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000602 }
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000603
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000604 auto propertyName = property.toPropertyKey(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +0000605 RETURN_IF_EXCEPTION(scope, encodedJSValue());
mark.lam@apple.comf626f162017-09-11 22:16:38 +0000606 scope.release();
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +0000607 return JSValue::encode(JSValue(base).get(exec, propertyName));
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000608}
609
oliver@apple.com211b3be2013-07-25 04:03:39 +0000610ALWAYS_INLINE EncodedJSValue getByValCellInt(ExecState* exec, JSCell* base, int32_t index)
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000611{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000612 VM* vm = &exec->vm();
613 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000614
615 if (index < 0) {
616 // Go the slowest way possible becase negative indices don't use indexed storage.
617 return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
618 }
619
620 // Use this since we know that the value is out of bounds.
sbarati@apple.com575aa2b2016-03-04 02:25:30 +0000621 return JSValue::encode(JSValue(base).get(exec, static_cast<unsigned>(index)));
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000622}
623
utatane.tea@gmail.com95eee7b2017-05-22 06:24:44 +0000624EncodedJSValue JIT_OPERATION operationGetByValObjectInt(ExecState* exec, JSObject* base, int32_t index)
oliver@apple.com211b3be2013-07-25 04:03:39 +0000625{
626 return getByValCellInt(exec, base, index);
627}
628
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000629EncodedJSValue JIT_OPERATION operationGetByValStringInt(ExecState* exec, JSString* base, int32_t index)
oliver@apple.com211b3be2013-07-25 04:03:39 +0000630{
631 return getByValCellInt(exec, base, index);
632}
633
utatane.tea@gmail.coma12d84b2017-09-08 15:36:05 +0000634EncodedJSValue JIT_OPERATION operationGetByValObjectString(ExecState* exec, JSCell* base, JSCell* string)
635{
636 VM& vm = exec->vm();
637 NativeCallFrameTracer tracer(&vm, exec);
638
639 auto scope = DECLARE_THROW_SCOPE(vm);
640
641 auto propertyName = asString(string)->toIdentifier(exec);
642 RETURN_IF_EXCEPTION(scope, encodedJSValue());
643
644 scope.release();
645 return JSValue::encode(getByValObject(exec, vm, asObject(base), propertyName));
646}
647
648EncodedJSValue JIT_OPERATION operationGetByValObjectSymbol(ExecState* exec, JSCell* base, JSCell* symbol)
649{
650 VM& vm = exec->vm();
651 NativeCallFrameTracer tracer(&vm, exec);
652
653 return JSValue::encode(getByValObject(exec, vm, asObject(base), asSymbol(symbol)->privateName()));
654}
655
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000656void JIT_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000657{
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000658 VM& vm = exec->vm();
659 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000660
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000661 putByValInternal<true, false>(exec, vm, encodedBase, encodedProperty, encodedValue);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000662}
663
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000664void JIT_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000665{
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000666 VM& vm = exec->vm();
667 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000668
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000669 putByValInternal<false, false>(exec, vm, encodedBase, encodedProperty, encodedValue);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000670}
671
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000672void JIT_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000673{
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000674 VM& vm = exec->vm();
675 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000676
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000677 putByValInternal<true, false>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000678}
679
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000680void JIT_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000681{
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000682 VM& vm = exec->vm();
683 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000684
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000685 putByValInternal<false, false>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
686}
687
688void JIT_OPERATION operationPutByValCellStringStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
689{
690 VM& vm = exec->vm();
691 NativeCallFrameTracer tracer(&vm, exec);
692
693 putByValCellStringInternal<true, false>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
694}
695
696void JIT_OPERATION operationPutByValCellStringNonStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
697{
698 VM& vm = exec->vm();
699 NativeCallFrameTracer tracer(&vm, exec);
700
701 putByValCellStringInternal<false, false>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
702}
703
704void JIT_OPERATION operationPutByValCellSymbolStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
705{
706 VM& vm = exec->vm();
707 NativeCallFrameTracer tracer(&vm, exec);
708
709 putByValCellInternal<true, false>(exec, vm, cell, asSymbol(symbol)->privateName(), JSValue::decode(encodedValue));
710}
711
712void JIT_OPERATION operationPutByValCellSymbolNonStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
713{
714 VM& vm = exec->vm();
715 NativeCallFrameTracer tracer(&vm, exec);
716
717 putByValCellInternal<false, false>(exec, vm, cell, asSymbol(symbol)->privateName(), JSValue::decode(encodedValue));
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000718}
719
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000720void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
barraclough@apple.come2130ff2011-06-07 23:03:32 +0000721{
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000722 VM& vm = exec->vm();
723 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000724
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000725 if (index >= 0) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000726 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000727 return;
728 }
729
oliver@apple.com68848412014-01-02 20:56:20 +0000730 PutPropertySlot slot(array, true);
mark.lam@apple.com23e96242017-09-09 16:21:45 +0000731 array->methodTable(vm)->put(
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000732 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000733}
734
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000735void JIT_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000736{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000737 VM* vm = &exec->vm();
738 NativeCallFrameTracer tracer(vm, exec);
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000739
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000740 if (index >= 0) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000741 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000742 return;
743 }
744
oliver@apple.com68848412014-01-02 20:56:20 +0000745 PutPropertySlot slot(array, false);
mark.lam@apple.com23e96242017-09-09 16:21:45 +0000746 array->methodTable(*vm)->put(
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000747 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
barraclough@apple.come2130ff2011-06-07 23:03:32 +0000748}
749
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000750void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000751{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000752 VM* vm = &exec->vm();
753 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000754
755 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
756
757 if (index >= 0) {
758 array->putByIndexInline(exec, index, jsValue, true);
759 return;
760 }
761
oliver@apple.com68848412014-01-02 20:56:20 +0000762 PutPropertySlot slot(array, true);
mark.lam@apple.com23e96242017-09-09 16:21:45 +0000763 array->methodTable(*vm)->put(
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000764 array, exec, Identifier::from(exec, index), jsValue, slot);
765}
766
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000767void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000768{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000769 VM* vm = &exec->vm();
770 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000771
772 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
773
774 if (index >= 0) {
775 array->putByIndexInline(exec, index, jsValue, false);
776 return;
777 }
778
oliver@apple.com68848412014-01-02 20:56:20 +0000779 PutPropertySlot slot(array, false);
mark.lam@apple.com23e96242017-09-09 16:21:45 +0000780 array->methodTable(*vm)->put(
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000781 array, exec, Identifier::from(exec, index), jsValue, slot);
782}
783
oliver@apple.come050d642013-10-19 00:09:28 +0000784void JIT_OPERATION operationPutByValDirectStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
785{
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000786 VM& vm = exec->vm();
787 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come050d642013-10-19 00:09:28 +0000788
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000789 putByValInternal<true, true>(exec, vm, encodedBase, encodedProperty, encodedValue);
oliver@apple.come050d642013-10-19 00:09:28 +0000790}
791
792void JIT_OPERATION operationPutByValDirectNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
793{
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000794 VM& vm = exec->vm();
795 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come050d642013-10-19 00:09:28 +0000796
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000797 putByValInternal<false, true>(exec, vm, encodedBase, encodedProperty, encodedValue);
oliver@apple.come050d642013-10-19 00:09:28 +0000798}
799
800void JIT_OPERATION operationPutByValDirectCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
801{
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000802 VM& vm = exec->vm();
803 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come050d642013-10-19 00:09:28 +0000804
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000805 putByValInternal<true, true>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
oliver@apple.come050d642013-10-19 00:09:28 +0000806}
807
808void JIT_OPERATION operationPutByValDirectCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
809{
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000810 VM& vm = exec->vm();
811 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come050d642013-10-19 00:09:28 +0000812
utatane.tea@gmail.comf4e61e62017-09-08 18:58:24 +0000813 putByValInternal<false, true>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
814}
815
816void JIT_OPERATION operationPutByValDirectCellStringStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
817{
818 VM& vm = exec->vm();
819 NativeCallFrameTracer tracer(&vm, exec);
820
821 putByValCellStringInternal<true, true>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
822}
823
824void JIT_OPERATION operationPutByValDirectCellStringNonStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
825{
826 VM& vm = exec->vm();
827 NativeCallFrameTracer tracer(&vm, exec);
828
829 putByValCellStringInternal<false, true>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
830}
831
832void JIT_OPERATION operationPutByValDirectCellSymbolStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
833{
834 VM& vm = exec->vm();
835 NativeCallFrameTracer tracer(&vm, exec);
836
837 putByValCellInternal<true, true>(exec, vm, cell, asSymbol(symbol)->privateName(), JSValue::decode(encodedValue));
838}
839
840void JIT_OPERATION operationPutByValDirectCellSymbolNonStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
841{
842 VM& vm = exec->vm();
843 NativeCallFrameTracer tracer(&vm, exec);
844
845 putByValCellInternal<false, true>(exec, vm, cell, asSymbol(symbol)->privateName(), JSValue::decode(encodedValue));
oliver@apple.come050d642013-10-19 00:09:28 +0000846}
847
848void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
849{
mark.lam@apple.com23e96242017-09-09 16:21:45 +0000850 VM& vm = exec->vm();
851 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come050d642013-10-19 00:09:28 +0000852 if (index >= 0) {
853 array->putDirectIndex(exec, index, JSValue::decode(encodedValue), 0, PutDirectIndexShouldThrow);
854 return;
855 }
856
oliver@apple.com68848412014-01-02 20:56:20 +0000857 PutPropertySlot slot(array, true);
mark.lam@apple.com23e96242017-09-09 16:21:45 +0000858 array->putDirect(vm, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
oliver@apple.come050d642013-10-19 00:09:28 +0000859}
860
861void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
862{
mark.lam@apple.com23e96242017-09-09 16:21:45 +0000863 VM& vm = exec->vm();
864 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come050d642013-10-19 00:09:28 +0000865
866 if (index >= 0) {
867 array->putDirectIndex(exec, index, JSValue::decode(encodedValue));
868 return;
869 }
870
oliver@apple.com68848412014-01-02 20:56:20 +0000871 PutPropertySlot slot(array, false);
mark.lam@apple.com23e96242017-09-09 16:21:45 +0000872 array->putDirect(vm, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
oliver@apple.come050d642013-10-19 00:09:28 +0000873}
874
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000875EncodedJSValue JIT_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
fpizlo@apple.com24d24e52011-10-04 02:55:54 +0000876{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000877 VM* vm = &exec->vm();
878 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000879
utatane.tea@gmail.com90782872017-09-30 01:16:52 +0000880 array->pushInline(exec, JSValue::decode(encodedValue));
fpizlo@apple.com24d24e52011-10-04 02:55:54 +0000881 return JSValue::encode(jsNumber(array->length()));
882}
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000883
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000884EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000885{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000886 VM* vm = &exec->vm();
887 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000888
utatane.tea@gmail.com90782872017-09-30 01:16:52 +0000889 array->pushInline(exec, JSValue(JSValue::EncodeAsDouble, value));
890 return JSValue::encode(jsNumber(array->length()));
891}
892
893EncodedJSValue JIT_OPERATION operationArrayPushMultiple(ExecState* exec, JSArray* array, void* buffer, int32_t elementCount)
894{
895 VM& vm = exec->vm();
896 NativeCallFrameTracer tracer(&vm, exec);
897 auto scope = DECLARE_THROW_SCOPE(vm);
898
899 // We assume that multiple JSArray::push calls with ArrayWithInt32/ArrayWithContiguous do not cause JS traps.
900 // If it can cause any JS interactions, we can call the caller JS function of this function and overwrite the
901 // content of ScratchBuffer. If the IndexingType is now ArrayWithInt32/ArrayWithContiguous, we can ensure
902 // that there is no indexed accessors in this object and its prototype chain.
903 //
904 // ArrayWithArrayStorage is also OK. It can have indexed accessors. But if you define an indexed accessor, the array's length
905 // becomes larger than that index. So Array#push never overlaps with this accessor. So accessors are never called unless
906 // the IndexingType is ArrayWithSlowPutArrayStorage which could have an indexed accessor in a prototype chain.
907 RELEASE_ASSERT(!shouldUseSlowPut(array->indexingType()));
908
909 EncodedJSValue* values = static_cast<EncodedJSValue*>(buffer);
910 for (int32_t i = 0; i < elementCount; ++i) {
911 array->pushInline(exec, JSValue::decode(values[i]));
912 RETURN_IF_EXCEPTION(scope, encodedJSValue());
913 }
914 return JSValue::encode(jsNumber(array->length()));
915}
916
917EncodedJSValue JIT_OPERATION operationArrayPushDoubleMultiple(ExecState* exec, JSArray* array, void* buffer, int32_t elementCount)
918{
919 VM& vm = exec->vm();
920 NativeCallFrameTracer tracer(&vm, exec);
921 auto scope = DECLARE_THROW_SCOPE(vm);
922
923 // We assume that multiple JSArray::push calls with ArrayWithDouble do not cause JS traps.
924 // If it can cause any JS interactions, we can call the caller JS function of this function and overwrite the
925 // content of ScratchBuffer. If the IndexingType is now ArrayWithDouble, we can ensure
926 // that there is no indexed accessors in this object and its prototype chain.
927 ASSERT(array->indexingType() == ArrayWithDouble);
928
929 double* values = static_cast<double*>(buffer);
930 for (int32_t i = 0; i < elementCount; ++i) {
931 array->pushInline(exec, JSValue(JSValue::EncodeAsDouble, values[i]));
932 RETURN_IF_EXCEPTION(scope, encodedJSValue());
933 }
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000934 return JSValue::encode(jsNumber(array->length()));
935}
936
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000937EncodedJSValue JIT_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000938{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000939 VM* vm = &exec->vm();
940 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000941
942 return JSValue::encode(array->pop(exec));
943}
944
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000945EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000946{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000947 VM* vm = &exec->vm();
948 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000949
950 array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
951
952 return JSValue::encode(array->pop(exec));
953}
954
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000955EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* argument)
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000956{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000957 SuperSamplerScope superSamplerScope(false);
958
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000959 VM& vm = globalObject->vm();
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000960 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000961
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +0000962 return JSValue::encode(regExpObject->execInline(exec, globalObject, argument));
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000963}
964
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000965EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000966{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000967 SuperSamplerScope superSamplerScope(false);
968
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000969 VM& vm = globalObject->vm();
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000970 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com80bd9ec2016-11-14 19:26:20 +0000971 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000972
973 JSValue argument = JSValue::decode(encodedArgument);
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000974
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000975 JSString* input = argument.toStringOrNull(exec);
mark.lam@apple.com135cad52017-09-11 06:23:39 +0000976 EXCEPTION_ASSERT(!!scope.exception() == !input);
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +0000977 if (!input)
mark.lam@apple.com80bd9ec2016-11-14 19:26:20 +0000978 return encodedJSValue();
979 scope.release();
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +0000980 return JSValue::encode(regExpObject->execInline(exec, globalObject, input));
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000981}
982
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000983EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000984{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +0000985 SuperSamplerScope superSamplerScope(false);
986
fpizlo@apple.com7518ba22016-03-06 20:11:09 +0000987 VM& vm = globalObject->vm();
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000988 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000989 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000990
991 JSValue base = JSValue::decode(encodedBase);
992 JSValue argument = JSValue::decode(encodedArgument);
993
keith_miller@apple.com45da7602017-01-27 01:47:52 +0000994 if (!base.inherits(vm, RegExpObject::info()))
mark.lam@apple.com284f4562016-08-30 20:54:54 +0000995 return throwVMTypeError(exec, scope);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000996
997 JSString* input = argument.toStringOrNull(exec);
mark.lam@apple.com135cad52017-09-11 06:23:39 +0000998 EXCEPTION_ASSERT(!!scope.exception() == !input);
fpizlo@apple.com239b0782016-03-03 05:58:59 +0000999 if (!input)
1000 return JSValue::encode(jsUndefined());
mark.lam@apple.com80bd9ec2016-11-14 19:26:20 +00001001 scope.release();
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001002 return JSValue::encode(asRegExpObject(base)->exec(exec, globalObject, input));
barraclough@apple.com077fdd42012-03-18 01:08:16 +00001003}
sbarati@apple.com0c3eb932017-02-24 04:07:30 +00001004
utatane.tea@gmail.com288e68f2017-09-13 07:02:13 +00001005EncodedJSValue JIT_OPERATION operationWeakMapGet(ExecState* exec, JSCell* weakMap, JSCell* object, int32_t hash)
1006{
1007 VM& vm = exec->vm();
1008 NativeCallFrameTracer tracer(&vm, exec);
1009 return JSValue::encode(jsCast<JSWeakMap*>(weakMap)->inlineGet(asObject(object), hash));
1010}
1011
sbarati@apple.com0c3eb932017-02-24 04:07:30 +00001012EncodedJSValue JIT_OPERATION operationParseIntNoRadixGeneric(ExecState* exec, EncodedJSValue value)
1013{
1014 VM& vm = exec->vm();
1015 NativeCallFrameTracer tracer(&vm, exec);
1016
1017 return toStringView(exec, JSValue::decode(value), [&] (StringView view) {
1018 // This version is as if radix was undefined. Hence, undefined.toNumber() === 0.
1019 return parseIntResult(parseInt(view, 0));
1020 });
1021}
1022
1023EncodedJSValue JIT_OPERATION operationParseIntStringNoRadix(ExecState* exec, JSString* string)
1024{
1025 VM& vm = exec->vm();
1026 NativeCallFrameTracer tracer(&vm, exec);
1027 auto scope = DECLARE_THROW_SCOPE(vm);
1028
fpizlo@apple.com9b46f342017-05-11 23:05:01 +00001029 auto viewWithString = string->viewWithUnderlyingString(exec);
sbarati@apple.com0c3eb932017-02-24 04:07:30 +00001030 RETURN_IF_EXCEPTION(scope, { });
1031
1032 // This version is as if radix was undefined. Hence, undefined.toNumber() === 0.
1033 return parseIntResult(parseInt(viewWithString.view, 0));
1034}
1035
1036EncodedJSValue JIT_OPERATION operationParseIntString(ExecState* exec, JSString* string, int32_t radix)
1037{
1038 VM& vm = exec->vm();
1039 NativeCallFrameTracer tracer(&vm, exec);
1040 auto scope = DECLARE_THROW_SCOPE(vm);
1041
fpizlo@apple.com9b46f342017-05-11 23:05:01 +00001042 auto viewWithString = string->viewWithUnderlyingString(exec);
sbarati@apple.com0c3eb932017-02-24 04:07:30 +00001043 RETURN_IF_EXCEPTION(scope, { });
1044
sbarati@apple.com0c3eb932017-02-24 04:07:30 +00001045 return parseIntResult(parseInt(viewWithString.view, radix));
1046}
1047
1048EncodedJSValue JIT_OPERATION operationParseIntGeneric(ExecState* exec, EncodedJSValue value, int32_t radix)
1049{
1050 VM& vm = exec->vm();
1051 NativeCallFrameTracer tracer(&vm, exec);
1052
1053 return toStringView(exec, JSValue::decode(value), [&] (StringView view) {
1054 return parseIntResult(parseInt(view, radix));
1055 });
1056}
barraclough@apple.com077fdd42012-03-18 01:08:16 +00001057
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001058size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* input)
barraclough@apple.com077fdd42012-03-18 01:08:16 +00001059{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +00001060 SuperSamplerScope superSamplerScope(false);
1061
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001062 VM& vm = globalObject->vm();
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001063 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +00001064
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +00001065 return regExpObject->testInline(exec, globalObject, input);
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +00001066}
barraclough@apple.com077fdd42012-03-18 01:08:16 +00001067
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001068size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +00001069{
fpizlo@apple.com5e29b762016-03-18 00:53:24 +00001070 SuperSamplerScope superSamplerScope(false);
1071
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001072 VM& vm = globalObject->vm();
fpizlo@apple.com7fdfeed2016-03-06 00:48:11 +00001073 NativeCallFrameTracer tracer(&vm, exec);
1074
1075 JSValue argument = JSValue::decode(encodedArgument);
1076
1077 JSString* input = argument.toStringOrNull(exec);
1078 if (!input)
1079 return false;
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +00001080 return regExpObject->testInline(exec, globalObject, input);
fpizlo@apple.com239b0782016-03-03 05:58:59 +00001081}
1082
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001083size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
fpizlo@apple.com239b0782016-03-03 05:58:59 +00001084{
fpizlo@apple.com57aea1c2016-04-11 18:20:59 +00001085 SuperSamplerScope superSamplerScope(false);
fpizlo@apple.com5e29b762016-03-18 00:53:24 +00001086
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001087 VM& vm = globalObject->vm();
fpizlo@apple.com239b0782016-03-03 05:58:59 +00001088 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001089 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.com239b0782016-03-03 05:58:59 +00001090
1091 JSValue base = JSValue::decode(encodedBase);
1092 JSValue argument = JSValue::decode(encodedArgument);
1093
keith_miller@apple.com45da7602017-01-27 01:47:52 +00001094 if (!base.inherits(vm, RegExpObject::info())) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001095 throwTypeError(exec, scope);
fpizlo@apple.com239b0782016-03-03 05:58:59 +00001096 return false;
1097 }
1098
1099 JSString* input = argument.toStringOrNull(exec);
mark.lam@apple.com135cad52017-09-11 06:23:39 +00001100 EXCEPTION_ASSERT(!!scope.exception() == !input);
fpizlo@apple.com239b0782016-03-03 05:58:59 +00001101 if (!input)
1102 return false;
mark.lam@apple.com80bd9ec2016-11-14 19:26:20 +00001103 scope.release();
fpizlo@apple.com7518ba22016-03-06 20:11:09 +00001104 return asRegExpObject(base)->test(exec, globalObject, input);
barraclough@apple.com077fdd42012-03-18 01:08:16 +00001105}
fpizlo@apple.comee10e452013-04-09 00:10:16 +00001106
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001107size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
commit-queue@webkit.org6efa2ca2011-07-19 00:36:37 +00001108{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001109 VM* vm = &exec->vm();
1110 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +00001111
commit-queue@webkit.org6efa2ca2011-07-19 00:36:37 +00001112 JSValue op1 = JSValue::decode(encodedOp1);
1113 JSValue op2 = JSValue::decode(encodedOp2);
1114
1115 ASSERT(op1.isCell());
1116 ASSERT(op2.isCell());
1117
1118 return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
1119}
1120
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001121size_t JIT_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com848a0cc2011-04-08 20:33:24 +00001122{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001123 VM* vm = &exec->vm();
1124 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com82acbbf2012-02-28 00:37:58 +00001125
1126 JSValue src1 = JSValue::decode(encodedOp1);
1127 JSValue src2 = JSValue::decode(encodedOp2);
oliver@apple.come07a4592012-01-25 19:43:06 +00001128
fpizlo@apple.com82acbbf2012-02-28 00:37:58 +00001129 return JSValue::strictEqual(exec, src1, src2);
barraclough@apple.com848a0cc2011-04-08 20:33:24 +00001130}
1131
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001132EncodedJSValue JIT_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
fpizlo@apple.com90e5f0e2011-09-22 22:42:54 +00001133{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001134 VM* vm = &exec->vm();
1135 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +00001136
fpizlo@apple.com90e5f0e2011-09-22 22:42:54 +00001137 return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
1138}
1139
utatane.tea@gmail.comdb32c542016-06-30 15:26:47 +00001140EncodedJSValue JIT_OPERATION operationToNumber(ExecState* exec, EncodedJSValue value)
1141{
1142 VM* vm = &exec->vm();
1143 NativeCallFrameTracer tracer(vm, exec);
1144
1145 return JSValue::encode(jsNumber(JSValue::decode(value).toNumber(exec)));
1146}
1147
sbarati@apple.com23315d62016-05-09 20:17:23 +00001148EncodedJSValue JIT_OPERATION operationGetByIdWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, UniquedStringImpl* impl)
1149{
1150 VM& vm = exec->vm();
1151 NativeCallFrameTracer tracer(&vm, exec);
1152
1153 JSValue baseValue = JSValue::decode(encodedBase);
1154 JSValue thisVal = JSValue::decode(encodedThis);
1155 PropertySlot slot(thisVal, PropertySlot::PropertySlot::InternalMethodType::Get);
1156 JSValue result = baseValue.get(exec, Identifier::fromUid(exec, impl), slot);
1157 return JSValue::encode(result);
1158}
1159
1160EncodedJSValue JIT_OPERATION operationGetByValWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript)
1161{
1162 VM& vm = exec->vm();
1163 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001164 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.com23315d62016-05-09 20:17:23 +00001165
1166 JSValue baseValue = JSValue::decode(encodedBase);
1167 JSValue thisVal = JSValue::decode(encodedThis);
1168 JSValue subscript = JSValue::decode(encodedSubscript);
1169
1170 if (LIKELY(baseValue.isCell() && subscript.isString())) {
1171 Structure& structure = *baseValue.asCell()->structure(vm);
1172 if (JSCell::canUseFastGetOwnProperty(structure)) {
1173 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
1174 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
1175 return JSValue::encode(result);
1176 }
1177 }
1178 }
1179
1180 PropertySlot slot(thisVal, PropertySlot::PropertySlot::InternalMethodType::Get);
1181 if (subscript.isUInt32()) {
1182 uint32_t i = subscript.asUInt32();
1183 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
1184 return JSValue::encode(asString(baseValue)->getIndex(exec, i));
1185
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +00001186 scope.release();
sbarati@apple.com23315d62016-05-09 20:17:23 +00001187 return JSValue::encode(baseValue.get(exec, i, slot));
1188 }
1189
1190 baseValue.requireObjectCoercible(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +00001191 RETURN_IF_EXCEPTION(scope, encodedJSValue());
sbarati@apple.com23315d62016-05-09 20:17:23 +00001192
1193 auto property = subscript.toPropertyKey(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +00001194 RETURN_IF_EXCEPTION(scope, encodedJSValue());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +00001195 scope.release();
sbarati@apple.com23315d62016-05-09 20:17:23 +00001196 return JSValue::encode(baseValue.get(exec, property, slot));
1197}
1198
1199void JIT_OPERATION operationPutByIdWithThisStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, UniquedStringImpl* impl)
1200{
1201 VM& vm = exec->vm();
1202 NativeCallFrameTracer tracer(&vm, exec);
1203
1204 putWithThis<true>(exec, encodedBase, encodedThis, encodedValue, Identifier::fromUid(exec, impl));
1205}
1206
1207void JIT_OPERATION operationPutByIdWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedValue, UniquedStringImpl* impl)
1208{
1209 VM& vm = exec->vm();
1210 NativeCallFrameTracer tracer(&vm, exec);
1211
1212 putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, Identifier::fromUid(exec, impl));
1213}
1214
1215void JIT_OPERATION operationPutByValWithThisStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
1216{
1217 VM& vm = exec->vm();
1218 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001219 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.com23315d62016-05-09 20:17:23 +00001220
1221 Identifier property = JSValue::decode(encodedSubscript).toPropertyKey(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +00001222 RETURN_IF_EXCEPTION(scope, void());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +00001223 scope.release();
sbarati@apple.com23315d62016-05-09 20:17:23 +00001224 putWithThis<true>(exec, encodedBase, encodedThis, encodedValue, property);
1225}
1226
1227void JIT_OPERATION operationPutByValWithThis(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedThis, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
1228{
1229 VM& vm = exec->vm();
1230 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com451de992016-09-07 22:10:50 +00001231 auto scope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.com23315d62016-05-09 20:17:23 +00001232
1233 Identifier property = JSValue::decode(encodedSubscript).toPropertyKey(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +00001234 RETURN_IF_EXCEPTION(scope, void());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +00001235 scope.release();
sbarati@apple.com23315d62016-05-09 20:17:23 +00001236 putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, property);
1237}
1238
utatane.tea@gmail.comf7db5592016-10-04 19:31:24 +00001239ALWAYS_INLINE static void defineDataProperty(ExecState* exec, VM& vm, JSObject* base, const Identifier& propertyName, JSValue value, int32_t attributes)
1240{
1241 PropertyDescriptor descriptor = toPropertyDescriptor(value, jsUndefined(), jsUndefined(), DefinePropertyAttributes(attributes));
achristensen@apple.com5c6da6e2017-09-25 22:37:03 +00001242 ASSERT((descriptor.attributes() & PropertyAttribute::Accessor) || (!descriptor.isAccessorDescriptor()));
utatane.tea@gmail.comf7db5592016-10-04 19:31:24 +00001243 if (base->methodTable(vm)->defineOwnProperty == JSObject::defineOwnProperty)
1244 JSObject::defineOwnProperty(base, exec, propertyName, descriptor, true);
1245 else
1246 base->methodTable(vm)->defineOwnProperty(base, exec, propertyName, descriptor, true);
1247}
1248
1249void JIT_OPERATION operationDefineDataProperty(ExecState* exec, JSObject* base, EncodedJSValue encodedProperty, EncodedJSValue encodedValue, int32_t attributes)
1250{
1251 VM& vm = exec->vm();
1252 NativeCallFrameTracer tracer(&vm, exec);
1253 auto scope = DECLARE_THROW_SCOPE(vm);
1254
1255 Identifier propertyName = JSValue::decode(encodedProperty).toPropertyKey(exec);
1256 RETURN_IF_EXCEPTION(scope, void());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +00001257 scope.release();
utatane.tea@gmail.comf7db5592016-10-04 19:31:24 +00001258 defineDataProperty(exec, vm, base, propertyName, JSValue::decode(encodedValue), attributes);
1259}
1260
1261void JIT_OPERATION operationDefineDataPropertyString(ExecState* exec, JSObject* base, JSString* property, EncodedJSValue encodedValue, int32_t attributes)
1262{
1263 VM& vm = exec->vm();
1264 NativeCallFrameTracer tracer(&vm, exec);
1265 auto scope = DECLARE_THROW_SCOPE(vm);
1266
1267 Identifier propertyName = property->toIdentifier(exec);
1268 RETURN_IF_EXCEPTION(scope, void());
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +00001269 scope.release();
utatane.tea@gmail.comf7db5592016-10-04 19:31:24 +00001270 defineDataProperty(exec, vm, base, propertyName, JSValue::decode(encodedValue), attributes);
1271}
1272
1273void JIT_OPERATION operationDefineDataPropertyStringIdent(ExecState* exec, JSObject* base, UniquedStringImpl* property, EncodedJSValue encodedValue, int32_t attributes)
1274{
1275 VM& vm = exec->vm();
1276 NativeCallFrameTracer tracer(&vm, exec);
1277 defineDataProperty(exec, vm, base, Identifier::fromUid(&vm, property), JSValue::decode(encodedValue), attributes);
1278}
1279
1280void JIT_OPERATION operationDefineDataPropertySymbol(ExecState* exec, JSObject* base, Symbol* property, EncodedJSValue encodedValue, int32_t attributes)
1281{
1282 VM& vm = exec->vm();
1283 NativeCallFrameTracer tracer(&vm, exec);
1284 defineDataProperty(exec, vm, base, Identifier::fromUid(property->privateName()), JSValue::decode(encodedValue), attributes);
1285}
1286
1287ALWAYS_INLINE static void defineAccessorProperty(ExecState* exec, VM& vm, JSObject* base, const Identifier& propertyName, JSObject* getter, JSObject* setter, int32_t attributes)
1288{
1289 PropertyDescriptor descriptor = toPropertyDescriptor(jsUndefined(), getter, setter, DefinePropertyAttributes(attributes));
achristensen@apple.com5c6da6e2017-09-25 22:37:03 +00001290 ASSERT((descriptor.attributes() & PropertyAttribute::Accessor) || (!descriptor.isAccessorDescriptor()));
utatane.tea@gmail.comf7db5592016-10-04 19:31:24 +00001291 if (base->methodTable(vm)->defineOwnProperty == JSObject::defineOwnProperty)
1292 JSObject::defineOwnProperty(base, exec, propertyName, descriptor, true);
1293 else
1294 base->methodTable(vm)->defineOwnProperty(base, exec, propertyName, descriptor, true);
1295}
1296
1297void JIT_OPERATION operationDefineAccessorProperty(ExecState* exec, JSObject* base, EncodedJSValue encodedProperty, JSObject* getter, JSObject* setter, int32_t attributes)
1298{
1299 VM& vm = exec->vm();
1300 NativeCallFrameTracer tracer(&vm, exec);
1301 auto scope = DECLARE_THROW_SCOPE(vm);
1302
1303 Identifier propertyName = JSValue::decode(encodedProperty).toPropertyKey(exec);
1304 RETURN_IF_EXCEPTION(scope, void());
1305 defineAccessorProperty(exec, vm, base, propertyName, getter, setter, attributes);
1306}
1307
1308void JIT_OPERATION operationDefineAccessorPropertyString(ExecState* exec, JSObject* base, JSString* property, JSObject* getter, JSObject* setter, int32_t attributes)
1309{
1310 VM& vm = exec->vm();
1311 NativeCallFrameTracer tracer(&vm, exec);
1312 auto scope = DECLARE_THROW_SCOPE(vm);
1313
1314 Identifier propertyName = property->toIdentifier(exec);
1315 RETURN_IF_EXCEPTION(scope, void());
1316 defineAccessorProperty(exec, vm, base, propertyName, getter, setter, attributes);
1317}
1318
1319void JIT_OPERATION operationDefineAccessorPropertyStringIdent(ExecState* exec, JSObject* base, UniquedStringImpl* property, JSObject* getter, JSObject* setter, int32_t attributes)
1320{
1321 VM& vm = exec->vm();
1322 NativeCallFrameTracer tracer(&vm, exec);
1323 defineAccessorProperty(exec, vm, base, Identifier::fromUid(&vm, property), getter, setter, attributes);
1324}
1325
1326void JIT_OPERATION operationDefineAccessorPropertySymbol(ExecState* exec, JSObject* base, Symbol* property, JSObject* getter, JSObject* setter, int32_t attributes)
1327{
1328 VM& vm = exec->vm();
1329 NativeCallFrameTracer tracer(&vm, exec);
1330 defineAccessorProperty(exec, vm, base, Identifier::fromUid(property->privateName()), getter, setter, attributes);
1331}
1332
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001333char* JIT_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +00001334{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001335 VM* vm = &exec->vm();
1336 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com1bc68482012-10-13 03:56:09 +00001337
fpizlo@apple.com59d1ddb2013-11-05 00:05:02 +00001338 return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +00001339}
1340
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001341char* JIT_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +00001342{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001343 VM* vm = &exec->vm();
1344 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com1bc68482012-10-13 03:56:09 +00001345
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001346 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +00001347}
1348
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001349char* JIT_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size, Butterfly* butterfly)
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +00001350{
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001351 VM& vm = exec->vm();
1352 NativeCallFrameTracer tracer(&vm, exec);
1353 auto scope = DECLARE_THROW_SCOPE(vm);
msaboff@apple.com51d65f22013-04-10 20:01:14 +00001354
msaboff@apple.com6ebf3b82013-04-11 16:19:35 +00001355 if (UNLIKELY(size < 0))
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001356 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 +00001357
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001358 JSArray* result;
1359 if (butterfly)
fpizlo@apple.com9a175952016-09-28 21:55:53 +00001360 result = JSArray::createWithButterfly(vm, nullptr, arrayStructure, butterfly);
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00001361 else
1362 result = JSArray::create(vm, arrayStructure, size);
fpizlo@apple.com8dde06b2015-10-12 22:41:01 +00001363 return bitwise_cast<char*>(result);
fpizlo@apple.com98a693c2011-09-28 05:33:21 +00001364}
1365
utatane.tea@gmail.comb9355b52017-09-22 12:19:54 +00001366char* JIT_OPERATION operationNewArrayWithSizeAndHint(ExecState* exec, Structure* arrayStructure, int32_t size, int32_t vectorLengthHint, Butterfly* butterfly)
1367{
1368 VM& vm = exec->vm();
1369 NativeCallFrameTracer tracer(&vm, exec);
1370 auto scope = DECLARE_THROW_SCOPE(vm);
1371
1372 if (UNLIKELY(size < 0))
1373 return bitwise_cast<char*>(throwException(exec, scope, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
1374
1375 JSArray* result;
1376 if (butterfly)
1377 result = JSArray::createWithButterfly(vm, nullptr, arrayStructure, butterfly);
1378 else {
1379 result = JSArray::tryCreate(vm, arrayStructure, size, vectorLengthHint);
1380 ASSERT(result);
1381 }
1382 return bitwise_cast<char*>(result);
1383}
1384
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001385char* JIT_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +00001386{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001387 VM& vm = exec->vm();
1388 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com59d1ddb2013-11-05 00:05:02 +00001389 return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
fpizlo@apple.com98a693c2011-09-28 05:33:21 +00001390}
1391
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001392char* JIT_OPERATION operationNewInt8ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001393 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001394{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001395 return newTypedArrayWithSize<JSInt8Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001396}
1397
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001398char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001399 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1400{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001401 VM& vm = exec->vm();
1402 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com43926962016-11-27 06:08:16 +00001403 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt8Array>(exec, structure, encodedValue, 0, std::nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001404}
1405
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001406char* JIT_OPERATION operationNewInt16ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001407 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001408{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001409 return newTypedArrayWithSize<JSInt16Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001410}
1411
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001412char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001413 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1414{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001415 VM& vm = exec->vm();
1416 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com43926962016-11-27 06:08:16 +00001417 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt16Array>(exec, structure, encodedValue, 0, std::nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001418}
1419
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001420char* JIT_OPERATION operationNewInt32ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001421 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001422{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001423 return newTypedArrayWithSize<JSInt32Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001424}
1425
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001426char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001427 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1428{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001429 VM& vm = exec->vm();
1430 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com43926962016-11-27 06:08:16 +00001431 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt32Array>(exec, structure, encodedValue, 0, std::nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001432}
1433
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001434char* JIT_OPERATION operationNewUint8ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001435 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001436{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001437 return newTypedArrayWithSize<JSUint8Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001438}
1439
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001440char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001441 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1442{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001443 VM& vm = exec->vm();
1444 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com43926962016-11-27 06:08:16 +00001445 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8Array>(exec, structure, encodedValue, 0, std::nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001446}
1447
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001448char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001449 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001450{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001451 return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001452}
1453
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001454char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001455 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1456{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001457 VM& vm = exec->vm();
1458 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com43926962016-11-27 06:08:16 +00001459 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8ClampedArray>(exec, structure, encodedValue, 0, std::nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001460}
1461
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001462char* JIT_OPERATION operationNewUint16ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001463 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001464{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001465 return newTypedArrayWithSize<JSUint16Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001466}
1467
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001468char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001469 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1470{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001471 VM& vm = exec->vm();
1472 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com43926962016-11-27 06:08:16 +00001473 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint16Array>(exec, structure, encodedValue, 0, std::nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001474}
1475
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001476char* JIT_OPERATION operationNewUint32ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001477 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001478{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001479 return newTypedArrayWithSize<JSUint32Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001480}
1481
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001482char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001483 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1484{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001485 VM& vm = exec->vm();
1486 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com43926962016-11-27 06:08:16 +00001487 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint32Array>(exec, structure, encodedValue, 0, std::nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001488}
1489
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001490char* JIT_OPERATION operationNewFloat32ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001491 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001492{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001493 return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001494}
1495
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001496char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001497 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1498{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001499 VM& vm = exec->vm();
1500 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com43926962016-11-27 06:08:16 +00001501 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat32Array>(exec, structure, encodedValue, 0, std::nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001502}
1503
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001504char* JIT_OPERATION operationNewFloat64ArrayWithSize(
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001505 ExecState* exec, Structure* structure, int32_t length, char* vector)
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001506{
fpizlo@apple.com30a72582016-09-08 16:47:34 +00001507 return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length, vector);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001508}
1509
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001510char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001511 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1512{
fpizlo@apple.com39303e02016-04-05 22:17:35 +00001513 VM& vm = exec->vm();
1514 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com43926962016-11-27 06:08:16 +00001515 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat64Array>(exec, structure, encodedValue, 0, std::nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001516}
1517
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00001518JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState* exec, Structure* structure, JSScope* scope, SymbolTable* table, EncodedJSValue initialValueEncoded)
fpizlo@apple.comc6446112012-05-23 20:52:42 +00001519{
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00001520 JSValue initialValue = JSValue::decode(initialValueEncoded);
1521 ASSERT(initialValue == jsUndefined() || initialValue == jsTDZValue());
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001522 VM& vm = exec->vm();
1523 NativeCallFrameTracer tracer(&vm, exec);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00001524 return JSLexicalEnvironment::create(vm, structure, scope, table, initialValue);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001525}
1526
1527JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState* exec, Structure* structure, int32_t length, int32_t minCapacity)
1528{
1529 VM& vm = exec->vm();
1530 NativeCallFrameTracer target(&vm, exec);
1531 DirectArguments* result = DirectArguments::create(
1532 vm, structure, length, std::max(length, minCapacity));
1533 // The caller will store to this object without barriers. Most likely, at this point, this is
1534 // still a young object and so no barriers are needed. But it's good to be careful anyway,
1535 // since the GC should be allowed to do crazy (like pretenuring, for example).
1536 vm.heap.writeBarrier(result);
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001537 return result;
fpizlo@apple.comc6446112012-05-23 20:52:42 +00001538}
1539
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001540JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment* scope)
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001541{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001542 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001543 NativeCallFrameTracer target(&vm, exec);
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001544
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001545 // We could pass the ScopedArgumentsTable* as an argument. We currently don't because I
1546 // didn't feel like changing the max number of arguments for a slow path call from 6 to 7.
1547 ScopedArgumentsTable* table = scope->symbolTable()->arguments();
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001548
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001549 return ScopedArguments::createByCopyingFrom(
1550 vm, structure, argumentStart, length, callee, table, scope);
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001551}
1552
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001553JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee)
fpizlo@apple.comd5547492012-06-07 00:23:36 +00001554{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001555 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001556 NativeCallFrameTracer target(&vm, exec);
1557 return ClonedArguments::createByCopyingFrom(
1558 exec, structure, argumentStart, length, callee);
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001559}
1560
mark.lam@apple.comf0e22f12017-09-14 04:21:05 +00001561JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
1562{
1563 VM& vm = exec->vm();
1564 NativeCallFrameTracer target(&vm, exec);
1565
1566 DeferGCForAWhile deferGC(vm.heap);
1567
1568 CodeBlock* codeBlock;
1569 if (inlineCallFrame)
1570 codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
1571 else
1572 codeBlock = exec->codeBlock();
1573
1574 unsigned length = argumentCount - 1;
1575 unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
1576 DirectArguments* result = DirectArguments::create(
1577 vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
1578
1579 result->callee().set(vm, result, callee);
1580
1581 Register* arguments =
1582 exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
1583 CallFrame::argumentOffset(0);
1584 for (unsigned i = length; i--;)
1585 result->setIndexQuickly(vm, i, arguments[i].jsValue());
1586
1587 return result;
1588}
1589
1590JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
1591{
1592 VM& vm = exec->vm();
1593 NativeCallFrameTracer target(&vm, exec);
1594
1595 DeferGCForAWhile deferGC(vm.heap);
1596
1597 CodeBlock* codeBlock;
1598 if (inlineCallFrame)
1599 codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
1600 else
1601 codeBlock = exec->codeBlock();
1602
1603 unsigned length = argumentCount - 1;
1604 ClonedArguments* result = ClonedArguments::createEmpty(
1605 vm, codeBlock->globalObject()->clonedArgumentsStructure(), callee, length);
1606
1607 Register* arguments =
1608 exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
1609 CallFrame::argumentOffset(0);
1610 for (unsigned i = length; i--;)
1611 result->putDirectIndex(exec, i, arguments[i].jsValue());
1612
1613
1614 return result;
1615}
1616
sbarati@apple.com6cfefd82016-08-13 02:14:42 +00001617JSCell* JIT_OPERATION operationCreateRest(ExecState* exec, Register* argumentStart, unsigned numberOfParamsToSkip, unsigned arraySize)
sbarati@apple.comc0722da2015-11-20 02:37:47 +00001618{
keith_miller@apple.com1b8b0062016-04-16 01:26:10 +00001619 VM* vm = &exec->vm();
1620 NativeCallFrameTracer tracer(vm, exec);
1621
sbarati@apple.com6cfefd82016-08-13 02:14:42 +00001622 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
sbarati@apple.com7a74ce72016-11-01 20:03:03 +00001623 Structure* structure = globalObject->restParameterStructure();
sbarati@apple.com6cfefd82016-08-13 02:14:42 +00001624 static_assert(sizeof(Register) == sizeof(JSValue), "This is a strong assumption here.");
1625 JSValue* argumentsToCopyRegion = bitwise_cast<JSValue*>(argumentStart) + numberOfParamsToSkip;
1626 return constructArray(exec, structure, argumentsToCopyRegion, arraySize);
sbarati@apple.comc0722da2015-11-20 02:37:47 +00001627}
1628
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001629size_t JIT_OPERATION operationObjectIsObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
oliver@apple.come722ad02013-01-09 02:37:29 +00001630{
mark.lam@apple.com87a5b6f2014-02-05 04:22:43 +00001631 VM& vm = exec->vm();
1632 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001633
keith_miller@apple.com45da7602017-01-27 01:47:52 +00001634 ASSERT(jsDynamicCast<JSObject*>(vm, object));
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001635
1636 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1637 return false;
1638 if (object->type() == JSFunctionType)
1639 return false;
1640 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1641 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001642 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001643 return false;
1644 }
1645
1646 return true;
1647}
1648
1649size_t JIT_OPERATION operationObjectIsFunction(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1650{
1651 VM& vm = exec->vm();
1652 NativeCallFrameTracer tracer(&vm, exec);
1653
keith_miller@apple.com45da7602017-01-27 01:47:52 +00001654 ASSERT(jsDynamicCast<JSObject*>(vm, object));
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001655
1656 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1657 return false;
1658 if (object->type() == JSFunctionType)
1659 return true;
1660 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1661 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001662 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001663 return true;
1664 }
1665
1666 return false;
1667}
1668
1669JSCell* JIT_OPERATION operationTypeOfObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1670{
1671 VM& vm = exec->vm();
1672 NativeCallFrameTracer tracer(&vm, exec);
1673
keith_miller@apple.com45da7602017-01-27 01:47:52 +00001674 ASSERT(jsDynamicCast<JSObject*>(vm, object));
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001675
1676 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1677 return vm.smallStrings.undefinedString();
1678 if (object->type() == JSFunctionType)
1679 return vm.smallStrings.functionString();
1680 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1681 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001682 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001683 return vm.smallStrings.functionString();
1684 }
1685
1686 return vm.smallStrings.objectString();
1687}
1688
1689int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
1690{
1691 VM& vm = exec->vm();
1692 NativeCallFrameTracer tracer(&vm, exec);
1693
keith_miller@apple.com45da7602017-01-27 01:47:52 +00001694 ASSERT(jsDynamicCast<JSObject*>(vm, object));
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001695
1696 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1697 return static_cast<int32_t>(TypeofType::Undefined);
1698 if (object->type() == JSFunctionType)
1699 return static_cast<int32_t>(TypeofType::Function);
1700 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1701 CallData callData;
utatane.tea@gmail.comf76f1b42016-03-05 17:01:04 +00001702 if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
fpizlo@apple.comb8823d52015-05-03 00:15:27 +00001703 return static_cast<int32_t>(TypeofType::Function);
1704 }
1705
1706 return static_cast<int32_t>(TypeofType::Object);
oliver@apple.come722ad02013-01-09 02:37:29 +00001707}
1708
fpizlo@apple.comb0e7f3d2016-12-10 01:22:15 +00001709char* JIT_OPERATION operationAllocateSimplePropertyStorageWithInitialCapacity(ExecState* exec)
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001710{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001711 VM& vm = exec->vm();
1712 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comc17054c2012-09-18 15:22:29 +00001713
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001714 return reinterpret_cast<char*>(
oliver@apple.coma03796a2013-07-25 04:01:20 +00001715 Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001716}
1717
fpizlo@apple.comb0e7f3d2016-12-10 01:22:15 +00001718char* JIT_OPERATION operationAllocateSimplePropertyStorage(ExecState* exec, size_t newSize)
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001719{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001720 VM& vm = exec->vm();
1721 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comc17054c2012-09-18 15:22:29 +00001722
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001723 return reinterpret_cast<char*>(
oliver@apple.coma03796a2013-07-25 04:01:20 +00001724 Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001725}
1726
fpizlo@apple.comb0e7f3d2016-12-10 01:22:15 +00001727char* JIT_OPERATION operationAllocateComplexPropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
1728{
1729 VM& vm = exec->vm();
1730 NativeCallFrameTracer tracer(&vm, exec);
1731
1732 ASSERT(!object->structure()->outOfLineCapacity());
1733 return reinterpret_cast<char*>(
1734 object->allocateMoreOutOfLineStorage(vm, 0, initialOutOfLineCapacity));
1735}
1736
1737char* JIT_OPERATION operationAllocateComplexPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
1738{
1739 VM& vm = exec->vm();
1740 NativeCallFrameTracer tracer(&vm, exec);
1741
1742 return reinterpret_cast<char*>(
1743 object->allocateMoreOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize));
1744}
1745
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001746char* JIT_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001747{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001748 VM& vm = exec->vm();
1749 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001750
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001751 if (!cell->isObject())
1752 return 0;
1753
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001754 return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001755}
1756
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001757char* JIT_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001758{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001759 VM& vm = exec->vm();
1760 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001761
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001762 if (!cell->isObject())
1763 return 0;
1764
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001765 return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001766}
1767
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001768char* JIT_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001769{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001770 VM& vm = exec->vm();
1771 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001772
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001773 if (!cell->isObject())
1774 return 0;
1775
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001776 return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001777}
1778
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001779char* JIT_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001780{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001781 VM& vm = exec->vm();
1782 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001783
1784 if (!cell->isObject())
1785 return 0;
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001786
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001787 return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001788}
1789
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001790StringImpl* JIT_OPERATION operationResolveRope(ExecState* exec, JSString* string)
fpizlo@apple.com70bb5c52012-12-11 05:22:49 +00001791{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001792 VM& vm = exec->vm();
1793 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com70bb5c52012-12-11 05:22:49 +00001794
1795 return string->value(exec).impl();
1796}
1797
sbarati@apple.com527ebc22016-10-05 06:16:15 +00001798JSString* JIT_OPERATION operationToLowerCase(ExecState* exec, JSString* string, uint32_t failingIndex)
1799{
1800 VM& vm = exec->vm();
1801 NativeCallFrameTracer tracer(&vm, exec);
1802
1803 auto scope = DECLARE_THROW_SCOPE(vm);
1804
1805 const String& inputString = string->value(exec);
1806 RETURN_IF_EXCEPTION(scope, nullptr);
sbarati@apple.comd5ee1a92016-10-15 20:56:24 +00001807 if (!inputString.length())
1808 return vm.smallStrings.emptyString();
1809
sbarati@apple.com527ebc22016-10-05 06:16:15 +00001810 String lowercasedString = inputString.is8Bit() ? inputString.convertToLowercaseWithoutLocaleStartingAtFailingIndex8Bit(failingIndex) : inputString.convertToLowercaseWithoutLocale();
1811 if (lowercasedString.impl() == inputString.impl())
1812 return string;
1813 scope.release();
1814 return jsString(exec, lowercasedString);
1815}
1816
utatane.tea@gmail.comfe5e95d2017-03-21 11:31:43 +00001817char* JIT_OPERATION operationInt32ToString(ExecState* exec, int32_t value, int32_t radix)
1818{
1819 VM& vm = exec->vm();
1820 NativeCallFrameTracer tracer(&vm, exec);
1821
1822 auto scope = DECLARE_THROW_SCOPE(vm);
1823
1824 if (radix < 2 || radix > 36) {
1825 throwVMError(exec, scope, createRangeError(exec, ASCIILiteral("toString() radix argument must be between 2 and 36")));
1826 return nullptr;
1827 }
1828
1829 return reinterpret_cast<char*>(int32ToString(vm, value, radix));
1830}
1831
1832char* JIT_OPERATION operationInt52ToString(ExecState* exec, int64_t value, int32_t radix)
1833{
1834 VM& vm = exec->vm();
1835 NativeCallFrameTracer tracer(&vm, exec);
1836
1837 auto scope = DECLARE_THROW_SCOPE(vm);
1838
1839 if (radix < 2 || radix > 36) {
1840 throwVMError(exec, scope, createRangeError(exec, ASCIILiteral("toString() radix argument must be between 2 and 36")));
1841 return nullptr;
1842 }
1843
1844 return reinterpret_cast<char*>(int52ToString(vm, value, radix));
1845}
1846
1847char* JIT_OPERATION operationDoubleToString(ExecState* exec, double value, int32_t radix)
1848{
1849 VM& vm = exec->vm();
1850 NativeCallFrameTracer tracer(&vm, exec);
1851
1852 auto scope = DECLARE_THROW_SCOPE(vm);
1853
1854 if (radix < 2 || radix > 36) {
1855 throwVMError(exec, scope, createRangeError(exec, ASCIILiteral("toString() radix argument must be between 2 and 36")));
1856 return nullptr;
1857 }
1858
1859 return reinterpret_cast<char*>(numberToString(vm, value, radix));
1860}
1861
1862char* JIT_OPERATION operationInt32ToStringWithValidRadix(ExecState* exec, int32_t value, int32_t radix)
1863{
1864 VM& vm = exec->vm();
1865 NativeCallFrameTracer tracer(&vm, exec);
1866
1867 return reinterpret_cast<char*>(int32ToString(vm, value, radix));
1868}
1869
1870char* JIT_OPERATION operationInt52ToStringWithValidRadix(ExecState* exec, int64_t value, int32_t radix)
1871{
1872 VM& vm = exec->vm();
1873 NativeCallFrameTracer tracer(&vm, exec);
1874
1875 return reinterpret_cast<char*>(int52ToString(vm, value, radix));
1876}
1877
1878char* JIT_OPERATION operationDoubleToStringWithValidRadix(ExecState* exec, double value, int32_t radix)
1879{
1880 VM& vm = exec->vm();
1881 NativeCallFrameTracer tracer(&vm, exec);
1882
1883 return reinterpret_cast<char*>(numberToString(vm, value, radix));
1884}
1885
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001886JSString* JIT_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
oliver@apple.com63af2d42013-07-25 04:03:33 +00001887{
1888 VM& vm = exec->vm();
1889 NativeCallFrameTracer tracer(&vm, exec);
1890
1891 return jsSingleCharacterString(exec, static_cast<UChar>(character));
1892}
1893
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001894JSCell* JIT_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001895{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001896 VM& vm = exec->vm();
1897 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001898
akling@apple.com019809c2013-10-06 18:16:48 +00001899 return StringObject::create(vm, structure, string);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001900}
1901
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001902JSCell* JIT_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001903{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001904 VM& vm = exec->vm();
1905 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001906
1907 return JSValue(cell).toString(exec);
1908}
1909
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001910JSCell* JIT_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001911{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001912 VM& vm = exec->vm();
1913 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001914
1915 return JSValue::decode(value).toString(exec);
1916}
1917
utatane.tea@gmail.com153559e2015-04-06 19:07:12 +00001918JSCell* JIT_OPERATION operationCallStringConstructorOnCell(ExecState* exec, JSCell* cell)
1919{
1920 VM& vm = exec->vm();
1921 NativeCallFrameTracer tracer(&vm, exec);
1922
1923 return stringConstructor(exec, cell);
1924}
1925
1926JSCell* JIT_OPERATION operationCallStringConstructor(ExecState* exec, EncodedJSValue value)
1927{
1928 VM& vm = exec->vm();
1929 NativeCallFrameTracer tracer(&vm, exec);
1930
1931 return stringConstructor(exec, JSValue::decode(value));
1932}
1933
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001934JSCell* JIT_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001935{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001936 VM& vm = exec->vm();
1937 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com24c49992014-04-19 21:13:46 +00001938
mark.lam@apple.com581437a2016-09-22 23:41:56 +00001939 return jsString(exec, left, right);
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001940}
1941
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001942JSCell* JIT_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001943{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001944 VM& vm = exec->vm();
1945 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001946
mark.lam@apple.com581437a2016-09-22 23:41:56 +00001947 return jsString(exec, a, b, c);
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001948}
1949
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001950JSCell* JIT_OPERATION operationStrCat2(ExecState* exec, EncodedJSValue a, EncodedJSValue b)
1951{
1952 VM& vm = exec->vm();
1953 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001954 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001955
1956 JSString* str1 = JSValue::decode(a).toString(exec);
mark.lam@apple.comcce76562017-05-08 16:56:32 +00001957 scope.assertNoException(); // Impossible, since we must have been given primitives.
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001958 JSString* str2 = JSValue::decode(b).toString(exec);
mark.lam@apple.comcce76562017-05-08 16:56:32 +00001959 scope.assertNoException();
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001960
mark.lam@apple.com581437a2016-09-22 23:41:56 +00001961 scope.release();
1962 return jsString(exec, str1, str2);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001963}
1964
1965JSCell* JIT_OPERATION operationStrCat3(ExecState* exec, EncodedJSValue a, EncodedJSValue b, EncodedJSValue c)
1966{
1967 VM& vm = exec->vm();
1968 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00001969 auto scope = DECLARE_THROW_SCOPE(vm);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001970
1971 JSString* str1 = JSValue::decode(a).toString(exec);
mark.lam@apple.comcce76562017-05-08 16:56:32 +00001972 scope.assertNoException(); // Impossible, since we must have been given primitives.
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001973 JSString* str2 = JSValue::decode(b).toString(exec);
mark.lam@apple.comcce76562017-05-08 16:56:32 +00001974 scope.assertNoException();
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001975 JSString* str3 = JSValue::decode(c).toString(exec);
mark.lam@apple.comcce76562017-05-08 16:56:32 +00001976 scope.assertNoException();
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001977
mark.lam@apple.com581437a2016-09-22 23:41:56 +00001978 scope.release();
1979 return jsString(exec, str1, str2, str3);
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001980}
1981
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001982char* JIT_OPERATION operationFindSwitchImmTargetForDouble(
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001983 ExecState* exec, EncodedJSValue encodedValue, size_t tableIndex)
1984{
keith_miller@apple.com1b8b0062016-04-16 01:26:10 +00001985 VM& vm = exec->vm();
1986 NativeCallFrameTracer tracer(&vm, exec);
1987
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001988 CodeBlock* codeBlock = exec->codeBlock();
oliver@apple.coma14cea52013-07-25 04:03:23 +00001989 SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001990 JSValue value = JSValue::decode(encodedValue);
1991 ASSERT(value.isDouble());
1992 double asDouble = value.asDouble();
1993 int32_t asInt32 = static_cast<int32_t>(asDouble);
1994 if (asDouble == asInt32)
1995 return static_cast<char*>(table.ctiForValue(asInt32).executableAddress());
1996 return static_cast<char*>(table.ctiDefault.executableAddress());
1997}
1998
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001999char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JSString* string)
oliver@apple.com5c826c02013-07-25 04:03:51 +00002000{
2001 VM& vm = exec->vm();
2002 NativeCallFrameTracer tracer(&vm, exec);
2003
2004 return static_cast<char*>(exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress());
2005}
2006
fpizlo@apple.com5a3036b2015-04-29 03:34:43 +00002007int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)
2008{
2009 VM& vm = exec->vm();
2010 NativeCallFrameTracer tracer(&vm, exec);
2011
2012 return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(string->value(exec).impl(), std::numeric_limits<int32_t>::min());
2013}
2014
commit-queue@webkit.org36c52882016-04-22 05:08:28 +00002015uintptr_t JIT_OPERATION operationCompareStringImplLess(StringImpl* a, StringImpl* b)
2016{
2017 return codePointCompare(a, b) < 0;
2018}
2019
2020uintptr_t JIT_OPERATION operationCompareStringImplLessEq(StringImpl* a, StringImpl* b)
2021{
2022 return codePointCompare(a, b) <= 0;
2023}
2024
2025uintptr_t JIT_OPERATION operationCompareStringImplGreater(StringImpl* a, StringImpl* b)
2026{
2027 return codePointCompare(a, b) > 0;
2028}
2029
2030uintptr_t JIT_OPERATION operationCompareStringImplGreaterEq(StringImpl* a, StringImpl* b)
2031{
2032 return codePointCompare(a, b) >= 0;
2033}
2034
2035uintptr_t JIT_OPERATION operationCompareStringLess(ExecState* exec, JSString* a, JSString* b)
2036{
2037 VM& vm = exec->vm();
2038 NativeCallFrameTracer tracer(&vm, exec);
2039
2040 return codePointCompareLessThan(asString(a)->value(exec), asString(b)->value(exec));
2041}
2042
2043uintptr_t JIT_OPERATION operationCompareStringLessEq(ExecState* exec, JSString* a, JSString* b)
2044{
2045 VM& vm = exec->vm();
2046 NativeCallFrameTracer tracer(&vm, exec);
2047
2048 return !codePointCompareLessThan(asString(b)->value(exec), asString(a)->value(exec));
2049}
2050
2051uintptr_t JIT_OPERATION operationCompareStringGreater(ExecState* exec, JSString* a, JSString* b)
2052{
2053 VM& vm = exec->vm();
2054 NativeCallFrameTracer tracer(&vm, exec);
2055
2056 return codePointCompareLessThan(asString(b)->value(exec), asString(a)->value(exec));
2057}
2058
2059uintptr_t JIT_OPERATION operationCompareStringGreaterEq(ExecState* exec, JSString* a, JSString* b)
2060{
2061 VM& vm = exec->vm();
2062 NativeCallFrameTracer tracer(&vm, exec);
2063
2064 return !codePointCompareLessThan(asString(a)->value(exec), asString(b)->value(exec));
2065}
2066
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +00002067void JIT_OPERATION operationNotifyWrite(ExecState* exec, WatchpointSet* set)
fpizlo@apple.com33961712013-11-20 05:49:05 +00002068{
2069 VM& vm = exec->vm();
2070 NativeCallFrameTracer tracer(&vm, exec);
2071
sbarati@apple.com0c3609d2016-06-28 21:30:20 +00002072 set->touch(vm, "Executed NotifyWrite");
fpizlo@apple.com33961712013-11-20 05:49:05 +00002073}
2074
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002075void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
2076{
2077 VM& vm = exec->vm();
2078 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00002079 auto scope = DECLARE_THROW_SCOPE(vm);
2080 throwStackOverflowError(exec, scope);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002081}
2082
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00002083int32_t JIT_OPERATION operationSizeOfVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
2084{
2085 VM& vm = exec->vm();
2086 NativeCallFrameTracer tracer(&vm, exec);
2087 JSValue arguments = JSValue::decode(encodedArguments);
2088
2089 return sizeOfVarargs(exec, arguments, firstVarArgOffset);
2090}
2091
sbarati@apple.coma3db4652016-09-20 01:05:50 +00002092int32_t JIT_OPERATION operationHasOwnProperty(ExecState* exec, JSObject* thisObject, EncodedJSValue encodedKey)
2093{
2094 VM& vm = exec->vm();
2095 NativeCallFrameTracer tracer(&vm, exec);
2096 auto scope = DECLARE_THROW_SCOPE(vm);
2097
2098 JSValue key = JSValue::decode(encodedKey);
2099 Identifier propertyName = key.toPropertyKey(exec);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +00002100 RETURN_IF_EXCEPTION(scope, false);
sbarati@apple.coma3db4652016-09-20 01:05:50 +00002101
2102 PropertySlot slot(thisObject, PropertySlot::InternalMethodType::GetOwnProperty);
2103 bool result = thisObject->hasOwnProperty(exec, propertyName.impl(), slot);
mark.lam@apple.come1ab17c2016-09-26 19:11:17 +00002104 RETURN_IF_EXCEPTION(scope, false);
sbarati@apple.coma3db4652016-09-20 01:05:50 +00002105
2106 HasOwnPropertyCache* hasOwnPropertyCache = vm.hasOwnPropertyCache();
2107 ASSERT(hasOwnPropertyCache);
2108 hasOwnPropertyCache->tryAdd(vm, slot, thisObject, propertyName.impl(), result);
2109 return result;
2110}
2111
utatane.tea@gmail.com8dae6082017-06-12 03:58:23 +00002112int32_t JIT_OPERATION operationArrayIndexOfString(ExecState* exec, Butterfly* butterfly, JSString* searchElement, int32_t index)
2113{
2114 VM& vm = exec->vm();
2115 NativeCallFrameTracer tracer(&vm, exec);
2116 auto scope = DECLARE_THROW_SCOPE(vm);
2117
2118 int32_t length = butterfly->publicLength();
2119 auto data = butterfly->contiguous().data();
2120 for (; index < length; ++index) {
2121 JSValue value = data[index].get();
2122 if (!value || !value.isString())
2123 continue;
2124 auto* string = asString(value);
2125 if (string == searchElement)
2126 return index;
2127 if (string->equal(exec, searchElement))
2128 return index;
2129 RETURN_IF_EXCEPTION(scope, { });
2130 }
2131 return -1;
2132}
2133
2134int32_t JIT_OPERATION operationArrayIndexOfValueInt32OrContiguous(ExecState* exec, Butterfly* butterfly, EncodedJSValue encodedValue, int32_t index)
2135{
2136 VM& vm = exec->vm();
2137 NativeCallFrameTracer tracer(&vm, exec);
2138 auto scope = DECLARE_THROW_SCOPE(vm);
2139
2140 JSValue searchElement = JSValue::decode(encodedValue);
2141
2142 int32_t length = butterfly->publicLength();
2143 auto data = butterfly->contiguous().data();
2144 for (; index < length; ++index) {
2145 JSValue value = data[index].get();
2146 if (!value)
2147 continue;
2148 if (JSValue::strictEqual(exec, searchElement, value))
2149 return index;
2150 RETURN_IF_EXCEPTION(scope, { });
2151 }
2152 return -1;
2153}
2154
2155int32_t JIT_OPERATION operationArrayIndexOfValueDouble(ExecState* exec, Butterfly* butterfly, EncodedJSValue encodedValue, int32_t index)
2156{
2157 VM& vm = exec->vm();
2158 NativeCallFrameTracer tracer(&vm, exec);
2159
2160 JSValue searchElement = JSValue::decode(encodedValue);
2161
2162 if (!searchElement.isNumber())
2163 return -1;
2164 double number = searchElement.asNumber();
2165
2166 int32_t length = butterfly->publicLength();
2167 const double* data = butterfly->contiguousDouble().data();
2168 for (; index < length; ++index) {
2169 // This comparison ignores NaN.
2170 if (data[index] == number)
2171 return index;
2172 }
2173 return -1;
2174}
2175
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00002176void JIT_OPERATION operationLoadVarargs(ExecState* exec, int32_t firstElementDest, EncodedJSValue encodedArguments, int32_t offset, int32_t length, int32_t mandatoryMinimum)
2177{
2178 VM& vm = exec->vm();
2179 NativeCallFrameTracer tracer(&vm, exec);
2180 JSValue arguments = JSValue::decode(encodedArguments);
2181
2182 loadVarargs(exec, VirtualRegister(firstElementDest), arguments, offset, length);
2183
2184 for (int32_t i = length; i < mandatoryMinimum; ++i)
2185 exec->r(firstElementDest + i) = jsUndefined();
2186}
2187
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00002188double JIT_OPERATION operationFModOnInts(int32_t a, int32_t b)
fpizlo@apple.com2c2536e2012-03-21 01:29:28 +00002189{
2190 return fmod(a, b);
2191}
2192
utatane.tea@gmail.comd2fca0a2015-12-15 03:51:42 +00002193#if USE(JSVALUE32_64)
2194double JIT_OPERATION operationRandom(JSGlobalObject* globalObject)
2195{
2196 return globalObject->weakRandomNumber();
2197}
2198#endif
2199
mark.lam@apple.com03a3e382016-01-08 18:44:36 +00002200JSCell* JIT_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +00002201{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00002202 VM* vm = &exec->vm();
2203 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com03a3e382016-01-08 18:44:36 +00002204 return JSC::stringFromCharCode(exec, op1);
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +00002205}
2206
mark.lam@apple.com151fe102016-01-13 23:28:38 +00002207EncodedJSValue JIT_OPERATION operationStringFromCharCodeUntyped(ExecState* exec, EncodedJSValue encodedValue)
2208{
2209 VM* vm = &exec->vm();
2210 NativeCallFrameTracer tracer(vm, exec);
2211 JSValue charValue = JSValue::decode(encodedValue);
2212 int32_t chInt = charValue.toUInt32(exec);
2213 return JSValue::encode(JSC::stringFromCharCode(exec, chInt));
2214}
2215
fpizlo@apple.comf2999932014-07-15 00:41:39 +00002216int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue encodedValue)
2217{
2218 JSValue value = JSValue::decode(encodedValue);
2219 if (!value.isDouble())
2220 return JSValue::notInt52;
2221 return tryConvertToInt52(value.asDouble());
2222}
2223
2224int64_t JIT_OPERATION operationConvertDoubleToInt52(double value)
2225{
2226 return tryConvertToInt52(value);
2227}
2228
sbarati@apple.comfa857522016-03-07 01:00:33 +00002229size_t JIT_OPERATION operationDefaultHasInstance(ExecState* exec, JSCell* value, JSCell* proto) // Returns jsBoolean(True|False) on 64-bit.
2230{
2231 VM* vm = &exec->vm();
2232 NativeCallFrameTracer tracer(vm, exec);
2233 if (JSObject::defaultHasInstance(exec, value, proto))
2234 return 1;
2235 return 0;
2236}
2237
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00002238char* JIT_OPERATION operationNewRawObject(ExecState* exec, Structure* structure, int32_t length, Butterfly* butterfly)
fpizlo@apple.com280ef002016-04-05 22:13:16 +00002239{
2240 VM& vm = exec->vm();
2241 NativeCallFrameTracer tracer(&vm, exec);
2242
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00002243 if (!butterfly
2244 && (structure->outOfLineCapacity() || hasIndexedProperties(structure->indexingType()))) {
fpizlo@apple.com280ef002016-04-05 22:13:16 +00002245 IndexingHeader header;
2246 header.setVectorLength(length);
2247 header.setPublicLength(0);
2248
2249 butterfly = Butterfly::create(
2250 vm, nullptr, 0, structure->outOfLineCapacity(),
2251 hasIndexedProperties(structure->indexingType()), header,
2252 length * sizeof(EncodedJSValue));
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00002253 }
fpizlo@apple.com280ef002016-04-05 22:13:16 +00002254
2255 JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
2256 result->butterfly(); // Ensure that the butterfly is in to-space.
2257 return bitwise_cast<char*>(result);
2258}
2259
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00002260JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState* exec, Structure* structure, Butterfly* butterfly)
fpizlo@apple.com280ef002016-04-05 22:13:16 +00002261{
2262 VM& vm = exec->vm();
2263 NativeCallFrameTracer tracer(&vm, exec);
2264
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00002265 if (!butterfly) {
2266 butterfly = Butterfly::create(
2267 vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0);
2268 }
fpizlo@apple.com280ef002016-04-05 22:13:16 +00002269
2270 JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
2271 result->butterfly(); // Ensure that the butterfly is in to-space.
2272 return result;
2273}
2274
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00002275JSCell* JIT_OPERATION operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength(ExecState* exec, Structure* structure, unsigned length, Butterfly* butterfly)
fpizlo@apple.com280ef002016-04-05 22:13:16 +00002276{
2277 VM& vm = exec->vm();
2278 NativeCallFrameTracer tracer(&vm, exec);
2279
2280 IndexingHeader header;
2281 header.setVectorLength(length);
2282 header.setPublicLength(0);
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +00002283 if (butterfly)
2284 *butterfly->indexingHeader() = header;
2285 else {
2286 butterfly = Butterfly::create(
2287 vm, nullptr, 0, structure->outOfLineCapacity(), true, header,
2288 sizeof(EncodedJSValue) * length);
2289 }
2290
fpizlo@apple.com280ef002016-04-05 22:13:16 +00002291 // Paradoxically this may allocate a JSArray. That's totally cool.
2292 JSObject* result = JSObject::createRawObject(exec, structure, butterfly);
2293 result->butterfly(); // Ensure that the butterfly is in to-space.
2294 return result;
2295}
2296
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002297JSCell* JIT_OPERATION operationNewArrayWithSpreadSlow(ExecState* exec, void* buffer, uint32_t numItems)
2298{
2299 VM& vm = exec->vm();
2300 NativeCallFrameTracer tracer(&vm, exec);
2301 auto scope = DECLARE_THROW_SCOPE(vm);
2302
2303 EncodedJSValue* values = static_cast<EncodedJSValue*>(buffer);
mark.lam@apple.com61dbb712017-03-16 21:53:33 +00002304 Checked<unsigned, RecordOverflow> checkedLength = 0;
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002305 for (unsigned i = 0; i < numItems; i++) {
2306 JSValue value = JSValue::decode(values[i]);
keith_miller@apple.com45da7602017-01-27 01:47:52 +00002307 if (JSFixedArray* array = jsDynamicCast<JSFixedArray*>(vm, value))
mark.lam@apple.com61dbb712017-03-16 21:53:33 +00002308 checkedLength += array->size();
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002309 else
mark.lam@apple.com61dbb712017-03-16 21:53:33 +00002310 ++checkedLength;
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002311 }
2312
mark.lam@apple.com61dbb712017-03-16 21:53:33 +00002313 if (UNLIKELY(checkedLength.hasOverflowed())) {
2314 throwOutOfMemoryError(exec, scope);
2315 return nullptr;
2316 }
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002317
mark.lam@apple.com61dbb712017-03-16 21:53:33 +00002318 unsigned length = checkedLength.unsafeGet();
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002319 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
2320 Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
2321
mark.lam@apple.com21476402017-04-27 19:24:07 +00002322 JSArray* result = JSArray::tryCreate(vm, structure, length);
mark.lam@apple.comc2e98e82017-03-23 20:31:18 +00002323 if (UNLIKELY(!result)) {
2324 throwOutOfMemoryError(exec, scope);
2325 return nullptr;
2326 }
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002327 RETURN_IF_EXCEPTION(scope, nullptr);
2328
2329 unsigned index = 0;
2330 for (unsigned i = 0; i < numItems; i++) {
2331 JSValue value = JSValue::decode(values[i]);
keith_miller@apple.com45da7602017-01-27 01:47:52 +00002332 if (JSFixedArray* array = jsDynamicCast<JSFixedArray*>(vm, value)) {
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002333 // We are spreading.
2334 for (unsigned i = 0; i < array->size(); i++) {
mark.lam@apple.com21476402017-04-27 19:24:07 +00002335 result->putDirectIndex(exec, index, array->get(i));
mark.lam@apple.com135cad52017-09-11 06:23:39 +00002336 RETURN_IF_EXCEPTION(scope, nullptr);
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002337 ++index;
2338 }
2339 } else {
2340 // We are not spreading.
mark.lam@apple.com21476402017-04-27 19:24:07 +00002341 result->putDirectIndex(exec, index, value);
mark.lam@apple.com135cad52017-09-11 06:23:39 +00002342 RETURN_IF_EXCEPTION(scope, nullptr);
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002343 ++index;
2344 }
2345 }
2346
2347 return result;
2348}
2349
2350JSCell* JIT_OPERATION operationSpreadGeneric(ExecState* exec, JSCell* iterable)
2351{
2352 VM& vm = exec->vm();
2353 NativeCallFrameTracer tracer(&vm, exec);
2354
2355 auto throwScope = DECLARE_THROW_SCOPE(vm);
2356
sbarati@apple.com5b8aea12017-01-24 00:15:21 +00002357 if (isJSArray(iterable)) {
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002358 JSArray* array = jsCast<JSArray*>(iterable);
sbarati@apple.com5b8aea12017-01-24 00:15:21 +00002359 if (array->isIteratorProtocolFastAndNonObservable()) {
2360 throwScope.release();
2361 return JSFixedArray::createFromArray(exec, vm, array);
2362 }
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002363 }
2364
2365 // FIXME: we can probably make this path faster by having our caller JS code call directly into
2366 // the iteration protocol builtin: https://bugs.webkit.org/show_bug.cgi?id=164520
2367
sbarati@apple.com5b8aea12017-01-24 00:15:21 +00002368 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002369 JSArray* array;
2370 {
2371 JSFunction* iterationFunction = globalObject->iteratorProtocolFunction();
2372 CallData callData;
2373 CallType callType = JSC::getCallData(iterationFunction, callData);
2374 ASSERT(callType != CallType::None);
2375
2376 MarkedArgumentBuffer arguments;
2377 arguments.append(iterable);
2378 JSValue arrayResult = call(exec, iterationFunction, callType, callData, jsNull(), arguments);
2379 RETURN_IF_EXCEPTION(throwScope, nullptr);
2380 array = jsCast<JSArray*>(arrayResult);
2381 }
2382
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +00002383 throwScope.release();
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002384 return JSFixedArray::createFromArray(exec, vm, array);
2385}
2386
2387JSCell* JIT_OPERATION operationSpreadFastArray(ExecState* exec, JSCell* cell)
2388{
2389 VM& vm = exec->vm();
2390 NativeCallFrameTracer tracer(&vm, exec);
2391
2392 ASSERT(isJSArray(cell));
2393 JSArray* array = jsCast<JSArray*>(cell);
sbarati@apple.com5b8aea12017-01-24 00:15:21 +00002394 ASSERT(array->isIteratorProtocolFastAndNonObservable());
sbarati@apple.com99ed4792016-11-12 02:58:11 +00002395
2396 return JSFixedArray::createFromArray(exec, vm, array);
2397}
2398
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00002399void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState* exec)
2400{
sbarati@apple.comc6fb7552016-06-07 20:07:56 +00002401 VM& vm = exec->vm();
2402 NativeCallFrameTracer tracer(&vm, exec);
2403
2404 vm.typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside DFG."));
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00002405}
2406
gskachkov@gmail.com077d7d52017-04-30 08:06:23 +00002407EncodedJSValue JIT_OPERATION operationResolveScopeForHoistingFuncDeclInEval(ExecState* exec, JSScope* scope, UniquedStringImpl* impl)
2408{
2409 VM& vm = exec->vm();
2410 NativeCallFrameTracer tracer(&vm, exec);
2411
2412 JSValue resolvedScope = JSScope::resolveScopeForHoistingFuncDeclInEval(exec, scope, Identifier::fromUid(exec, impl));
2413 return JSValue::encode(resolvedScope);
2414}
2415
sbarati@apple.come67fd782016-04-19 01:38:30 +00002416JSCell* JIT_OPERATION operationResolveScope(ExecState* exec, JSScope* scope, UniquedStringImpl* impl)
2417{
2418 VM& vm = exec->vm();
2419 NativeCallFrameTracer tracer(&vm, exec);
2420
2421 JSObject* resolvedScope = JSScope::resolve(exec, scope, Identifier::fromUid(exec, impl));
2422 return resolvedScope;
2423}
2424
2425EncodedJSValue JIT_OPERATION operationGetDynamicVar(ExecState* exec, JSObject* scope, UniquedStringImpl* impl, unsigned getPutInfoBits)
2426{
2427 VM& vm = exec->vm();
2428 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00002429 auto throwScope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.come67fd782016-04-19 01:38:30 +00002430
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00002431 Identifier ident = Identifier::fromUid(exec, impl);
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +00002432 throwScope.release();
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00002433 return JSValue::encode(scope->getPropertySlot(exec, ident, [&] (bool found, PropertySlot& slot) -> JSValue {
2434 if (!found) {
2435 GetPutInfo getPutInfo(getPutInfoBits);
2436 if (getPutInfo.resolveMode() == ThrowIfNotFound)
mark.lam@apple.com284f4562016-08-30 20:54:54 +00002437 throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00002438 return jsUndefined();
sbarati@apple.come67fd782016-04-19 01:38:30 +00002439 }
sbarati@apple.come67fd782016-04-19 01:38:30 +00002440
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00002441 if (scope->isGlobalLexicalEnvironment()) {
2442 // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
2443 JSValue result = slot.getValue(exec, ident);
2444 if (result == jsTDZValue()) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00002445 throwException(exec, throwScope, createTDZError(exec));
utatane.tea@gmail.comd80165c2016-06-06 01:56:11 +00002446 return jsUndefined();
2447 }
2448 return result;
2449 }
2450
2451 return slot.getValue(exec, ident);
2452 }));
sbarati@apple.come67fd782016-04-19 01:38:30 +00002453}
2454
2455void JIT_OPERATION operationPutDynamicVar(ExecState* exec, JSObject* scope, EncodedJSValue value, UniquedStringImpl* impl, unsigned getPutInfoBits)
2456{
2457 VM& vm = exec->vm();
2458 NativeCallFrameTracer tracer(&vm, exec);
mark.lam@apple.com284f4562016-08-30 20:54:54 +00002459 auto throwScope = DECLARE_THROW_SCOPE(vm);
sbarati@apple.come67fd782016-04-19 01:38:30 +00002460
2461 const Identifier& ident = Identifier::fromUid(exec, impl);
2462 GetPutInfo getPutInfo(getPutInfoBits);
2463 bool hasProperty = scope->hasProperty(exec, ident);
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +00002464 RETURN_IF_EXCEPTION(throwScope, void());
sbarati@apple.come67fd782016-04-19 01:38:30 +00002465 if (hasProperty
2466 && scope->isGlobalLexicalEnvironment()
2467 && !isInitialization(getPutInfo.initializationMode())) {
2468 // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
2469 PropertySlot slot(scope, PropertySlot::InternalMethodType::Get);
2470 JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot);
2471 if (slot.getValue(exec, ident) == jsTDZValue()) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00002472 throwException(exec, throwScope, createTDZError(exec));
sbarati@apple.come67fd782016-04-19 01:38:30 +00002473 return;
2474 }
2475 }
2476
2477 if (getPutInfo.resolveMode() == ThrowIfNotFound && !hasProperty) {
mark.lam@apple.com284f4562016-08-30 20:54:54 +00002478 throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
sbarati@apple.come67fd782016-04-19 01:38:30 +00002479 return;
2480 }
2481
2482 CodeOrigin origin = exec->codeOrigin();
2483 bool strictMode;
2484 if (origin.inlineCallFrame)
2485 strictMode = origin.inlineCallFrame->baselineCodeBlock->isStrictMode();
2486 else
2487 strictMode = exec->codeBlock()->isStrictMode();
2488 PutPropertySlot slot(scope, strictMode, PutPropertySlot::UnknownContext, isInitialization(getPutInfo.initializationMode()));
mark.lam@apple.comfc11d5c2016-11-19 01:46:01 +00002489 throwScope.release();
mark.lam@apple.com23e96242017-09-09 16:21:45 +00002490 scope->methodTable(vm)->put(scope, exec, ident, JSValue::decode(value), slot);
sbarati@apple.come67fd782016-04-19 01:38:30 +00002491}
2492
sbarati@apple.com21fc86e2016-09-06 23:22:01 +00002493int32_t JIT_OPERATION operationMapHash(ExecState* exec, EncodedJSValue input)
2494{
2495 VM& vm = exec->vm();
2496 NativeCallFrameTracer tracer(&vm, exec);
2497
2498 return jsMapHash(exec, vm, normalizeMapKey(JSValue::decode(input)));
2499}
2500
2501JSCell* JIT_OPERATION operationJSMapFindBucket(ExecState* exec, JSCell* map, EncodedJSValue key, int32_t hash)
2502{
2503 VM& vm = exec->vm();
2504 NativeCallFrameTracer tracer(&vm, exec);
2505 JSMap::BucketType** bucket = jsCast<JSMap*>(map)->findBucket(exec, normalizeMapKey(JSValue::decode(key)), hash);
2506 if (!bucket)
utatane.tea@gmail.com0cf9fa02017-08-23 22:19:13 +00002507 return vm.sentinelMapBucket.get();
sbarati@apple.com21fc86e2016-09-06 23:22:01 +00002508 return *bucket;
2509}
2510
2511JSCell* JIT_OPERATION operationJSSetFindBucket(ExecState* exec, JSCell* map, EncodedJSValue key, int32_t hash)
2512{
2513 VM& vm = exec->vm();
2514 NativeCallFrameTracer tracer(&vm, exec);
2515 JSSet::BucketType** bucket = jsCast<JSSet*>(map)->findBucket(exec, normalizeMapKey(JSValue::decode(key)), hash);
2516 if (!bucket)
utatane.tea@gmail.com0cf9fa02017-08-23 22:19:13 +00002517 return vm.sentinelSetBucket.get();
sbarati@apple.com21fc86e2016-09-06 23:22:01 +00002518 return *bucket;
2519}
2520
sbarati@apple.comc1f73c32017-09-01 05:41:08 +00002521void JIT_OPERATION operationThrowDFG(ExecState* exec, EncodedJSValue valueToThrow)
2522{
2523 VM& vm = exec->vm();
2524 NativeCallFrameTracer tracer(&vm, exec);
2525 auto scope = DECLARE_THROW_SCOPE(vm);
2526 scope.throwException(exec, JSValue::decode(valueToThrow));
2527}
2528
2529void JIT_OPERATION operationThrowStaticError(ExecState* exec, JSString* message, uint32_t errorType)
2530{
2531 VM& vm = exec->vm();
2532 NativeCallFrameTracer tracer(&vm, exec);
2533 auto scope = DECLARE_THROW_SCOPE(vm);
2534 String errorMessage = message->value(exec);
2535 scope.throwException(exec, createError(exec, static_cast<ErrorType>(errorType), errorMessage));
2536}
2537
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00002538extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00002539{
fpizlo@apple.com98225492013-09-10 18:29:45 +00002540 // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
2541 // really be profitable.
2542 DeferGCForAWhile deferGC(codeBlock->vm()->heap);
2543
fpizlo@apple.com5e0bc7432017-10-08 01:10:19 +00002544 sanitizeStackForVM(codeBlock->vm());
2545
oliver@apple.com284cc3d2013-07-25 04:00:33 +00002546 if (Options::verboseOSR())
2547 dataLog(*codeBlock, ": Entered reoptimize\n");
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00002548 // We must be called with the baseline code block.
oliver@apple.com5a24fdd2013-07-25 04:00:54 +00002549 ASSERT(JITCode::isBaselineCode(codeBlock->jitType()));
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00002550
2551 // If I am my own replacement, then reoptimization has already been triggered.
2552 // This can happen in recursive functions.
oliver@apple.comd2a16382013-07-25 04:04:18 +00002553 if (codeBlock->replacement() == codeBlock) {
2554 if (Options::verboseOSR())
2555 dataLog(*codeBlock, ": Not reoptimizing because we've already been jettisoned.\n");
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00002556 return;
oliver@apple.comd2a16382013-07-25 04:04:18 +00002557 }
2558
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00002559 // Otherwise, the replacement must be optimized code. Use this as an opportunity
2560 // to check our logic.
2561 ASSERT(codeBlock->hasOptimizedReplacement());
oliver@apple.comd2a16382013-07-25 04:04:18 +00002562 CodeBlock* optimizedCodeBlock = codeBlock->replacement();
2563 ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00002564
2565 bool didTryToEnterIntoInlinedLoops = false;
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00002566 for (InlineCallFrame* inlineCallFrame = exit->m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->directCaller.inlineCallFrame) {
ggaren@apple.com81def5f2015-10-09 23:10:16 +00002567 if (inlineCallFrame->baselineCodeBlock->ownerScriptExecutable()->didTryToEnterInLoop()) {
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00002568 didTryToEnterIntoInlinedLoops = true;
2569 break;
2570 }
2571 }
oliver@apple.comd2a16382013-07-25 04:04:18 +00002572
2573 // In order to trigger reoptimization, one of two things must have happened:
2574 // 1) We exited more than some number of times.
2575 // 2) We exited and got stuck in a loop, and now we're exiting again.
2576 bool didExitABunch = optimizedCodeBlock->shouldReoptimizeNow();
2577 bool didGetStuckInLoop =
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00002578 (codeBlock->checkIfOptimizationThresholdReached() || didTryToEnterIntoInlinedLoops)
oliver@apple.comd2a16382013-07-25 04:04:18 +00002579 && optimizedCodeBlock->shouldReoptimizeFromLoopNow();
2580
2581 if (!didExitABunch && !didGetStuckInLoop) {
2582 if (Options::verboseOSR())
2583 dataLog(*codeBlock, ": Not reoptimizing ", *optimizedCodeBlock, " because it either didn't exit enough or didn't loop enough after exit.\n");
2584 codeBlock->optimizeAfterLongWarmUp();
2585 return;
2586 }
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00002587
fpizlo@apple.com0dda6d72014-02-02 02:25:13 +00002588 optimizedCodeBlock->jettison(Profiler::JettisonDueToOSRExit, CountReoptimization);
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00002589}
2590
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002591#if ENABLE(FTL_JIT)
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002592static bool shouldTriggerFTLCompile(CodeBlock* codeBlock, JITCode* jitCode)
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002593{
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002594 if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002595 CODEBLOCK_LOG_EVENT(codeBlock, "abortFTLCompile", ());
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002596 if (Options::verboseOSR())
2597 dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
2598 jitCode->dontOptimizeAnytimeSoon(codeBlock);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002599 return false;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002600 }
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002601
2602 if (!codeBlock->hasOptimizedReplacement()
2603 && !jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002604 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("counter = ", jitCode->tierUpCounter));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002605 if (Options::verboseOSR())
2606 dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002607 return false;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002608 }
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002609 return true;
2610}
2611
2612static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
2613{
fpizlo@apple.com080f5282017-03-16 21:19:23 +00002614 if (codeBlock->codeType() == GlobalCode) {
2615 // Global code runs once, so we don't want to do anything. We don't want to defer indefinitely,
2616 // since this may have been spuriously called from tier-up initiated in a loop, and that loop may
2617 // later want to run faster code. Deferring for warm-up seems safest.
2618 jitCode->optimizeAfterWarmUp(codeBlock);
2619 return;
2620 }
2621
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002622 Worklist::State worklistState;
msaboff@apple.com95894332014-01-29 19:18:54 +00002623 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002624 worklistState = worklist->completeAllReadyPlansForVM(
2625 *vm, CompilationKey(codeBlock->baselineVersion(), FTLMode));
2626 } else
2627 worklistState = Worklist::NotKnown;
2628
2629 if (worklistState == Worklist::Compiling) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002630 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002631 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2632 codeBlock, CompilationDeferred);
2633 return;
2634 }
2635
2636 if (codeBlock->hasOptimizedReplacement()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002637 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("has replacement"));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002638 // That's great, we've compiled the code - next time we call this function,
2639 // we'll enter that replacement.
2640 jitCode->optimizeSoon(codeBlock);
2641 return;
2642 }
2643
2644 if (worklistState == Worklist::Compiled) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002645 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002646 // This means that we finished compiling, but failed somehow; in that case the
2647 // thresholds will be set appropriately.
2648 if (Options::verboseOSR())
2649 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
2650 return;
2651 }
2652
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002653 CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLReplacement", ());
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002654 // We need to compile the code.
2655 compile(
ggaren@apple.com81def5f2015-10-09 23:10:16 +00002656 *vm, codeBlock->newReplacement(), codeBlock, FTLMode, UINT_MAX,
2657 Operands<JSValue>(), ToFTLDeferredCompilationCallback::create());
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002658
2659 // If we reached here, the counter has not be reset. Do that now.
2660 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2661 codeBlock, CompilationDeferred);
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002662}
2663
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002664void JIT_OPERATION triggerTierUpNow(ExecState* exec)
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002665{
2666 VM* vm = &exec->vm();
2667 NativeCallFrameTracer tracer(vm, exec);
sbarati@apple.comefcb30a2016-06-23 23:28:50 +00002668 DeferGCForAWhile deferGC(vm->heap);
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002669 CodeBlock* codeBlock = exec->codeBlock();
2670
fpizlo@apple.com5e0bc7432017-10-08 01:10:19 +00002671 sanitizeStackForVM(vm);
2672
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +00002673 if (codeBlock->jitType() != JITCode::DFGJIT) {
2674 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2675 RELEASE_ASSERT_NOT_REACHED();
2676 }
2677
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002678 JITCode* jitCode = codeBlock->jitCode()->dfg();
2679
2680 if (Options::verboseOSR()) {
2681 dataLog(
2682 *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
2683 jitCode->tierUpCounter, "\n");
2684 }
benjamin@webkit.org8f625992015-05-18 20:45:34 +00002685
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002686 if (shouldTriggerFTLCompile(codeBlock, jitCode))
2687 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002688
2689 if (codeBlock->hasOptimizedReplacement()) {
2690 if (jitCode->tierUpEntryTriggers.isEmpty()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002691 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("replacement in place, delaying indefinitely"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002692 // There is nothing more we can do, the only way this will be entered
2693 // is through the function entry point.
2694 jitCode->dontOptimizeAnytimeSoon(codeBlock);
2695 return;
2696 }
2697 if (jitCode->osrEntryBlock() && jitCode->tierUpEntryTriggers.size() == 1) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002698 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("trigger in place, delaying indefinitely"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002699 // There is only one outer loop and its trigger must have been set
2700 // when the plan completed.
2701 // Exiting the inner loop is useless, we can ignore the counter and leave
2702 // the trigger do its job.
2703 jitCode->dontOptimizeAnytimeSoon(codeBlock);
2704 return;
2705 }
2706 }
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002707}
2708
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002709static char* tierUpCommon(ExecState* exec, unsigned originBytecodeIndex, unsigned osrEntryBytecodeIndex)
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002710{
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002711 VM* vm = &exec->vm();
2712 CodeBlock* codeBlock = exec->codeBlock();
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002713
2714 // Resolve any pending plan for OSR Enter on this function.
2715 Worklist::State worklistState;
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002716 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
2717 worklistState = worklist->completeAllReadyPlansForVM(
2718 *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode));
2719 } else
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002720 worklistState = Worklist::NotKnown;
2721
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002722 JITCode* jitCode = codeBlock->jitCode()->dfg();
jfbastien@apple.come5514572017-02-04 01:17:38 +00002723
2724 // The following is only true for triggerTierUpNowInLoop, which can never
2725 // be an OSR entry.
2726 bool canOSRFromHere = originBytecodeIndex == osrEntryBytecodeIndex;
fpizlo@apple.com5e0bc7432017-10-08 01:10:19 +00002727
jfbastien@apple.come5514572017-02-04 01:17:38 +00002728 bool triggeredSlowPathToStartCompilation = false;
2729 auto tierUpEntryTriggers = jitCode->tierUpEntryTriggers.find(originBytecodeIndex);
2730 if (tierUpEntryTriggers != jitCode->tierUpEntryTriggers.end()) {
2731 switch (tierUpEntryTriggers->value) {
2732 case JITCode::TriggerReason::DontTrigger:
2733 // The trigger isn't set, we entered because the counter reached its
2734 // threshold.
2735 break;
2736
2737 case JITCode::TriggerReason::CompilationDone:
2738 // The trigger was set because compilation completed. Don't unset it
2739 // so that further DFG executions OSR enters as well.
2740 RELEASE_ASSERT(canOSRFromHere);
2741 break;
2742
2743 case JITCode::TriggerReason::StartCompilation:
2744 // We were asked to enter as soon as possible and start compiling an
2745 // entry for the current bytecode location. Unset this trigger so we
2746 // don't continually enter.
2747 RELEASE_ASSERT(canOSRFromHere);
2748 tierUpEntryTriggers->value = JITCode::TriggerReason::DontTrigger;
2749 triggeredSlowPathToStartCompilation = true;
2750 break;
2751 }
2752 }
2753
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002754 if (worklistState == Worklist::Compiling) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002755 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002756 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2757 codeBlock, CompilationDeferred);
2758 return nullptr;
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002759 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002760
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002761 if (worklistState == Worklist::Compiled) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002762 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002763 // This means that compilation failed and we already set the thresholds.
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002764 if (Options::verboseOSR())
2765 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
2766 return nullptr;
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002767 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002768
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002769 // If we can OSR Enter, do it right away.
jfbastien@apple.come5514572017-02-04 01:17:38 +00002770 if (canOSRFromHere) {
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002771 unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(originBytecodeIndex);
2772 if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
fpizlo@apple.com080f5282017-03-16 21:19:23 +00002773 if (Options::verboseOSR())
2774 dataLog("OSR entry: From ", RawPointer(jitCode), " got entry block ", RawPointer(entryBlock), "\n");
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002775 if (void* address = FTL::prepareOSREntry(exec, codeBlock, entryBlock, originBytecodeIndex, streamIndex)) {
2776 CODEBLOCK_LOG_EVENT(entryBlock, "osrEntry", ("at bc#", originBytecodeIndex));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002777 return static_cast<char*>(address);
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002778 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002779 }
2780 }
2781
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002782 // - If we don't have an FTL code block, then try to compile one.
2783 // - If we do have an FTL code block, then try to enter for a while.
2784 // - If we couldn't enter for a while, then trigger OSR entry.
msaboff@apple.com95894332014-01-29 19:18:54 +00002785
jfbastien@apple.come5514572017-02-04 01:17:38 +00002786 if (!shouldTriggerFTLCompile(codeBlock, jitCode) && !triggeredSlowPathToStartCompilation)
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002787 return nullptr;
2788
jfbastien@apple.come5514572017-02-04 01:17:38 +00002789 if (!jitCode->neverExecutedEntry && !triggeredSlowPathToStartCompilation) {
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002790 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2791
2792 if (!codeBlock->hasOptimizedReplacement())
2793 return nullptr;
fpizlo@apple.com239b0782016-03-03 05:58:59 +00002794
2795 if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002796 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding OSR entry compile"));
fpizlo@apple.com239b0782016-03-03 05:58:59 +00002797 jitCode->osrEntryRetry++;
2798 return nullptr;
2799 }
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002800 } else
2801 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding replacement compile"));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002802
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002803 // It's time to try to compile code for OSR entry.
2804 if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002805 if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002806 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed, OSR entry threshold not met"));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002807 jitCode->osrEntryRetry++;
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002808 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2809 codeBlock, CompilationDeferred);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002810 return nullptr;
2811 }
2812
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002813 FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002814 entryCode->countEntryFailure();
2815 if (entryCode->entryFailureCount() <
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002816 Options::ftlOSREntryFailureCountForReoptimization()) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002817 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002818 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2819 codeBlock, CompilationDeferred);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002820 return nullptr;
2821 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002822
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002823 // OSR entry failed. Oh no! This implies that we need to retry. We retry
2824 // without exponential backoff and we only do this for the entry code block.
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002825 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed too many times"));
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002826 unsigned osrEntryBytecode = entryBlock->jitCode()->ftlForOSREntry()->bytecodeIndex();
ggaren@apple.com81def5f2015-10-09 23:10:16 +00002827 jitCode->clearOSREntryBlock();
fpizlo@apple.com0c606702014-02-06 07:11:48 +00002828 jitCode->osrEntryRetry = 0;
jfbastien@apple.come5514572017-02-04 01:17:38 +00002829 jitCode->tierUpEntryTriggers.set(osrEntryBytecode, JITCode::TriggerReason::DontTrigger);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002830 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2831 codeBlock, CompilationDeferred);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002832 return nullptr;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002833 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002834
jfbastien@apple.come5514572017-02-04 01:17:38 +00002835 if (!canOSRFromHere) {
2836 // We can't OSR from here, or even start a compilation because doing so
2837 // calls jitCode->reconstruct which would get the wrong state.
2838 if (Options::verboseOSR())
2839 dataLog("Non-OSR-able bc#", originBytecodeIndex, " in ", *codeBlock, " setting parent loop bc#", osrEntryBytecodeIndex, "'s trigger and backing off.\n");
2840 jitCode->tierUpEntryTriggers.set(osrEntryBytecodeIndex, JITCode::TriggerReason::StartCompilation);
2841 jitCode->setOptimizationThresholdBasedOnCompilationResult(codeBlock, CompilationDeferred);
2842 return nullptr;
2843 }
2844
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002845 unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(osrEntryBytecodeIndex);
jfbastien@apple.come5514572017-02-04 01:17:38 +00002846
2847 if (!triggeredSlowPathToStartCompilation) {
2848 auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(osrEntryBytecodeIndex);
2849 if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end()) {
2850 for (unsigned osrEntryCandidate : tierUpHierarchyEntry->value) {
2851 if (jitCode->tierUpEntrySeen.contains(osrEntryCandidate)) {
2852 // Ask an enclosing loop to compile, instead of doing so here.
2853 if (Options::verboseOSR())
2854 dataLog("Inner-loop bc#", originBytecodeIndex, " in ", *codeBlock, " setting parent loop bc#", osrEntryCandidate, "'s trigger and backing off.\n");
2855 jitCode->tierUpEntryTriggers.set(osrEntryCandidate, JITCode::TriggerReason::StartCompilation);
2856 jitCode->setOptimizationThresholdBasedOnCompilationResult(codeBlock, CompilationDeferred);
2857 return nullptr;
2858 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002859 }
2860 }
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002861 }
2862
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002863 // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile
2864 // something.
2865 auto triggerIterator = jitCode->tierUpEntryTriggers.find(osrEntryBytecodeIndex);
jfbastien@apple.comf132a4a2017-01-26 19:52:35 +00002866 RELEASE_ASSERT(triggerIterator != jitCode->tierUpEntryTriggers.end());
jfbastien@apple.come5514572017-02-04 01:17:38 +00002867 JITCode::TriggerReason* triggerAddress = &(triggerIterator->value);
jfbastien@apple.comf132a4a2017-01-26 19:52:35 +00002868
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002869 Operands<JSValue> mustHandleValues;
2870 jitCode->reconstruct(
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002871 exec, codeBlock, CodeOrigin(osrEntryBytecodeIndex), streamIndex, mustHandleValues);
ggaren@apple.com81def5f2015-10-09 23:10:16 +00002872 CodeBlock* replacementCodeBlock = codeBlock->newReplacement();
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002873
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002874 CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLOSR", ());
msaboff@apple.com95894332014-01-29 19:18:54 +00002875 CompilationResult forEntryResult = compile(
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002876 *vm, replacementCodeBlock, codeBlock, FTLForOSREntryMode, osrEntryBytecodeIndex,
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002877 mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(triggerAddress));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002878
2879 if (jitCode->neverExecutedEntry)
2880 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2881
2882 if (forEntryResult != CompilationSuccessful) {
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002883 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR ecompilation not successful"));
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002884 jitCode->setOptimizationThresholdBasedOnCompilationResult(
2885 codeBlock, CompilationDeferred);
2886 return nullptr;
2887 }
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002888
2889 CODEBLOCK_LOG_EVENT(jitCode->osrEntryBlock(), "osrEntry", ("at bc#", originBytecodeIndex));
2890 // It's possible that the for-entry compile already succeeded. In that case OSR
2891 // entry will succeed unless we ran out of stack. It's not clear what we should do.
2892 // We signal to try again after a while if that happens.
fpizlo@apple.com080f5282017-03-16 21:19:23 +00002893 if (Options::verboseOSR())
2894 dataLog("Immediate OSR entry: From ", RawPointer(jitCode), " got entry block ", RawPointer(jitCode->osrEntryBlock()), "\n");
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002895 void* address = FTL::prepareOSREntry(
2896 exec, codeBlock, jitCode->osrEntryBlock(), originBytecodeIndex, streamIndex);
2897 return static_cast<char*>(address);
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002898}
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00002899
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002900void JIT_OPERATION triggerTierUpNowInLoop(ExecState* exec, unsigned bytecodeIndex)
2901{
2902 VM* vm = &exec->vm();
2903 NativeCallFrameTracer tracer(vm, exec);
sbarati@apple.comefcb30a2016-06-23 23:28:50 +00002904 DeferGCForAWhile deferGC(vm->heap);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002905 CodeBlock* codeBlock = exec->codeBlock();
2906
fpizlo@apple.com5e0bc7432017-10-08 01:10:19 +00002907 sanitizeStackForVM(vm);
2908
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002909 if (codeBlock->jitType() != JITCode::DFGJIT) {
2910 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2911 RELEASE_ASSERT_NOT_REACHED();
2912 }
2913
2914 JITCode* jitCode = codeBlock->jitCode()->dfg();
2915
2916 if (Options::verboseOSR()) {
2917 dataLog(
2918 *codeBlock, ": Entered triggerTierUpNowInLoop with executeCounter = ",
2919 jitCode->tierUpCounter, "\n");
2920 }
2921
2922 auto tierUpHierarchyEntry = jitCode->tierUpInLoopHierarchy.find(bytecodeIndex);
2923 if (tierUpHierarchyEntry != jitCode->tierUpInLoopHierarchy.end()
2924 && !tierUpHierarchyEntry->value.isEmpty()) {
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002925 tierUpCommon(exec, bytecodeIndex, tierUpHierarchyEntry->value.first());
2926 } else if (shouldTriggerFTLCompile(codeBlock, jitCode))
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002927 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
2928
2929 // Since we cannot OSR Enter here, the default "optimizeSoon()" is not useful.
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002930 if (codeBlock->hasOptimizedReplacement()) {
2931 CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR in loop failed, deferring"));
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002932 jitCode->setOptimizationThresholdBasedOnCompilationResult(codeBlock, CompilationDeferred);
fpizlo@apple.com4a528d02016-05-11 00:08:50 +00002933 }
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002934}
2935
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002936char* JIT_OPERATION triggerOSREntryNow(ExecState* exec, unsigned bytecodeIndex)
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002937{
2938 VM* vm = &exec->vm();
2939 NativeCallFrameTracer tracer(vm, exec);
sbarati@apple.comefcb30a2016-06-23 23:28:50 +00002940 DeferGCForAWhile deferGC(vm->heap);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002941 CodeBlock* codeBlock = exec->codeBlock();
2942
fpizlo@apple.com5e0bc7432017-10-08 01:10:19 +00002943 sanitizeStackForVM(vm);
2944
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002945 if (codeBlock->jitType() != JITCode::DFGJIT) {
2946 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
2947 RELEASE_ASSERT_NOT_REACHED();
2948 }
2949
2950 JITCode* jitCode = codeBlock->jitCode()->dfg();
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002951 jitCode->tierUpEntrySeen.add(bytecodeIndex);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002952
2953 if (Options::verboseOSR()) {
2954 dataLog(
2955 *codeBlock, ": Entered triggerOSREntryNow with executeCounter = ",
2956 jitCode->tierUpCounter, "\n");
2957 }
2958
commit-queue@webkit.org485b53c2017-01-27 01:33:38 +00002959 return tierUpCommon(exec, bytecodeIndex, bytecodeIndex);
benjamin@webkit.org31527f52016-03-09 17:51:38 +00002960}
2961
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002962#endif // ENABLE(FTL_JIT)
2963
barraclough@apple.comc7af2d32011-05-26 21:37:05 +00002964} // extern "C"
fpizlo@apple.com04659ba2012-02-21 09:49:22 +00002965} } // namespace JSC::DFG
2966
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +00002967#endif // ENABLE(DFG_JIT)
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +00002968
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +00002969#endif // ENABLE(JIT)