| Index: src/typedarray.js | 
| diff --git a/src/typedarray.js b/src/typedarray.js | 
| index d5357b4f2cbdbd3c656041754ac6ea0b863def16..f9e732fa7f8f35bfd13598746c8a02f9af98b2ef 100644 | 
| --- a/src/typedarray.js | 
| +++ b/src/typedarray.js | 
| @@ -144,30 +144,103 @@ function CreateSubArray(elementSize, constructor) { | 
| } | 
| } | 
|  | 
| +function TypedArraySetFromArrayLike(target, source, sourceLength, offset) { | 
| +  if (offset > 0) { | 
| +    for (var i = 0; i < sourceLength; i++) { | 
| +      target[offset + i] = source[i]; | 
| +    } | 
| +  } | 
| +  else { | 
| +    for (var i = 0; i < sourceLength; i++) { | 
| +      target[i] = source[i]; | 
| +    } | 
| +  } | 
| +} | 
| + | 
| +function TypedArraySetFromOverlappingTypedArray(target, source, offset) { | 
| +  var sourceElementSize = source.BYTES_PER_ELEMENT; | 
| +  var targetElementSize = target.BYTES_PER_ELEMENT; | 
| +  var sourceLength = source.length; | 
| + | 
| +  // Copy left part. | 
| +  function CopyLeftPart() { | 
| +    // First un-mutated byte after the next write | 
| +    var targetPtr = target.byteOffset + (offset + 1) * targetElementSize; | 
| +    // Next read at sourcePtr. We do not care for memory changing before | 
| +    // sourcePtr - we have already copied it. | 
| +    var sourcePtr = source.byteOffset; | 
| +    for (var leftIndex = 0; | 
| +         leftIndex < sourceLength && targetPtr <= sourcePtr; | 
| +         leftIndex++) { | 
| +      target[offset + leftIndex] = source[leftIndex]; | 
| +      targetPtr += targetElementSize; | 
| +      sourcePtr += sourceElementSize; | 
| +    } | 
| +    return leftIndex; | 
| +  } | 
| +  var leftIndex = CopyLeftPart(); | 
| + | 
| +  // Copy rigth part; | 
| +  function CopyRightPart() { | 
| +    // First unmutated byte before the next write | 
| +    var targetPtr = | 
| +      target.byteOffset + (offset + sourceLength - 1) * targetElementSize; | 
| +    // Next read before sourcePtr. We do not care for memory changing after | 
| +    // sourcePtr - we have already copied it. | 
| +    var sourcePtr = | 
| +      source.byteOffset + sourceLength * sourceElementSize; | 
| +    for(var rightIndex = sourceLength - 1; | 
| +        rightIndex >= leftIndex && targetPtr >= sourcePtr; | 
| +        rightIndex--) { | 
| +      target[offset + rightIndex] = source[rightIndex]; | 
| +      targetPtr -= targetElementSize; | 
| +      sourcePtr -= sourceElementSize; | 
| +    } | 
| +    return rightIndex; | 
| +  } | 
| +  var rightIndex = CopyRightPart(); | 
| + | 
| +  var temp = new $Array(rightIndex + 1 - leftIndex); | 
| +  for (var i = leftIndex; i <= rightIndex; i++) { | 
| +    temp[i - leftIndex] = source[i]; | 
| +  } | 
| +  for (i = leftIndex; i <= rightIndex; i++) { | 
| +    target[offset + i] = temp[i - leftIndex]; | 
| +  } | 
| +} | 
| + | 
| function TypedArraySet(obj, offset) { | 
| var intOffset = IS_UNDEFINED(offset) ? 0 : TO_INTEGER(offset); | 
| if (intOffset < 0) { | 
| throw MakeTypeError("typed_array_set_negative_offset"); | 
| } | 
| -  if (%TypedArraySetFastCases(this, obj, intOffset)) | 
| -    return; | 
| - | 
| -  var l = obj.length; | 
| -  if (IS_UNDEFINED(l)) { | 
| -    if (IS_NUMBER(obj)) { | 
| -        // For number as a first argument, throw TypeError | 
| -        // instead of silently ignoring the call, so that | 
| -        // the user knows (s)he did something wrong. | 
| -        // (Consistent with Firefox and Blink/WebKit) | 
| -        throw MakeTypeError("invalid_argument"); | 
| -    } | 
| -    return; | 
| -  } | 
| -  if (intOffset + l > this.length) { | 
| -    throw MakeRangeError("typed_array_set_source_too_large"); | 
| -  } | 
| -  for (var i = 0; i < l; i++) { | 
| -    this[intOffset + i] = obj[i]; | 
| +  switch (%TypedArraySetFastCases(this, obj, intOffset)) { | 
| +    // These numbers should be synchronized with runtime.cc. | 
| +    case 0: // TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE | 
| +      return; | 
| +    case 1: // TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING | 
| +      TypedArraySetFromOverlappingTypedArray(this, obj, intOffset); | 
| +      return; | 
| +    case 2: // TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING | 
| +      TypedArraySetFromArrayLike(this, obj, obj.length, intOffset); | 
| +      return; | 
| +    case 3: // TYPED_ARRAY_SET_NON_TYPED_ARRAY | 
| +      var l = obj.length; | 
| +      if (IS_UNDEFINED(l)) { | 
| +        if (IS_NUMBER(obj)) { | 
| +            // For number as a first argument, throw TypeError | 
| +            // instead of silently ignoring the call, so that | 
| +            // the user knows (s)he did something wrong. | 
| +            // (Consistent with Firefox and Blink/WebKit) | 
| +            throw MakeTypeError("invalid_argument"); | 
| +        } | 
| +        return; | 
| +      } | 
| +      if (intOffset + l > this.length) { | 
| +        throw MakeRangeError("typed_array_set_source_too_large"); | 
| +      } | 
| +      TypedArraySetFromArrayLike(this, obj, l, intOffset); | 
| +      return; | 
| } | 
| } | 
|  | 
|  |