| Index: src/builtins/builtins-array-gen.cc
 | 
| diff --git a/src/builtins/builtins-array-gen.cc b/src/builtins/builtins-array-gen.cc
 | 
| index 36f9b142b15329fb88eb5105501a32609f259867..28cf251eb3710228d90598bc7466d809c8f6a5f7 100644
 | 
| --- a/src/builtins/builtins-array-gen.cc
 | 
| +++ b/src/builtins/builtins-array-gen.cc
 | 
| @@ -164,6 +164,20 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
 | 
|  
 | 
|    void MapResultGenerator() { ArraySpeciesCreate(len_); }
 | 
|  
 | 
| +  void TypedArrayMapResultGenerator() {
 | 
| +    // 6. Let A be ? TypedArraySpeciesCreate(O, len).
 | 
| +    Node* a = TypedArraySpeciesCreateByLength(context(), o(), len_);
 | 
| +    // In the Spec and our current implementation, the length check is already
 | 
| +    // performed in TypedArraySpeciesCreate. Repeating the check here to
 | 
| +    // keep this invariant local.
 | 
| +    // TODO(tebbi): Change this to a release mode check.
 | 
| +    CSA_ASSERT(
 | 
| +        this, WordEqual(len_, LoadObjectField(a, JSTypedArray::kLengthOffset)));
 | 
| +    fast_typed_array_target_ = Word32Equal(LoadInstanceType(LoadElements(o_)),
 | 
| +                                           LoadInstanceType(LoadElements(a)));
 | 
| +    a_.Bind(a);
 | 
| +  }
 | 
| +
 | 
|    Node* SpecCompliantMapProcessor(Node* k_value, Node* k) {
 | 
|      //  i. Let kValue be ? Get(O, Pk). Performed by the caller of
 | 
|      //  SpecCompliantMapProcessor.
 | 
| @@ -238,6 +252,48 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
 | 
|      return a();
 | 
|    }
 | 
|  
 | 
| +  // See tc39.github.io/ecma262/#sec-%typedarray%.prototype.map.
 | 
| +  Node* TypedArrayMapProcessor(Node* k_value, Node* k) {
 | 
| +    // 8. c. Let mappedValue be ? Call(callbackfn, T, « kValue, k, O »).
 | 
| +    Node* mappedValue = CallJS(CodeFactory::Call(isolate()), context(),
 | 
| +                               callbackfn(), this_arg(), k_value, k, o());
 | 
| +    Label fast(this), slow(this), done(this), detached(this, Label::kDeferred);
 | 
| +
 | 
| +    // 8. d. Perform ? Set(A, Pk, mappedValue, true).
 | 
| +    // Since we know that A is a TypedArray, this always ends up in
 | 
| +    // #sec-integer-indexed-exotic-objects-set-p-v-receiver and then
 | 
| +    // tc39.github.io/ecma262/#sec-integerindexedelementset .
 | 
| +    Branch(fast_typed_array_target_, &fast, &slow);
 | 
| +
 | 
| +    BIND(&fast);
 | 
| +    // #sec-integerindexedelementset 3. Let numValue be ? ToNumber(value).
 | 
| +    Node* num_value = ToNumber(context(), mappedValue);
 | 
| +    // The only way how this can bailout is because of a detached buffer.
 | 
| +    EmitElementStore(
 | 
| +        a(), k, num_value, false, source_elements_kind_,
 | 
| +        KeyedAccessStoreMode::STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
 | 
| +        &detached);
 | 
| +    Goto(&done);
 | 
| +
 | 
| +    BIND(&slow);
 | 
| +    CallRuntime(Runtime::kSetProperty, context(), a(), k, mappedValue,
 | 
| +                SmiConstant(STRICT));
 | 
| +    Goto(&done);
 | 
| +
 | 
| +    BIND(&detached);
 | 
| +    {
 | 
| +      // tc39.github.io/ecma262/#sec-integerindexedelementset
 | 
| +      // 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
 | 
| +      CallRuntime(Runtime::kThrowTypeError, context_,
 | 
| +                  SmiConstant(MessageTemplate::kDetachedOperation),
 | 
| +                  name_string_);
 | 
| +      Unreachable();
 | 
| +    }
 | 
| +
 | 
| +    BIND(&done);
 | 
| +    return a();
 | 
| +  }
 | 
| +
 | 
|    void NullPostLoopAction() {}
 | 
|  
 | 
|   protected:
 | 
| @@ -376,7 +432,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
 | 
|        const char* name, const BuiltinResultGenerator& generator,
 | 
|        const CallResultProcessor& processor, const PostLoopAction& action,
 | 
|        ForEachDirection direction = ForEachDirection::kForward) {
 | 
| -    Node* name_string =
 | 
| +    name_string_ =
 | 
|          HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name));
 | 
|  
 | 
|      // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray
 | 
| @@ -411,7 +467,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
 | 
|      {
 | 
|        CallRuntime(Runtime::kThrowTypeError, context_,
 | 
|                    SmiConstant(MessageTemplate::kDetachedOperation),
 | 
| -                  name_string);
 | 
| +                  name_string_);
 | 
|        Unreachable();
 | 
|      }
 | 
|  
 | 
| @@ -448,20 +504,20 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
 | 
|      } else {
 | 
|        k_.Bind(NumberDec(len()));
 | 
|      }
 | 
| -    generator(this);
 | 
| -    Node* elements_type = LoadInstanceType(LoadElements(o_));
 | 
| -    Switch(elements_type, &unexpected_instance_type, instance_types.data(),
 | 
| +    Node* instance_type = LoadInstanceType(LoadElements(o_));
 | 
| +    Switch(instance_type, &unexpected_instance_type, instance_types.data(),
 | 
|             label_ptrs.data(), labels.size());
 | 
|  
 | 
|      for (size_t i = 0; i < labels.size(); ++i) {
 | 
|        BIND(&labels[i]);
 | 
|        Label done(this);
 | 
| +      source_elements_kind_ = ElementsKindForInstanceType(
 | 
| +          static_cast<InstanceType>(instance_types[i]));
 | 
| +      generator(this);
 | 
|        // TODO(tebbi): Silently cancelling the loop on buffer detachment is a
 | 
| -      // spec violation. Should go to &detached and throw a TypeError instead.
 | 
| -      VisitAllTypedArrayElements(
 | 
| -          ElementsKindForInstanceType(
 | 
| -              static_cast<InstanceType>(instance_types[i])),
 | 
| -          array_buffer, processor, &done, direction);
 | 
| +      // spec violation. Should go to &throw_detached and throw a TypeError
 | 
| +      // instead.
 | 
| +      VisitAllTypedArrayElements(array_buffer, processor, &done, direction);
 | 
|        Goto(&done);
 | 
|        // No exception, return success
 | 
|        BIND(&done);
 | 
| @@ -540,7 +596,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
 | 
|      }
 | 
|    }
 | 
|  
 | 
| -  void VisitAllTypedArrayElements(ElementsKind kind, Node* array_buffer,
 | 
| +  void VisitAllTypedArrayElements(Node* array_buffer,
 | 
|                                    const CallResultProcessor& processor,
 | 
|                                    Label* detached, ForEachDirection direction) {
 | 
|      VariableList list({&a_, &k_, &to_}, zone());
 | 
| @@ -554,8 +610,8 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
 | 
|            LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
 | 
|                            MachineType::Pointer());
 | 
|        Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr);
 | 
| -      Node* value = LoadFixedTypedArrayElementAsTagged(data_ptr, index, kind,
 | 
| -                                                       SMI_PARAMETERS);
 | 
| +      Node* value = LoadFixedTypedArrayElementAsTagged(
 | 
| +          data_ptr, index, source_elements_kind_, SMI_PARAMETERS);
 | 
|        k_.Bind(index);
 | 
|        a_.Bind(processor(this, value, index));
 | 
|      };
 | 
| @@ -740,10 +796,13 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
 | 
|    Node* receiver_ = nullptr;
 | 
|    Node* new_target_ = nullptr;
 | 
|    Node* argc_ = nullptr;
 | 
| +  Node* fast_typed_array_target_ = nullptr;
 | 
| +  Node* name_string_ = nullptr;
 | 
|    Variable k_;
 | 
|    Variable a_;
 | 
|    Variable to_;
 | 
|    Label fully_spec_compliant_;
 | 
| +  ElementsKind source_elements_kind_ = ElementsKind::NO_ELEMENTS;
 | 
|  };
 | 
|  
 | 
|  TF_BUILTIN(FastArrayPop, CodeStubAssembler) {
 | 
| @@ -1348,6 +1407,26 @@ TF_BUILTIN(ArrayMap, ArrayBuiltinCodeStubAssembler) {
 | 
|        Builtins::CallableFor(isolate(), Builtins::kArrayMapLoopContinuation));
 | 
|  }
 | 
|  
 | 
| +TF_BUILTIN(TypedArrayPrototypeMap, ArrayBuiltinCodeStubAssembler) {
 | 
| +  Node* argc =
 | 
| +      ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
 | 
| +  CodeStubArguments args(this, argc);
 | 
| +  Node* context = Parameter(BuiltinDescriptor::kContext);
 | 
| +  Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
 | 
| +  Node* receiver = args.GetReceiver();
 | 
| +  Node* callbackfn = args.GetOptionalArgumentValue(0, UndefinedConstant());
 | 
| +  Node* this_arg = args.GetOptionalArgumentValue(1, UndefinedConstant());
 | 
| +
 | 
| +  InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
 | 
| +                                new_target, argc);
 | 
| +
 | 
| +  GenerateIteratingTypedArrayBuiltinBody(
 | 
| +      "%TypedArray%.prototype.map",
 | 
| +      &ArrayBuiltinCodeStubAssembler::TypedArrayMapResultGenerator,
 | 
| +      &ArrayBuiltinCodeStubAssembler::TypedArrayMapProcessor,
 | 
| +      &ArrayBuiltinCodeStubAssembler::NullPostLoopAction);
 | 
| +}
 | 
| +
 | 
|  TF_BUILTIN(ArrayIsArray, CodeStubAssembler) {
 | 
|    Node* object = Parameter(Descriptor::kArg);
 | 
|    Node* context = Parameter(Descriptor::kContext);
 | 
| 
 |