Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(433)

Side by Side Diff: src/ast/ast.cc

Issue 1439693002: [runtime] Support Proxy setPrototypeOf trap (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@2015-11-09_new_Proxy_1417063011
Patch Set: merging with master Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ast/ast.h ('k') | src/ast/ast-value-factory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/builtins.h" 9 #include "src/builtins.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
11 #include "src/contexts.h" 11 #include "src/contexts.h"
12 #include "src/conversions.h" 12 #include "src/conversions.h"
13 #include "src/hashmap.h" 13 #include "src/hashmap.h"
14 #include "src/parsing/parser.h" 14 #include "src/parsing/parser.h"
15 #include "src/property.h" 15 #include "src/property.h"
16 #include "src/property-details.h" 16 #include "src/property-details.h"
17 #include "src/string-stream.h" 17 #include "src/string-stream.h"
18 #include "src/type-info.h" 18 #include "src/type-info.h"
19 19
20 namespace v8 { 20 namespace v8 {
21 namespace internal { 21 namespace internal {
22 22
23 // ---------------------------------------------------------------------------- 23 // ----------------------------------------------------------------------------
24 // All the Accept member functions for each syntax tree node type. 24 // All the Accept member functions for each syntax tree node type.
25 25
26 #define DECL_ACCEPT(type) \ 26 #define DECL_ACCEPT(type) \
27 void type::Accept(AstVisitor* v) { v->Visit##type(this); } 27 void type::Accept(AstVisitor* v) { v->Visit##type(this); }
28 AST_NODE_LIST(DECL_ACCEPT) 28 AST_NODE_LIST(DECL_ACCEPT)
29 #undef DECL_ACCEPT 29 #undef DECL_ACCEPT
30 30
31 31
32 // ---------------------------------------------------------------------------- 32 // ----------------------------------------------------------------------------
33 // Implementation of other node functionality. 33 // Implementation of other node functionality.
34 34
35 35
36 bool Expression::IsSmiLiteral() const { 36 bool Expression::IsSmiLiteral() const {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 161
162 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate, 162 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate,
163 FeedbackVectorSpec* spec, 163 FeedbackVectorSpec* spec,
164 FeedbackVectorSlotCache* cache) { 164 FeedbackVectorSlotCache* cache) {
165 AssignVectorSlots(expression(), spec, &slot_); 165 AssignVectorSlots(expression(), spec, &slot_);
166 } 166 }
167 167
168 168
169 Token::Value Assignment::binary_op() const { 169 Token::Value Assignment::binary_op() const {
170 switch (op()) { 170 switch (op()) {
171 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; 171 case Token::ASSIGN_BIT_OR:
172 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; 172 return Token::BIT_OR;
173 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; 173 case Token::ASSIGN_BIT_XOR:
174 case Token::ASSIGN_SHL: return Token::SHL; 174 return Token::BIT_XOR;
175 case Token::ASSIGN_SAR: return Token::SAR; 175 case Token::ASSIGN_BIT_AND:
176 case Token::ASSIGN_SHR: return Token::SHR; 176 return Token::BIT_AND;
177 case Token::ASSIGN_ADD: return Token::ADD; 177 case Token::ASSIGN_SHL:
178 case Token::ASSIGN_SUB: return Token::SUB; 178 return Token::SHL;
179 case Token::ASSIGN_MUL: return Token::MUL; 179 case Token::ASSIGN_SAR:
180 case Token::ASSIGN_DIV: return Token::DIV; 180 return Token::SAR;
181 case Token::ASSIGN_MOD: return Token::MOD; 181 case Token::ASSIGN_SHR:
182 default: UNREACHABLE(); 182 return Token::SHR;
183 case Token::ASSIGN_ADD:
184 return Token::ADD;
185 case Token::ASSIGN_SUB:
186 return Token::SUB;
187 case Token::ASSIGN_MUL:
188 return Token::MUL;
189 case Token::ASSIGN_DIV:
190 return Token::DIV;
191 case Token::ASSIGN_MOD:
192 return Token::MOD;
193 default:
194 UNREACHABLE();
183 } 195 }
184 return Token::ILLEGAL; 196 return Token::ILLEGAL;
185 } 197 }
186 198
187 199
188 bool FunctionLiteral::AllowsLazyCompilation() { 200 bool FunctionLiteral::AllowsLazyCompilation() {
189 return scope()->AllowsLazyCompilation(); 201 return scope()->AllowsLazyCompilation();
190 } 202 }
191 203
192 204
193 bool FunctionLiteral::AllowsLazyCompilationWithoutContext() { 205 bool FunctionLiteral::AllowsLazyCompilationWithoutContext() {
194 return scope()->AllowsLazyCompilationWithoutContext(); 206 return scope()->AllowsLazyCompilationWithoutContext();
195 } 207 }
196 208
197 209
198 int FunctionLiteral::start_position() const { 210 int FunctionLiteral::start_position() const {
199 return scope()->start_position(); 211 return scope()->start_position();
200 } 212 }
201 213
202 214
203 int FunctionLiteral::end_position() const { 215 int FunctionLiteral::end_position() const { return scope()->end_position(); }
204 return scope()->end_position();
205 }
206 216
207 217
208 LanguageMode FunctionLiteral::language_mode() const { 218 LanguageMode FunctionLiteral::language_mode() const {
209 return scope()->language_mode(); 219 return scope()->language_mode();
210 } 220 }
211 221
212 222
213 bool FunctionLiteral::NeedsHomeObject(Expression* expr) { 223 bool FunctionLiteral::NeedsHomeObject(Expression* expr) {
214 if (expr == nullptr || !expr->IsFunctionLiteral()) return false; 224 if (expr == nullptr || !expr->IsFunctionLiteral()) return false;
215 DCHECK_NOT_NULL(expr->AsFunctionLiteral()->scope()); 225 DCHECK_NOT_NULL(expr->AsFunctionLiteral()->scope());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 ObjectLiteral::Property* property = properties()->at(i); 274 ObjectLiteral::Property* property = properties()->at(i);
265 Expression* value = property->value(); 275 Expression* value = property->value();
266 if (FunctionLiteral::NeedsHomeObject(value)) { 276 if (FunctionLiteral::NeedsHomeObject(value)) {
267 property->SetSlot(spec->AddStoreICSlot()); 277 property->SetSlot(spec->AddStoreICSlot());
268 } 278 }
269 } 279 }
270 } 280 }
271 281
272 282
273 bool ObjectLiteral::Property::IsCompileTimeValue() { 283 bool ObjectLiteral::Property::IsCompileTimeValue() {
274 return kind_ == CONSTANT || 284 return kind_ == CONSTANT || (kind_ == MATERIALIZED_LITERAL &&
275 (kind_ == MATERIALIZED_LITERAL && 285 CompileTimeValue::IsCompileTimeValue(value_));
276 CompileTimeValue::IsCompileTimeValue(value_));
277 } 286 }
278 287
279 288
280 void ObjectLiteral::Property::set_emit_store(bool emit_store) { 289 void ObjectLiteral::Property::set_emit_store(bool emit_store) {
281 emit_store_ = emit_store; 290 emit_store_ = emit_store;
282 } 291 }
283 292
284 293
285 bool ObjectLiteral::Property::emit_store() { 294 bool ObjectLiteral::Property::emit_store() { return emit_store_; }
286 return emit_store_;
287 }
288 295
289 296
290 void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate, 297 void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
291 FeedbackVectorSpec* spec, 298 FeedbackVectorSpec* spec,
292 FeedbackVectorSlotCache* cache) { 299 FeedbackVectorSlotCache* cache) {
293 // This logic that computes the number of slots needed for vector store 300 // This logic that computes the number of slots needed for vector store
294 // ics must mirror FullCodeGenerator::VisitObjectLiteral. 301 // ics must mirror FullCodeGenerator::VisitObjectLiteral.
295 int property_index = 0; 302 int property_index = 0;
296 for (; property_index < properties()->length(); property_index++) { 303 for (; property_index < properties()->length(); property_index++) {
297 ObjectLiteral::Property* property = properties()->at(property_index); 304 ObjectLiteral::Property* property = properties()->at(property_index);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) { 391 bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) {
385 return property != NULL && 392 return property != NULL &&
386 property->kind() != ObjectLiteral::Property::PROTOTYPE; 393 property->kind() != ObjectLiteral::Property::PROTOTYPE;
387 } 394 }
388 395
389 396
390 void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { 397 void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
391 if (!constant_properties_.is_null()) return; 398 if (!constant_properties_.is_null()) return;
392 399
393 // Allocate a fixed array to hold all the constant properties. 400 // Allocate a fixed array to hold all the constant properties.
394 Handle<FixedArray> constant_properties = isolate->factory()->NewFixedArray( 401 Handle<FixedArray> constant_properties =
395 boilerplate_properties_ * 2, TENURED); 402 isolate->factory()->NewFixedArray(boilerplate_properties_ * 2, TENURED);
396 403
397 int position = 0; 404 int position = 0;
398 // Accumulate the value in local variables and store it at the end. 405 // Accumulate the value in local variables and store it at the end.
399 bool is_simple = true; 406 bool is_simple = true;
400 int depth_acc = 1; 407 int depth_acc = 1;
401 uint32_t max_element_index = 0; 408 uint32_t max_element_index = 0;
402 uint32_t elements = 0; 409 uint32_t elements = 0;
403 for (int i = 0; i < properties()->length(); i++) { 410 for (int i = 0; i < properties()->length(); i++) {
404 ObjectLiteral::Property* property = properties()->at(i); 411 ObjectLiteral::Property* property = properties()->at(i);
405 if (!IsBoilerplateProperty(property)) { 412 if (!IsBoilerplateProperty(property)) {
(...skipping 30 matching lines...) Expand all
436 may_store_doubles_ = true; 443 may_store_doubles_ = true;
437 } 444 }
438 445
439 is_simple = is_simple && !value->IsUninitialized(); 446 is_simple = is_simple && !value->IsUninitialized();
440 447
441 // Keep track of the number of elements in the object literal and 448 // Keep track of the number of elements in the object literal and
442 // the largest element index. If the largest element index is 449 // the largest element index. If the largest element index is
443 // much larger than the number of elements, creating an object 450 // much larger than the number of elements, creating an object
444 // literal with fast elements will be a waste of space. 451 // literal with fast elements will be a waste of space.
445 uint32_t element_index = 0; 452 uint32_t element_index = 0;
446 if (key->IsString() 453 if (key->IsString() &&
447 && Handle<String>::cast(key)->AsArrayIndex(&element_index) 454 Handle<String>::cast(key)->AsArrayIndex(&element_index) &&
448 && element_index > max_element_index) { 455 element_index > max_element_index) {
449 max_element_index = element_index; 456 max_element_index = element_index;
450 elements++; 457 elements++;
451 } else if (key->IsSmi()) { 458 } else if (key->IsSmi()) {
452 int key_value = Smi::cast(*key)->value(); 459 int key_value = Smi::cast(*key)->value();
453 if (key_value > 0 460 if (key_value > 0 &&
454 && static_cast<uint32_t>(key_value) > max_element_index) { 461 static_cast<uint32_t>(key_value) > max_element_index) {
455 max_element_index = key_value; 462 max_element_index = key_value;
456 } 463 }
457 elements++; 464 elements++;
458 } 465 }
459 466
460 // Add name, value pair to the fixed array. 467 // Add name, value pair to the fixed array.
461 constant_properties->set(position++, *key); 468 constant_properties->set(position++, *key);
462 constant_properties->set(position++, *value); 469 constant_properties->set(position++, *value);
463 } 470 }
464 471
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 } 611 }
605 612
606 613
607 static bool IsTypeof(Expression* expr) { 614 static bool IsTypeof(Expression* expr) {
608 UnaryOperation* maybe_unary = expr->AsUnaryOperation(); 615 UnaryOperation* maybe_unary = expr->AsUnaryOperation();
609 return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF; 616 return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF;
610 } 617 }
611 618
612 619
613 // Check for the pattern: typeof <expression> equals <string literal>. 620 // Check for the pattern: typeof <expression> equals <string literal>.
614 static bool MatchLiteralCompareTypeof(Expression* left, 621 static bool MatchLiteralCompareTypeof(Expression* left, Token::Value op,
615 Token::Value op, 622 Expression* right, Expression** expr,
616 Expression* right,
617 Expression** expr,
618 Handle<String>* check) { 623 Handle<String>* check) {
619 if (IsTypeof(left) && right->IsStringLiteral() && Token::IsEqualityOp(op)) { 624 if (IsTypeof(left) && right->IsStringLiteral() && Token::IsEqualityOp(op)) {
620 *expr = left->AsUnaryOperation()->expression(); 625 *expr = left->AsUnaryOperation()->expression();
621 *check = Handle<String>::cast(right->AsLiteral()->value()); 626 *check = Handle<String>::cast(right->AsLiteral()->value());
622 return true; 627 return true;
623 } 628 }
624 return false; 629 return false;
625 } 630 }
626 631
627 632
628 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr, 633 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr,
629 Handle<String>* check) { 634 Handle<String>* check) {
630 return MatchLiteralCompareTypeof(left_, op_, right_, expr, check) || 635 return MatchLiteralCompareTypeof(left_, op_, right_, expr, check) ||
631 MatchLiteralCompareTypeof(right_, op_, left_, expr, check); 636 MatchLiteralCompareTypeof(right_, op_, left_, expr, check);
632 } 637 }
633 638
634 639
635 static bool IsVoidOfLiteral(Expression* expr) { 640 static bool IsVoidOfLiteral(Expression* expr) {
636 UnaryOperation* maybe_unary = expr->AsUnaryOperation(); 641 UnaryOperation* maybe_unary = expr->AsUnaryOperation();
637 return maybe_unary != NULL && 642 return maybe_unary != NULL && maybe_unary->op() == Token::VOID &&
638 maybe_unary->op() == Token::VOID && 643 maybe_unary->expression()->IsLiteral();
639 maybe_unary->expression()->IsLiteral();
640 } 644 }
641 645
642 646
643 // Check for the pattern: void <literal> equals <expression> or 647 // Check for the pattern: void <literal> equals <expression> or
644 // undefined equals <expression> 648 // undefined equals <expression>
645 static bool MatchLiteralCompareUndefined(Expression* left, 649 static bool MatchLiteralCompareUndefined(Expression* left, Token::Value op,
646 Token::Value op, 650 Expression* right, Expression** expr,
647 Expression* right,
648 Expression** expr,
649 Isolate* isolate) { 651 Isolate* isolate) {
650 if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) { 652 if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) {
651 *expr = right; 653 *expr = right;
652 return true; 654 return true;
653 } 655 }
654 if (left->IsUndefinedLiteral(isolate) && Token::IsEqualityOp(op)) { 656 if (left->IsUndefinedLiteral(isolate) && Token::IsEqualityOp(op)) {
655 *expr = right; 657 *expr = right;
656 return true; 658 return true;
657 } 659 }
658 return false; 660 return false;
659 } 661 }
660 662
661 663
662 bool CompareOperation::IsLiteralCompareUndefined( 664 bool CompareOperation::IsLiteralCompareUndefined(Expression** expr,
663 Expression** expr, Isolate* isolate) { 665 Isolate* isolate) {
664 return MatchLiteralCompareUndefined(left_, op_, right_, expr, isolate) || 666 return MatchLiteralCompareUndefined(left_, op_, right_, expr, isolate) ||
665 MatchLiteralCompareUndefined(right_, op_, left_, expr, isolate); 667 MatchLiteralCompareUndefined(right_, op_, left_, expr, isolate);
666 } 668 }
667 669
668 670
669 // Check for the pattern: null equals <expression> 671 // Check for the pattern: null equals <expression>
670 static bool MatchLiteralCompareNull(Expression* left, 672 static bool MatchLiteralCompareNull(Expression* left, Token::Value op,
671 Token::Value op, 673 Expression* right, Expression** expr) {
672 Expression* right,
673 Expression** expr) {
674 if (left->IsNullLiteral() && Token::IsEqualityOp(op)) { 674 if (left->IsNullLiteral() && Token::IsEqualityOp(op)) {
675 *expr = right; 675 *expr = right;
676 return true; 676 return true;
677 } 677 }
678 return false; 678 return false;
679 } 679 }
680 680
681 681
682 bool CompareOperation::IsLiteralCompareNull(Expression** expr) { 682 bool CompareOperation::IsLiteralCompareNull(Expression** expr) {
683 return MatchLiteralCompareNull(left_, op_, right_, expr) || 683 return MatchLiteralCompareNull(left_, op_, right_, expr) ||
684 MatchLiteralCompareNull(right_, op_, left_, expr); 684 MatchLiteralCompareNull(right_, op_, left_, expr);
685 } 685 }
686 686
687 687
688 // ---------------------------------------------------------------------------- 688 // ----------------------------------------------------------------------------
689 // Inlining support 689 // Inlining support
690 690
691 bool Declaration::IsInlineable() const { 691 bool Declaration::IsInlineable() const {
692 return proxy()->var()->IsStackAllocated(); 692 return proxy()->var()->IsStackAllocated();
693 } 693 }
694 694
695 bool FunctionDeclaration::IsInlineable() const { 695 bool FunctionDeclaration::IsInlineable() const { return false; }
696 return false;
697 }
698 696
699 697
700 // ---------------------------------------------------------------------------- 698 // ----------------------------------------------------------------------------
701 // Recording of type feedback 699 // Recording of type feedback
702 700
703 // TODO(rossberg): all RecordTypeFeedback functions should disappear 701 // TODO(rossberg): all RecordTypeFeedback functions should disappear
704 // once we use the common type field in the AST consistently. 702 // once we use the common type field in the AST consistently.
705 703
706 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { 704 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
707 set_to_boolean_types(oracle->ToBooleanTypes(test_id())); 705 set_to_boolean_types(oracle->ToBooleanTypes(test_id()));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 // changes 788 // changes
791 Expression* expression = expressions->at(i); 789 Expression* expression = expressions->at(i);
792 if (expression != NULL) Visit(expression); 790 if (expression != NULL) Visit(expression);
793 } 791 }
794 } 792 }
795 793
796 794
797 // ---------------------------------------------------------------------------- 795 // ----------------------------------------------------------------------------
798 // Regular expressions 796 // Regular expressions
799 797
800 #define MAKE_ACCEPT(Name) \ 798 #define MAKE_ACCEPT(Name) \
801 void* RegExp##Name::Accept(RegExpVisitor* visitor, void* data) { \ 799 void* RegExp##Name::Accept(RegExpVisitor* visitor, void* data) { \
802 return visitor->Visit##Name(this, data); \ 800 return visitor->Visit##Name(this, data); \
803 } 801 }
804 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ACCEPT) 802 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ACCEPT)
805 #undef MAKE_ACCEPT 803 #undef MAKE_ACCEPT
806 804
807 #define MAKE_TYPE_CASE(Name) \ 805 #define MAKE_TYPE_CASE(Name) \
808 RegExp##Name* RegExpTree::As##Name() { \ 806 RegExp##Name* RegExpTree::As##Name() { return NULL; } \
809 return NULL; \
810 } \
811 bool RegExpTree::Is##Name() { return false; } 807 bool RegExpTree::Is##Name() { return false; }
812 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE) 808 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
813 #undef MAKE_TYPE_CASE 809 #undef MAKE_TYPE_CASE
814 810
815 #define MAKE_TYPE_CASE(Name) \ 811 #define MAKE_TYPE_CASE(Name) \
816 RegExp##Name* RegExp##Name::As##Name() { \ 812 RegExp##Name* RegExp##Name::As##Name() { return this; } \
817 return this; \
818 } \
819 bool RegExp##Name::Is##Name() { return true; } 813 bool RegExp##Name::Is##Name() { return true; }
820 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE) 814 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
821 #undef MAKE_TYPE_CASE 815 #undef MAKE_TYPE_CASE
822 816
823 817
824 static Interval ListCaptureRegisters(ZoneList<RegExpTree*>* children) { 818 static Interval ListCaptureRegisters(ZoneList<RegExpTree*>* children) {
825 Interval result = Interval::Empty(); 819 Interval result = Interval::Empty();
826 for (int i = 0; i < children->length(); i++) 820 for (int i = 0; i < children->length(); i++)
827 result = result.Union(children->at(i)->CaptureRegisters()); 821 result = result.Union(children->at(i)->CaptureRegisters());
828 return result; 822 return result;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 856
863 bool RegExpAssertion::IsAnchoredAtEnd() { 857 bool RegExpAssertion::IsAnchoredAtEnd() {
864 return assertion_type() == RegExpAssertion::END_OF_INPUT; 858 return assertion_type() == RegExpAssertion::END_OF_INPUT;
865 } 859 }
866 860
867 861
868 bool RegExpAlternative::IsAnchoredAtStart() { 862 bool RegExpAlternative::IsAnchoredAtStart() {
869 ZoneList<RegExpTree*>* nodes = this->nodes(); 863 ZoneList<RegExpTree*>* nodes = this->nodes();
870 for (int i = 0; i < nodes->length(); i++) { 864 for (int i = 0; i < nodes->length(); i++) {
871 RegExpTree* node = nodes->at(i); 865 RegExpTree* node = nodes->at(i);
872 if (node->IsAnchoredAtStart()) { return true; } 866 if (node->IsAnchoredAtStart()) {
873 if (node->max_match() > 0) { return false; } 867 return true;
868 }
869 if (node->max_match() > 0) {
870 return false;
871 }
874 } 872 }
875 return false; 873 return false;
876 } 874 }
877 875
878 876
879 bool RegExpAlternative::IsAnchoredAtEnd() { 877 bool RegExpAlternative::IsAnchoredAtEnd() {
880 ZoneList<RegExpTree*>* nodes = this->nodes(); 878 ZoneList<RegExpTree*>* nodes = this->nodes();
881 for (int i = nodes->length() - 1; i >= 0; i--) { 879 for (int i = nodes->length() - 1; i >= 0; i--) {
882 RegExpTree* node = nodes->at(i); 880 RegExpTree* node = nodes->at(i);
883 if (node->IsAnchoredAtEnd()) { return true; } 881 if (node->IsAnchoredAtEnd()) {
884 if (node->max_match() > 0) { return false; } 882 return true;
883 }
884 if (node->max_match() > 0) {
885 return false;
886 }
885 } 887 }
886 return false; 888 return false;
887 } 889 }
888 890
889 891
890 bool RegExpDisjunction::IsAnchoredAtStart() { 892 bool RegExpDisjunction::IsAnchoredAtStart() {
891 ZoneList<RegExpTree*>* alternatives = this->alternatives(); 893 ZoneList<RegExpTree*>* alternatives = this->alternatives();
892 for (int i = 0; i < alternatives->length(); i++) { 894 for (int i = 0; i < alternatives->length(); i++) {
893 if (!alternatives->at(i)->IsAnchoredAtStart()) 895 if (!alternatives->at(i)->IsAnchoredAtStart()) return false;
894 return false;
895 } 896 }
896 return true; 897 return true;
897 } 898 }
898 899
899 900
900 bool RegExpDisjunction::IsAnchoredAtEnd() { 901 bool RegExpDisjunction::IsAnchoredAtEnd() {
901 ZoneList<RegExpTree*>* alternatives = this->alternatives(); 902 ZoneList<RegExpTree*>* alternatives = this->alternatives();
902 for (int i = 0; i < alternatives->length(); i++) { 903 for (int i = 0; i < alternatives->length(); i++) {
903 if (!alternatives->at(i)->IsAnchoredAtEnd()) 904 if (!alternatives->at(i)->IsAnchoredAtEnd()) return false;
904 return false;
905 } 905 }
906 return true; 906 return true;
907 } 907 }
908 908
909 909
910 bool RegExpLookaround::IsAnchoredAtStart() { 910 bool RegExpLookaround::IsAnchoredAtStart() {
911 return is_positive() && type() == LOOKAHEAD && body()->IsAnchoredAtStart(); 911 return is_positive() && type() == LOOKAHEAD && body()->IsAnchoredAtStart();
912 } 912 }
913 913
914 914
915 bool RegExpCapture::IsAnchoredAtStart() { 915 bool RegExpCapture::IsAnchoredAtStart() { return body()->IsAnchoredAtStart(); }
916 return body()->IsAnchoredAtStart();
917 }
918 916
919 917
920 bool RegExpCapture::IsAnchoredAtEnd() { 918 bool RegExpCapture::IsAnchoredAtEnd() { return body()->IsAnchoredAtEnd(); }
921 return body()->IsAnchoredAtEnd();
922 }
923 919
924 920
925 // Convert regular expression trees to a simple sexp representation. 921 // Convert regular expression trees to a simple sexp representation.
926 // This representation should be different from the input grammar 922 // This representation should be different from the input grammar
927 // in as many cases as possible, to make it more difficult for incorrect 923 // in as many cases as possible, to make it more difficult for incorrect
928 // parses to look as correct ones which is likely if the input and 924 // parses to look as correct ones which is likely if the input and
929 // output formats are alike. 925 // output formats are alike.
930 class RegExpUnparser final : public RegExpVisitor { 926 class RegExpUnparser final : public RegExpVisitor {
931 public: 927 public:
932 RegExpUnparser(std::ostream& os, Zone* zone) : os_(os), zone_(zone) {} 928 RegExpUnparser(std::ostream& os, Zone* zone) : os_(os), zone_(zone) {}
933 void VisitCharacterRange(CharacterRange that); 929 void VisitCharacterRange(CharacterRange that);
934 #define MAKE_CASE(Name) void* Visit##Name(RegExp##Name*, void* data) override; 930 #define MAKE_CASE(Name) void* Visit##Name(RegExp##Name*, void* data) override;
935 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) 931 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
936 #undef MAKE_CASE 932 #undef MAKE_CASE
937 private: 933 private:
938 std::ostream& os_; 934 std::ostream& os_;
939 Zone* zone_; 935 Zone* zone_;
940 }; 936 };
941 937
942 938
943 void* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) { 939 void* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) {
944 os_ << "(|"; 940 os_ << "(|";
945 for (int i = 0; i < that->alternatives()->length(); i++) { 941 for (int i = 0; i < that->alternatives()->length(); i++) {
946 os_ << " "; 942 os_ << " ";
947 that->alternatives()->at(i)->Accept(this, data); 943 that->alternatives()->at(i)->Accept(this, data);
948 } 944 }
949 os_ << ")"; 945 os_ << ")";
950 return NULL; 946 return NULL;
951 } 947 }
952 948
953 949
954 void* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) { 950 void* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) {
955 os_ << "(:"; 951 os_ << "(:";
956 for (int i = 0; i < that->nodes()->length(); i++) { 952 for (int i = 0; i < that->nodes()->length(); i++) {
957 os_ << " "; 953 os_ << " ";
958 that->nodes()->at(i)->Accept(this, data); 954 that->nodes()->at(i)->Accept(this, data);
959 } 955 }
960 os_ << ")"; 956 os_ << ")";
961 return NULL; 957 return NULL;
962 } 958 }
963 959
964 960
965 void RegExpUnparser::VisitCharacterRange(CharacterRange that) { 961 void RegExpUnparser::VisitCharacterRange(CharacterRange that) {
966 os_ << AsUC16(that.from()); 962 os_ << AsUC16(that.from());
967 if (!that.IsSingleton()) { 963 if (!that.IsSingleton()) {
968 os_ << "-" << AsUC16(that.to()); 964 os_ << "-" << AsUC16(that.to());
969 } 965 }
970 } 966 }
971 967
972 968
973
974 void* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that, 969 void* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that,
975 void* data) { 970 void* data) {
976 if (that->is_negated()) os_ << "^"; 971 if (that->is_negated()) os_ << "^";
977 os_ << "["; 972 os_ << "[";
978 for (int i = 0; i < that->ranges(zone_)->length(); i++) { 973 for (int i = 0; i < that->ranges(zone_)->length(); i++) {
979 if (i > 0) os_ << " "; 974 if (i > 0) os_ << " ";
980 VisitCharacterRange(that->ranges(zone_)->at(i)); 975 VisitCharacterRange(that->ranges(zone_)->at(i));
981 } 976 }
982 os_ << "]"; 977 os_ << "]";
983 return NULL; 978 return NULL;
984 } 979 }
985 980
986 981
987 void* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) { 982 void* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) {
988 switch (that->assertion_type()) { 983 switch (that->assertion_type()) {
989 case RegExpAssertion::START_OF_INPUT: 984 case RegExpAssertion::START_OF_INPUT:
990 os_ << "@^i"; 985 os_ << "@^i";
991 break; 986 break;
992 case RegExpAssertion::END_OF_INPUT: 987 case RegExpAssertion::END_OF_INPUT:
993 os_ << "@$i"; 988 os_ << "@$i";
994 break; 989 break;
995 case RegExpAssertion::START_OF_LINE: 990 case RegExpAssertion::START_OF_LINE:
996 os_ << "@^l"; 991 os_ << "@^l";
997 break; 992 break;
998 case RegExpAssertion::END_OF_LINE: 993 case RegExpAssertion::END_OF_LINE:
999 os_ << "@$l"; 994 os_ << "@$l";
1000 break; 995 break;
1001 case RegExpAssertion::BOUNDARY: 996 case RegExpAssertion::BOUNDARY:
1002 os_ << "@b"; 997 os_ << "@b";
1003 break; 998 break;
1004 case RegExpAssertion::NON_BOUNDARY: 999 case RegExpAssertion::NON_BOUNDARY:
1005 os_ << "@B"; 1000 os_ << "@B";
1006 break; 1001 break;
1007 } 1002 }
1008 return NULL; 1003 return NULL;
1009 } 1004 }
1010 1005
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 bool Literal::Match(void* literal1, void* literal2) { 1138 bool Literal::Match(void* literal1, void* literal2) {
1144 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); 1139 const AstValue* x = static_cast<Literal*>(literal1)->raw_value();
1145 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); 1140 const AstValue* y = static_cast<Literal*>(literal2)->raw_value();
1146 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || 1141 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) ||
1147 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); 1142 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber());
1148 } 1143 }
1149 1144
1150 1145
1151 } // namespace internal 1146 } // namespace internal
1152 } // namespace v8 1147 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/ast.h ('k') | src/ast/ast-value-factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698