| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |