Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(397)

Side by Side Diff: src/builtins/builtins.cc

Issue 2152693002: [stubs] Introduce NonPrimitiveToPrimitive builtin. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comments. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-factory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/builtins/builtins.h" 5 #include "src/builtins/builtins.h"
6 6
7 #include "src/api-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/base/ieee754.h" 10 #include "src/base/ieee754.h"
(...skipping 5783 matching lines...) Expand 10 before | Expand all | Expand 10 after
5794 switch (tail_call_mode) { 5794 switch (tail_call_mode) {
5795 case TailCallMode::kDisallow: 5795 case TailCallMode::kDisallow:
5796 return CallBoundFunction(); 5796 return CallBoundFunction();
5797 case TailCallMode::kAllow: 5797 case TailCallMode::kAllow:
5798 return TailCallBoundFunction(); 5798 return TailCallBoundFunction();
5799 } 5799 }
5800 UNREACHABLE(); 5800 UNREACHABLE();
5801 return Handle<Code>::null(); 5801 return Handle<Code>::null();
5802 } 5802 }
5803 5803
5804 Handle<Code> Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) {
5805 switch (hint) {
5806 case ToPrimitiveHint::kDefault:
5807 return NonPrimitiveToPrimitive_Default();
5808 case ToPrimitiveHint::kNumber:
5809 return NonPrimitiveToPrimitive_Number();
5810 case ToPrimitiveHint::kString:
5811 return NonPrimitiveToPrimitive_String();
5812 }
5813 UNREACHABLE();
5814 return Handle<Code>::null();
5815 }
5816
5817 Handle<Code> Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) {
5818 switch (hint) {
5819 case OrdinaryToPrimitiveHint::kNumber:
5820 return OrdinaryToPrimitive_Number();
5821 case OrdinaryToPrimitiveHint::kString:
5822 return OrdinaryToPrimitive_String();
5823 }
5824 UNREACHABLE();
5825 return Handle<Code>::null();
5826 }
5827
5804 Handle<Code> Builtins::InterpreterPushArgsAndCall(TailCallMode tail_call_mode, 5828 Handle<Code> Builtins::InterpreterPushArgsAndCall(TailCallMode tail_call_mode,
5805 CallableType function_type) { 5829 CallableType function_type) {
5806 switch (tail_call_mode) { 5830 switch (tail_call_mode) {
5807 case TailCallMode::kDisallow: 5831 case TailCallMode::kDisallow:
5808 if (function_type == CallableType::kJSFunction) { 5832 if (function_type == CallableType::kJSFunction) {
5809 return InterpreterPushArgsAndCallFunction(); 5833 return InterpreterPushArgsAndCallFunction();
5810 } else { 5834 } else {
5811 return InterpreterPushArgsAndCall(); 5835 return InterpreterPushArgsAndCall();
5812 } 5836 }
5813 case TailCallMode::kAllow: 5837 case TailCallMode::kAllow:
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
6080 } 6104 }
6081 6105
6082 void Generate_StoreIC_SlowSloppy(CodeStubAssembler* assembler) { 6106 void Generate_StoreIC_SlowSloppy(CodeStubAssembler* assembler) {
6083 Generate_StoreIC_Slow(assembler, SLOPPY); 6107 Generate_StoreIC_Slow(assembler, SLOPPY);
6084 } 6108 }
6085 6109
6086 void Generate_StoreIC_SlowStrict(CodeStubAssembler* assembler) { 6110 void Generate_StoreIC_SlowStrict(CodeStubAssembler* assembler) {
6087 Generate_StoreIC_Slow(assembler, STRICT); 6111 Generate_StoreIC_Slow(assembler, STRICT);
6088 } 6112 }
6089 6113
6114 // 7.1.1.1 OrdinaryToPrimitive ( O, hint )
6115 void Generate_OrdinaryToPrimitive(CodeStubAssembler* assembler,
6116 OrdinaryToPrimitiveHint hint) {
6117 typedef CodeStubAssembler::Label Label;
6118 typedef compiler::Node Node;
6119 typedef CodeStubAssembler::Variable Variable;
6120
6121 Node* input = assembler->Parameter(0);
6122 Node* context = assembler->Parameter(1);
6123
6124 Variable var_result(assembler, MachineRepresentation::kTagged);
6125 Label return_result(assembler, &var_result);
6126
6127 Handle<String> method_names[2];
6128 switch (hint) {
6129 case OrdinaryToPrimitiveHint::kNumber:
6130 method_names[0] = assembler->factory()->valueOf_string();
6131 method_names[1] = assembler->factory()->toString_string();
6132 break;
6133 case OrdinaryToPrimitiveHint::kString:
6134 method_names[0] = assembler->factory()->toString_string();
6135 method_names[1] = assembler->factory()->valueOf_string();
6136 break;
6137 }
6138 for (Handle<String> name : method_names) {
6139 // Lookup the {name} on the {input}.
6140 Callable callable = CodeFactory::GetProperty(assembler->isolate());
6141 Node* name_string = assembler->HeapConstant(name);
6142 Node* method = assembler->CallStub(callable, context, input, name_string);
6143
6144 // Check if the {method} is callable.
6145 Label if_methodiscallable(assembler),
6146 if_methodisnotcallable(assembler, Label::kDeferred);
6147 assembler->GotoIf(assembler->WordIsSmi(method), &if_methodisnotcallable);
6148 Node* method_map = assembler->LoadMap(method);
6149 Node* method_bit_field = assembler->LoadMapBitField(method_map);
6150 assembler->Branch(
6151 assembler->Word32Equal(
6152 assembler->Word32And(method_bit_field, assembler->Int32Constant(
6153 1 << Map::kIsCallable)),
6154 assembler->Int32Constant(0)),
6155 &if_methodisnotcallable, &if_methodiscallable);
6156
6157 assembler->Bind(&if_methodiscallable);
6158 {
6159 // Call the {method} on the {input}.
6160 Callable callable = CodeFactory::Call(assembler->isolate());
6161 Node* result = assembler->CallJS(callable, context, method, input);
6162 var_result.Bind(result);
6163
6164 // Return the {result} if it is a primitive.
6165 assembler->GotoIf(assembler->WordIsSmi(result), &return_result);
6166 Node* result_instance_type = assembler->LoadInstanceType(result);
6167 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE);
6168 assembler->GotoIf(assembler->Int32LessThanOrEqual(
6169 result_instance_type,
6170 assembler->Int32Constant(LAST_PRIMITIVE_TYPE)),
6171 &return_result);
6172 }
6173
6174 // Just continue with the next {name} if the {method} is not callable.
6175 assembler->Goto(&if_methodisnotcallable);
6176 assembler->Bind(&if_methodisnotcallable);
6177 }
6178
6179 assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, context);
6180
6181 assembler->Bind(&return_result);
6182 assembler->Return(var_result.value());
6183 }
6184
6185 void Generate_OrdinaryToPrimitive_Number(CodeStubAssembler* assembler) {
6186 Generate_OrdinaryToPrimitive(assembler, OrdinaryToPrimitiveHint::kNumber);
6187 }
6188
6189 void Generate_OrdinaryToPrimitive_String(CodeStubAssembler* assembler) {
6190 Generate_OrdinaryToPrimitive(assembler, OrdinaryToPrimitiveHint::kString);
6191 }
6192
6193 // ES6 section 7.1.1 ToPrimitive ( input [ , PreferredType ] )
6194 void Generate_NonPrimitiveToPrimitive(CodeStubAssembler* assembler,
6195 ToPrimitiveHint hint) {
6196 typedef CodeStubAssembler::Label Label;
6197 typedef compiler::Node Node;
6198
6199 Node* input = assembler->Parameter(0);
6200 Node* context = assembler->Parameter(1);
6201
6202 // Lookup the @@toPrimitive property on the {input}.
6203 Callable callable = CodeFactory::GetProperty(assembler->isolate());
6204 Node* to_primitive_symbol =
6205 assembler->HeapConstant(assembler->factory()->to_primitive_symbol());
6206 Node* exotic_to_prim =
6207 assembler->CallStub(callable, context, input, to_primitive_symbol);
6208
6209 // Check if {exotic_to_prim} is neither null nor undefined.
6210 Label ordinary_to_primitive(assembler);
6211 assembler->GotoIf(
6212 assembler->WordEqual(exotic_to_prim, assembler->NullConstant()),
6213 &ordinary_to_primitive);
6214 assembler->GotoIf(
6215 assembler->WordEqual(exotic_to_prim, assembler->UndefinedConstant()),
6216 &ordinary_to_primitive);
6217 {
6218 // Invoke the {exotic_to_prim} method on the {input} with a string
6219 // representation of the {hint}.
6220 Callable callable = CodeFactory::Call(assembler->isolate());
6221 Node* hint_string = assembler->HeapConstant(
6222 assembler->factory()->ToPrimitiveHintString(hint));
6223 Node* result = assembler->CallJS(callable, context, exotic_to_prim, input,
6224 hint_string);
6225
6226 // Verify that the {result} is actually a primitive.
6227 Label if_resultisprimitive(assembler),
6228 if_resultisnotprimitive(assembler, Label::kDeferred);
6229 assembler->GotoIf(assembler->WordIsSmi(result), &if_resultisprimitive);
6230 Node* result_instance_type = assembler->LoadInstanceType(result);
6231 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE);
6232 assembler->Branch(assembler->Int32LessThanOrEqual(
6233 result_instance_type,
6234 assembler->Int32Constant(LAST_PRIMITIVE_TYPE)),
6235 &if_resultisprimitive, &if_resultisnotprimitive);
6236
6237 assembler->Bind(&if_resultisprimitive);
6238 {
6239 // Just return the {result}.
6240 assembler->Return(result);
6241 }
6242
6243 assembler->Bind(&if_resultisnotprimitive);
6244 {
6245 // Somehow the @@toPrimitive method on {input} didn't yield a primitive.
6246 assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive,
6247 context);
6248 }
6249 }
6250
6251 // Convert using the OrdinaryToPrimitive algorithm instead.
6252 assembler->Bind(&ordinary_to_primitive);
6253 {
6254 Callable callable = CodeFactory::OrdinaryToPrimitive(
6255 assembler->isolate(), (hint == ToPrimitiveHint::kString)
6256 ? OrdinaryToPrimitiveHint::kString
6257 : OrdinaryToPrimitiveHint::kNumber);
6258 assembler->TailCallStub(callable, context, input);
6259 }
6260 }
6261
6262 void Generate_NonPrimitiveToPrimitive_Default(CodeStubAssembler* assembler) {
6263 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kDefault);
6264 }
6265
6266 void Generate_NonPrimitiveToPrimitive_Number(CodeStubAssembler* assembler) {
6267 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kNumber);
6268 }
6269
6270 void Generate_NonPrimitiveToPrimitive_String(CodeStubAssembler* assembler) {
6271 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kString);
6272 }
6273
6090 void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) { 6274 void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) {
6091 ElementHandlerCompiler::GenerateStoreSlow(masm); 6275 ElementHandlerCompiler::GenerateStoreSlow(masm);
6092 } 6276 }
6093 6277
6094 void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { 6278 void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
6095 NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm); 6279 NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm);
6096 } 6280 }
6097 6281
6098 void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) { 6282 void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) {
6099 KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY); 6283 KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY);
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
6662 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 6846 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
6663 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 6847 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
6664 #undef DEFINE_BUILTIN_ACCESSOR_C 6848 #undef DEFINE_BUILTIN_ACCESSOR_C
6665 #undef DEFINE_BUILTIN_ACCESSOR_A 6849 #undef DEFINE_BUILTIN_ACCESSOR_A
6666 #undef DEFINE_BUILTIN_ACCESSOR_T 6850 #undef DEFINE_BUILTIN_ACCESSOR_T
6667 #undef DEFINE_BUILTIN_ACCESSOR_S 6851 #undef DEFINE_BUILTIN_ACCESSOR_S
6668 #undef DEFINE_BUILTIN_ACCESSOR_H 6852 #undef DEFINE_BUILTIN_ACCESSOR_H
6669 6853
6670 } // namespace internal 6854 } // namespace internal
6671 } // namespace v8 6855 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698