| Index: src/interpreter/interpreter-intrinsics.cc
|
| diff --git a/src/interpreter/interpreter-intrinsics.cc b/src/interpreter/interpreter-intrinsics.cc
|
| index fc7cfc766d5dcb306bac06b0ef056a56f3f9d181..ae8e83a8267ba8d5cdb532ba5ecafd3c30b5607a 100644
|
| --- a/src/interpreter/interpreter-intrinsics.cc
|
| +++ b/src/interpreter/interpreter-intrinsics.cc
|
| @@ -103,11 +103,11 @@ Node* IntrinsicsHelper::InvokeIntrinsic(Node* function_id, Node* context,
|
| return result.value();
|
| }
|
|
|
| -Node* IntrinsicsHelper::CompareInstanceType(Node* map, int type,
|
| +Node* IntrinsicsHelper::CompareInstanceType(Node* object, int type,
|
| InstanceTypeCompareMode mode) {
|
| InterpreterAssembler::Variable return_value(assembler_,
|
| MachineRepresentation::kTagged);
|
| - Node* instance_type = __ LoadInstanceType(map);
|
| + Node* instance_type = __ LoadInstanceType(object);
|
|
|
| InterpreterAssembler::Label if_true(assembler_), if_false(assembler_),
|
| end(assembler_);
|
| @@ -340,6 +340,66 @@ Node* IntrinsicsHelper::ValueOf(Node* args_reg, Node* arg_count,
|
| return return_value.value();
|
| }
|
|
|
| +Node* IntrinsicsHelper::ClassOf(Node* args_reg, Node* arg_count,
|
| + Node* context) {
|
| + InterpreterAssembler::Variable return_value(assembler_,
|
| + MachineRepresentation::kTagged);
|
| + InterpreterAssembler::Label done(assembler_), null(assembler_),
|
| + function(assembler_), non_function_constructor(assembler_);
|
| +
|
| + Node* object = __ LoadRegister(args_reg);
|
| +
|
| + // If the object is not a JSReceiver, we return null.
|
| + __ GotoIf(__ WordIsSmi(object), &null);
|
| + STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
| + Node* is_js_receiver = CompareInstanceType(object, FIRST_JS_RECEIVER_TYPE,
|
| + kInstanceTypeGreaterThanOrEqual);
|
| + __ GotoUnless(is_js_receiver, &null);
|
| +
|
| + // Return 'Function' for JSFunction and JSBoundFunction objects.
|
| + Node* is_function = CompareInstanceType(object, FIRST_FUNCTION_TYPE,
|
| + kInstanceTypeGreaterThanOrEqual);
|
| + STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
|
| + __ GotoIf(is_function, &function);
|
| +
|
| + // Check if the constructor in the map is a JS function.
|
| + Node* constructor = __ LoadMapConstructor(__ LoadMap(object));
|
| + Node* constructor_is_js_function =
|
| + CompareInstanceType(constructor, JS_FUNCTION_TYPE, kInstanceTypeEqual);
|
| + __ GotoUnless(constructor_is_js_function, &non_function_constructor);
|
| +
|
| + // Grab the instance class name from the constructor function.
|
| + Node* shared =
|
| + __ LoadObjectField(constructor, JSFunction::kSharedFunctionInfoOffset);
|
| + return_value.Bind(
|
| + __ LoadObjectField(shared, SharedFunctionInfo::kInstanceClassNameOffset));
|
| + __ Goto(&done);
|
| +
|
| + // Non-JS objects have class null.
|
| + __ Bind(&null);
|
| + {
|
| + return_value.Bind(__ LoadRoot(Heap::kNullValueRootIndex));
|
| + __ Goto(&done);
|
| + }
|
| +
|
| + // Functions have class 'Function'.
|
| + __ Bind(&function);
|
| + {
|
| + return_value.Bind(__ LoadRoot(Heap::kFunction_stringRootIndex));
|
| + __ Goto(&done);
|
| + }
|
| +
|
| + // Objects with a non-function constructor have class 'Object'.
|
| + __ Bind(&non_function_constructor);
|
| + {
|
| + return_value.Bind(__ LoadRoot(Heap::kObject_stringRootIndex));
|
| + __ Goto(&done);
|
| + }
|
| +
|
| + __ Bind(&done);
|
| + return return_value.value();
|
| +}
|
| +
|
| void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) {
|
| InterpreterAssembler::Label match(assembler_);
|
| Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected));
|
|
|