| 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/ast/ast.h" | 5 #include "src/ast/ast.h" |
| 6 | 6 |
| 7 #include <cmath> // For isfinite. | 7 #include <cmath> // For isfinite. |
| 8 | 8 |
| 9 #include "src/ast/compile-time-value.h" | 9 #include "src/ast/compile-time-value.h" |
| 10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 #undef GENERATE_CASE | 155 #undef GENERATE_CASE |
| 156 #undef JUMP_NODE_LIST | 156 #undef JUMP_NODE_LIST |
| 157 default: | 157 default: |
| 158 return false; | 158 return false; |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 | 161 |
| 162 VariableProxy::VariableProxy(Variable* var, int start_position, | 162 VariableProxy::VariableProxy(Variable* var, int start_position, |
| 163 int end_position) | 163 int end_position) |
| 164 : Expression(start_position, kVariableProxy), | 164 : Expression(start_position, kVariableProxy), |
| 165 bit_field_(IsThisField::encode(var->is_this()) | | |
| 166 IsAssignedField::encode(false) | | |
| 167 IsResolvedField::encode(false)), | |
| 168 end_position_(end_position), | 165 end_position_(end_position), |
| 169 raw_name_(var->raw_name()), | 166 raw_name_(var->raw_name()), |
| 170 next_unresolved_(nullptr) { | 167 next_unresolved_(nullptr) { |
| 168 bit_field_ |= IsThisField::encode(var->is_this()) | |
| 169 IsAssignedField::encode(false) | IsResolvedField::encode(false); |
| 171 BindTo(var); | 170 BindTo(var); |
| 172 } | 171 } |
| 173 | 172 |
| 174 VariableProxy::VariableProxy(const AstRawString* name, | 173 VariableProxy::VariableProxy(const AstRawString* name, |
| 175 VariableKind variable_kind, int start_position, | 174 VariableKind variable_kind, int start_position, |
| 176 int end_position) | 175 int end_position) |
| 177 : Expression(start_position, kVariableProxy), | 176 : Expression(start_position, kVariableProxy), |
| 178 bit_field_(IsThisField::encode(variable_kind == THIS_VARIABLE) | | |
| 179 IsAssignedField::encode(false) | | |
| 180 IsResolvedField::encode(false)), | |
| 181 end_position_(end_position), | 177 end_position_(end_position), |
| 182 raw_name_(name), | 178 raw_name_(name), |
| 183 next_unresolved_(nullptr) {} | 179 next_unresolved_(nullptr) { |
| 180 bit_field_ |= IsThisField::encode(variable_kind == THIS_VARIABLE) | |
| 181 IsAssignedField::encode(false) | IsResolvedField::encode(false); |
| 182 } |
| 184 | 183 |
| 185 VariableProxy::VariableProxy(const VariableProxy* copy_from) | 184 VariableProxy::VariableProxy(const VariableProxy* copy_from) |
| 186 : Expression(copy_from->position(), kVariableProxy), | 185 : Expression(copy_from->position(), kVariableProxy), |
| 187 bit_field_(copy_from->bit_field_), | |
| 188 end_position_(copy_from->end_position_), | 186 end_position_(copy_from->end_position_), |
| 189 next_unresolved_(nullptr) { | 187 next_unresolved_(nullptr) { |
| 188 bit_field_ = copy_from->bit_field_; |
| 190 if (copy_from->is_resolved()) { | 189 if (copy_from->is_resolved()) { |
| 191 var_ = copy_from->var_; | 190 var_ = copy_from->var_; |
| 192 } else { | 191 } else { |
| 193 raw_name_ = copy_from->raw_name_; | 192 raw_name_ = copy_from->raw_name_; |
| 194 } | 193 } |
| 195 } | 194 } |
| 196 | 195 |
| 197 void VariableProxy::BindTo(Variable* var) { | 196 void VariableProxy::BindTo(Variable* var) { |
| 198 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name()); | 197 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name()); |
| 199 set_var(var); | 198 set_var(var); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 void ForInStatement::AssignFeedbackVectorSlots(Isolate* isolate, | 241 void ForInStatement::AssignFeedbackVectorSlots(Isolate* isolate, |
| 243 FeedbackVectorSpec* spec, | 242 FeedbackVectorSpec* spec, |
| 244 FeedbackVectorSlotCache* cache) { | 243 FeedbackVectorSlotCache* cache) { |
| 245 AssignVectorSlots(each(), spec, &each_slot_); | 244 AssignVectorSlots(each(), spec, &each_slot_); |
| 246 for_in_feedback_slot_ = spec->AddGeneralSlot(); | 245 for_in_feedback_slot_ = spec->AddGeneralSlot(); |
| 247 } | 246 } |
| 248 | 247 |
| 249 Assignment::Assignment(Token::Value op, Expression* target, Expression* value, | 248 Assignment::Assignment(Token::Value op, Expression* target, Expression* value, |
| 250 int pos) | 249 int pos) |
| 251 : Expression(pos, kAssignment), | 250 : Expression(pos, kAssignment), |
| 252 bit_field_( | |
| 253 IsUninitializedField::encode(false) | KeyTypeField::encode(ELEMENT) | | |
| 254 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)), | |
| 255 target_(target), | 251 target_(target), |
| 256 value_(value), | 252 value_(value), |
| 257 binary_operation_(NULL) {} | 253 binary_operation_(NULL) { |
| 254 bit_field_ |= IsUninitializedField::encode(false) | |
| 255 KeyTypeField::encode(ELEMENT) | |
| 256 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op); |
| 257 } |
| 258 | 258 |
| 259 void Assignment::AssignFeedbackVectorSlots(Isolate* isolate, | 259 void Assignment::AssignFeedbackVectorSlots(Isolate* isolate, |
| 260 FeedbackVectorSpec* spec, | 260 FeedbackVectorSpec* spec, |
| 261 FeedbackVectorSlotCache* cache) { | 261 FeedbackVectorSlotCache* cache) { |
| 262 AssignVectorSlots(target(), spec, &slot_); | 262 AssignVectorSlots(target(), spec, &slot_); |
| 263 } | 263 } |
| 264 | 264 |
| 265 | 265 |
| 266 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate, | 266 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate, |
| 267 FeedbackVectorSpec* spec, | 267 FeedbackVectorSpec* spec, |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 Handle<Object> key = property->key()->AsLiteral()->value(); | 531 Handle<Object> key = property->key()->AsLiteral()->value(); |
| 532 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); | 532 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); |
| 533 | 533 |
| 534 // Ensure objects that may, at any point in time, contain fields with double | 534 // Ensure objects that may, at any point in time, contain fields with double |
| 535 // representation are always treated as nested objects. This is true for | 535 // representation are always treated as nested objects. This is true for |
| 536 // computed fields (value is undefined), and smi and double literals | 536 // computed fields (value is undefined), and smi and double literals |
| 537 // (value->IsNumber()). | 537 // (value->IsNumber()). |
| 538 // TODO(verwaest): Remove once we can store them inline. | 538 // TODO(verwaest): Remove once we can store them inline. |
| 539 if (FLAG_track_double_fields && | 539 if (FLAG_track_double_fields && |
| 540 (value->IsNumber() || value->IsUninitialized(isolate))) { | 540 (value->IsNumber() || value->IsUninitialized(isolate))) { |
| 541 may_store_doubles_ = true; | 541 bit_field_ = MayStoreDoublesField::update(bit_field_, true); |
| 542 } | 542 } |
| 543 | 543 |
| 544 is_simple = is_simple && !value->IsUninitialized(isolate); | 544 is_simple = is_simple && !value->IsUninitialized(isolate); |
| 545 | 545 |
| 546 // Keep track of the number of elements in the object literal and | 546 // Keep track of the number of elements in the object literal and |
| 547 // the largest element index. If the largest element index is | 547 // the largest element index. If the largest element index is |
| 548 // much larger than the number of elements, creating an object | 548 // much larger than the number of elements, creating an object |
| 549 // literal with fast elements will be a waste of space. | 549 // literal with fast elements will be a waste of space. |
| 550 uint32_t element_index = 0; | 550 uint32_t element_index = 0; |
| 551 if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) { | 551 if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) { |
| 552 max_element_index = Max(element_index, max_element_index); | 552 max_element_index = Max(element_index, max_element_index); |
| 553 elements++; | 553 elements++; |
| 554 key = isolate->factory()->NewNumberFromUint(element_index); | 554 key = isolate->factory()->NewNumberFromUint(element_index); |
| 555 } else if (key->ToArrayIndex(&element_index)) { | 555 } else if (key->ToArrayIndex(&element_index)) { |
| 556 max_element_index = Max(element_index, max_element_index); | 556 max_element_index = Max(element_index, max_element_index); |
| 557 elements++; | 557 elements++; |
| 558 } else if (key->IsNumber()) { | 558 } else if (key->IsNumber()) { |
| 559 key = isolate->factory()->NumberToString(key); | 559 key = isolate->factory()->NumberToString(key); |
| 560 } | 560 } |
| 561 | 561 |
| 562 // Add name, value pair to the fixed array. | 562 // Add name, value pair to the fixed array. |
| 563 constant_properties->set(position++, *key); | 563 constant_properties->set(position++, *key); |
| 564 constant_properties->set(position++, *value); | 564 constant_properties->set(position++, *value); |
| 565 } | 565 } |
| 566 | 566 |
| 567 constant_properties_ = constant_properties; | 567 constant_properties_ = constant_properties; |
| 568 fast_elements_ = | 568 bit_field_ = FastElementsField::update( |
| 569 (max_element_index <= 32) || ((2 * elements) >= max_element_index); | 569 bit_field_, |
| 570 has_elements_ = elements > 0; | 570 (max_element_index <= 32) || ((2 * elements) >= max_element_index)); |
| 571 bit_field_ = HasElementsField::update(bit_field_, elements > 0); |
| 572 |
| 571 set_is_simple(is_simple); | 573 set_is_simple(is_simple); |
| 572 set_depth(depth_acc); | 574 set_depth(depth_acc); |
| 573 } | 575 } |
| 574 | 576 |
| 575 | 577 |
| 576 void ArrayLiteral::BuildConstantElements(Isolate* isolate) { | 578 void ArrayLiteral::BuildConstantElements(Isolate* isolate) { |
| 577 DCHECK_LT(first_spread_index_, 0); | 579 DCHECK_LT(first_spread_index_, 0); |
| 578 | 580 |
| 579 if (!constant_elements_.is_null()) return; | 581 if (!constant_elements_.is_null()) return; |
| 580 | 582 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 *expr = left->AsUnaryOperation()->expression(); | 754 *expr = left->AsUnaryOperation()->expression(); |
| 753 *check = Handle<String>::cast(right->AsLiteral()->value()); | 755 *check = Handle<String>::cast(right->AsLiteral()->value()); |
| 754 return true; | 756 return true; |
| 755 } | 757 } |
| 756 return false; | 758 return false; |
| 757 } | 759 } |
| 758 | 760 |
| 759 | 761 |
| 760 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr, | 762 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr, |
| 761 Handle<String>* check) { | 763 Handle<String>* check) { |
| 762 return MatchLiteralCompareTypeof(left_, op_, right_, expr, check) || | 764 return MatchLiteralCompareTypeof(left_, op(), right_, expr, check) || |
| 763 MatchLiteralCompareTypeof(right_, op_, left_, expr, check); | 765 MatchLiteralCompareTypeof(right_, op(), left_, expr, check); |
| 764 } | 766 } |
| 765 | 767 |
| 766 | 768 |
| 767 static bool IsVoidOfLiteral(Expression* expr) { | 769 static bool IsVoidOfLiteral(Expression* expr) { |
| 768 UnaryOperation* maybe_unary = expr->AsUnaryOperation(); | 770 UnaryOperation* maybe_unary = expr->AsUnaryOperation(); |
| 769 return maybe_unary != NULL && | 771 return maybe_unary != NULL && |
| 770 maybe_unary->op() == Token::VOID && | 772 maybe_unary->op() == Token::VOID && |
| 771 maybe_unary->expression()->IsLiteral(); | 773 maybe_unary->expression()->IsLiteral(); |
| 772 } | 774 } |
| 773 | 775 |
| 774 | 776 |
| 775 // Check for the pattern: void <literal> equals <expression> or | 777 // Check for the pattern: void <literal> equals <expression> or |
| 776 // undefined equals <expression> | 778 // undefined equals <expression> |
| 777 static bool MatchLiteralCompareUndefined(Expression* left, | 779 static bool MatchLiteralCompareUndefined(Expression* left, |
| 778 Token::Value op, | 780 Token::Value op, |
| 779 Expression* right, | 781 Expression* right, |
| 780 Expression** expr) { | 782 Expression** expr) { |
| 781 if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) { | 783 if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) { |
| 782 *expr = right; | 784 *expr = right; |
| 783 return true; | 785 return true; |
| 784 } | 786 } |
| 785 if (left->IsUndefinedLiteral() && Token::IsEqualityOp(op)) { | 787 if (left->IsUndefinedLiteral() && Token::IsEqualityOp(op)) { |
| 786 *expr = right; | 788 *expr = right; |
| 787 return true; | 789 return true; |
| 788 } | 790 } |
| 789 return false; | 791 return false; |
| 790 } | 792 } |
| 791 | 793 |
| 792 bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) { | 794 bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) { |
| 793 return MatchLiteralCompareUndefined(left_, op_, right_, expr) || | 795 return MatchLiteralCompareUndefined(left_, op(), right_, expr) || |
| 794 MatchLiteralCompareUndefined(right_, op_, left_, expr); | 796 MatchLiteralCompareUndefined(right_, op(), left_, expr); |
| 795 } | 797 } |
| 796 | 798 |
| 797 | 799 |
| 798 // Check for the pattern: null equals <expression> | 800 // Check for the pattern: null equals <expression> |
| 799 static bool MatchLiteralCompareNull(Expression* left, | 801 static bool MatchLiteralCompareNull(Expression* left, |
| 800 Token::Value op, | 802 Token::Value op, |
| 801 Expression* right, | 803 Expression* right, |
| 802 Expression** expr) { | 804 Expression** expr) { |
| 803 if (left->IsNullLiteral() && Token::IsEqualityOp(op)) { | 805 if (left->IsNullLiteral() && Token::IsEqualityOp(op)) { |
| 804 *expr = right; | 806 *expr = right; |
| 805 return true; | 807 return true; |
| 806 } | 808 } |
| 807 return false; | 809 return false; |
| 808 } | 810 } |
| 809 | 811 |
| 810 | 812 |
| 811 bool CompareOperation::IsLiteralCompareNull(Expression** expr) { | 813 bool CompareOperation::IsLiteralCompareNull(Expression** expr) { |
| 812 return MatchLiteralCompareNull(left_, op_, right_, expr) || | 814 return MatchLiteralCompareNull(left_, op(), right_, expr) || |
| 813 MatchLiteralCompareNull(right_, op_, left_, expr); | 815 MatchLiteralCompareNull(right_, op(), left_, expr); |
| 814 } | 816 } |
| 815 | 817 |
| 816 | 818 |
| 817 // ---------------------------------------------------------------------------- | 819 // ---------------------------------------------------------------------------- |
| 818 // Recording of type feedback | 820 // Recording of type feedback |
| 819 | 821 |
| 820 // TODO(rossberg): all RecordTypeFeedback functions should disappear | 822 // TODO(rossberg): all RecordTypeFeedback functions should disappear |
| 821 // once we use the common type field in the AST consistently. | 823 // once we use the common type field in the AST consistently. |
| 822 | 824 |
| 823 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { | 825 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 958 // static | 960 // static |
| 959 bool Literal::Match(void* literal1, void* literal2) { | 961 bool Literal::Match(void* literal1, void* literal2) { |
| 960 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 962 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
| 961 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 963 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
| 962 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || | 964 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || |
| 963 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 965 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
| 964 } | 966 } |
| 965 | 967 |
| 966 } // namespace internal | 968 } // namespace internal |
| 967 } // namespace v8 | 969 } // namespace v8 |
| OLD | NEW |