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

Side by Side Diff: runtime/vm/parser.cc

Issue 24975002: - Implement a first cut for const String.env in the VM to allow (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/isolate.cc ('k') | sdk/lib/core/bool.dart » ('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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/bigint_operations.h" 8 #include "vm/bigint_operations.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 3083 matching lines...) Expand 10 before | Expand all | Expand 10 after
3094 if ((CurrentToken() == Token::kLBRACE) || 3094 if ((CurrentToken() == Token::kLBRACE) ||
3095 (CurrentToken() == Token::kARROW)) { 3095 (CurrentToken() == Token::kARROW)) {
3096 if (method->has_abstract) { 3096 if (method->has_abstract) {
3097 ErrorMsg(method->name_pos, 3097 ErrorMsg(method->name_pos,
3098 "abstract method '%s' may not have a function body", 3098 "abstract method '%s' may not have a function body",
3099 method->name->ToCString()); 3099 method->name->ToCString());
3100 } else if (method->has_external) { 3100 } else if (method->has_external) {
3101 ErrorMsg(method->name_pos, 3101 ErrorMsg(method->name_pos,
3102 "external method '%s' may not have a function body", 3102 "external method '%s' may not have a function body",
3103 method->name->ToCString()); 3103 method->name->ToCString());
3104 } else if (method->IsFactoryOrConstructor() && method->has_const) { 3104 } else if (method->IsConstructor() && method->has_const) {
3105 ErrorMsg(method->name_pos, 3105 ErrorMsg(method->name_pos,
3106 "const constructor or factory '%s' may not have a function body", 3106 "const constructor '%s' may not have a function body",
3107 method->name->ToCString());
3108 } else if (method->IsFactory() && method->has_const) {
3109 ErrorMsg(method->name_pos,
3110 "const factory '%s' may not have a function body",
3107 method->name->ToCString()); 3111 method->name->ToCString());
3108 } 3112 }
3109 if (method->redirect_name != NULL) { 3113 if (method->redirect_name != NULL) {
3110 ErrorMsg(method->name_pos, 3114 ErrorMsg(method->name_pos,
3111 "Constructor with redirection may not have a function body"); 3115 "Constructor with redirection may not have a function body");
3112 } 3116 }
3113 if (CurrentToken() == Token::kLBRACE) { 3117 if (CurrentToken() == Token::kLBRACE) {
3114 SkipBlock(); 3118 SkipBlock();
3115 method_end_pos = TokenPos(); 3119 method_end_pos = TokenPos();
3116 ExpectToken(Token::kRBRACE); 3120 ExpectToken(Token::kRBRACE);
3117 } else { 3121 } else {
3118 ConsumeToken(); 3122 ConsumeToken();
3119 SkipExpr(); 3123 SkipExpr();
3120 method_end_pos = TokenPos(); 3124 method_end_pos = TokenPos();
3121 ExpectSemicolon(); 3125 ExpectSemicolon();
3122 } 3126 }
3123 } else if (IsLiteral("native")) { 3127 } else if (IsLiteral("native")) {
3124 if (method->has_abstract) { 3128 if (method->has_abstract) {
3125 ErrorMsg(method->name_pos, 3129 ErrorMsg(method->name_pos,
3126 "abstract method '%s' may not have a function body", 3130 "abstract method '%s' may not have a function body",
3127 method->name->ToCString()); 3131 method->name->ToCString());
3128 } else if (method->IsFactoryOrConstructor() && method->has_const) { 3132 } else if (method->IsConstructor() && method->has_const) {
3129 ErrorMsg(method->name_pos, 3133 ErrorMsg(method->name_pos,
3130 "const constructor or factory '%s' may not be native", 3134 "const constructor '%s' may not be native",
3131 method->name->ToCString()); 3135 method->name->ToCString());
3132 } 3136 }
3133 if (method->redirect_name != NULL) { 3137 if (method->redirect_name != NULL) {
3134 ErrorMsg(method->name_pos, 3138 ErrorMsg(method->name_pos,
3135 "Constructor with redirection may not have a function body"); 3139 "Constructor with redirection may not have a function body");
3136 } 3140 }
3137 ParseNativeDeclaration(); 3141 ParseNativeDeclaration();
3138 method_end_pos = TokenPos(); 3142 method_end_pos = TokenPos();
3139 ExpectSemicolon(); 3143 ExpectSemicolon();
3140 } else { 3144 } else {
(...skipping 5560 matching lines...) Expand 10 before | Expand all | Expand 10 after
8701 ASSERT(getter.kind() == RawFunction::kImplicitGetter); 8705 ASSERT(getter.kind() == RawFunction::kImplicitGetter);
8702 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name); 8706 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name);
8703 } 8707 }
8704 8708
8705 8709
8706 RawObject* Parser::EvaluateConstConstructorCall( 8710 RawObject* Parser::EvaluateConstConstructorCall(
8707 const Class& type_class, 8711 const Class& type_class,
8708 const AbstractTypeArguments& type_arguments, 8712 const AbstractTypeArguments& type_arguments,
8709 const Function& constructor, 8713 const Function& constructor,
8710 ArgumentListNode* arguments) { 8714 ArgumentListNode* arguments) {
8711 const int kNumExtraArgs = 2; // implicit rcvr and construction phase args. 8715 // Factories have one extra argument: the type arguments.
8716 // Constructors have 2 extra arguments: rcvr and construction phase.
8717 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2;
8712 const int num_arguments = arguments->length() + kNumExtraArgs; 8718 const int num_arguments = arguments->length() + kNumExtraArgs;
8713 const Array& arg_values = Array::Handle(Array::New(num_arguments)); 8719 const Array& arg_values = Array::Handle(Array::New(num_arguments));
8714 Instance& instance = Instance::Handle(); 8720 Instance& instance = Instance::Handle();
8715 ASSERT(!constructor.IsFactory()); 8721 if (!constructor.IsFactory()) {
8716 instance = Instance::New(type_class, Heap::kOld); 8722 instance = Instance::New(type_class, Heap::kOld);
8717 if (!type_arguments.IsNull()) { 8723 if (!type_arguments.IsNull()) {
8718 if (!type_arguments.IsInstantiated()) { 8724 if (!type_arguments.IsInstantiated()) {
8719 ErrorMsg("type must be constant in const constructor"); 8725 ErrorMsg("type must be constant in const constructor");
8726 }
8727 instance.SetTypeArguments(
8728 AbstractTypeArguments::Handle(type_arguments.Canonicalize()));
8720 } 8729 }
8721 instance.SetTypeArguments( 8730 arg_values.SetAt(0, instance);
8722 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); 8731 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
8732 } else {
8733 // Prepend type_arguments to list of arguments to factory.
8734 ASSERT(type_arguments.IsZoneHandle());
8735 arg_values.SetAt(0, type_arguments);
8723 } 8736 }
8724 arg_values.SetAt(0, instance);
8725 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
8726 for (int i = 0; i < arguments->length(); i++) { 8737 for (int i = 0; i < arguments->length(); i++) {
8727 AstNode* arg = arguments->NodeAt(i); 8738 AstNode* arg = arguments->NodeAt(i);
8728 // Arguments have been evaluated to a literal value already. 8739 // Arguments have been evaluated to a literal value already.
8729 ASSERT(arg->IsLiteralNode()); 8740 ASSERT(arg->IsLiteralNode());
8730 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); 8741 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal());
8731 } 8742 }
8732 const Array& args_descriptor = 8743 const Array& args_descriptor =
8733 Array::Handle(ArgumentsDescriptor::New(num_arguments, 8744 Array::Handle(ArgumentsDescriptor::New(num_arguments,
8734 arguments->names())); 8745 arguments->names()));
8735 const Object& result = 8746 const Object& result =
8736 Object::Handle(DartEntry::InvokeFunction(constructor, 8747 Object::Handle(DartEntry::InvokeFunction(constructor,
8737 arg_values, 8748 arg_values,
8738 args_descriptor)); 8749 args_descriptor));
8739 if (result.IsError()) { 8750 if (result.IsError()) {
8740 // An exception may not occur in every parse attempt, i.e., the 8751 // An exception may not occur in every parse attempt, i.e., the
8741 // generated AST is not deterministic. Therefore mark the function as 8752 // generated AST is not deterministic. Therefore mark the function as
8742 // not optimizable. 8753 // not optimizable.
8743 current_function().set_is_optimizable(false); 8754 current_function().set_is_optimizable(false);
8744 if (result.IsUnhandledException()) { 8755 if (result.IsUnhandledException()) {
8745 return result.raw(); 8756 return result.raw();
8746 } else { 8757 } else {
8747 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); 8758 isolate()->long_jump_base()->Jump(1, Error::Cast(result));
8748 UNREACHABLE(); 8759 UNREACHABLE();
8749 return Object::null(); 8760 return Object::null();
8750 } 8761 }
8751 } else { 8762 } else {
8763 if (constructor.IsFactory()) {
8764 // The factory method returns the allocated object.
8765 instance ^= result.raw();
8766 }
8752 return TryCanonicalize(instance, TokenPos()); 8767 return TryCanonicalize(instance, TokenPos());
8753 } 8768 }
8754 } 8769 }
8755 8770
8756 8771
8757 // Do a lookup for the identifier in the block scope and the class scope 8772 // Do a lookup for the identifier in the block scope and the class scope
8758 // return true if the identifier is found, false otherwise. 8773 // return true if the identifier is found, false otherwise.
8759 // If node is non NULL return an AST node corresponding to the identifier. 8774 // If node is non NULL return an AST node corresponding to the identifier.
8760 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, 8775 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
8761 const String &ident, 8776 const String &ident,
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after
9878 external_constructor_name.ToCString()); 9893 external_constructor_name.ToCString());
9879 } 9894 }
9880 const Object& constructor_result = Object::Handle( 9895 const Object& constructor_result = Object::Handle(
9881 EvaluateConstConstructorCall(type_class, 9896 EvaluateConstConstructorCall(type_class,
9882 type_arguments, 9897 type_arguments,
9883 constructor, 9898 constructor,
9884 arguments)); 9899 arguments));
9885 if (constructor_result.IsUnhandledException()) { 9900 if (constructor_result.IsUnhandledException()) {
9886 new_object = GenerateRethrow(new_pos, constructor_result); 9901 new_object = GenerateRethrow(new_pos, constructor_result);
9887 } else { 9902 } else {
9888 const Instance& const_instance = Instance::Cast(constructor_result); 9903 // Const constructors can return null in the case where a const native
9904 // factory returns a null value. Thus we cannot use a Instance::Cast here.
9905 Instance& const_instance = Instance::Handle();
9906 const_instance ^= constructor_result.raw();
9889 new_object = new LiteralNode(new_pos, 9907 new_object = new LiteralNode(new_pos,
9890 Instance::ZoneHandle(const_instance.raw())); 9908 Instance::ZoneHandle(const_instance.raw()));
9891 if (!type_bound.IsNull()) { 9909 if (!type_bound.IsNull()) {
9892 ASSERT(!type_bound.IsMalformed()); 9910 ASSERT(!type_bound.IsMalformed());
9893 Error& malformed_error = Error::Handle(); 9911 Error& malformed_error = Error::Handle();
9894 ASSERT(!is_top_level_); // We cannot check unresolved types. 9912 ASSERT(!is_top_level_); // We cannot check unresolved types.
9895 if (!const_instance.IsInstanceOf(type_bound, 9913 if (!const_instance.IsInstanceOf(type_bound,
9896 TypeArguments::Handle(), 9914 TypeArguments::Handle(),
9897 &malformed_error)) { 9915 &malformed_error)) {
9898 type_bound = ClassFinalizer::NewFinalizedMalformedType( 9916 type_bound = ClassFinalizer::NewFinalizedMalformedType(
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
10554 void Parser::SkipQualIdent() { 10572 void Parser::SkipQualIdent() {
10555 ASSERT(IsIdentifier()); 10573 ASSERT(IsIdentifier());
10556 ConsumeToken(); 10574 ConsumeToken();
10557 if (CurrentToken() == Token::kPERIOD) { 10575 if (CurrentToken() == Token::kPERIOD) {
10558 ConsumeToken(); // Consume the kPERIOD token. 10576 ConsumeToken(); // Consume the kPERIOD token.
10559 ExpectIdentifier("identifier expected after '.'"); 10577 ExpectIdentifier("identifier expected after '.'");
10560 } 10578 }
10561 } 10579 }
10562 10580
10563 } // namespace dart 10581 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate.cc ('k') | sdk/lib/core/bool.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698