Commit 13670e50 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Add ValueOf intrinsic.

BUG=v8:4822

Review-Url: https://codereview.chromium.org/2097473002
Cr-Commit-Position: refs/heads/master@{#37215}
parent 059f2fa1
...@@ -111,49 +111,34 @@ Node* IntrinsicsHelper::CompareInstanceType(Node* map, int type, ...@@ -111,49 +111,34 @@ Node* IntrinsicsHelper::CompareInstanceType(Node* map, int type,
InterpreterAssembler::Label if_true(assembler_), if_false(assembler_), InterpreterAssembler::Label if_true(assembler_), if_false(assembler_),
end(assembler_); end(assembler_);
Node* condition;
if (mode == kInstanceTypeEqual) { if (mode == kInstanceTypeEqual) {
condition = __ Word32Equal(instance_type, __ Int32Constant(type)); return __ Word32Equal(instance_type, __ Int32Constant(type));
} else { } else {
DCHECK(mode == kInstanceTypeGreaterThanOrEqual); DCHECK(mode == kInstanceTypeGreaterThanOrEqual);
condition = return __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type));
__ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type));
} }
__ Branch(condition, &if_true, &if_false);
__ Bind(&if_true);
{
return_value.Bind(__ BooleanConstant(true));
__ Goto(&end);
}
__ Bind(&if_false);
{
return_value.Bind(__ BooleanConstant(false));
__ Goto(&end);
}
__ Bind(&end);
return return_value.value();
} }
Node* IntrinsicsHelper::IsInstanceType(Node* input, int type) { Node* IntrinsicsHelper::IsInstanceType(Node* input, int type) {
InterpreterAssembler::Variable return_value(assembler_, InterpreterAssembler::Variable return_value(assembler_,
MachineRepresentation::kTagged); MachineRepresentation::kTagged);
InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), InterpreterAssembler::Label if_not_smi(assembler_), return_true(assembler_),
end(assembler_); return_false(assembler_), end(assembler_);
Node* arg = __ LoadRegister(input); Node* arg = __ LoadRegister(input);
__ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); __ GotoIf(__ WordIsSmi(arg), &return_false);
__ Bind(&if_smi); Node* condition = CompareInstanceType(arg, type, kInstanceTypeEqual);
__ Branch(condition, &return_true, &return_false);
__ Bind(&return_true);
{ {
return_value.Bind(__ BooleanConstant(false)); return_value.Bind(__ BooleanConstant(true));
__ Goto(&end); __ Goto(&end);
} }
__ Bind(&if_not_smi); __ Bind(&return_false);
{ {
return_value.Bind(CompareInstanceType(arg, type, kInstanceTypeEqual)); return_value.Bind(__ BooleanConstant(false));
__ Goto(&end); __ Goto(&end);
} }
...@@ -165,23 +150,26 @@ Node* IntrinsicsHelper::IsJSReceiver(Node* input, Node* arg_count, ...@@ -165,23 +150,26 @@ Node* IntrinsicsHelper::IsJSReceiver(Node* input, Node* arg_count,
Node* context) { Node* context) {
InterpreterAssembler::Variable return_value(assembler_, InterpreterAssembler::Variable return_value(assembler_,
MachineRepresentation::kTagged); MachineRepresentation::kTagged);
InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), InterpreterAssembler::Label return_true(assembler_), return_false(assembler_),
end(assembler_); end(assembler_);
Node* arg = __ LoadRegister(input); Node* arg = __ LoadRegister(input);
__ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); __ GotoIf(__ WordIsSmi(arg), &return_false);
__ Bind(&if_smi); STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
Node* condition = CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE,
kInstanceTypeGreaterThanOrEqual);
__ Branch(condition, &return_true, &return_false);
__ Bind(&return_true);
{ {
return_value.Bind(__ BooleanConstant(false)); return_value.Bind(__ BooleanConstant(true));
__ Goto(&end); __ Goto(&end);
} }
__ Bind(&if_not_smi); __ Bind(&return_false);
{ {
STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); return_value.Bind(__ BooleanConstant(false));
return_value.Bind(CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE,
kInstanceTypeGreaterThanOrEqual));
__ Goto(&end); __ Goto(&end);
} }
...@@ -331,6 +319,31 @@ Node* IntrinsicsHelper::Call(Node* args_reg, Node* arg_count, Node* context) { ...@@ -331,6 +319,31 @@ Node* IntrinsicsHelper::Call(Node* args_reg, Node* arg_count, Node* context) {
return result; return result;
} }
Node* IntrinsicsHelper::ValueOf(Node* args_reg, Node* arg_count,
Node* context) {
InterpreterAssembler::Variable return_value(assembler_,
MachineRepresentation::kTagged);
InterpreterAssembler::Label done(assembler_);
Node* object = __ LoadRegister(args_reg);
return_value.Bind(object);
// If the object is a smi return the object.
__ GotoIf(__ WordIsSmi(object), &done);
// If the object is not a value type, return the object.
Node* condition =
CompareInstanceType(object, JS_VALUE_TYPE, kInstanceTypeEqual);
__ GotoUnless(condition, &done);
// If the object is a value type, return the value field.
return_value.Bind(__ LoadObjectField(object, JSValue::kValueOffset));
__ Goto(&done);
__ Bind(&done);
return return_value.value();
}
void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) {
InterpreterAssembler::Label match(assembler_); InterpreterAssembler::Label match(assembler_);
Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected));
......
...@@ -44,7 +44,8 @@ namespace interpreter { ...@@ -44,7 +44,8 @@ namespace interpreter {
V(ToLength, to_length, 1) \ V(ToLength, to_length, 1) \
V(ToInteger, to_integer, 1) \ V(ToInteger, to_integer, 1) \
V(ToNumber, to_number, 1) \ V(ToNumber, to_number, 1) \
V(ToObject, to_object, 1) V(ToObject, to_object, 1) \
V(ValueOf, value_of, 1)
class IntrinsicsHelper { class IntrinsicsHelper {
public: public:
......
...@@ -253,6 +253,27 @@ TEST(IntrinsicAsStubCall) { ...@@ -253,6 +253,27 @@ TEST(IntrinsicAsStubCall) {
->SameValue(*sub_string_helper.NewObject("'bar'"))); ->SameValue(*sub_string_helper.NewObject("'bar'")));
} }
TEST(ValueOf) {
HandleAndZoneScope handles;
Isolate* isolate = handles.main_isolate();
Factory* factory = isolate->factory();
InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
Runtime::kInlineValueOf);
CHECK_EQ(Smi::FromInt(1234), *helper.Invoke(helper.NewObject("1234")));
CHECK_EQ(Smi::FromInt(5678),
*helper.Invoke(helper.NewObject("new Object(5678)")));
CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("true")));
CHECK_EQ(*factory->false_value(),
*helper.Invoke(helper.NewObject("new Object(false)")));
CHECK(helper.Invoke(helper.NewObject("'foobar'"))
->SameValue(*helper.NewObject("'foobar'")));
CHECK(helper.Invoke(helper.NewObject("new Object('foobar')"))
->SameValue(*helper.NewObject("'foobar'")));
}
} // namespace interpreter } // namespace interpreter
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment