| 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 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 // If the object is a value type, return the value field. | 324 // If the object is a value type, return the value field. |
| 325 return_value.Bind(__ LoadObjectField(object, JSValue::kValueOffset)); | 325 return_value.Bind(__ LoadObjectField(object, JSValue::kValueOffset)); |
| 326 __ Goto(&done); | 326 __ Goto(&done); |
| 327 | 327 |
| 328 __ Bind(&done); | 328 __ Bind(&done); |
| 329 return return_value.value(); | 329 return return_value.value(); |
| 330 } | 330 } |
| 331 | 331 |
| 332 Node* IntrinsicsHelper::ClassOf(Node* args_reg, Node* arg_count, | 332 Node* IntrinsicsHelper::ClassOf(Node* args_reg, Node* arg_count, |
| 333 Node* context) { | 333 Node* context) { |
| 334 InterpreterAssembler::Variable return_value(assembler_, | 334 Node* value = __ LoadRegister(args_reg); |
| 335 MachineRepresentation::kTagged); | 335 return __ ClassOf(value); |
| 336 InterpreterAssembler::Label done(assembler_), null(assembler_), | |
| 337 function(assembler_), non_function_constructor(assembler_); | |
| 338 | |
| 339 Node* object = __ LoadRegister(args_reg); | |
| 340 | |
| 341 // If the object is not a JSReceiver, we return null. | |
| 342 __ GotoIf(__ TaggedIsSmi(object), &null); | |
| 343 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | |
| 344 Node* is_js_receiver = CompareInstanceType(object, FIRST_JS_RECEIVER_TYPE, | |
| 345 kInstanceTypeGreaterThanOrEqual); | |
| 346 __ GotoUnless(is_js_receiver, &null); | |
| 347 | |
| 348 // Return 'Function' for JSFunction and JSBoundFunction objects. | |
| 349 Node* is_function = CompareInstanceType(object, FIRST_FUNCTION_TYPE, | |
| 350 kInstanceTypeGreaterThanOrEqual); | |
| 351 STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE); | |
| 352 __ GotoIf(is_function, &function); | |
| 353 | |
| 354 // Check if the constructor in the map is a JS function. | |
| 355 Node* constructor = __ LoadMapConstructor(__ LoadMap(object)); | |
| 356 Node* constructor_is_js_function = | |
| 357 CompareInstanceType(constructor, JS_FUNCTION_TYPE, kInstanceTypeEqual); | |
| 358 __ GotoUnless(constructor_is_js_function, &non_function_constructor); | |
| 359 | |
| 360 // Grab the instance class name from the constructor function. | |
| 361 Node* shared = | |
| 362 __ LoadObjectField(constructor, JSFunction::kSharedFunctionInfoOffset); | |
| 363 return_value.Bind( | |
| 364 __ LoadObjectField(shared, SharedFunctionInfo::kInstanceClassNameOffset)); | |
| 365 __ Goto(&done); | |
| 366 | |
| 367 // Non-JS objects have class null. | |
| 368 __ Bind(&null); | |
| 369 { | |
| 370 return_value.Bind(__ LoadRoot(Heap::kNullValueRootIndex)); | |
| 371 __ Goto(&done); | |
| 372 } | |
| 373 | |
| 374 // Functions have class 'Function'. | |
| 375 __ Bind(&function); | |
| 376 { | |
| 377 return_value.Bind(__ LoadRoot(Heap::kFunction_stringRootIndex)); | |
| 378 __ Goto(&done); | |
| 379 } | |
| 380 | |
| 381 // Objects with a non-function constructor have class 'Object'. | |
| 382 __ Bind(&non_function_constructor); | |
| 383 { | |
| 384 return_value.Bind(__ LoadRoot(Heap::kObject_stringRootIndex)); | |
| 385 __ Goto(&done); | |
| 386 } | |
| 387 | |
| 388 __ Bind(&done); | |
| 389 return return_value.value(); | |
| 390 } | 336 } |
| 391 | 337 |
| 392 void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { | 338 void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { |
| 393 InterpreterAssembler::Label match(assembler_); | 339 InterpreterAssembler::Label match(assembler_); |
| 394 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); | 340 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); |
| 395 __ GotoIf(comparison, &match); | 341 __ GotoIf(comparison, &match); |
| 396 __ Abort(kWrongArgumentCountForInvokeIntrinsic); | 342 __ Abort(kWrongArgumentCountForInvokeIntrinsic); |
| 397 __ Goto(&match); | 343 __ Goto(&match); |
| 398 __ Bind(&match); | 344 __ Bind(&match); |
| 399 } | 345 } |
| 400 | 346 |
| 401 } // namespace interpreter | 347 } // namespace interpreter |
| 402 } // namespace internal | 348 } // namespace internal |
| 403 } // namespace v8 | 349 } // namespace v8 |
| OLD | NEW |