1 // Copyright 2016 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 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h"
7 #include "src/conversions.h"
8 #include "src/counters.h"
9 #include "src/objects-inl.h"
10
11 namespace v8 {
12 namespace internal {
13
14 // -----------------------------------------------------------------------------
15 // ES6 section 21.1 ArrayBuffer Objects
16
17 // ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case.
BUILTIN(ArrayBufferConstructor)18 BUILTIN(ArrayBufferConstructor) {
19 HandleScope scope(isolate);
20 Handle<JSFunction> target = args.target();
21 DCHECK(*target == target->native_context()->array_buffer_fun() ||
22 *target == target->native_context()->shared_array_buffer_fun());
23 THROW_NEW_ERROR_RETURN_FAILURE(
24 isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
25 handle(target->shared()->name(), isolate)));
26 }
27
28 // ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Construct]] case.
BUILTIN(ArrayBufferConstructor_ConstructStub)29 BUILTIN(ArrayBufferConstructor_ConstructStub) {
30 HandleScope scope(isolate);
31 Handle<JSFunction> target = args.target();
32 Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
33 Handle<Object> length = args.atOrUndefined(isolate, 1);
34 DCHECK(*target == target->native_context()->array_buffer_fun() ||
35 *target == target->native_context()->shared_array_buffer_fun());
36 Handle<Object> number_length;
37 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_length,
38 Object::ToInteger(isolate, length));
39 if (number_length->Number() < 0.0) {
40 THROW_NEW_ERROR_RETURN_FAILURE(
41 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength));
42 }
43 Handle<JSObject> result;
44 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
45 JSObject::New(target, new_target));
46 size_t byte_length;
47 if (!TryNumberToSize(*number_length, &byte_length)) {
48 THROW_NEW_ERROR_RETURN_FAILURE(
49 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength));
50 }
51 SharedFlag shared_flag =
52 (*target == target->native_context()->array_buffer_fun())
53 ? SharedFlag::kNotShared
54 : SharedFlag::kShared;
55 if (!JSArrayBuffer::SetupAllocatingData(Handle<JSArrayBuffer>::cast(result),
56 isolate, byte_length, true,
57 shared_flag)) {
58 THROW_NEW_ERROR_RETURN_FAILURE(
59 isolate, NewRangeError(MessageTemplate::kArrayBufferAllocationFailed));
60 }
61 return *result;
62 }
63
64 // ES6 section 24.1.4.1 get ArrayBuffer.prototype.byteLength
BUILTIN(ArrayBufferPrototypeGetByteLength)65 BUILTIN(ArrayBufferPrototypeGetByteLength) {
66 HandleScope scope(isolate);
67 CHECK_RECEIVER(JSArrayBuffer, array_buffer,
68 "get ArrayBuffer.prototype.byteLength");
69
70 if (array_buffer->is_shared()) {
71 THROW_NEW_ERROR_RETURN_FAILURE(
72 isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
73 isolate->factory()->NewStringFromAsciiChecked(
74 "get ArrayBuffer.prototype.byteLength"),
75 args.receiver()));
76 }
77 // TODO(franzih): According to the ES6 spec, we should throw a TypeError
78 // here if the JSArrayBuffer is detached.
79 return array_buffer->byte_length();
80 }
81
82 // ES6 section 24.1.3.1 ArrayBuffer.isView ( arg )
BUILTIN(ArrayBufferIsView)83 BUILTIN(ArrayBufferIsView) {
84 SealHandleScope shs(isolate);
85 DCHECK_EQ(2, args.length());
86 Object* arg = args[1];
87 return isolate->heap()->ToBoolean(arg->IsJSArrayBufferView());
88 }
89
90 } // namespace internal
91 } // namespace v8
92