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

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, 2 months 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
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 3167 matching lines...) Expand 10 before | Expand all | Expand 10 after
3178 if ((CurrentToken() == Token::kLBRACE) || 3178 if ((CurrentToken() == Token::kLBRACE) ||
3179 (CurrentToken() == Token::kARROW)) { 3179 (CurrentToken() == Token::kARROW)) {
3180 if (method->has_abstract) { 3180 if (method->has_abstract) {
3181 ErrorMsg(method->name_pos, 3181 ErrorMsg(method->name_pos,
3182 "abstract method '%s' may not have a function body", 3182 "abstract method '%s' may not have a function body",
3183 method->name->ToCString()); 3183 method->name->ToCString());
3184 } else if (method->has_external) { 3184 } else if (method->has_external) {
3185 ErrorMsg(method->name_pos, 3185 ErrorMsg(method->name_pos,
3186 "external method '%s' may not have a function body", 3186 "external method '%s' may not have a function body",
3187 method->name->ToCString()); 3187 method->name->ToCString());
3188 } else if (method->IsFactoryOrConstructor() && method->has_const) { 3188 } else if (method->IsConstructor() && method->has_const) {
3189 ErrorMsg(method->name_pos, 3189 ErrorMsg(method->name_pos,
3190 "const constructor or factory '%s' may not have a function body", 3190 "const constructor '%s' may not have a function body",
3191 method->name->ToCString());
3192 } else if (method->IsFactory() && method->has_const) {
3193 ErrorMsg(method->name_pos,
3194 "const factory '%s' may not have a function body",
3191 method->name->ToCString()); 3195 method->name->ToCString());
3192 } 3196 }
3193 if (method->redirect_name != NULL) { 3197 if (method->redirect_name != NULL) {
3194 ErrorMsg(method->name_pos, 3198 ErrorMsg(method->name_pos,
3195 "Constructor with redirection may not have a function body"); 3199 "Constructor with redirection may not have a function body");
3196 } 3200 }
3197 if (CurrentToken() == Token::kLBRACE) { 3201 if (CurrentToken() == Token::kLBRACE) {
3198 SkipBlock(); 3202 SkipBlock();
3199 method_end_pos = TokenPos(); 3203 method_end_pos = TokenPos();
3200 ExpectToken(Token::kRBRACE); 3204 ExpectToken(Token::kRBRACE);
3201 } else { 3205 } else {
3202 ConsumeToken(); 3206 ConsumeToken();
3203 SkipExpr(); 3207 SkipExpr();
3204 method_end_pos = TokenPos(); 3208 method_end_pos = TokenPos();
3205 ExpectSemicolon(); 3209 ExpectSemicolon();
3206 } 3210 }
3207 } else if (IsLiteral("native")) { 3211 } else if (IsLiteral("native")) {
3208 if (method->has_abstract) { 3212 if (method->has_abstract) {
3209 ErrorMsg(method->name_pos, 3213 ErrorMsg(method->name_pos,
3210 "abstract method '%s' may not have a function body", 3214 "abstract method '%s' may not have a function body",
3211 method->name->ToCString()); 3215 method->name->ToCString());
3212 } else if (method->IsFactoryOrConstructor() && method->has_const) { 3216 } else if (method->IsConstructor() && method->has_const) {
3213 ErrorMsg(method->name_pos, 3217 ErrorMsg(method->name_pos,
3214 "const constructor or factory '%s' may not be native", 3218 "const constructor '%s' may not be native",
3215 method->name->ToCString()); 3219 method->name->ToCString());
3216 } 3220 }
3217 if (method->redirect_name != NULL) { 3221 if (method->redirect_name != NULL) {
3218 ErrorMsg(method->name_pos, 3222 ErrorMsg(method->name_pos,
3219 "Constructor with redirection may not have a function body"); 3223 "Constructor with redirection may not have a function body");
3220 } 3224 }
3221 ParseNativeDeclaration(); 3225 ParseNativeDeclaration();
3222 method_end_pos = TokenPos(); 3226 method_end_pos = TokenPos();
3223 ExpectSemicolon(); 3227 ExpectSemicolon();
3224 } else { 3228 } else {
(...skipping 5539 matching lines...) Expand 10 before | Expand all | Expand 10 after
8764 ASSERT(getter.kind() == RawFunction::kImplicitGetter); 8768 ASSERT(getter.kind() == RawFunction::kImplicitGetter);
8765 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name); 8769 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name);
8766 } 8770 }
8767 8771
8768 8772
8769 RawObject* Parser::EvaluateConstConstructorCall( 8773 RawObject* Parser::EvaluateConstConstructorCall(
8770 const Class& type_class, 8774 const Class& type_class,
8771 const AbstractTypeArguments& type_arguments, 8775 const AbstractTypeArguments& type_arguments,
8772 const Function& constructor, 8776 const Function& constructor,
8773 ArgumentListNode* arguments) { 8777 ArgumentListNode* arguments) {
8774 const int kNumExtraArgs = 2; // implicit rcvr and construction phase args. 8778 // Factories have one extra argument: the type arguments.
8779 // Constructors have 2 extra arguments: rcvr and construction phase.
8780 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2;
8775 const int num_arguments = arguments->length() + kNumExtraArgs; 8781 const int num_arguments = arguments->length() + kNumExtraArgs;
8776 const Array& arg_values = Array::Handle(Array::New(num_arguments)); 8782 const Array& arg_values = Array::Handle(Array::New(num_arguments));
8777 Instance& instance = Instance::Handle(); 8783 Instance& instance = Instance::Handle();
8778 ASSERT(!constructor.IsFactory()); 8784 if (!constructor.IsFactory()) {
8779 instance = Instance::New(type_class, Heap::kOld); 8785 instance = Instance::New(type_class, Heap::kOld);
8780 if (!type_arguments.IsNull()) { 8786 if (!type_arguments.IsNull()) {
8781 if (!type_arguments.IsInstantiated()) { 8787 if (!type_arguments.IsInstantiated()) {
8782 ErrorMsg("type must be constant in const constructor"); 8788 ErrorMsg("type must be constant in const constructor");
8789 }
8790 instance.SetTypeArguments(
8791 AbstractTypeArguments::Handle(type_arguments.Canonicalize()));
8783 } 8792 }
8784 instance.SetTypeArguments( 8793 arg_values.SetAt(0, instance);
8785 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); 8794 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
8795 } else {
8796 // Prepend type_arguments to list of arguments to factory.
8797 ASSERT(type_arguments.IsZoneHandle());
8798 arg_values.SetAt(0, type_arguments);
8786 } 8799 }
8787 arg_values.SetAt(0, instance);
8788 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
8789 for (int i = 0; i < arguments->length(); i++) { 8800 for (int i = 0; i < arguments->length(); i++) {
8790 AstNode* arg = arguments->NodeAt(i); 8801 AstNode* arg = arguments->NodeAt(i);
8791 // Arguments have been evaluated to a literal value already. 8802 // Arguments have been evaluated to a literal value already.
8792 ASSERT(arg->IsLiteralNode()); 8803 ASSERT(arg->IsLiteralNode());
8793 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); 8804 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal());
8794 } 8805 }
8795 const Array& args_descriptor = 8806 const Array& args_descriptor =
8796 Array::Handle(ArgumentsDescriptor::New(num_arguments, 8807 Array::Handle(ArgumentsDescriptor::New(num_arguments,
8797 arguments->names())); 8808 arguments->names()));
8798 const Object& result = 8809 const Object& result =
8799 Object::Handle(DartEntry::InvokeFunction(constructor, 8810 Object::Handle(DartEntry::InvokeFunction(constructor,
8800 arg_values, 8811 arg_values,
8801 args_descriptor)); 8812 args_descriptor));
8802 if (result.IsError()) { 8813 if (result.IsError()) {
8803 // An exception may not occur in every parse attempt, i.e., the 8814 // An exception may not occur in every parse attempt, i.e., the
8804 // generated AST is not deterministic. Therefore mark the function as 8815 // generated AST is not deterministic. Therefore mark the function as
8805 // not optimizable. 8816 // not optimizable.
8806 current_function().set_is_optimizable(false); 8817 current_function().set_is_optimizable(false);
8807 if (result.IsUnhandledException()) { 8818 if (result.IsUnhandledException()) {
8808 return result.raw(); 8819 return result.raw();
8809 } else { 8820 } else {
8810 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); 8821 isolate()->long_jump_base()->Jump(1, Error::Cast(result));
8811 UNREACHABLE(); 8822 UNREACHABLE();
8812 return Object::null(); 8823 return Object::null();
8813 } 8824 }
8814 } else { 8825 } else {
8826 if (constructor.IsFactory()) {
8827 // The factory method returns the allocated object.
8828 instance ^= result.raw();
8829 }
8815 return TryCanonicalize(instance, TokenPos()); 8830 return TryCanonicalize(instance, TokenPos());
8816 } 8831 }
8817 } 8832 }
8818 8833
8819 8834
8820 // Do a lookup for the identifier in the block scope and the class scope 8835 // Do a lookup for the identifier in the block scope and the class scope
8821 // return true if the identifier is found, false otherwise. 8836 // return true if the identifier is found, false otherwise.
8822 // If node is non NULL return an AST node corresponding to the identifier. 8837 // If node is non NULL return an AST node corresponding to the identifier.
8823 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, 8838 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
8824 const String &ident, 8839 const String &ident,
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after
9928 external_constructor_name.ToCString()); 9943 external_constructor_name.ToCString());
9929 } 9944 }
9930 const Object& constructor_result = Object::Handle( 9945 const Object& constructor_result = Object::Handle(
9931 EvaluateConstConstructorCall(type_class, 9946 EvaluateConstConstructorCall(type_class,
9932 type_arguments, 9947 type_arguments,
9933 constructor, 9948 constructor,
9934 arguments)); 9949 arguments));
9935 if (constructor_result.IsUnhandledException()) { 9950 if (constructor_result.IsUnhandledException()) {
9936 new_object = GenerateRethrow(new_pos, constructor_result); 9951 new_object = GenerateRethrow(new_pos, constructor_result);
9937 } else { 9952 } else {
9938 const Instance& const_instance = Instance::Cast(constructor_result); 9953 // Const constructors can return null in the case where a const native
9954 // factory returns a null value. Thus we cannot use a Instance::Cast here.
9955 Instance& const_instance = Instance::Handle();
9956 const_instance ^= constructor_result.raw();
9939 new_object = new LiteralNode(new_pos, 9957 new_object = new LiteralNode(new_pos,
9940 Instance::ZoneHandle(const_instance.raw())); 9958 Instance::ZoneHandle(const_instance.raw()));
9941 if (!type_bound.IsNull()) { 9959 if (!type_bound.IsNull()) {
9942 ASSERT(!type_bound.IsMalformed()); 9960 ASSERT(!type_bound.IsMalformed());
9943 Error& malformed_error = Error::Handle(); 9961 Error& malformed_error = Error::Handle();
9944 ASSERT(!is_top_level_); // We cannot check unresolved types. 9962 ASSERT(!is_top_level_); // We cannot check unresolved types.
9945 if (!const_instance.IsInstanceOf(type_bound, 9963 if (!const_instance.IsInstanceOf(type_bound,
9946 TypeArguments::Handle(), 9964 TypeArguments::Handle(),
9947 &malformed_error)) { 9965 &malformed_error)) {
9948 type_bound = ClassFinalizer::NewFinalizedMalformedType( 9966 type_bound = ClassFinalizer::NewFinalizedMalformedType(
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
10603 void Parser::SkipQualIdent() { 10621 void Parser::SkipQualIdent() {
10604 ASSERT(IsIdentifier()); 10622 ASSERT(IsIdentifier());
10605 ConsumeToken(); 10623 ConsumeToken();
10606 if (CurrentToken() == Token::kPERIOD) { 10624 if (CurrentToken() == Token::kPERIOD) {
10607 ConsumeToken(); // Consume the kPERIOD token. 10625 ConsumeToken(); // Consume the kPERIOD token.
10608 ExpectIdentifier("identifier expected after '.'"); 10626 ExpectIdentifier("identifier expected after '.'");
10609 } 10627 }
10610 } 10628 }
10611 10629
10612 } // namespace dart 10630 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698