OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/interpreter-intrinsics.h" | 5 #include "src/interpreter/interpreter-intrinsics.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 { | 96 { |
97 __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic); | 97 __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic); |
98 result.Bind(__ UndefinedConstant()); | 98 result.Bind(__ UndefinedConstant()); |
99 __ Goto(&end); | 99 __ Goto(&end); |
100 } | 100 } |
101 | 101 |
102 __ Bind(&end); | 102 __ Bind(&end); |
103 return result.value(); | 103 return result.value(); |
104 } | 104 } |
105 | 105 |
106 Node* IntrinsicsHelper::CompareInstanceType(Node* map, int type, | 106 Node* IntrinsicsHelper::CompareInstanceType(Node* object, int type, |
107 InstanceTypeCompareMode mode) { | 107 InstanceTypeCompareMode mode) { |
108 InterpreterAssembler::Variable return_value(assembler_, | 108 InterpreterAssembler::Variable return_value(assembler_, |
109 MachineRepresentation::kTagged); | 109 MachineRepresentation::kTagged); |
110 Node* instance_type = __ LoadInstanceType(map); | 110 Node* instance_type = __ LoadInstanceType(object); |
111 | 111 |
112 InterpreterAssembler::Label if_true(assembler_), if_false(assembler_), | 112 InterpreterAssembler::Label if_true(assembler_), if_false(assembler_), |
113 end(assembler_); | 113 end(assembler_); |
114 if (mode == kInstanceTypeEqual) { | 114 if (mode == kInstanceTypeEqual) { |
115 return __ Word32Equal(instance_type, __ Int32Constant(type)); | 115 return __ Word32Equal(instance_type, __ Int32Constant(type)); |
116 } else { | 116 } else { |
117 DCHECK(mode == kInstanceTypeGreaterThanOrEqual); | 117 DCHECK(mode == kInstanceTypeGreaterThanOrEqual); |
118 return __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type)); | 118 return __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type)); |
119 } | 119 } |
120 } | 120 } |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 __ GotoUnless(condition, &done); | 333 __ GotoUnless(condition, &done); |
334 | 334 |
335 // If the object is a value type, return the value field. | 335 // If the object is a value type, return the value field. |
336 return_value.Bind(__ LoadObjectField(object, JSValue::kValueOffset)); | 336 return_value.Bind(__ LoadObjectField(object, JSValue::kValueOffset)); |
337 __ Goto(&done); | 337 __ Goto(&done); |
338 | 338 |
339 __ Bind(&done); | 339 __ Bind(&done); |
340 return return_value.value(); | 340 return return_value.value(); |
341 } | 341 } |
342 | 342 |
| 343 Node* IntrinsicsHelper::ClassOf(Node* args_reg, Node* arg_count, |
| 344 Node* context) { |
| 345 InterpreterAssembler::Variable return_value(assembler_, |
| 346 MachineRepresentation::kTagged); |
| 347 InterpreterAssembler::Label done(assembler_), null(assembler_), |
| 348 function(assembler_), non_function_constructor(assembler_); |
| 349 |
| 350 Node* object = __ LoadRegister(args_reg); |
| 351 |
| 352 // If the object is not a JSReceiver, we return null. |
| 353 __ GotoIf(__ WordIsSmi(object), &null); |
| 354 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 355 Node* is_js_receiver = CompareInstanceType(object, FIRST_JS_RECEIVER_TYPE, |
| 356 kInstanceTypeGreaterThanOrEqual); |
| 357 __ GotoUnless(is_js_receiver, &null); |
| 358 |
| 359 // Return 'Function' for JSFunction and JSBoundFunction objects. |
| 360 Node* is_function = CompareInstanceType(object, FIRST_FUNCTION_TYPE, |
| 361 kInstanceTypeGreaterThanOrEqual); |
| 362 STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE); |
| 363 __ GotoIf(is_function, &function); |
| 364 |
| 365 // Check if the constructor in the map is a JS function. |
| 366 Node* constructor = __ LoadMapConstructor(__ LoadMap(object)); |
| 367 Node* constructor_is_js_function = |
| 368 CompareInstanceType(constructor, JS_FUNCTION_TYPE, kInstanceTypeEqual); |
| 369 __ GotoUnless(constructor_is_js_function, &non_function_constructor); |
| 370 |
| 371 // Grab the instance class name from the constructor function. |
| 372 Node* shared = |
| 373 __ LoadObjectField(constructor, JSFunction::kSharedFunctionInfoOffset); |
| 374 return_value.Bind( |
| 375 __ LoadObjectField(shared, SharedFunctionInfo::kInstanceClassNameOffset)); |
| 376 __ Goto(&done); |
| 377 |
| 378 // Non-JS objects have class null. |
| 379 __ Bind(&null); |
| 380 { |
| 381 return_value.Bind(__ LoadRoot(Heap::kNullValueRootIndex)); |
| 382 __ Goto(&done); |
| 383 } |
| 384 |
| 385 // Functions have class 'Function'. |
| 386 __ Bind(&function); |
| 387 { |
| 388 return_value.Bind(__ LoadRoot(Heap::kFunction_stringRootIndex)); |
| 389 __ Goto(&done); |
| 390 } |
| 391 |
| 392 // Objects with a non-function constructor have class 'Object'. |
| 393 __ Bind(&non_function_constructor); |
| 394 { |
| 395 return_value.Bind(__ LoadRoot(Heap::kObject_stringRootIndex)); |
| 396 __ Goto(&done); |
| 397 } |
| 398 |
| 399 __ Bind(&done); |
| 400 return return_value.value(); |
| 401 } |
| 402 |
343 void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { | 403 void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { |
344 InterpreterAssembler::Label match(assembler_); | 404 InterpreterAssembler::Label match(assembler_); |
345 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); | 405 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); |
346 __ GotoIf(comparison, &match); | 406 __ GotoIf(comparison, &match); |
347 __ Abort(kWrongArgumentCountForInvokeIntrinsic); | 407 __ Abort(kWrongArgumentCountForInvokeIntrinsic); |
348 __ Goto(&match); | 408 __ Goto(&match); |
349 __ Bind(&match); | 409 __ Bind(&match); |
350 } | 410 } |
351 | 411 |
352 } // namespace interpreter | 412 } // namespace interpreter |
353 } // namespace internal | 413 } // namespace internal |
354 } // namespace v8 | 414 } // namespace v8 |
OLD | NEW |