Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/builtins/builtins-sharedarraybuffer.cc

Issue 2741413006: [SAB] Implement SharedArrayBuffer.prototype.slice (Closed)
Patch Set: remove old test Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/messages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stub-assembler.h" 8 #include "src/code-stub-assembler.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13 #define CHECK_IS_SHARED_ARRAY_BUFFER(name, method) \
14 if (!name->is_shared()) { \
15 THROW_NEW_ERROR_RETURN_FAILURE( \
16 isolate, \
17 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \
18 isolate->factory()->NewStringFromAsciiChecked(method), \
19 name)); \
20 }
21
13 using compiler::Node; 22 using compiler::Node;
14 23
15 class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler { 24 class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler {
16 public: 25 public:
17 explicit SharedArrayBufferBuiltinsAssembler( 26 explicit SharedArrayBufferBuiltinsAssembler(
18 compiler::CodeAssemblerState* state) 27 compiler::CodeAssemblerState* state)
19 : CodeStubAssembler(state) {} 28 : CodeStubAssembler(state) {}
20 29
21 protected: 30 protected:
22 void ValidateSharedTypedArray(Node* tagged, Node* context, 31 void ValidateSharedTypedArray(Node* tagged, Node* context,
23 Node** out_instance_type, 32 Node** out_instance_type,
24 Node** out_backing_store); 33 Node** out_backing_store);
25 Node* ConvertTaggedAtomicIndexToWord32(Node* tagged, Node* context, 34 Node* ConvertTaggedAtomicIndexToWord32(Node* tagged, Node* context,
26 Node** number_index); 35 Node** number_index);
27 void ValidateAtomicIndex(Node* index_word, Node* array_length_word, 36 void ValidateAtomicIndex(Node* index_word, Node* array_length_word,
28 Node* context); 37 Node* context);
29 }; 38 };
30 39
31 // ES7 sharedmem 6.3.4.1 get SharedArrayBuffer.prototype.byteLength 40 // ES7 sharedmem 6.3.4.1 get SharedArrayBuffer.prototype.byteLength
32 BUILTIN(SharedArrayBufferPrototypeGetByteLength) { 41 BUILTIN(SharedArrayBufferPrototypeGetByteLength) {
42 const char* const kMethodName = "get SharedArrayBuffer.prototype.byteLength";
33 HandleScope scope(isolate); 43 HandleScope scope(isolate);
34 CHECK_RECEIVER(JSArrayBuffer, array_buffer, 44 CHECK_RECEIVER(JSArrayBuffer, array_buffer,
35 "get SharedArrayBuffer.prototype.byteLength"); 45 "get SharedArrayBuffer.prototype.byteLength");
36 if (!array_buffer->is_shared()) { 46 CHECK_IS_SHARED_ARRAY_BUFFER(array_buffer, kMethodName);
37 THROW_NEW_ERROR_RETURN_FAILURE(
38 isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
39 isolate->factory()->NewStringFromAsciiChecked(
40 "get SharedArrayBuffer.prototype.byteLength"),
41 args.receiver()));
42 }
43 return array_buffer->byte_length(); 47 return array_buffer->byte_length();
44 } 48 }
45 49
50 // ES #sec-sharedarraybuffer.prototype.slice
51 // SharedArrayBuffer.prototype.slice ( start, end )
52 BUILTIN(SharedArrayBufferPrototypeSlice) {
Dan Ehrenberg 2017/03/16 07:45:06 Would it be possible to reuse most of the implemen
binji 2017/03/16 16:17:00 I thought so at first, but there are enough differ
Dan Ehrenberg 2017/03/17 10:30:44 Well, I'd still would prefer for it to be de-dupli
53 const char* const kMethodName = "SharedArrayBuffer.prototype.slice";
54 HandleScope scope(isolate);
55 Handle<Object> start = args.at(1);
56 Handle<Object> end = args.atOrUndefined(isolate, 2);
57
58 // 2. If Type(O) is not Object, throw a TypeError exception.
59 // 3. If O does not have an [[ArrayBufferData]] internal slot, throw a
60 // TypeError exception.
61 CHECK_RECEIVER(JSArrayBuffer, array_buffer, kMethodName);
62 // 4. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
63 CHECK_IS_SHARED_ARRAY_BUFFER(array_buffer, kMethodName);
64
65 // 5. Let len be O.[[ArrayBufferByteLength]].
66 double const len = array_buffer->byte_length()->Number();
67
68 // 6. Let relativeStart be ? ToInteger(start).
69 Handle<Object> relative_start;
70 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, relative_start,
71 Object::ToInteger(isolate, start));
72
73 // 7. If relativeStart < 0, let first be max((len + relativeStart), 0); else
74 // let first be min(relativeStart, len).
75 double const first = (relative_start->Number() < 0)
76 ? Max(len + relative_start->Number(), 0.0)
77 : Min(relative_start->Number(), len);
78 Handle<Object> first_obj = isolate->factory()->NewNumber(first);
79
80 // 8. If end is undefined, let relativeEnd be len; else let relativeEnd be ?
81 // ToInteger(end).
82 double relative_end;
83 if (end->IsUndefined(isolate)) {
84 relative_end = len;
85 } else {
86 Handle<Object> relative_end_obj;
87 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, relative_end_obj,
88 Object::ToInteger(isolate, end));
89 relative_end = relative_end_obj->Number();
90 }
91
92 // 9. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let
93 // final be min(relativeEnd, len).
94 double const final_ = (relative_end < 0) ? Max(len + relative_end, 0.0)
95 : Min(relative_end, len);
96
97 // 10. Let newLen be max(final-first, 0).
98 double const new_len = Max(final_ - first, 0.0);
99 Handle<Object> new_len_obj = isolate->factory()->NewNumber(new_len);
100
101 // 11. Let ctor be ? SpeciesConstructor(O, %SharedArrayBuffer%).
102 Handle<JSFunction> sharedarraybuffer_fun = isolate->shared_array_buffer_fun();
103 Handle<Object> ctor;
104 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
105 isolate, ctor,
106 Object::SpeciesConstructor(isolate,
107 Handle<JSReceiver>::cast(args.receiver()),
108 sharedarraybuffer_fun));
109
110 // 12. Let new be ? Construct(ctor, newLen).
111 Handle<JSReceiver> new_;
112 {
113 const int argc = 1;
114
115 ScopedVector<Handle<Object>> argv(argc);
116 argv[0] = new_len_obj;
117
118 Handle<Object> new_obj;
119 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
120 isolate, new_obj,
121 Execution::New(Handle<JSFunction>::cast(ctor), argc, argv.start()));
122
123 new_ = Handle<JSReceiver>::cast(new_obj);
124 }
125
126 // 13. If new does not have an [[ArrayBufferData]] internal slot, throw a
127 // TypeError exception.
128 if (!new_->IsJSArrayBuffer()) {
129 THROW_NEW_ERROR_RETURN_FAILURE(
130 isolate,
131 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
132 isolate->factory()->NewStringFromAsciiChecked(kMethodName),
133 new_));
134 }
135
136 // 14. If IsSharedArrayBuffer(new) is false, throw a TypeError exception.
137 Handle<JSArrayBuffer> new_array_buffer = Handle<JSArrayBuffer>::cast(new_);
138 CHECK_IS_SHARED_ARRAY_BUFFER(new_array_buffer, kMethodName);
139
140 // 15. If new.[[ArrayBufferData]] and O.[[ArrayBufferData]] are the same
141 // Shared Data Block values, throw a TypeError exception.
142 if (new_array_buffer->backing_store() == array_buffer->backing_store()) {
143 THROW_NEW_ERROR_RETURN_FAILURE(
144 isolate, NewTypeError(MessageTemplate::kSharedArrayBufferSpeciesThis));
145 }
146
147 // 16. If new.[[ArrayBufferByteLength]] < newLen, throw a TypeError exception.
148 if (new_array_buffer->byte_length()->Number() < new_len) {
149 THROW_NEW_ERROR_RETURN_FAILURE(
150 isolate, NewTypeError(MessageTemplate::kSharedArrayBufferTooShort));
151 }
152
153 // 17. Let fromBuf be O.[[ArrayBufferData]].
154 // 18. Let toBuf be new.[[ArrayBufferData]].
155 // 19. Perform CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen).
156 size_t first_size = 0, new_len_size = 0;
157 CHECK(TryNumberToSize(*first_obj, &first_size));
158 CHECK(TryNumberToSize(*new_len_obj, &new_len_size));
159 DCHECK(NumberToSize(new_array_buffer->byte_length()) >= new_len_size);
160
161 if (new_len_size != 0) {
162 size_t from_byte_length = NumberToSize(array_buffer->byte_length());
163 USE(from_byte_length);
164 DCHECK(first_size <= from_byte_length);
165 DCHECK(from_byte_length - first_size >= new_len_size);
166 uint8_t* from_data =
167 reinterpret_cast<uint8_t*>(array_buffer->backing_store());
168 uint8_t* to_data =
169 reinterpret_cast<uint8_t*>(new_array_buffer->backing_store());
170 CopyBytes(to_data, from_data + first_size, new_len_size);
171 }
172
173 return *new_;
174 }
175
46 void SharedArrayBufferBuiltinsAssembler::ValidateSharedTypedArray( 176 void SharedArrayBufferBuiltinsAssembler::ValidateSharedTypedArray(
47 Node* tagged, Node* context, Node** out_instance_type, 177 Node* tagged, Node* context, Node** out_instance_type,
48 Node** out_backing_store) { 178 Node** out_backing_store) {
49 Label not_float_or_clamped(this), invalid(this); 179 Label not_float_or_clamped(this), invalid(this);
50 180
51 // Fail if it is not a heap object. 181 // Fail if it is not a heap object.
52 GotoIf(TaggedIsSmi(tagged), &invalid); 182 GotoIf(TaggedIsSmi(tagged), &invalid);
53 183
54 // Fail if the array's instance type is not JSTypedArray. 184 // Fail if the array's instance type is not JSTypedArray.
55 GotoIf(Word32NotEqual(LoadInstanceType(tagged), 185 GotoIf(Word32NotEqual(LoadInstanceType(tagged),
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 462
333 // This shouldn't happen, we've already validated the type. 463 // This shouldn't happen, we've already validated the type.
334 Bind(&other); 464 Bind(&other);
335 Unreachable(); 465 Unreachable();
336 #endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 466 #endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64
337 // || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X 467 // || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X
338 } 468 }
339 469
340 } // namespace internal 470 } // namespace internal
341 } // namespace v8 471 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698