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/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 #undef GENERATE_CASE | 159 #undef GENERATE_CASE |
160 #undef JUMP_NODE_LIST | 160 #undef JUMP_NODE_LIST |
161 default: | 161 default: |
162 return false; | 162 return false; |
163 } | 163 } |
164 } | 164 } |
165 | 165 |
166 VariableProxy::VariableProxy(Variable* var, int start_position, | 166 VariableProxy::VariableProxy(Variable* var, int start_position, |
167 int end_position) | 167 int end_position) |
168 : Expression(start_position, kVariableProxy), | 168 : Expression(start_position, kVariableProxy), |
169 bit_field_(IsThisField::encode(var->is_this()) | | |
170 IsAssignedField::encode(false) | | |
171 IsResolvedField::encode(false)), | |
172 end_position_(end_position), | 169 end_position_(end_position), |
173 raw_name_(var->raw_name()), | 170 raw_name_(var->raw_name()), |
174 next_unresolved_(nullptr) { | 171 next_unresolved_(nullptr) { |
| 172 bit_field_ |= IsThisField::encode(var->is_this()) | |
| 173 IsAssignedField::encode(false) | IsResolvedField::encode(false); |
175 BindTo(var); | 174 BindTo(var); |
176 } | 175 } |
177 | 176 |
178 VariableProxy::VariableProxy(const AstRawString* name, | 177 VariableProxy::VariableProxy(const AstRawString* name, |
179 Variable::Kind variable_kind, int start_position, | 178 Variable::Kind variable_kind, int start_position, |
180 int end_position) | 179 int end_position) |
181 : Expression(start_position, kVariableProxy), | 180 : Expression(start_position, kVariableProxy), |
182 bit_field_(IsThisField::encode(variable_kind == Variable::THIS) | | |
183 IsAssignedField::encode(false) | | |
184 IsResolvedField::encode(false)), | |
185 end_position_(end_position), | 181 end_position_(end_position), |
186 raw_name_(name), | 182 raw_name_(name), |
187 next_unresolved_(nullptr) {} | 183 next_unresolved_(nullptr) { |
| 184 bit_field_ |= IsThisField::encode(variable_kind == Variable::THIS) | |
| 185 IsAssignedField::encode(false) | IsResolvedField::encode(false); |
| 186 } |
188 | 187 |
189 VariableProxy::VariableProxy(const VariableProxy* copy_from) | 188 VariableProxy::VariableProxy(const VariableProxy* copy_from) |
190 : Expression(copy_from->position(), kVariableProxy), | 189 : Expression(copy_from->position(), kVariableProxy), |
191 bit_field_(copy_from->bit_field_), | |
192 end_position_(copy_from->end_position_), | 190 end_position_(copy_from->end_position_), |
193 next_unresolved_(nullptr) { | 191 next_unresolved_(nullptr) { |
| 192 bit_field_ = copy_from->bit_field_; |
194 if (copy_from->is_resolved()) { | 193 if (copy_from->is_resolved()) { |
195 var_ = copy_from->var_; | 194 var_ = copy_from->var_; |
196 } else { | 195 } else { |
197 raw_name_ = copy_from->raw_name_; | 196 raw_name_ = copy_from->raw_name_; |
198 } | 197 } |
199 } | 198 } |
200 | 199 |
201 void VariableProxy::BindTo(Variable* var) { | 200 void VariableProxy::BindTo(Variable* var) { |
202 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name()); | 201 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name()); |
203 set_var(var); | 202 set_var(var); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 void ForInStatement::AssignFeedbackVectorSlots(Isolate* isolate, | 245 void ForInStatement::AssignFeedbackVectorSlots(Isolate* isolate, |
247 FeedbackVectorSpec* spec, | 246 FeedbackVectorSpec* spec, |
248 FeedbackVectorSlotCache* cache) { | 247 FeedbackVectorSlotCache* cache) { |
249 AssignVectorSlots(each(), spec, &each_slot_); | 248 AssignVectorSlots(each(), spec, &each_slot_); |
250 for_in_feedback_slot_ = spec->AddGeneralSlot(); | 249 for_in_feedback_slot_ = spec->AddGeneralSlot(); |
251 } | 250 } |
252 | 251 |
253 Assignment::Assignment(Token::Value op, Expression* target, Expression* value, | 252 Assignment::Assignment(Token::Value op, Expression* target, Expression* value, |
254 int pos) | 253 int pos) |
255 : Expression(pos, kAssignment), | 254 : Expression(pos, kAssignment), |
256 bit_field_( | |
257 IsUninitializedField::encode(false) | KeyTypeField::encode(ELEMENT) | | |
258 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)), | |
259 target_(target), | 255 target_(target), |
260 value_(value), | 256 value_(value), |
261 binary_operation_(NULL) {} | 257 binary_operation_(NULL) { |
| 258 bit_field_ |= IsUninitializedField::encode(false) | |
| 259 KeyTypeField::encode(ELEMENT) | |
| 260 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op); |
| 261 } |
262 | 262 |
263 void Assignment::AssignFeedbackVectorSlots(Isolate* isolate, | 263 void Assignment::AssignFeedbackVectorSlots(Isolate* isolate, |
264 FeedbackVectorSpec* spec, | 264 FeedbackVectorSpec* spec, |
265 FeedbackVectorSlotCache* cache) { | 265 FeedbackVectorSlotCache* cache) { |
266 AssignVectorSlots(target(), spec, &slot_); | 266 AssignVectorSlots(target(), spec, &slot_); |
267 } | 267 } |
268 | 268 |
269 | 269 |
270 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate, | 270 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate, |
271 FeedbackVectorSpec* spec, | 271 FeedbackVectorSpec* spec, |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 Handle<Object> key = property->key()->AsLiteral()->value(); | 544 Handle<Object> key = property->key()->AsLiteral()->value(); |
545 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); | 545 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); |
546 | 546 |
547 // Ensure objects that may, at any point in time, contain fields with double | 547 // Ensure objects that may, at any point in time, contain fields with double |
548 // representation are always treated as nested objects. This is true for | 548 // representation are always treated as nested objects. This is true for |
549 // computed fields (value is undefined), and smi and double literals | 549 // computed fields (value is undefined), and smi and double literals |
550 // (value->IsNumber()). | 550 // (value->IsNumber()). |
551 // TODO(verwaest): Remove once we can store them inline. | 551 // TODO(verwaest): Remove once we can store them inline. |
552 if (FLAG_track_double_fields && | 552 if (FLAG_track_double_fields && |
553 (value->IsNumber() || value->IsUninitialized(isolate))) { | 553 (value->IsNumber() || value->IsUninitialized(isolate))) { |
554 may_store_doubles_ = true; | 554 bit_field_ = MayStoreDoublesField::update(bit_field_, true); |
555 } | 555 } |
556 | 556 |
557 is_simple = is_simple && !value->IsUninitialized(isolate); | 557 is_simple = is_simple && !value->IsUninitialized(isolate); |
558 | 558 |
559 // Keep track of the number of elements in the object literal and | 559 // Keep track of the number of elements in the object literal and |
560 // the largest element index. If the largest element index is | 560 // the largest element index. If the largest element index is |
561 // much larger than the number of elements, creating an object | 561 // much larger than the number of elements, creating an object |
562 // literal with fast elements will be a waste of space. | 562 // literal with fast elements will be a waste of space. |
563 uint32_t element_index = 0; | 563 uint32_t element_index = 0; |
564 if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) { | 564 if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) { |
565 max_element_index = Max(element_index, max_element_index); | 565 max_element_index = Max(element_index, max_element_index); |
566 elements++; | 566 elements++; |
567 key = isolate->factory()->NewNumberFromUint(element_index); | 567 key = isolate->factory()->NewNumberFromUint(element_index); |
568 } else if (key->ToArrayIndex(&element_index)) { | 568 } else if (key->ToArrayIndex(&element_index)) { |
569 max_element_index = Max(element_index, max_element_index); | 569 max_element_index = Max(element_index, max_element_index); |
570 elements++; | 570 elements++; |
571 } else if (key->IsNumber()) { | 571 } else if (key->IsNumber()) { |
572 key = isolate->factory()->NumberToString(key); | 572 key = isolate->factory()->NumberToString(key); |
573 } | 573 } |
574 | 574 |
575 // Add name, value pair to the fixed array. | 575 // Add name, value pair to the fixed array. |
576 constant_properties->set(position++, *key); | 576 constant_properties->set(position++, *key); |
577 constant_properties->set(position++, *value); | 577 constant_properties->set(position++, *value); |
578 } | 578 } |
579 | 579 |
580 constant_properties_ = constant_properties; | 580 constant_properties_ = constant_properties; |
581 fast_elements_ = | 581 bit_field_ = FastElementsField::update( |
582 (max_element_index <= 32) || ((2 * elements) >= max_element_index); | 582 bit_field_, |
583 has_elements_ = elements > 0; | 583 (max_element_index <= 32) || ((2 * elements) >= max_element_index)); |
| 584 bit_field_ = HasElementsField::update(bit_field_, elements > 0); |
| 585 |
584 set_is_simple(is_simple); | 586 set_is_simple(is_simple); |
585 set_depth(depth_acc); | 587 set_depth(depth_acc); |
586 } | 588 } |
587 | 589 |
588 | 590 |
589 void ArrayLiteral::BuildConstantElements(Isolate* isolate) { | 591 void ArrayLiteral::BuildConstantElements(Isolate* isolate) { |
590 DCHECK_LT(first_spread_index_, 0); | 592 DCHECK_LT(first_spread_index_, 0); |
591 | 593 |
592 if (!constant_elements_.is_null()) return; | 594 if (!constant_elements_.is_null()) return; |
593 | 595 |
(...skipping 158 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 // static | 954 // static |
953 bool Literal::Match(void* literal1, void* literal2) { | 955 bool Literal::Match(void* literal1, void* literal2) { |
954 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 956 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
955 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 957 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
956 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || | 958 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || |
957 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 959 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
958 } | 960 } |
959 | 961 |
960 } // namespace internal | 962 } // namespace internal |
961 } // namespace v8 | 963 } // namespace v8 |
OLD | NEW |