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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/compile_time_constants.dart

Issue 11299009: Support type literals as compile-time constants. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 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
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 part of dart2js; 5 part of dart2js;
6 6
7 /** 7 /**
8 * The [ConstantHandler] keeps track of compile-time constants, 8 * The [ConstantHandler] keeps track of compile-time constants,
9 * initializations of global and static fields, and default values of 9 * initializations of global and static fields, and default values of
10 * optional parameters. 10 * optional parameters.
(...skipping 10 matching lines...) Expand all
21 21
22 /** Set of all registered compiled constants. */ 22 /** Set of all registered compiled constants. */
23 final Set<Constant> compiledConstants; 23 final Set<Constant> compiledConstants;
24 24
25 /** The set of variable elements that are in the process of being computed. */ 25 /** The set of variable elements that are in the process of being computed. */
26 final Set<VariableElement> pendingVariables; 26 final Set<VariableElement> pendingVariables;
27 27
28 /** Caches the statics where the initial value cannot be eagerly compiled. */ 28 /** Caches the statics where the initial value cannot be eagerly compiled. */
29 final Set<VariableElement> lazyStatics; 29 final Set<VariableElement> lazyStatics;
30 30
31
32 ConstantHandler(Compiler compiler, this.constantSystem) 31 ConstantHandler(Compiler compiler, this.constantSystem)
33 : initialVariableValues = new Map<VariableElement, dynamic>(), 32 : initialVariableValues = new Map<VariableElement, dynamic>(),
34 compiledConstants = new Set<Constant>(), 33 compiledConstants = new Set<Constant>(),
35 pendingVariables = new Set<VariableElement>(), 34 pendingVariables = new Set<VariableElement>(),
36 lazyStatics = new Set<VariableElement>(), 35 lazyStatics = new Set<VariableElement>(),
37 super(compiler); 36 super(compiler);
38 String get name => 'ConstantHandler'; 37 String get name => 'ConstantHandler';
39 38
40 void registerCompileTimeConstant(Constant constant) { 39 void registerCompileTimeConstant(Constant constant) {
41 compiler.enqueuer.codegen.registerInstantiatedClass( 40 compiler.enqueuer.codegen.registerInstantiatedClass(
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 } 240 }
242 return initialValue; 241 return initialValue;
243 } 242 }
244 } 243 }
245 244
246 class CompileTimeConstantEvaluator extends Visitor { 245 class CompileTimeConstantEvaluator extends Visitor {
247 bool isEvaluatingConstant; 246 bool isEvaluatingConstant;
248 final ConstantSystem constantSystem; 247 final ConstantSystem constantSystem;
249 final TreeElements elements; 248 final TreeElements elements;
250 final Compiler compiler; 249 final Compiler compiler;
250 bool enabledRuntimeTypeSupport = false;
251 251
252 CompileTimeConstantEvaluator(this.constantSystem, 252 CompileTimeConstantEvaluator(this.constantSystem,
253 this.elements, 253 this.elements,
254 this.compiler, 254 this.compiler,
255 {bool isConst: false}) 255 {bool isConst: false})
256 : this.isEvaluatingConstant = isConst; 256 : this.isEvaluatingConstant = isConst;
257 257
258 Constant evaluate(Node node) { 258 Constant evaluate(Node node) {
259 return node.accept(this); 259 return node.accept(this);
260 } 260 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 } 393 }
394 accumulator = new DartString.concat(accumulator, expressionString); 394 accumulator = new DartString.concat(accumulator, expressionString);
395 StringConstant partString = evaluate(part.string); 395 StringConstant partString = evaluate(part.string);
396 if (partString == null) return null; 396 if (partString == null) return null;
397 accumulator = new DartString.concat(accumulator, partString.value); 397 accumulator = new DartString.concat(accumulator, partString.value);
398 }; 398 };
399 registerStringInstance(); 399 registerStringInstance();
400 return constantSystem.createString(accumulator, node); 400 return constantSystem.createString(accumulator, node);
401 } 401 }
402 402
403 Constant makeTypeConstant(Element element) {
404 // If we use a type literal in a constant, the compile time constant
405 // emitter will generate a call to the runtime type cache helper, so we
406 // resolve it and put it into the codegen work list.
407 if (!enabledRuntimeTypeSupport) {
ngeoffray 2012/11/19 16:54:09 Instead of having a helper, you can have an implem
karlklose 2012/11/20 14:04:38 As discussed offline, I'll leave that change for n
408 SourceString helperName = const SourceString('createRuntimeType');
409 Element helper = compiler.findHelper(helperName);
410 compiler.enqueuer.resolution.addToWorkList(helper);
411 compiler.enqueuer.codegen.addToWorkList(helper);
412 enabledRuntimeTypeSupport = true;
413 }
414
415 DartType elementType = element.computeType(compiler).asRaw();
416 DartType constantType = compiler.typeClass.computeType(compiler);
417 Constant constant = new TypeConstant(elementType, constantType);
418 compiler.constantHandler.registerCompileTimeConstant(constant);
419 return constant;
420 }
421
403 // TODO(floitsch): provide better error-messages. 422 // TODO(floitsch): provide better error-messages.
404 Constant visitSend(Send send) { 423 Constant visitSend(Send send) {
405 Element element = elements[send]; 424 Element element = elements[send];
406 if (send.isPropertyAccess) { 425 if (send.isPropertyAccess) {
407 if (Elements.isStaticOrTopLevelFunction(element)) { 426 if (Elements.isStaticOrTopLevelFunction(element)) {
408 compiler.codegenWorld.staticFunctionsNeedingGetter.add(element); 427 compiler.codegenWorld.staticFunctionsNeedingGetter.add(element);
409 Constant constant = new FunctionConstant(element); 428 Constant constant = new FunctionConstant(element);
410 compiler.constantHandler.registerCompileTimeConstant(constant); 429 compiler.constantHandler.registerCompileTimeConstant(constant);
411 compiler.enqueuer.codegen.registerStaticUse(element); 430 compiler.enqueuer.codegen.registerStaticUse(element);
412 return constant; 431 return constant;
413 } else if (Elements.isStaticOrTopLevelField(element)) { 432 } else if (Elements.isStaticOrTopLevelField(element)) {
414 Constant result; 433 Constant result;
415 if (element.modifiers.isConst()) { 434 if (element.modifiers.isConst()) {
416 result = compiler.compileConstant(element); 435 result = compiler.compileConstant(element);
417 } else if (element.modifiers.isFinal() && !isEvaluatingConstant) { 436 } else if (element.modifiers.isFinal() && !isEvaluatingConstant) {
418 result = compiler.compileVariable(element); 437 result = compiler.compileVariable(element);
419 } 438 }
420 if (result != null) return result; 439 if (result != null) return result;
440 } else if (Elements.isClass(element) || Elements.isTypedef(element)) {
ngeoffray 2012/11/19 16:54:09 Could you use element.impliesType instead?
karlklose 2012/11/20 14:04:38 That is not the same because type variables imply
441 return makeTypeConstant(element);
421 } 442 }
422 return signalNotCompileTimeConstant(send); 443 return signalNotCompileTimeConstant(send);
423 } else if (send.isCall) { 444 } else if (send.isCall) {
424 if (identical(element, compiler.identicalFunction) 445 if (identical(element, compiler.identicalFunction)
425 && send.argumentCount() == 2) { 446 && send.argumentCount() == 2) {
426 Constant left = evaluate(send.argumentsNode.nodes.head); 447 Constant left = evaluate(send.argumentsNode.nodes.head);
427 Constant right = evaluate(send.argumentsNode.nodes.tail.head); 448 Constant right = evaluate(send.argumentsNode.nodes.tail.head);
428 Constant result = constantSystem.identity.fold(left, right); 449 Constant result = constantSystem.identity.fold(left, right);
429 if (result != null) return result; 450 if (result != null) return result;
451 } else if (Elements.isClass(element) || Elements.isTypedef(element)) {
ngeoffray 2012/11/19 16:54:09 ditto
karlklose 2012/11/20 14:04:38 ditto
452 return makeTypeConstant(element);
430 } 453 }
431 return signalNotCompileTimeConstant(send); 454 return signalNotCompileTimeConstant(send);
432 } else if (send.isPrefix) { 455 } else if (send.isPrefix) {
433 assert(send.isOperator); 456 assert(send.isOperator);
434 Constant receiverConstant = evaluate(send.receiver); 457 Constant receiverConstant = evaluate(send.receiver);
435 if (receiverConstant == null) return null; 458 if (receiverConstant == null) return null;
436 Operator op = send.selector; 459 Operator op = send.selector;
437 Constant folded; 460 Constant folded;
438 switch (op.source.stringValue) { 461 switch (op.source.stringValue) {
439 case "!": 462 case "!":
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 // Use the default value. 846 // Use the default value.
824 fieldValue = compiler.compileConstant(field); 847 fieldValue = compiler.compileConstant(field);
825 } 848 }
826 jsNewArguments.add(fieldValue); 849 jsNewArguments.add(fieldValue);
827 }, 850 },
828 includeBackendMembers: true, 851 includeBackendMembers: true,
829 includeSuperMembers: true); 852 includeSuperMembers: true);
830 return jsNewArguments; 853 return jsNewArguments;
831 } 854 }
832 } 855 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698