OLD | NEW |
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/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include "src/bailout-reason.h" | 7 #include "src/bailout-reason.h" |
8 #include "src/field-index.h" | 8 #include "src/field-index.h" |
9 #include "src/hydrogen.h" | 9 #include "src/hydrogen.h" |
10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 HValue* code_object, HValue* literals); | 106 HValue* code_object, HValue* literals); |
107 void BuildInstallCode(HValue* js_function, HValue* shared_info); | 107 void BuildInstallCode(HValue* js_function, HValue* shared_info); |
108 | 108 |
109 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map, | 109 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map, |
110 HValue* iterator, | 110 HValue* iterator, |
111 int field_offset); | 111 int field_offset); |
112 void BuildInstallFromOptimizedCodeMap(HValue* js_function, | 112 void BuildInstallFromOptimizedCodeMap(HValue* js_function, |
113 HValue* shared_info, | 113 HValue* shared_info, |
114 HValue* native_context); | 114 HValue* native_context); |
115 | 115 |
| 116 HValue* CheckString(HValue* input, bool convert); |
| 117 |
116 private: | 118 private: |
117 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); | 119 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); |
118 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, | 120 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, |
119 ElementsKind kind); | 121 ElementsKind kind); |
120 | 122 |
121 base::SmartArrayPointer<HParameter*> parameters_; | 123 base::SmartArrayPointer<HParameter*> parameters_; |
122 HValue* arguments_length_; | 124 HValue* arguments_length_; |
123 CompilationInfo* info_; | 125 CompilationInfo* info_; |
124 CodeStubDescriptor descriptor_; | 126 CodeStubDescriptor descriptor_; |
125 HContext* context_; | 127 HContext* context_; |
(...skipping 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1449 result_type, state.fixed_right_arg(), | 1451 result_type, state.fixed_right_arg(), |
1450 allocation_mode, state.strength()); | 1452 allocation_mode, state.strength()); |
1451 } | 1453 } |
1452 | 1454 |
1453 | 1455 |
1454 Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode() { | 1456 Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode() { |
1455 return DoGenerateCode(this); | 1457 return DoGenerateCode(this); |
1456 } | 1458 } |
1457 | 1459 |
1458 | 1460 |
| 1461 HValue* CodeStubGraphBuilderBase::CheckString(HValue* input, bool convert) { |
| 1462 if (!convert) return BuildCheckString(input); |
| 1463 IfBuilder if_inputissmi(this); |
| 1464 HValue* inputissmi = if_inputissmi.If<HIsSmiAndBranch>(input); |
| 1465 if_inputissmi.Then(); |
| 1466 { |
| 1467 // Convert the input smi to a string. |
| 1468 Push(BuildNumberToString(input, Type::SignedSmall())); |
| 1469 } |
| 1470 if_inputissmi.Else(); |
| 1471 { |
| 1472 HValue* input_map = |
| 1473 Add<HLoadNamedField>(input, inputissmi, HObjectAccess::ForMap()); |
| 1474 HValue* input_instance_type = Add<HLoadNamedField>( |
| 1475 input_map, inputissmi, HObjectAccess::ForMapInstanceType()); |
| 1476 IfBuilder if_inputisstring(this); |
| 1477 if_inputisstring.If<HCompareNumericAndBranch>( |
| 1478 input_instance_type, Add<HConstant>(FIRST_NONSTRING_TYPE), Token::LT); |
| 1479 if_inputisstring.Then(); |
| 1480 { |
| 1481 // The input is already a string. |
| 1482 Push(input); |
| 1483 } |
| 1484 if_inputisstring.Else(); |
| 1485 { |
| 1486 // Convert to primitive first (if necessary), see |
| 1487 // ES6 section 12.7.3 The Addition operator. |
| 1488 IfBuilder if_inputisprimitive(this); |
| 1489 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); |
| 1490 if_inputisprimitive.If<HCompareNumericAndBranch>( |
| 1491 input_instance_type, Add<HConstant>(LAST_PRIMITIVE_TYPE), Token::LTE); |
| 1492 if_inputisprimitive.Then(); |
| 1493 { |
| 1494 // The input is already a primitive. |
| 1495 Push(input); |
| 1496 } |
| 1497 if_inputisprimitive.Else(); |
| 1498 { |
| 1499 // TODO(bmeurer): Add support for fast ToPrimitive conversion using |
| 1500 // a dedicated ToPrimitiveStub. |
| 1501 Add<HPushArguments>(input); |
| 1502 Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kToPrimitive), |
| 1503 1)); |
| 1504 } |
| 1505 if_inputisprimitive.End(); |
| 1506 // Convert the primitive to a string value. |
| 1507 ToStringDescriptor descriptor(isolate()); |
| 1508 ToStringStub stub(isolate()); |
| 1509 HValue* values[] = {context(), Pop()}; |
| 1510 Push(AddUncasted<HCallWithDescriptor>( |
| 1511 Add<HConstant>(stub.GetCode()), 0, descriptor, |
| 1512 Vector<HValue*>(values, arraysize(values)))); |
| 1513 } |
| 1514 if_inputisstring.End(); |
| 1515 } |
| 1516 if_inputissmi.End(); |
| 1517 return Pop(); |
| 1518 } |
| 1519 |
| 1520 |
1459 template <> | 1521 template <> |
1460 HValue* CodeStubGraphBuilder<StringAddStub>::BuildCodeInitializedStub() { | 1522 HValue* CodeStubGraphBuilder<StringAddStub>::BuildCodeInitializedStub() { |
1461 StringAddStub* stub = casted_stub(); | 1523 StringAddStub* stub = casted_stub(); |
1462 StringAddFlags flags = stub->flags(); | 1524 StringAddFlags flags = stub->flags(); |
1463 PretenureFlag pretenure_flag = stub->pretenure_flag(); | 1525 PretenureFlag pretenure_flag = stub->pretenure_flag(); |
1464 | 1526 |
1465 HValue* left = GetParameter(StringAddStub::kLeft); | 1527 HValue* left = GetParameter(StringAddStub::kLeft); |
1466 HValue* right = GetParameter(StringAddStub::kRight); | 1528 HValue* right = GetParameter(StringAddStub::kRight); |
1467 | 1529 |
1468 // Make sure that both arguments are strings if not known in advance. | 1530 // Make sure that both arguments are strings if not known in advance. |
1469 if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) { | 1531 if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) { |
1470 left = BuildCheckString(left); | 1532 left = |
| 1533 CheckString(left, (flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT); |
1471 } | 1534 } |
1472 if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { | 1535 if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { |
1473 right = BuildCheckString(right); | 1536 right = |
| 1537 CheckString(right, (flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT); |
1474 } | 1538 } |
1475 | 1539 |
1476 return BuildStringAdd(left, right, HAllocationMode(pretenure_flag)); | 1540 return BuildStringAdd(left, right, HAllocationMode(pretenure_flag)); |
1477 } | 1541 } |
1478 | 1542 |
1479 | 1543 |
1480 Handle<Code> StringAddStub::GenerateCode() { | 1544 Handle<Code> StringAddStub::GenerateCode() { |
1481 return DoGenerateCode(this); | 1545 return DoGenerateCode(this); |
1482 } | 1546 } |
1483 | 1547 |
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2209 return Pop(); | 2273 return Pop(); |
2210 } | 2274 } |
2211 | 2275 |
2212 | 2276 |
2213 Handle<Code> KeyedLoadGenericStub::GenerateCode() { | 2277 Handle<Code> KeyedLoadGenericStub::GenerateCode() { |
2214 return DoGenerateCode(this); | 2278 return DoGenerateCode(this); |
2215 } | 2279 } |
2216 | 2280 |
2217 } // namespace internal | 2281 } // namespace internal |
2218 } // namespace v8 | 2282 } // namespace v8 |
OLD | NEW |