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/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
10 | 10 |
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 { | 1232 { |
1233 // The {value} is a Smi, convert it to a String. | 1233 // The {value} is a Smi, convert it to a String. |
1234 Callable callable = CodeFactory::NumberToString(isolate()); | 1234 Callable callable = CodeFactory::NumberToString(isolate()); |
1235 var_value.Bind(CallStub(callable, context, value)); | 1235 var_value.Bind(CallStub(callable, context, value)); |
1236 Goto(&if_valueisstring); | 1236 Goto(&if_valueisstring); |
1237 } | 1237 } |
1238 Bind(&if_valueisstring); | 1238 Bind(&if_valueisstring); |
1239 return var_value.value(); | 1239 return var_value.value(); |
1240 } | 1240 } |
1241 | 1241 |
| 1242 Node* CodeStubAssembler::ToThisValue(Node* context, Node* value, |
| 1243 PrimitiveType primitive_type, |
| 1244 char const* method_name) { |
| 1245 // We might need to loop once due to JSValue unboxing. |
| 1246 Variable var_value(this, MachineRepresentation::kTagged); |
| 1247 Label loop(this, &var_value), done_loop(this), |
| 1248 done_throw(this, Label::kDeferred); |
| 1249 var_value.Bind(value); |
| 1250 Goto(&loop); |
| 1251 Bind(&loop); |
| 1252 { |
| 1253 // Load the current {value}. |
| 1254 value = var_value.value(); |
| 1255 |
| 1256 // Check if the {value} is a Smi or a HeapObject. |
| 1257 GotoIf(WordIsSmi(value), (primitive_type == PrimitiveType::kNumber) |
| 1258 ? &done_loop |
| 1259 : &done_throw); |
| 1260 |
| 1261 // Load the mape of the {value}. |
| 1262 Node* value_map = LoadMap(value); |
| 1263 |
| 1264 // Load the instance type of the {value}. |
| 1265 Node* value_instance_type = LoadMapInstanceType(value_map); |
| 1266 |
| 1267 // Check if {value} is a JSValue. |
| 1268 Label if_valueisvalue(this, Label::kDeferred), if_valueisnotvalue(this); |
| 1269 Branch(Word32Equal(value_instance_type, Int32Constant(JS_VALUE_TYPE)), |
| 1270 &if_valueisvalue, &if_valueisnotvalue); |
| 1271 |
| 1272 Bind(&if_valueisvalue); |
| 1273 { |
| 1274 // Load the actual value from the {value}. |
| 1275 var_value.Bind(LoadObjectField(value, JSValue::kValueOffset)); |
| 1276 Goto(&loop); |
| 1277 } |
| 1278 |
| 1279 Bind(&if_valueisnotvalue); |
| 1280 { |
| 1281 switch (primitive_type) { |
| 1282 case PrimitiveType::kBoolean: |
| 1283 GotoIf(WordEqual(value_map, BooleanMapConstant()), &done_loop); |
| 1284 break; |
| 1285 case PrimitiveType::kNumber: |
| 1286 GotoIf( |
| 1287 Word32Equal(value_instance_type, Int32Constant(HEAP_NUMBER_TYPE)), |
| 1288 &done_loop); |
| 1289 break; |
| 1290 case PrimitiveType::kString: |
| 1291 GotoIf(Int32LessThan(value_instance_type, |
| 1292 Int32Constant(FIRST_NONSTRING_TYPE)), |
| 1293 &done_loop); |
| 1294 break; |
| 1295 case PrimitiveType::kSymbol: |
| 1296 GotoIf(Word32Equal(value_instance_type, Int32Constant(SYMBOL_TYPE)), |
| 1297 &done_loop); |
| 1298 break; |
| 1299 } |
| 1300 Goto(&done_throw); |
| 1301 } |
| 1302 } |
| 1303 |
| 1304 Bind(&done_throw); |
| 1305 { |
| 1306 // The {value} is not a compatible receiver for this method. |
| 1307 CallRuntime(Runtime::kThrowNotGeneric, context, |
| 1308 HeapConstant(factory()->NewStringFromAsciiChecked(method_name, |
| 1309 TENURED))); |
| 1310 Goto(&done_loop); // Never reached. |
| 1311 } |
| 1312 |
| 1313 Bind(&done_loop); |
| 1314 return var_value.value(); |
| 1315 } |
| 1316 |
1242 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index) { | 1317 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index) { |
1243 // Translate the {index} into a Word. | 1318 // Translate the {index} into a Word. |
1244 index = SmiToWord(index); | 1319 index = SmiToWord(index); |
1245 | 1320 |
1246 // We may need to loop in case of cons or sliced strings. | 1321 // We may need to loop in case of cons or sliced strings. |
1247 Variable var_index(this, MachineType::PointerRepresentation()); | 1322 Variable var_index(this, MachineType::PointerRepresentation()); |
1248 Variable var_result(this, MachineRepresentation::kWord32); | 1323 Variable var_result(this, MachineRepresentation::kWord32); |
1249 Variable var_string(this, MachineRepresentation::kTagged); | 1324 Variable var_string(this, MachineRepresentation::kTagged); |
1250 Variable* loop_vars[] = {&var_index, &var_string}; | 1325 Variable* loop_vars[] = {&var_index, &var_string}; |
1251 Label done_loop(this, &var_result), loop(this, 2, loop_vars); | 1326 Label done_loop(this, &var_result), loop(this, 2, loop_vars); |
(...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2780 } | 2855 } |
2781 Bind(&miss); | 2856 Bind(&miss); |
2782 { | 2857 { |
2783 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, | 2858 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, |
2784 p->vector); | 2859 p->vector); |
2785 } | 2860 } |
2786 } | 2861 } |
2787 | 2862 |
2788 } // namespace internal | 2863 } // namespace internal |
2789 } // namespace v8 | 2864 } // namespace v8 |
OLD | NEW |