1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 (function(global, utils) { 6 7 "use strict"; 8 9 %CheckIsBootstrapping(); 10 11 // ------------------------------------------------------------------- 12 // Imports 13 14 var GlobalArrayBuffer = global.ArrayBuffer; 15 var MakeTypeError; 16 var MaxSimple; 17 var MinSimple; 18 var SpeciesConstructor; 19 var speciesSymbol = utils.ImportNow("species_symbol"); 20 21 utils.Import(function(from) { 22 MakeTypeError = from.MakeTypeError; 23 MaxSimple = from.MaxSimple; 24 MinSimple = from.MinSimple; 25 SpeciesConstructor = from.SpeciesConstructor; 26 }); 27 28 // ------------------------------------------------------------------- 29 30 function ArrayBufferGetByteLen() { 31 if (!IS_ARRAYBUFFER(this)) { 32 throw MakeTypeError(kIncompatibleMethodReceiver, 33 'ArrayBuffer.prototype.byteLength', this); 34 } 35 return %_ArrayBufferGetByteLength(this); 36 } 37 38 // ES6 Draft 15.13.5.5.3 39 function ArrayBufferSlice(start, end) { 40 if (!IS_ARRAYBUFFER(this)) { 41 throw MakeTypeError(kIncompatibleMethodReceiver, 42 'ArrayBuffer.prototype.slice', this); 43 } 44 45 var relativeStart = TO_INTEGER(start); 46 if (!IS_UNDEFINED(end)) { 47 end = TO_INTEGER(end); 48 } 49 var first; 50 var byte_length = %_ArrayBufferGetByteLength(this); 51 if (relativeStart < 0) { 52 first = MaxSimple(byte_length + relativeStart, 0); 53 } else { 54 first = MinSimple(relativeStart, byte_length); 55 } 56 var relativeEnd = IS_UNDEFINED(end) ? byte_length : end; 57 var fin; 58 if (relativeEnd < 0) { 59 fin = MaxSimple(byte_length + relativeEnd, 0); 60 } else { 61 fin = MinSimple(relativeEnd, byte_length); 62 } 63 64 if (fin < first) { 65 fin = first; 66 } 67 var newLen = fin - first; 68 var constructor = SpeciesConstructor(this, GlobalArrayBuffer, true); 69 var result = new constructor(newLen); 70 if (!IS_ARRAYBUFFER(result)) { 71 throw MakeTypeError(kIncompatibleMethodReceiver, 72 'ArrayBuffer.prototype.slice', result); 73 } 74 // Checks for detached source/target ArrayBuffers are done inside of 75 // %ArrayBufferSliceImpl; the reordering of checks does not violate 76 // the spec because all exceptions thrown are TypeErrors. 77 if (result === this) { 78 throw MakeTypeError(kArrayBufferSpeciesThis); 79 } 80 if (%_ArrayBufferGetByteLength(result) < newLen) { 81 throw MakeTypeError(kArrayBufferTooShort); 82 } 83 84 %ArrayBufferSliceImpl(this, result, first, newLen); 85 return result; 86 } 87 88 89 function ArrayBufferSpecies() { 90 return this; 91 } 92 93 utils.InstallGetter(GlobalArrayBuffer, speciesSymbol, ArrayBufferSpecies); 94 95 utils.InstallGetter(GlobalArrayBuffer.prototype, "byteLength", 96 ArrayBufferGetByteLen); 97 98 utils.InstallFunctions(GlobalArrayBuffer.prototype, DONT_ENUM, [ 99 "slice", ArrayBufferSlice 100 ]); 101 102 }) 103