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
14var GlobalArrayBuffer = global.ArrayBuffer;
15var MakeTypeError;
16var MaxSimple;
17var MinSimple;
18var SpeciesConstructor;
19
20utils.Import(function(from) {
21  MakeTypeError = from.MakeTypeError;
22  MaxSimple = from.MaxSimple;
23  MinSimple = from.MinSimple;
24  SpeciesConstructor = from.SpeciesConstructor;
25});
26
27// -------------------------------------------------------------------
28
29function ArrayBufferGetByteLen() {
30  if (!IS_ARRAYBUFFER(this)) {
31    throw MakeTypeError(kIncompatibleMethodReceiver,
32                        'ArrayBuffer.prototype.byteLength', this);
33  }
34  return %_ArrayBufferGetByteLength(this);
35}
36
37// ES6 Draft 15.13.5.5.3
38function ArrayBufferSlice(start, end) {
39  if (!IS_ARRAYBUFFER(this)) {
40    throw MakeTypeError(kIncompatibleMethodReceiver,
41                        'ArrayBuffer.prototype.slice', this);
42  }
43
44  var relativeStart = TO_INTEGER(start);
45  if (!IS_UNDEFINED(end)) {
46    end = TO_INTEGER(end);
47  }
48  var first;
49  var byte_length = %_ArrayBufferGetByteLength(this);
50  if (relativeStart < 0) {
51    first = MaxSimple(byte_length + relativeStart, 0);
52  } else {
53    first = MinSimple(relativeStart, byte_length);
54  }
55  var relativeEnd = IS_UNDEFINED(end) ? byte_length : end;
56  var fin;
57  if (relativeEnd < 0) {
58    fin = MaxSimple(byte_length + relativeEnd, 0);
59  } else {
60    fin = MinSimple(relativeEnd, byte_length);
61  }
62
63  if (fin < first) {
64    fin = first;
65  }
66  var newLen = fin - first;
67  var constructor = SpeciesConstructor(this, GlobalArrayBuffer, true);
68  var result = new constructor(newLen);
69  if (!IS_ARRAYBUFFER(result)) {
70    throw MakeTypeError(kIncompatibleMethodReceiver,
71                        'ArrayBuffer.prototype.slice', result);
72  }
73  // TODO(littledan): Check for a detached ArrayBuffer
74  if (result === this) {
75    throw MakeTypeError(kArrayBufferSpeciesThis);
76  }
77  if (%_ArrayBufferGetByteLength(result) < newLen) {
78    throw MakeTypeError(kArrayBufferTooShort);
79  }
80
81  %ArrayBufferSliceImpl(this, result, first, newLen);
82  return result;
83}
84
85utils.InstallGetter(GlobalArrayBuffer.prototype, "byteLength",
86                    ArrayBufferGetByteLen);
87
88utils.InstallFunctions(GlobalArrayBuffer.prototype, DONT_ENUM, [
89  "slice", ArrayBufferSlice
90]);
91
92})
93