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 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 Variable::Kind variable_kind, int start_position, | 174 Variable::Kind 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 == Variable::THIS) | | |
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 == Variable::THIS) | |
| 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 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 Handle<Object> key = property->key()->AsLiteral()->value(); | 540 Handle<Object> key = property->key()->AsLiteral()->value(); |
541 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); | 541 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); |
542 | 542 |
543 // Ensure objects that may, at any point in time, contain fields with double | 543 // Ensure objects that may, at any point in time, contain fields with double |
544 // representation are always treated as nested objects. This is true for | 544 // representation are always treated as nested objects. This is true for |
545 // computed fields (value is undefined), and smi and double literals | 545 // computed fields (value is undefined), and smi and double literals |
546 // (value->IsNumber()). | 546 // (value->IsNumber()). |
547 // TODO(verwaest): Remove once we can store them inline. | 547 // TODO(verwaest): Remove once we can store them inline. |
548 if (FLAG_track_double_fields && | 548 if (FLAG_track_double_fields && |
549 (value->IsNumber() || value->IsUninitialized(isolate))) { | 549 (value->IsNumber() || value->IsUninitialized(isolate))) { |
550 may_store_doubles_ = true; | 550 bit_field_ = MayStoreDoublesField::update(bit_field_, true); |
551 } | 551 } |
552 | 552 |
553 is_simple = is_simple && !value->IsUninitialized(isolate); | 553 is_simple = is_simple && !value->IsUninitialized(isolate); |
554 | 554 |
555 // Keep track of the number of elements in the object literal and | 555 // Keep track of the number of elements in the object literal and |
556 // the largest element index. If the largest element index is | 556 // the largest element index. If the largest element index is |
557 // much larger than the number of elements, creating an object | 557 // much larger than the number of elements, creating an object |
558 // literal with fast elements will be a waste of space. | 558 // literal with fast elements will be a waste of space. |
559 uint32_t element_index = 0; | 559 uint32_t element_index = 0; |
560 if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) { | 560 if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) { |
561 max_element_index = Max(element_index, max_element_index); | 561 max_element_index = Max(element_index, max_element_index); |
562 elements++; | 562 elements++; |
563 key = isolate->factory()->NewNumberFromUint(element_index); | 563 key = isolate->factory()->NewNumberFromUint(element_index); |
564 } else if (key->ToArrayIndex(&element_index)) { | 564 } else if (key->ToArrayIndex(&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 } else if (key->IsNumber()) { | 567 } else if (key->IsNumber()) { |
568 key = isolate->factory()->NumberToString(key); | 568 key = isolate->factory()->NumberToString(key); |
569 } | 569 } |
570 | 570 |
571 // Add name, value pair to the fixed array. | 571 // Add name, value pair to the fixed array. |
572 constant_properties->set(position++, *key); | 572 constant_properties->set(position++, *key); |
573 constant_properties->set(position++, *value); | 573 constant_properties->set(position++, *value); |
574 } | 574 } |
575 | 575 |
576 constant_properties_ = constant_properties; | 576 constant_properties_ = constant_properties; |
577 fast_elements_ = | 577 bit_field_ = FastElementsField::update( |
578 (max_element_index <= 32) || ((2 * elements) >= max_element_index); | 578 bit_field_, |
579 has_elements_ = elements > 0; | 579 (max_element_index <= 32) || ((2 * elements) >= max_element_index)); |
| 580 bit_field_ = HasElementsField::update(bit_field_, elements > 0); |
| 581 |
580 set_is_simple(is_simple); | 582 set_is_simple(is_simple); |
581 set_depth(depth_acc); | 583 set_depth(depth_acc); |
582 } | 584 } |
583 | 585 |
584 | 586 |
585 void ArrayLiteral::BuildConstantElements(Isolate* isolate) { | 587 void ArrayLiteral::BuildConstantElements(Isolate* isolate) { |
586 DCHECK_LT(first_spread_index_, 0); | 588 DCHECK_LT(first_spread_index_, 0); |
587 | 589 |
588 if (!constant_elements_.is_null()) return; | 590 if (!constant_elements_.is_null()) return; |
589 | 591 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 *expr = left->AsUnaryOperation()->expression(); | 764 *expr = left->AsUnaryOperation()->expression(); |
763 *check = Handle<String>::cast(right->AsLiteral()->value()); | 765 *check = Handle<String>::cast(right->AsLiteral()->value()); |
764 return true; | 766 return true; |
765 } | 767 } |
766 return false; | 768 return false; |
767 } | 769 } |
768 | 770 |
769 | 771 |
770 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr, | 772 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr, |
771 Handle<String>* check) { | 773 Handle<String>* check) { |
772 return MatchLiteralCompareTypeof(left_, op_, right_, expr, check) || | 774 return MatchLiteralCompareTypeof(left_, op(), right_, expr, check) || |
773 MatchLiteralCompareTypeof(right_, op_, left_, expr, check); | 775 MatchLiteralCompareTypeof(right_, op(), left_, expr, check); |
774 } | 776 } |
775 | 777 |
776 | 778 |
777 static bool IsVoidOfLiteral(Expression* expr) { | 779 static bool IsVoidOfLiteral(Expression* expr) { |
778 UnaryOperation* maybe_unary = expr->AsUnaryOperation(); | 780 UnaryOperation* maybe_unary = expr->AsUnaryOperation(); |
779 return maybe_unary != NULL && | 781 return maybe_unary != NULL && |
780 maybe_unary->op() == Token::VOID && | 782 maybe_unary->op() == Token::VOID && |
781 maybe_unary->expression()->IsLiteral(); | 783 maybe_unary->expression()->IsLiteral(); |
782 } | 784 } |
783 | 785 |
784 | 786 |
785 // Check for the pattern: void <literal> equals <expression> or | 787 // Check for the pattern: void <literal> equals <expression> or |
786 // undefined equals <expression> | 788 // undefined equals <expression> |
787 static bool MatchLiteralCompareUndefined(Expression* left, | 789 static bool MatchLiteralCompareUndefined(Expression* left, |
788 Token::Value op, | 790 Token::Value op, |
789 Expression* right, | 791 Expression* right, |
790 Expression** expr) { | 792 Expression** expr) { |
791 if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) { | 793 if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) { |
792 *expr = right; | 794 *expr = right; |
793 return true; | 795 return true; |
794 } | 796 } |
795 if (left->IsUndefinedLiteral() && Token::IsEqualityOp(op)) { | 797 if (left->IsUndefinedLiteral() && Token::IsEqualityOp(op)) { |
796 *expr = right; | 798 *expr = right; |
797 return true; | 799 return true; |
798 } | 800 } |
799 return false; | 801 return false; |
800 } | 802 } |
801 | 803 |
802 bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) { | 804 bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) { |
803 return MatchLiteralCompareUndefined(left_, op_, right_, expr) || | 805 return MatchLiteralCompareUndefined(left_, op(), right_, expr) || |
804 MatchLiteralCompareUndefined(right_, op_, left_, expr); | 806 MatchLiteralCompareUndefined(right_, op(), left_, expr); |
805 } | 807 } |
806 | 808 |
807 | 809 |
808 // Check for the pattern: null equals <expression> | 810 // Check for the pattern: null equals <expression> |
809 static bool MatchLiteralCompareNull(Expression* left, | 811 static bool MatchLiteralCompareNull(Expression* left, |
810 Token::Value op, | 812 Token::Value op, |
811 Expression* right, | 813 Expression* right, |
812 Expression** expr) { | 814 Expression** expr) { |
813 if (left->IsNullLiteral() && Token::IsEqualityOp(op)) { | 815 if (left->IsNullLiteral() && Token::IsEqualityOp(op)) { |
814 *expr = right; | 816 *expr = right; |
815 return true; | 817 return true; |
816 } | 818 } |
817 return false; | 819 return false; |
818 } | 820 } |
819 | 821 |
820 | 822 |
821 bool CompareOperation::IsLiteralCompareNull(Expression** expr) { | 823 bool CompareOperation::IsLiteralCompareNull(Expression** expr) { |
822 return MatchLiteralCompareNull(left_, op_, right_, expr) || | 824 return MatchLiteralCompareNull(left_, op(), right_, expr) || |
823 MatchLiteralCompareNull(right_, op_, left_, expr); | 825 MatchLiteralCompareNull(right_, op(), left_, expr); |
824 } | 826 } |
825 | 827 |
826 | 828 |
827 // ---------------------------------------------------------------------------- | 829 // ---------------------------------------------------------------------------- |
828 // Recording of type feedback | 830 // Recording of type feedback |
829 | 831 |
830 // TODO(rossberg): all RecordTypeFeedback functions should disappear | 832 // TODO(rossberg): all RecordTypeFeedback functions should disappear |
831 // once we use the common type field in the AST consistently. | 833 // once we use the common type field in the AST consistently. |
832 | 834 |
833 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { | 835 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 // static | 970 // static |
969 bool Literal::Match(void* literal1, void* literal2) { | 971 bool Literal::Match(void* literal1, void* literal2) { |
970 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 972 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
971 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 973 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
972 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || | 974 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || |
973 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 975 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
974 } | 976 } |
975 | 977 |
976 } // namespace internal | 978 } // namespace internal |
977 } // namespace v8 | 979 } // namespace v8 |
OLD | NEW |