Index: src/code-stub-assembler.cc |
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
index c0380bb8c1df22cff8ce5801e9300d4e4aa5b380..616f628c44966e6f851c89914eb8b912cbc85cef 100644 |
--- a/src/code-stub-assembler.cc |
+++ b/src/code-stub-assembler.cc |
@@ -1239,6 +1239,81 @@ Node* CodeStubAssembler::ToThisString(Node* context, Node* value, |
return var_value.value(); |
} |
+Node* CodeStubAssembler::ToThisValue(Node* context, Node* value, |
+ PrimitiveType primitive_type, |
+ char const* method_name) { |
+ // We might need to loop once due to JSValue unboxing. |
+ Variable var_value(this, MachineRepresentation::kTagged); |
+ Label loop(this, &var_value), done_loop(this), |
+ done_throw(this, Label::kDeferred); |
+ var_value.Bind(value); |
+ Goto(&loop); |
+ Bind(&loop); |
+ { |
+ // Load the current {value}. |
+ value = var_value.value(); |
+ |
+ // Check if the {value} is a Smi or a HeapObject. |
+ GotoIf(WordIsSmi(value), (primitive_type == PrimitiveType::kNumber) |
+ ? &done_loop |
+ : &done_throw); |
+ |
+ // Load the mape of the {value}. |
+ Node* value_map = LoadMap(value); |
+ |
+ // Load the instance type of the {value}. |
+ Node* value_instance_type = LoadMapInstanceType(value_map); |
+ |
+ // Check if {value} is a JSValue. |
+ Label if_valueisvalue(this, Label::kDeferred), if_valueisnotvalue(this); |
+ Branch(Word32Equal(value_instance_type, Int32Constant(JS_VALUE_TYPE)), |
+ &if_valueisvalue, &if_valueisnotvalue); |
+ |
+ Bind(&if_valueisvalue); |
+ { |
+ // Load the actual value from the {value}. |
+ var_value.Bind(LoadObjectField(value, JSValue::kValueOffset)); |
+ Goto(&loop); |
+ } |
+ |
+ Bind(&if_valueisnotvalue); |
+ { |
+ switch (primitive_type) { |
+ case PrimitiveType::kBoolean: |
+ GotoIf(WordEqual(value_map, BooleanMapConstant()), &done_loop); |
+ break; |
+ case PrimitiveType::kNumber: |
+ GotoIf( |
+ Word32Equal(value_instance_type, Int32Constant(HEAP_NUMBER_TYPE)), |
+ &done_loop); |
+ break; |
+ case PrimitiveType::kString: |
+ GotoIf(Int32LessThan(value_instance_type, |
+ Int32Constant(FIRST_NONSTRING_TYPE)), |
+ &done_loop); |
+ break; |
+ case PrimitiveType::kSymbol: |
+ GotoIf(Word32Equal(value_instance_type, Int32Constant(SYMBOL_TYPE)), |
+ &done_loop); |
+ break; |
+ } |
+ Goto(&done_throw); |
+ } |
+ } |
+ |
+ Bind(&done_throw); |
+ { |
+ // The {value} is not a compatible receiver for this method. |
+ CallRuntime(Runtime::kThrowNotGeneric, context, |
+ HeapConstant(factory()->NewStringFromAsciiChecked(method_name, |
+ TENURED))); |
+ Goto(&done_loop); // Never reached. |
+ } |
+ |
+ Bind(&done_loop); |
+ return var_value.value(); |
+} |
+ |
Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index) { |
// Translate the {index} into a Word. |
index = SmiToWord(index); |