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

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

Issue 2752143004: [refactor] Separate generated builtins and C++ builtins into separate files (Closed)
Patch Set: tentative gcmole fix 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-number-gen.cc ('k') | src/builtins/builtins-object-gen.cc » ('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 #include "src/counters.h" 9 #include "src/counters.h"
10 #include "src/keys.h" 10 #include "src/keys.h"
11 #include "src/lookup.h" 11 #include "src/lookup.h"
12 #include "src/objects-inl.h" 12 #include "src/objects-inl.h"
13 #include "src/property-descriptor.h" 13 #include "src/property-descriptor.h"
14 14
15 namespace v8 { 15 namespace v8 {
16 namespace internal { 16 namespace internal {
17 17
18 typedef compiler::Node Node;
19
20 class ObjectBuiltinsAssembler : public CodeStubAssembler {
21 public:
22 explicit ObjectBuiltinsAssembler(compiler::CodeAssemblerState* state)
23 : CodeStubAssembler(state) {}
24
25 protected:
26 void IsString(Node* object, Label* if_string, Label* if_notstring);
27 void ReturnToStringFormat(Node* context, Node* string);
28 };
29
30 void ObjectBuiltinsAssembler::IsString(Node* object, Label* if_string,
31 Label* if_notstring) {
32 Label if_notsmi(this);
33 Branch(TaggedIsSmi(object), if_notstring, &if_notsmi);
34
35 Bind(&if_notsmi);
36 {
37 Node* instance_type = LoadInstanceType(object);
38
39 Branch(IsStringInstanceType(instance_type), if_string, if_notstring);
40 }
41 }
42
43 void ObjectBuiltinsAssembler::ReturnToStringFormat(Node* context,
44 Node* string) {
45 Node* lhs = HeapConstant(factory()->NewStringFromStaticChars("[object "));
46 Node* rhs = HeapConstant(factory()->NewStringFromStaticChars("]"));
47
48 Callable callable =
49 CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED);
50
51 Return(CallStub(callable, context, CallStub(callable, context, lhs, string),
52 rhs));
53 }
54
55 // ----------------------------------------------------------------------------- 18 // -----------------------------------------------------------------------------
56 // ES6 section 19.1 Object Objects 19 // ES6 section 19.1 Object Objects
57 20
58 TF_BUILTIN(ObjectHasOwnProperty, ObjectBuiltinsAssembler) {
59 Node* object = Parameter(0);
60 Node* key = Parameter(1);
61 Node* context = Parameter(4);
62
63 Label call_runtime(this), return_true(this), return_false(this);
64
65 // Smi receivers do not have own properties.
66 Label if_objectisnotsmi(this);
67 Branch(TaggedIsSmi(object), &return_false, &if_objectisnotsmi);
68 Bind(&if_objectisnotsmi);
69
70 Node* map = LoadMap(object);
71 Node* instance_type = LoadMapInstanceType(map);
72
73 {
74 Variable var_index(this, MachineType::PointerRepresentation());
75 Variable var_unique(this, MachineRepresentation::kTagged);
76
77 Label keyisindex(this), if_iskeyunique(this);
78 TryToName(key, &keyisindex, &var_index, &if_iskeyunique, &var_unique,
79 &call_runtime);
80
81 Bind(&if_iskeyunique);
82 TryHasOwnProperty(object, map, instance_type, var_unique.value(),
83 &return_true, &return_false, &call_runtime);
84
85 Bind(&keyisindex);
86 // Handle negative keys in the runtime.
87 GotoIf(IntPtrLessThan(var_index.value(), IntPtrConstant(0)), &call_runtime);
88 TryLookupElement(object, map, instance_type, var_index.value(),
89 &return_true, &return_false, &call_runtime);
90 }
91 Bind(&return_true);
92 Return(BooleanConstant(true));
93
94 Bind(&return_false);
95 Return(BooleanConstant(false));
96
97 Bind(&call_runtime);
98 Return(CallRuntime(Runtime::kObjectHasOwnProperty, context, object, key));
99 }
100
101 // ES6 19.1.2.1 Object.assign 21 // ES6 19.1.2.1 Object.assign
102 BUILTIN(ObjectAssign) { 22 BUILTIN(ObjectAssign) {
103 HandleScope scope(isolate); 23 HandleScope scope(isolate);
104 Handle<Object> target = args.atOrUndefined(isolate, 1); 24 Handle<Object> target = args.atOrUndefined(isolate, 1);
105 25
106 // 1. Let to be ? ToObject(target). 26 // 1. Let to be ? ToObject(target).
107 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target, 27 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target,
108 Object::ToObject(isolate, target)); 28 Object::ToObject(isolate, target));
109 Handle<JSReceiver> to = Handle<JSReceiver>::cast(target); 29 Handle<JSReceiver> to = Handle<JSReceiver>::cast(target);
110 // 2. If only one argument was passed, return to. 30 // 2. If only one argument was passed, return to.
(...skipping 19 matching lines...) Expand all
130 isolate, name, Object::ToName(isolate, args.atOrUndefined(isolate, 1))); 50 isolate, name, Object::ToName(isolate, args.atOrUndefined(isolate, 1)));
131 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 51 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
132 isolate, object, JSReceiver::ToObject(isolate, args.receiver())); 52 isolate, object, JSReceiver::ToObject(isolate, args.receiver()));
133 Maybe<PropertyAttributes> maybe = 53 Maybe<PropertyAttributes> maybe =
134 JSReceiver::GetOwnPropertyAttributes(object, name); 54 JSReceiver::GetOwnPropertyAttributes(object, name);
135 if (!maybe.IsJust()) return isolate->heap()->exception(); 55 if (!maybe.IsJust()) return isolate->heap()->exception();
136 if (maybe.FromJust() == ABSENT) return isolate->heap()->false_value(); 56 if (maybe.FromJust() == ABSENT) return isolate->heap()->false_value();
137 return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0); 57 return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0);
138 } 58 }
139 59
140 // ES6 section 19.1.3.6 Object.prototype.toString
141 TF_BUILTIN(ObjectProtoToString, ObjectBuiltinsAssembler) {
142 Label return_undefined(this, Label::kDeferred),
143 return_null(this, Label::kDeferred),
144 return_arguments(this, Label::kDeferred), return_array(this),
145 return_api(this, Label::kDeferred), return_object(this),
146 return_regexp(this), return_function(this), return_error(this),
147 return_date(this), return_jsvalue(this),
148 return_jsproxy(this, Label::kDeferred);
149
150 Label if_isproxy(this, Label::kDeferred);
151
152 Label checkstringtag(this);
153 Label if_tostringtag(this), if_notostringtag(this);
154
155 Node* receiver = Parameter(0);
156 Node* context = Parameter(3);
157
158 GotoIf(WordEqual(receiver, UndefinedConstant()), &return_undefined);
159
160 GotoIf(WordEqual(receiver, NullConstant()), &return_null);
161
162 Callable to_object = CodeFactory::ToObject(isolate());
163 receiver = CallStub(to_object, context, receiver);
164
165 Node* receiver_instance_type = LoadInstanceType(receiver);
166
167 // for proxies, check IsArray before getting @@toStringTag
168 Variable var_proxy_is_array(this, MachineRepresentation::kTagged);
169 var_proxy_is_array.Bind(BooleanConstant(false));
170
171 Branch(Word32Equal(receiver_instance_type, Int32Constant(JS_PROXY_TYPE)),
172 &if_isproxy, &checkstringtag);
173
174 Bind(&if_isproxy);
175 {
176 // This can throw
177 var_proxy_is_array.Bind(
178 CallRuntime(Runtime::kArrayIsArray, context, receiver));
179 Goto(&checkstringtag);
180 }
181
182 Bind(&checkstringtag);
183 {
184 Node* to_string_tag_symbol =
185 HeapConstant(isolate()->factory()->to_string_tag_symbol());
186
187 GetPropertyStub stub(isolate());
188 Callable get_property =
189 Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
190 Node* to_string_tag_value =
191 CallStub(get_property, context, receiver, to_string_tag_symbol);
192
193 IsString(to_string_tag_value, &if_tostringtag, &if_notostringtag);
194
195 Bind(&if_tostringtag);
196 ReturnToStringFormat(context, to_string_tag_value);
197 }
198 Bind(&if_notostringtag);
199 {
200 size_t const kNumCases = 11;
201 Label* case_labels[kNumCases];
202 int32_t case_values[kNumCases];
203 case_labels[0] = &return_api;
204 case_values[0] = JS_API_OBJECT_TYPE;
205 case_labels[1] = &return_api;
206 case_values[1] = JS_SPECIAL_API_OBJECT_TYPE;
207 case_labels[2] = &return_arguments;
208 case_values[2] = JS_ARGUMENTS_TYPE;
209 case_labels[3] = &return_array;
210 case_values[3] = JS_ARRAY_TYPE;
211 case_labels[4] = &return_function;
212 case_values[4] = JS_BOUND_FUNCTION_TYPE;
213 case_labels[5] = &return_function;
214 case_values[5] = JS_FUNCTION_TYPE;
215 case_labels[6] = &return_error;
216 case_values[6] = JS_ERROR_TYPE;
217 case_labels[7] = &return_date;
218 case_values[7] = JS_DATE_TYPE;
219 case_labels[8] = &return_regexp;
220 case_values[8] = JS_REGEXP_TYPE;
221 case_labels[9] = &return_jsvalue;
222 case_values[9] = JS_VALUE_TYPE;
223 case_labels[10] = &return_jsproxy;
224 case_values[10] = JS_PROXY_TYPE;
225
226 Switch(receiver_instance_type, &return_object, case_values, case_labels,
227 arraysize(case_values));
228
229 Bind(&return_undefined);
230 Return(HeapConstant(isolate()->factory()->undefined_to_string()));
231
232 Bind(&return_null);
233 Return(HeapConstant(isolate()->factory()->null_to_string()));
234
235 Bind(&return_arguments);
236 Return(HeapConstant(isolate()->factory()->arguments_to_string()));
237
238 Bind(&return_array);
239 Return(HeapConstant(isolate()->factory()->array_to_string()));
240
241 Bind(&return_function);
242 Return(HeapConstant(isolate()->factory()->function_to_string()));
243
244 Bind(&return_error);
245 Return(HeapConstant(isolate()->factory()->error_to_string()));
246
247 Bind(&return_date);
248 Return(HeapConstant(isolate()->factory()->date_to_string()));
249
250 Bind(&return_regexp);
251 Return(HeapConstant(isolate()->factory()->regexp_to_string()));
252
253 Bind(&return_api);
254 {
255 Node* class_name = CallRuntime(Runtime::kClassOf, context, receiver);
256 ReturnToStringFormat(context, class_name);
257 }
258
259 Bind(&return_jsvalue);
260 {
261 Label return_boolean(this), return_number(this), return_string(this);
262
263 Node* value = LoadJSValueValue(receiver);
264 GotoIf(TaggedIsSmi(value), &return_number);
265 Node* instance_type = LoadInstanceType(value);
266
267 GotoIf(IsStringInstanceType(instance_type), &return_string);
268 GotoIf(Word32Equal(instance_type, Int32Constant(HEAP_NUMBER_TYPE)),
269 &return_number);
270 GotoIf(Word32Equal(instance_type, Int32Constant(ODDBALL_TYPE)),
271 &return_boolean);
272
273 CSA_ASSERT(this, Word32Equal(instance_type, Int32Constant(SYMBOL_TYPE)));
274 Goto(&return_object);
275
276 Bind(&return_string);
277 Return(HeapConstant(isolate()->factory()->string_to_string()));
278
279 Bind(&return_number);
280 Return(HeapConstant(isolate()->factory()->number_to_string()));
281
282 Bind(&return_boolean);
283 Return(HeapConstant(isolate()->factory()->boolean_to_string()));
284 }
285
286 Bind(&return_jsproxy);
287 {
288 GotoIf(WordEqual(var_proxy_is_array.value(), BooleanConstant(true)),
289 &return_array);
290
291 Node* map = LoadMap(receiver);
292
293 // Return object if the proxy {receiver} is not callable.
294 Branch(IsCallableMap(map), &return_function, &return_object);
295 }
296
297 // Default
298 Bind(&return_object);
299 Return(HeapConstant(isolate()->factory()->object_to_string()));
300 }
301 }
302
303 // ES6 19.3.7 Object.prototype.valueOf
304 TF_BUILTIN(ObjectPrototypeValueOf, CodeStubAssembler) {
305 Node* receiver = Parameter(0);
306 Node* context = Parameter(3);
307
308 Callable to_object = CodeFactory::ToObject(isolate());
309 receiver = CallStub(to_object, context, receiver);
310
311 Return(receiver);
312 }
313
314 TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) {
315 Node* prototype = Parameter(1);
316 Node* properties = Parameter(2);
317 Node* context = Parameter(3 + 2);
318
319 Label call_runtime(this, Label::kDeferred), prototype_valid(this),
320 no_properties(this);
321 {
322 Comment("Argument 1 check: prototype");
323 GotoIf(WordEqual(prototype, NullConstant()), &prototype_valid);
324 BranchIfJSReceiver(prototype, &prototype_valid, &call_runtime);
325 }
326
327 Bind(&prototype_valid);
328 {
329 Comment("Argument 2 check: properties");
330 // Check that we have a simple object
331 GotoIf(TaggedIsSmi(properties), &call_runtime);
332 // Undefined implies no properties.
333 GotoIf(WordEqual(properties, UndefinedConstant()), &no_properties);
334 Node* properties_map = LoadMap(properties);
335 GotoIf(IsSpecialReceiverMap(properties_map), &call_runtime);
336 // Stay on the fast path only if there are no elements.
337 GotoIfNot(WordEqual(LoadElements(properties),
338 LoadRoot(Heap::kEmptyFixedArrayRootIndex)),
339 &call_runtime);
340 // Handle dictionary objects or fast objects with properties in runtime.
341 Node* bit_field3 = LoadMapBitField3(properties_map);
342 GotoIf(IsSetWord32<Map::DictionaryMap>(bit_field3), &call_runtime);
343 Branch(IsSetWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3),
344 &call_runtime, &no_properties);
345 }
346
347 // Create a new object with the given prototype.
348 Bind(&no_properties);
349 {
350 Variable map(this, MachineRepresentation::kTagged);
351 Variable properties(this, MachineRepresentation::kTagged);
352 Label non_null_proto(this), instantiate_map(this), good(this);
353
354 Branch(WordEqual(prototype, NullConstant()), &good, &non_null_proto);
355
356 Bind(&good);
357 {
358 map.Bind(LoadContextElement(
359 context, Context::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP));
360 properties.Bind(AllocateNameDictionary(NameDictionary::kInitialCapacity));
361 Goto(&instantiate_map);
362 }
363
364 Bind(&non_null_proto);
365 {
366 properties.Bind(EmptyFixedArrayConstant());
367 Node* object_function =
368 LoadContextElement(context, Context::OBJECT_FUNCTION_INDEX);
369 Node* object_function_map = LoadObjectField(
370 object_function, JSFunction::kPrototypeOrInitialMapOffset);
371 map.Bind(object_function_map);
372 GotoIf(WordEqual(prototype, LoadMapPrototype(map.value())),
373 &instantiate_map);
374 // Try loading the prototype info.
375 Node* prototype_info =
376 LoadMapPrototypeInfo(LoadMap(prototype), &call_runtime);
377 Comment("Load ObjectCreateMap from PrototypeInfo");
378 Node* weak_cell =
379 LoadObjectField(prototype_info, PrototypeInfo::kObjectCreateMap);
380 GotoIf(WordEqual(weak_cell, UndefinedConstant()), &call_runtime);
381 map.Bind(LoadWeakCellValue(weak_cell, &call_runtime));
382 Goto(&instantiate_map);
383 }
384
385 Bind(&instantiate_map);
386 {
387 Node* instance = AllocateJSObjectFromMap(map.value(), properties.value());
388 Return(instance);
389 }
390 }
391
392 Bind(&call_runtime);
393 {
394 Return(CallRuntime(Runtime::kObjectCreate, context, prototype, properties));
395 }
396 }
397
398 // ES6 section 19.1.2.3 Object.defineProperties 60 // ES6 section 19.1.2.3 Object.defineProperties
399 BUILTIN(ObjectDefineProperties) { 61 BUILTIN(ObjectDefineProperties) {
400 HandleScope scope(isolate); 62 HandleScope scope(isolate);
401 DCHECK_EQ(3, args.length()); 63 DCHECK_EQ(3, args.length());
402 Handle<Object> target = args.at(1); 64 Handle<Object> target = args.at(1);
403 Handle<Object> properties = args.at(2); 65 Handle<Object> properties = args.at(2);
404 66
405 RETURN_RESULT_OR_FAILURE( 67 RETURN_RESULT_OR_FAILURE(
406 isolate, JSReceiver::DefineProperties(isolate, target, properties)); 68 isolate, JSReceiver::DefineProperties(isolate, target, properties));
407 } 69 }
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 HandleScope scope(isolate); 543 HandleScope scope(isolate);
882 Handle<Object> object = args.atOrUndefined(isolate, 1); 544 Handle<Object> object = args.atOrUndefined(isolate, 1);
883 if (object->IsJSReceiver()) { 545 if (object->IsJSReceiver()) {
884 MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object), 546 MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object),
885 SEALED, Object::THROW_ON_ERROR), 547 SEALED, Object::THROW_ON_ERROR),
886 isolate->heap()->exception()); 548 isolate->heap()->exception());
887 } 549 }
888 return *object; 550 return *object;
889 } 551 }
890 552
891 TF_BUILTIN(CreateIterResultObject, ObjectBuiltinsAssembler) {
892 typedef CreateIterResultObjectDescriptor Descriptor;
893
894 Node* const value = Parameter(Descriptor::kValue);
895 Node* const done = Parameter(Descriptor::kDone);
896 Node* const context = Parameter(Descriptor::kContext);
897
898 Node* const native_context = LoadNativeContext(context);
899 Node* const map =
900 LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
901
902 Node* const result = AllocateJSObjectFromMap(map);
903
904 StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kValueOffset, value);
905 StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kDoneOffset, done);
906
907 Return(result);
908 }
909
910 TF_BUILTIN(HasProperty, ObjectBuiltinsAssembler) {
911 typedef HasPropertyDescriptor Descriptor;
912
913 Node* key = Parameter(Descriptor::kKey);
914 Node* object = Parameter(Descriptor::kObject);
915 Node* context = Parameter(Descriptor::kContext);
916
917 Return(HasProperty(object, key, context, Runtime::kHasProperty));
918 }
919
920 TF_BUILTIN(InstanceOf, ObjectBuiltinsAssembler) {
921 typedef CompareDescriptor Descriptor;
922
923 Node* object = Parameter(Descriptor::kLeft);
924 Node* callable = Parameter(Descriptor::kRight);
925 Node* context = Parameter(Descriptor::kContext);
926
927 Return(InstanceOf(object, callable, context));
928 }
929
930 // ES6 section 7.3.19 OrdinaryHasInstance ( C, O )
931 TF_BUILTIN(OrdinaryHasInstance, ObjectBuiltinsAssembler) {
932 typedef CompareDescriptor Descriptor;
933
934 Node* constructor = Parameter(Descriptor::kLeft);
935 Node* object = Parameter(Descriptor::kRight);
936 Node* context = Parameter(Descriptor::kContext);
937
938 Return(OrdinaryHasInstance(context, constructor, object));
939 }
940
941 TF_BUILTIN(GetSuperConstructor, ObjectBuiltinsAssembler) {
942 typedef TypeofDescriptor Descriptor;
943
944 Node* object = Parameter(Descriptor::kObject);
945 Node* context = Parameter(Descriptor::kContext);
946
947 Return(GetSuperConstructor(object, context));
948 }
949
950 } // namespace internal 553 } // namespace internal
951 } // namespace v8 554 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-number-gen.cc ('k') | src/builtins/builtins-object-gen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698