Index: src/code-stubs-hydrogen.cc |
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc |
index d841ea05cb76abe0e1d9040fcd76847271d64895..70f6e6150c6b94bc94c2b43b854bad4c7a1096a4 100644 |
--- a/src/code-stubs-hydrogen.cc |
+++ b/src/code-stubs-hydrogen.cc |
@@ -299,6 +299,117 @@ Handle<Code> NumberToStringStub::GenerateCode() { |
} |
+// Returns the type string of a value; see ECMA-262, 11.4.3 (p 47). |
+// Possible optimizations: put the type string into the oddballs. |
+template <> |
+HValue* CodeStubGraphBuilder<TypeofStub>::BuildCodeStub() { |
+ Factory* factory = isolate()->factory(); |
+ HConstant* number_string = Add<HConstant>(factory->number_string()); |
+ HValue* object = GetParameter(TypeofStub::kObject); |
+ |
+ IfBuilder is_smi(this); |
+ HValue* smi_check = is_smi.If<HIsSmiAndBranch>(object); |
+ is_smi.Then(); |
+ { Push(number_string); } |
+ is_smi.Else(); |
+ { |
+ IfBuilder is_number(this); |
+ is_number.If<HCompareMap>(object, isolate()->factory()->heap_number_map()); |
+ is_number.Then(); |
+ { Push(number_string); } |
+ is_number.Else(); |
+ { |
+ HConstant* undefined_string = Add<HConstant>(factory->undefined_string()); |
+ HValue* map = AddLoadMap(object, smi_check); |
+ HValue* instance_type = Add<HLoadNamedField>( |
+ map, nullptr, HObjectAccess::ForMapInstanceType()); |
+ IfBuilder is_string(this); |
+ is_string.If<HCompareNumericAndBranch>( |
+ instance_type, Add<HConstant>(FIRST_NONSTRING_TYPE), Token::LT); |
+ is_string.Then(); |
+ { Push(Add<HConstant>(factory->string_string())); } |
+ is_string.Else(); |
+ { |
+ HConstant* object_string = Add<HConstant>(factory->object_string()); |
+ IfBuilder is_oddball(this); |
+ is_oddball.If<HCompareNumericAndBranch>( |
+ instance_type, Add<HConstant>(ODDBALL_TYPE), Token::EQ); |
+ is_oddball.Then(); |
+ { |
+ IfBuilder is_true_or_false(this); |
+ is_true_or_false.If<HCompareObjectEqAndBranch>( |
+ object, graph()->GetConstantTrue()); |
+ is_true_or_false.OrIf<HCompareObjectEqAndBranch>( |
+ object, graph()->GetConstantFalse()); |
+ is_true_or_false.Then(); |
+ { Push(Add<HConstant>(factory->boolean_string())); } |
+ is_true_or_false.Else(); |
+ { |
+ IfBuilder is_null(this); |
+ is_null.If<HCompareObjectEqAndBranch>(object, |
+ graph()->GetConstantNull()); |
+ is_null.Then(); |
+ { Push(object_string); } |
+ is_null.Else(); |
+ { Push(undefined_string); } |
+ } |
+ is_true_or_false.End(); |
+ } |
+ is_oddball.Else(); |
+ { |
+ IfBuilder is_symbol(this); |
+ is_symbol.If<HCompareNumericAndBranch>( |
+ instance_type, Add<HConstant>(SYMBOL_TYPE), Token::EQ); |
+ is_symbol.Then(); |
+ { Push(Add<HConstant>(factory->symbol_string())); } |
+ is_symbol.Else(); |
+ { |
+ IfBuilder is_function(this); |
+ HConstant* js_function = Add<HConstant>(JS_FUNCTION_TYPE); |
+ HConstant* js_function_proxy = |
+ Add<HConstant>(JS_FUNCTION_PROXY_TYPE); |
+ is_function.If<HCompareNumericAndBranch>(instance_type, js_function, |
+ Token::EQ); |
+ is_function.OrIf<HCompareNumericAndBranch>( |
+ instance_type, js_function_proxy, Token::EQ); |
+ is_function.Then(); |
+ { Push(Add<HConstant>(factory->function_string())); } |
+ is_function.Else(); |
+ { |
+ // Is it an undetectable object? |
+ IfBuilder is_undetectable(this); |
+ is_undetectable.If<HIsUndetectableAndBranch>(object); |
+ is_undetectable.Then(); |
+ { |
+ // typeof an undetectable object is 'undefined'. |
+ Push(undefined_string); |
+ } |
+ is_undetectable.Else(); |
+ { |
+ // For any kind of object not handled above, the spec rule for |
+ // host objects gives that it is okay to return "object". |
+ Push(object_string); |
+ } |
+ } |
+ is_function.End(); |
+ } |
+ is_symbol.End(); |
+ } |
+ is_oddball.End(); |
+ } |
+ is_string.End(); |
+ } |
+ is_number.End(); |
+ } |
+ is_smi.End(); |
+ |
+ return environment()->Pop(); |
+} |
+ |
+ |
+Handle<Code> TypeofStub::GenerateCode() { return DoGenerateCode(this); } |
+ |
+ |
template <> |
HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { |
Factory* factory = isolate()->factory(); |