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

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 3177 matching lines...) Expand 10 before | Expand all | Expand 10 after
3188 if ((CurrentToken() == Token::kLBRACE) || 3188 if ((CurrentToken() == Token::kLBRACE) ||
3189 (CurrentToken() == Token::kARROW)) { 3189 (CurrentToken() == Token::kARROW)) {
3190 if (method->has_abstract) { 3190 if (method->has_abstract) {
3191 ErrorMsg(method->name_pos, 3191 ErrorMsg(method->name_pos,
3192 "abstract method '%s' may not have a function body", 3192 "abstract method '%s' may not have a function body",
3193 method->name->ToCString()); 3193 method->name->ToCString());
3194 } else if (method->has_external) { 3194 } else if (method->has_external) {
3195 ErrorMsg(method->name_pos, 3195 ErrorMsg(method->name_pos,
3196 "external method '%s' may not have a function body", 3196 "external method '%s' may not have a function body",
3197 method->name->ToCString()); 3197 method->name->ToCString());
3198 } else if (method->IsFactoryOrConstructor() && method->has_const) { 3198 } else if (method->IsConstructor() && method->has_const) {
3199 ErrorMsg(method->name_pos, 3199 ErrorMsg(method->name_pos,
3200 "const constructor or factory '%s' may not have a function body", 3200 "const constructor '%s' may not have a function body",
3201 method->name->ToCString());
3202 } else if (method->IsFactory() && method->has_const) {
3203 ErrorMsg(method->name_pos,
3204 "const factory '%s' may not have a function body",
3201 method->name->ToCString()); 3205 method->name->ToCString());
3202 } 3206 }
3203 if (method->redirect_name != NULL) { 3207 if (method->redirect_name != NULL) {
3204 ErrorMsg(method->name_pos, 3208 ErrorMsg(method->name_pos,
3205 "Constructor with redirection may not have a function body"); 3209 "Constructor with redirection may not have a function body");
3206 } 3210 }
3207 if (CurrentToken() == Token::kLBRACE) { 3211 if (CurrentToken() == Token::kLBRACE) {
3208 SkipBlock(); 3212 SkipBlock();
3209 method_end_pos = TokenPos(); 3213 method_end_pos = TokenPos();
3210 ExpectToken(Token::kRBRACE); 3214 ExpectToken(Token::kRBRACE);
3211 } else { 3215 } else {
3212 ConsumeToken(); 3216 ConsumeToken();
3213 SkipExpr(); 3217 SkipExpr();
3214 method_end_pos = TokenPos(); 3218 method_end_pos = TokenPos();
3215 ExpectSemicolon(); 3219 ExpectSemicolon();
3216 } 3220 }
3217 } else if (IsLiteral("native")) { 3221 } else if (IsLiteral("native")) {
3218 if (method->has_abstract) { 3222 if (method->has_abstract) {
3219 ErrorMsg(method->name_pos, 3223 ErrorMsg(method->name_pos,
3220 "abstract method '%s' may not have a function body", 3224 "abstract method '%s' may not have a function body",
3221 method->name->ToCString()); 3225 method->name->ToCString());
3222 } else if (method->IsFactoryOrConstructor() && method->has_const) { 3226 } else if (method->IsConstructor() && method->has_const) {
3223 ErrorMsg(method->name_pos, 3227 ErrorMsg(method->name_pos,
3224 "const constructor or factory '%s' may not be native", 3228 "const constructor '%s' may not be native",
3225 method->name->ToCString()); 3229 method->name->ToCString());
3226 } 3230 }
3227 if (method->redirect_name != NULL) { 3231 if (method->redirect_name != NULL) {
3228 ErrorMsg(method->name_pos, 3232 ErrorMsg(method->name_pos,
3229 "Constructor with redirection may not have a function body"); 3233 "Constructor with redirection may not have a function body");
3230 } 3234 }
3231 ParseNativeDeclaration(); 3235 ParseNativeDeclaration();
3232 method_end_pos = TokenPos(); 3236 method_end_pos = TokenPos();
3233 ExpectSemicolon(); 3237 ExpectSemicolon();
3234 } else { 3238 } else {
(...skipping 5529 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 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after
9940 external_constructor_name.ToCString()); 9955 external_constructor_name.ToCString());
9941 } 9956 }
9942 const Object& constructor_result = Object::Handle( 9957 const Object& constructor_result = Object::Handle(
9943 EvaluateConstConstructorCall(type_class, 9958 EvaluateConstConstructorCall(type_class,
9944 type_arguments, 9959 type_arguments,
9945 constructor, 9960 constructor,
9946 arguments)); 9961 arguments));
9947 if (constructor_result.IsUnhandledException()) { 9962 if (constructor_result.IsUnhandledException()) {
9948 new_object = GenerateRethrow(new_pos, constructor_result); 9963 new_object = GenerateRethrow(new_pos, constructor_result);
9949 } else { 9964 } else {
9950 const Instance& const_instance = Instance::Cast(constructor_result); 9965 // Const constructors can return null in the case where a const native
9966 // factory returns a null value. Thus we cannot use a Instance::Cast here.
9967 Instance& const_instance = Instance::Handle();
9968 const_instance ^= constructor_result.raw();
9951 new_object = new LiteralNode(new_pos, 9969 new_object = new LiteralNode(new_pos,
9952 Instance::ZoneHandle(const_instance.raw())); 9970 Instance::ZoneHandle(const_instance.raw()));
9953 if (!type_bound.IsNull()) { 9971 if (!type_bound.IsNull()) {
9954 ASSERT(!type_bound.IsMalformed()); 9972 ASSERT(!type_bound.IsMalformed());
9955 Error& malformed_error = Error::Handle(); 9973 Error& malformed_error = Error::Handle();
9956 ASSERT(!is_top_level_); // We cannot check unresolved types. 9974 ASSERT(!is_top_level_); // We cannot check unresolved types.
9957 if (!const_instance.IsInstanceOf(type_bound, 9975 if (!const_instance.IsInstanceOf(type_bound,
9958 TypeArguments::Handle(), 9976 TypeArguments::Handle(),
9959 &malformed_error)) { 9977 &malformed_error)) {
9960 type_bound = ClassFinalizer::NewFinalizedMalformedType( 9978 type_bound = ClassFinalizer::NewFinalizedMalformedType(
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
10619 void Parser::SkipQualIdent() { 10637 void Parser::SkipQualIdent() {
10620 ASSERT(IsIdentifier()); 10638 ASSERT(IsIdentifier());
10621 ConsumeToken(); 10639 ConsumeToken();
10622 if (CurrentToken() == Token::kPERIOD) { 10640 if (CurrentToken() == Token::kPERIOD) {
10623 ConsumeToken(); // Consume the kPERIOD token. 10641 ConsumeToken(); // Consume the kPERIOD token.
10624 ExpectIdentifier("identifier expected after '.'"); 10642 ExpectIdentifier("identifier expected after '.'");
10625 } 10643 }
10626 } 10644 }
10627 10645
10628 } // namespace dart 10646 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate.cc ('k') | sdk/lib/core/int.dart » ('j') | sdk/lib/core/int.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698