@@ -69,6 +69,7 @@ static JSC_DECLARE_HOST_FUNCTION(arrayProtoFuncToReversed);
6969static JSC_DECLARE_HOST_FUNCTION (arrayProtoFuncToSorted);
7070static JSC_DECLARE_HOST_FUNCTION (arrayProtoFuncWith);
7171static JSC_DECLARE_HOST_FUNCTION (arrayProtoFuncIncludes);
72+ static JSC_DECLARE_HOST_FUNCTION (arrayProtoFuncCopyWithin);
7273
7374// ------------------------------ ArrayPrototype ----------------------------
7475
@@ -127,7 +128,7 @@ void ArrayPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
127128 JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION (vm.propertyNames ->builtinNames ().findIndexPublicName (), arrayPrototypeFindIndexCodeGenerator, static_cast <unsigned >(PropertyAttribute::DontEnum));
128129 JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION (vm.propertyNames ->builtinNames ().findLastIndexPublicName (), arrayPrototypeFindLastIndexCodeGenerator, static_cast <unsigned >(PropertyAttribute::DontEnum));
129130 JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION (vm.propertyNames ->includes , arrayProtoFuncIncludes, static_cast <unsigned >(PropertyAttribute::DontEnum), 1 , ImplementationVisibility::Public, ArrayIncludesIntrinsic);
130- JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION (vm.propertyNames ->builtinNames (). copyWithinPublicName (), arrayPrototypeCopyWithinCodeGenerator , static_cast <unsigned >(PropertyAttribute::DontEnum));
131+ JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION (vm.propertyNames ->copyWithin , arrayProtoFuncCopyWithin , static_cast <unsigned >(PropertyAttribute::DontEnum), 2 , ImplementationVisibility::Public );
131132 JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION (vm.propertyNames ->builtinNames ().atPublicName (), arrayPrototypeAtCodeGenerator, static_cast <unsigned >(PropertyAttribute::DontEnum));
132133 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION (vm.propertyNames ->toReversed , arrayProtoFuncToReversed, static_cast <unsigned >(PropertyAttribute::DontEnum), 0 , ImplementationVisibility::Public);
133134 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION (vm.propertyNames ->toSorted , arrayProtoFuncToSorted, static_cast <unsigned >(PropertyAttribute::DontEnum), 1 , ImplementationVisibility::Public);
@@ -146,7 +147,7 @@ void ArrayPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
146147 unscopables->convertToDictionary (vm);
147148 const Identifier* const unscopableNames[] = {
148149 &vm.propertyNames ->builtinNames ().atPublicName (),
149- &vm.propertyNames ->builtinNames (). copyWithinPublicName () ,
150+ &vm.propertyNames ->copyWithin ,
150151 &vm.propertyNames ->builtinNames ().entriesPublicName (),
151152 &vm.propertyNames ->fill ,
152153 &vm.propertyNames ->builtinNames ().findPublicName (),
@@ -2202,6 +2203,72 @@ JSC_DEFINE_HOST_FUNCTION(arrayProtoFuncIncludes, (JSGlobalObject* globalObject,
22022203 return JSValue::encode (jsBoolean (false ));
22032204}
22042205
2206+ JSC_DEFINE_HOST_FUNCTION (arrayProtoFuncCopyWithin, (JSGlobalObject* globalObject, CallFrame* callFrame))
2207+ {
2208+ VM & vm = globalObject->vm ();
2209+ auto scope = DECLARE_THROW_SCOPE (vm);
2210+
2211+ JSValue thisValue = callFrame->thisValue ().toThis (globalObject, ECMAMode::strict ());
2212+ RETURN_IF_EXCEPTION (scope, { });
2213+
2214+ if (UNLIKELY (thisValue.isUndefinedOrNull ()))
2215+ return throwVMTypeError (globalObject, scope, " Array.prototype.copyWithin requires that |this| not be null or undefined" _s);
2216+ auto * thisObject = thisValue.toObject (globalObject);
2217+ RETURN_IF_EXCEPTION (scope, { });
2218+
2219+ uint64_t length = toLength (globalObject, thisObject);
2220+ RETURN_IF_EXCEPTION (scope, { });
2221+
2222+ uint64_t to = argumentClampedIndexFromStartOrEnd (globalObject, callFrame->argument (0 ), length);
2223+ RETURN_IF_EXCEPTION (scope, { });
2224+ uint64_t from = argumentClampedIndexFromStartOrEnd (globalObject, callFrame->argument (1 ), length);
2225+ RETURN_IF_EXCEPTION (scope, { });
2226+ uint64_t finalIndex = argumentClampedIndexFromStartOrEnd (globalObject, callFrame->argument (2 ), length, length);
2227+ RETURN_IF_EXCEPTION (scope, { });
2228+
2229+ if (finalIndex < from)
2230+ return JSValue::encode (thisValue);
2231+
2232+ ASSERT (to <= length);
2233+ ASSERT (from <= length);
2234+
2235+ uint64_t count = std::min (length - std::max (to, from), finalIndex - from);
2236+ ASSERT (count <= length);
2237+ if (!count)
2238+ return JSValue::encode (thisObject);
2239+
2240+ if (LIKELY (isJSArray (thisObject))) {
2241+ JSArray* thisArray = asArray (thisObject);
2242+ if (thisArray->fastCopywithin (globalObject, from, to, count, length))
2243+ return JSValue::encode (thisValue);
2244+ }
2245+
2246+ int8_t direction = 1 ;
2247+ if (from < to && to < from + count) {
2248+ direction = -1 ;
2249+ from = from + count - 1 ;
2250+ to = to + count - 1 ;
2251+ }
2252+
2253+ for (uint64_t i = 0 ; i < count; ++i, from += direction, to += direction) {
2254+ if (thisObject->hasProperty (globalObject, from)) {
2255+ JSValue fromValue = thisObject->getIndex (globalObject, from);
2256+ RETURN_IF_EXCEPTION (scope, { });
2257+ thisObject->putByIndexInline (globalObject, to, fromValue, true );
2258+ RETURN_IF_EXCEPTION (scope, { });
2259+ } else {
2260+ bool success = thisObject->deleteProperty (globalObject, to);
2261+ RETURN_IF_EXCEPTION (scope, { });
2262+ if (UNLIKELY (!success)) {
2263+ throwTypeError (globalObject, scope, UnableToDeletePropertyError);
2264+ return { };
2265+ }
2266+ }
2267+ }
2268+
2269+ return JSValue::encode (thisObject);
2270+ }
2271+
22052272} // namespace JSC
22062273
22072274WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
0 commit comments