Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 void Builtins::Generate_StringToNumber(CodeStubAssembler* assembler) { | 112 void Builtins::Generate_StringToNumber(CodeStubAssembler* assembler) { |
| 113 typedef compiler::Node Node; | 113 typedef compiler::Node Node; |
| 114 typedef TypeConversionDescriptor Descriptor; | 114 typedef TypeConversionDescriptor Descriptor; |
| 115 | 115 |
| 116 Node* input = assembler->Parameter(Descriptor::kArgument); | 116 Node* input = assembler->Parameter(Descriptor::kArgument); |
| 117 Node* context = assembler->Parameter(Descriptor::kContext); | 117 Node* context = assembler->Parameter(Descriptor::kContext); |
| 118 | 118 |
| 119 assembler->Return(assembler->StringToNumber(context, input)); | 119 assembler->Return(assembler->StringToNumber(context, input)); |
| 120 } | 120 } |
| 121 | 121 |
| 122 // ES6 section 7.1.3 ToNumber ( argument ) | 122 // ES6 section 7.1.3 ToNumber ( argument ) |
|
Igor Sheludko
2016/09/09 11:33:15
// static
or remove it.
| |
| 123 void Builtins::Generate_NonNumberToNumber(CodeStubAssembler* assembler) { | 123 void Builtins::Generate_NonNumberToNumber(CodeStubAssembler* assembler) { |
| 124 typedef CodeStubAssembler::Label Label; | |
| 125 typedef compiler::Node Node; | 124 typedef compiler::Node Node; |
| 126 typedef CodeStubAssembler::Variable Variable; | |
| 127 typedef TypeConversionDescriptor Descriptor; | 125 typedef TypeConversionDescriptor Descriptor; |
| 128 | 126 |
| 129 Node* input = assembler->Parameter(Descriptor::kArgument); | 127 Node* input = assembler->Parameter(Descriptor::kArgument); |
| 130 Node* context = assembler->Parameter(Descriptor::kContext); | 128 Node* context = assembler->Parameter(Descriptor::kContext); |
| 131 | 129 |
| 132 // We might need to loop once here due to ToPrimitive conversions. | 130 assembler->Return(assembler->NonNumberToNumber(context, input)); |
| 133 Variable var_input(assembler, MachineRepresentation::kTagged); | 131 } |
| 134 Label loop(assembler, &var_input); | |
| 135 var_input.Bind(input); | |
| 136 assembler->Goto(&loop); | |
| 137 assembler->Bind(&loop); | |
| 138 { | |
| 139 // Load the current {input} value (known to be a HeapObject). | |
| 140 Node* input = var_input.value(); | |
| 141 | 132 |
| 142 // Dispatch on the {input} instance type. | 133 // static |
|
Igor Sheludko
2016/09/09 11:33:15
// ES6 section 7.1.3 ToNumber ( argument )
| |
| 143 Node* input_instance_type = assembler->LoadInstanceType(input); | 134 void Builtins::Generate_ToNumber(CodeStubAssembler* assembler) { |
| 144 Label if_inputisstring(assembler), if_inputisoddball(assembler), | 135 typedef compiler::Node Node; |
| 145 if_inputisreceiver(assembler, Label::kDeferred), | 136 typedef TypeConversionDescriptor Descriptor; |
| 146 if_inputisother(assembler, Label::kDeferred); | |
| 147 assembler->GotoIf(assembler->Int32LessThan( | |
| 148 input_instance_type, | |
| 149 assembler->Int32Constant(FIRST_NONSTRING_TYPE)), | |
| 150 &if_inputisstring); | |
| 151 assembler->GotoIf( | |
| 152 assembler->Word32Equal(input_instance_type, | |
| 153 assembler->Int32Constant(ODDBALL_TYPE)), | |
| 154 &if_inputisoddball); | |
| 155 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | |
| 156 assembler->Branch(assembler->Int32GreaterThanOrEqual( | |
| 157 input_instance_type, | |
| 158 assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE)), | |
| 159 &if_inputisreceiver, &if_inputisother); | |
| 160 | 137 |
| 161 assembler->Bind(&if_inputisstring); | 138 Node* input = assembler->Parameter(Descriptor::kArgument); |
| 162 { | 139 Node* context = assembler->Parameter(Descriptor::kContext); |
| 163 // The {input} is a String, use the fast stub to convert it to a Number. | |
| 164 assembler->Return(assembler->StringToNumber(context, input)); | |
| 165 } | |
| 166 | 140 |
| 167 assembler->Bind(&if_inputisoddball); | 141 assembler->Return(assembler->ToNumber(context, input)); |
| 168 { | |
| 169 // The {input} is an Oddball, we just need to the Number value of it. | |
| 170 Node* result = | |
| 171 assembler->LoadObjectField(input, Oddball::kToNumberOffset); | |
| 172 assembler->Return(result); | |
| 173 } | |
| 174 | |
| 175 assembler->Bind(&if_inputisreceiver); | |
| 176 { | |
| 177 // The {input} is a JSReceiver, we need to convert it to a Primitive first | |
| 178 // using the ToPrimitive type conversion, preferably yielding a Number. | |
| 179 Callable callable = CodeFactory::NonPrimitiveToPrimitive( | |
| 180 assembler->isolate(), ToPrimitiveHint::kNumber); | |
| 181 Node* result = assembler->CallStub(callable, context, input); | |
| 182 | |
| 183 // Check if the {result} is already a Number. | |
| 184 Label if_resultisnumber(assembler), if_resultisnotnumber(assembler); | |
| 185 assembler->GotoIf(assembler->WordIsSmi(result), &if_resultisnumber); | |
| 186 Node* result_map = assembler->LoadMap(result); | |
| 187 assembler->Branch( | |
| 188 assembler->WordEqual(result_map, assembler->HeapNumberMapConstant()), | |
| 189 &if_resultisnumber, &if_resultisnotnumber); | |
| 190 | |
| 191 assembler->Bind(&if_resultisnumber); | |
| 192 { | |
| 193 // The ToPrimitive conversion already gave us a Number, so we're done. | |
| 194 assembler->Return(result); | |
| 195 } | |
| 196 | |
| 197 assembler->Bind(&if_resultisnotnumber); | |
| 198 { | |
| 199 // We now have a Primitive {result}, but it's not yet a Number. | |
| 200 var_input.Bind(result); | |
| 201 assembler->Goto(&loop); | |
| 202 } | |
| 203 } | |
| 204 | |
| 205 assembler->Bind(&if_inputisother); | |
| 206 { | |
| 207 // The {input} is something else (i.e. Symbol or Simd128Value), let the | |
| 208 // runtime figure out the correct exception. | |
| 209 // Note: We cannot tail call to the runtime here, as js-to-wasm | |
| 210 // trampolines also use this code currently, and they declare all | |
| 211 // outgoing parameters as untagged, while we would push a tagged | |
| 212 // object here. | |
| 213 Node* result = assembler->CallRuntime(Runtime::kToNumber, context, input); | |
| 214 assembler->Return(result); | |
| 215 } | |
| 216 } | |
| 217 } | 142 } |
| 218 | 143 |
| 219 Handle<Code> Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) { | 144 Handle<Code> Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) { |
| 220 switch (hint) { | 145 switch (hint) { |
| 221 case OrdinaryToPrimitiveHint::kNumber: | 146 case OrdinaryToPrimitiveHint::kNumber: |
| 222 return OrdinaryToPrimitive_Number(); | 147 return OrdinaryToPrimitive_Number(); |
| 223 case OrdinaryToPrimitiveHint::kString: | 148 case OrdinaryToPrimitiveHint::kString: |
| 224 return OrdinaryToPrimitive_String(); | 149 return OrdinaryToPrimitive_String(); |
| 225 } | 150 } |
| 226 UNREACHABLE(); | 151 UNREACHABLE(); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 | 249 |
| 325 assembler->Bind(&return_true); | 250 assembler->Bind(&return_true); |
| 326 assembler->Return(assembler->BooleanConstant(true)); | 251 assembler->Return(assembler->BooleanConstant(true)); |
| 327 | 252 |
| 328 assembler->Bind(&return_false); | 253 assembler->Bind(&return_false); |
| 329 assembler->Return(assembler->BooleanConstant(false)); | 254 assembler->Return(assembler->BooleanConstant(false)); |
| 330 } | 255 } |
| 331 | 256 |
| 332 } // namespace internal | 257 } // namespace internal |
| 333 } // namespace v8 | 258 } // namespace v8 |
| OLD | NEW |