@@ -50,6 +50,13 @@ Handle<JSObject> createArrayConstructor(Runtime &runtime) {
50
50
nullptr ,
51
51
arrayPrototypeToLocaleString,
52
52
0 );
53
+ defineMethod (
54
+ runtime,
55
+ arrayPrototype,
56
+ Predefined::getSymbolID (Predefined::at),
57
+ nullptr ,
58
+ arrayPrototypeAt,
59
+ 1 );
53
60
defineMethod (
54
61
runtime,
55
62
arrayPrototype,
@@ -539,6 +546,78 @@ arrayPrototypeToLocaleString(void *, Runtime &runtime, NativeArgs args) {
539
546
return HermesValue::encodeStringValue (*builder->getStringPrimitive ());
540
547
}
541
548
549
+ // 23.1.3.1
550
+ CallResult<HermesValue>
551
+ arrayPrototypeAt (void *, Runtime &runtime, NativeArgs args) {
552
+ GCScope gcScope (runtime);
553
+ // 1. Let O be ? ToObject(this value).
554
+ auto objRes = toObject (runtime, args.getThisHandle ());
555
+ if (LLVM_UNLIKELY (objRes == ExecutionStatus::EXCEPTION)) {
556
+ return ExecutionStatus::EXCEPTION;
557
+ }
558
+ auto O = runtime.makeHandle <JSObject>(objRes.getValue ());
559
+
560
+ // 2. Let len be ? LengthOfArrayLike(O).
561
+ Handle <JSArray> jsArr = Handle <JSArray>::dyn_vmcast (O);
562
+ uint32_t len = 0 ;
563
+ if (LLVM_LIKELY (jsArr)) {
564
+ // Fast path for getting the length.
565
+ len = JSArray::getLength (jsArr.get (), runtime);
566
+ } else {
567
+ // Slow path
568
+ CallResult<PseudoHandle<>> propRes = JSObject::getNamed_RJS (
569
+ O, runtime, Predefined::getSymbolID (Predefined::length));
570
+ if (LLVM_UNLIKELY (propRes == ExecutionStatus::EXCEPTION)) {
571
+ return ExecutionStatus::EXCEPTION;
572
+ }
573
+ auto lenRes = toLength (runtime, runtime.makeHandle (std::move (*propRes)));
574
+ if (LLVM_UNLIKELY (lenRes == ExecutionStatus::EXCEPTION)) {
575
+ return ExecutionStatus::EXCEPTION;
576
+ }
577
+ len = lenRes->getNumber ();
578
+ }
579
+
580
+ // 3. Let relativeIndex be ? ToIntegerOrInfinity(index).
581
+ auto idx = args.getArgHandle (0 );
582
+ auto relativeIndexRes = toIntegerOrInfinity (runtime, idx);
583
+ if (relativeIndexRes == ExecutionStatus::EXCEPTION) {
584
+ return ExecutionStatus::EXCEPTION;
585
+ }
586
+ const double relativeIndex = relativeIndexRes->getNumber ();
587
+
588
+ double k;
589
+ // 4. If relativeIndex ≥ 0, then
590
+ if (relativeIndex >= 0 ) {
591
+ // a. Let k be relativeIndex.
592
+ k = relativeIndex;
593
+ } else {
594
+ // 5. Else,
595
+ // a. Let k be len + relativeIndex.
596
+ k = len + relativeIndex;
597
+ }
598
+
599
+ // 6. If k < 0 or k ≥ len, return undefined.
600
+ if (k < 0 || k >= len) {
601
+ return HermesValue::encodeUndefinedValue ();
602
+ }
603
+
604
+ // 7. Return ? Get(O, ! ToString(𝔽(k))).
605
+ if (LLVM_LIKELY (jsArr)) {
606
+ const SmallHermesValue elm = jsArr->at (runtime, k);
607
+ if (elm.isEmpty ()) {
608
+ return HermesValue::encodeUndefinedValue ();
609
+ } else {
610
+ return elm.unboxToHV (runtime);
611
+ }
612
+ }
613
+ CallResult<PseudoHandle<>> propRes = JSObject::getComputed_RJS (
614
+ O, runtime, runtime.makeHandle (HermesValue::encodeDoubleValue (k)));
615
+ if (LLVM_UNLIKELY (propRes == ExecutionStatus::EXCEPTION)) {
616
+ return ExecutionStatus::EXCEPTION;
617
+ }
618
+ return propRes->getHermesValue ();
619
+ }
620
+
542
621
CallResult<HermesValue>
543
622
arrayPrototypeConcat (void *, Runtime &runtime, NativeArgs args) {
544
623
GCScope gcScope (runtime);
0 commit comments