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

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

Issue 23094003: Make sure type information is not lost in snapshots created in production mode, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/snapshot_test.cc » ('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 3130 matching lines...) Expand 10 before | Expand all | Expand 10 after
3141 Function& getter = Function::Handle(); 3141 Function& getter = Function::Handle();
3142 Function& setter = Function::Handle(); 3142 Function& setter = Function::Handle();
3143 Field& class_field = Field::Handle(); 3143 Field& class_field = Field::Handle();
3144 Instance& init_value = Instance::Handle(); 3144 Instance& init_value = Instance::Handle();
3145 while (true) { 3145 while (true) {
3146 bool has_initializer = CurrentToken() == Token::kASSIGN; 3146 bool has_initializer = CurrentToken() == Token::kASSIGN;
3147 bool has_simple_literal = false; 3147 bool has_simple_literal = false;
3148 if (has_initializer) { 3148 if (has_initializer) {
3149 ConsumeToken(); 3149 ConsumeToken();
3150 init_value = Object::sentinel().raw(); 3150 init_value = Object::sentinel().raw();
3151 // For static const fields, the initialization expression 3151 // For static const fields and static final non-const fields, the
3152 // will be parsed through the kImplicitStaticFinalGetter method 3152 // initialization expression will be parsed through the
3153 // invocation/compilation. 3153 // kImplicitStaticFinalGetter method invocation/compilation.
3154 // For instance fields, the expression is parsed when a constructor 3154 // For instance fields, the expression is parsed when a constructor
3155 // is compiled. 3155 // is compiled.
3156 // For static const fields with very simple initializer expressions 3156 // For static const fields and static final non-const fields with very
3157 // (e.g. a literal number or string) we optimize away the 3157 // simple initializer expressions (e.g. a literal number or string), we
3158 // kImplicitStaticFinalGetter and initialize the field here. 3158 // optimize away the kImplicitStaticFinalGetter and initialize the field
3159 // We also do it for static final non-const fields, but only in production 3159 // here. However, the class finalizer will check the value type for
3160 // mode. 3160 // assignability once the declared field type can be resolved. If the
3161 // value is not assignable (assuming checked mode and disregarding actual
3162 // mode), the field value is reset and a kImplicitStaticFinalGetter is
3163 // created at finalization time.
3161 3164
3162 if (field->has_static && 3165 if (field->has_static && (field->has_const || field->has_final) &&
3163 (field->has_const ||
3164 (!FLAG_enable_type_checks && field->has_final)) &&
3165 (LookaheadToken(1) == Token::kSEMICOLON)) { 3166 (LookaheadToken(1) == Token::kSEMICOLON)) {
3166 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); 3167 has_simple_literal = IsSimpleLiteral(*field->type, &init_value);
3167 } 3168 }
3168 SkipExpr(); 3169 SkipExpr();
3169 } else { 3170 } else {
3170 if (field->has_const || (field->has_static && field->has_final)) { 3171 if (field->has_const || (field->has_static && field->has_final)) {
3171 ErrorMsg(field->name_pos, 3172 ErrorMsg(field->name_pos,
3172 "%s%s field '%s' must have an initializer expression", 3173 "%s%s field '%s' must have an initializer expression",
3173 field->has_static ? "static " : "", 3174 field->has_static ? "static " : "",
3174 field->has_const ? "const" : "final", 3175 field->has_const ? "const" : "final",
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after
4245 } 4246 }
4246 4247
4247 4248
4248 void Parser::ParseTopLevelVariable(TopLevel* top_level, 4249 void Parser::ParseTopLevelVariable(TopLevel* top_level,
4249 intptr_t metadata_pos) { 4250 intptr_t metadata_pos) {
4250 TRACE_PARSER("ParseTopLevelVariable"); 4251 TRACE_PARSER("ParseTopLevelVariable");
4251 const bool is_const = (CurrentToken() == Token::kCONST); 4252 const bool is_const = (CurrentToken() == Token::kCONST);
4252 // Const fields are implicitly final. 4253 // Const fields are implicitly final.
4253 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); 4254 const bool is_final = is_const || (CurrentToken() == Token::kFINAL);
4254 const bool is_static = true; 4255 const bool is_static = true;
4255 const AbstractType& type = 4256 const AbstractType& type = AbstractType::ZoneHandle(ParseConstFinalVarOrType(
4256 AbstractType::ZoneHandle(ParseConstFinalVarOrType( 4257 ClassFinalizer::kResolveTypeParameters));
4257 FLAG_enable_type_checks ? ClassFinalizer::kResolveTypeParameters :
4258 ClassFinalizer::kIgnore));
4259 Field& field = Field::Handle(); 4258 Field& field = Field::Handle();
4260 Function& getter = Function::Handle(); 4259 Function& getter = Function::Handle();
4261 while (true) { 4260 while (true) {
4262 const intptr_t name_pos = TokenPos(); 4261 const intptr_t name_pos = TokenPos();
4263 String& var_name = *ExpectIdentifier("variable name expected"); 4262 String& var_name = *ExpectIdentifier("variable name expected");
4264 4263
4265 if (library_.LookupLocalObject(var_name) != Object::null()) { 4264 if (library_.LookupLocalObject(var_name) != Object::null()) {
4266 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); 4265 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString());
4267 } 4266 }
4268 String& accessor_name = String::Handle(Field::GetterName(var_name)); 4267 String& accessor_name = String::Handle(Field::GetterName(var_name));
(...skipping 17 matching lines...) Expand all
4286 field.set_value(Instance::Handle(Instance::null())); 4285 field.set_value(Instance::Handle(Instance::null()));
4287 top_level->fields.Add(field); 4286 top_level->fields.Add(field);
4288 library_.AddObject(field, var_name); 4287 library_.AddObject(field, var_name);
4289 if (metadata_pos >= 0) { 4288 if (metadata_pos >= 0) {
4290 library_.AddFieldMetadata(field, metadata_pos); 4289 library_.AddFieldMetadata(field, metadata_pos);
4291 } 4290 }
4292 if (CurrentToken() == Token::kASSIGN) { 4291 if (CurrentToken() == Token::kASSIGN) {
4293 ConsumeToken(); 4292 ConsumeToken();
4294 Instance& field_value = Instance::Handle(Object::sentinel().raw()); 4293 Instance& field_value = Instance::Handle(Object::sentinel().raw());
4295 bool has_simple_literal = false; 4294 bool has_simple_literal = false;
4296 if ((is_const || (!FLAG_enable_type_checks && is_final)) && 4295 if ((is_const || is_final) && (LookaheadToken(1) == Token::kSEMICOLON)) {
4297 (LookaheadToken(1) == Token::kSEMICOLON)) {
4298 has_simple_literal = IsSimpleLiteral(type, &field_value); 4296 has_simple_literal = IsSimpleLiteral(type, &field_value);
4299 } 4297 }
4300 SkipExpr(); 4298 SkipExpr();
4301 field.set_value(field_value); 4299 field.set_value(field_value);
4302 if (!has_simple_literal) { 4300 if (!has_simple_literal) {
4303 // Create a static const getter. 4301 // Create a static final getter.
4304 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name)); 4302 String& getter_name = String::Handle(Field::GetterSymbol(var_name));
4305 getter = Function::New(getter_name, 4303 getter = Function::New(getter_name,
4306 RawFunction::kImplicitStaticFinalGetter, 4304 RawFunction::kImplicitStaticFinalGetter,
4307 is_static, 4305 is_static,
4308 is_const, 4306 is_const,
4309 /* is_abstract = */ false, 4307 /* is_abstract = */ false,
4310 /* is_external = */ false, 4308 /* is_external = */ false,
4311 current_class(), 4309 current_class(),
4312 name_pos); 4310 name_pos);
4313 getter.set_result_type(type); 4311 getter.set_result_type(type);
4314 top_level->functions.Add(getter); 4312 top_level->functions.Add(getter);
(...skipping 6028 matching lines...) Expand 10 before | Expand all | Expand 10 after
10343 void Parser::SkipQualIdent() { 10341 void Parser::SkipQualIdent() {
10344 ASSERT(IsIdentifier()); 10342 ASSERT(IsIdentifier());
10345 ConsumeToken(); 10343 ConsumeToken();
10346 if (CurrentToken() == Token::kPERIOD) { 10344 if (CurrentToken() == Token::kPERIOD) {
10347 ConsumeToken(); // Consume the kPERIOD token. 10345 ConsumeToken(); // Consume the kPERIOD token.
10348 ExpectIdentifier("identifier expected after '.'"); 10346 ExpectIdentifier("identifier expected after '.'");
10349 } 10347 }
10350 } 10348 }
10351 10349
10352 } // namespace dart 10350 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/snapshot_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698