Home | History | Annotate | Download | only in js
      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