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

Unified Diff: lib/compiler/implementation/ssa/builder.dart

Issue 11346002: Support argument definition test in constructors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/ssa/builder.dart
===================================================================
--- lib/compiler/implementation/ssa/builder.dart (revision 14192)
+++ lib/compiler/implementation/ssa/builder.dart (working copy)
@@ -867,7 +867,7 @@
HGraph graph;
LocalsHandler localsHandler;
HInstruction rethrowableException;
- Map<Element, HParameterValue> parameters;
+ Map<Element, HInstruction> parameters;
final RuntimeTypeInformation rti;
Map<TargetElement, JumpHandler> jumpTargets;
@@ -907,7 +907,7 @@
stack = new List<HInstruction>(),
activationVariables = new Map<Element, HLocalValue>(),
jumpTargets = new Map<TargetElement, JumpHandler>(),
- parameters = new Map<Element, HParameterValue>(),
+ parameters = new Map<Element, HInstruction>(),
sourceElementStack = <Element>[work.element],
inliningStack = <InliningState>[],
rti = builder.compiler.codegenWorld.rti,
@@ -1153,6 +1153,10 @@
FunctionSignature params = constructor.computeSignature(compiler);
params.orderedForEachParameter((Element parameter) {
HInstruction argument = compiledArguments[index++];
+ // Because we are inlining the initializer, we must update
+ // what was given as parameter. This will be used in case
+ // there is a parameter check expression in the initializer.
+ parameters[parameter] = argument;
localsHandler.updateLocal(parameter, argument);
// Don't forget to update the field, if the parameter is of the
// form [:this.x:].
@@ -1166,7 +1170,20 @@
TreeElements oldElements = elements;
elements =
compiler.enqueuer.resolution.getCachedElements(constructor);
+
+ ClosureClassMap oldClosureData = localsHandler.closureData;
+ localsHandler.closureData =
+ compiler.closureToClassMapper.computeClosureToClassMapping(
+ constructor, constructor.parseNode(compiler), elements);
+
+ params.orderedForEachParameter((Element parameterElement) {
+ if (elements.isParameterChecked(parameterElement)) {
+ addParameterCheckInstruction(parameterElement);
+ }
+ });
+
buildInitializers(constructor, constructors, fieldValues);
+ localsHandler.closureData = oldClosureData;
elements = oldElements;
});
}
@@ -1356,6 +1373,22 @@
functionSignature.orderedForEachParameter((parameter) {
bodyCallInputs.add(localsHandler.readLocal(parameter));
});
+
+ // If parameters are checked, we pass the already computed
+ // boolean to the constructor body.
+ TreeElements elements =
+ compiler.enqueuer.resolution.getCachedElements(constructor);
+ Node node = constructor.parseNode(compiler);
+ ClosureClassMap parameterClosureData =
+ compiler.closureToClassMapper.getMappingForNestedFunction(node);
+ functionSignature.orderedForEachParameter((parameter) {
+ if (elements.isParameterChecked(parameter)) {
+ Element fieldCheck =
+ parameterClosureData.parametersWithSentinel[parameter];
+ bodyCallInputs.add(localsHandler.readLocal(fieldCheck));
+ }
+ });
+
// TODO(ahe): The constructor name is statically resolved. See
// SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner
// way to do this?
@@ -1376,48 +1409,56 @@
}
void addParameterCheckInstruction(Element element) {
- // This is the code we emit for a parameter that is being checked
- // on whether it was given at value at the call site:
- //
- // foo([a = 42) {
- // if (?a) print('parameter passed $a');
- // }
- //
- // foo([a = 42]) {
- // var t1 = a === sentinel;
- // if (t1) a = 42;
- // if (!t1) print('parameter passed ' + a);
- // }
+ HInstruction check;
+ Element checkResultElement =
+ localsHandler.closureData.parametersWithSentinel[element];
+ if (currentElement.isGenerativeConstructorBody()) {
+ // A generative constructor body receives extra parameters that
+ // indicate if a parameter was passed to the factory.
+ check = new HParameterValue(checkResultElement);
+ add(check);
+ } else {
+ // This is the code we emit for a parameter that is being checked
+ // on whether it was given at value at the call site:
+ //
+ // foo([a = 42) {
+ // if (?a) print('parameter passed $a');
+ // }
+ //
+ // foo([a = 42]) {
+ // var t1 = a === sentinel;
+ // if (t1) a = 42;
+ // if (!t1) print('parameter passed ' + a);
+ // }
- // Fetch the original default value of [element];
- ConstantHandler handler = compiler.constantHandler;
- Constant constant = handler.compileVariable(element);
- HConstant defaultValue = constant == null
- ? graph.addConstantNull(constantSystem)
- : graph.addConstant(constant);
+ // Fetch the original default value of [element];
+ ConstantHandler handler = compiler.constantHandler;
+ Constant constant = handler.compileVariable(element);
+ HConstant defaultValue = constant == null
+ ? graph.addConstantNull(constantSystem)
+ : graph.addConstant(constant);
- // Emit the equality check with the sentinel.
- HConstant sentinel = graph.addConstant(SentinelConstant.SENTINEL);
- Element equalsHelper = interceptors.getTripleEqualsInterceptor();
- HInstruction target = new HStatic(equalsHelper);
- add(target);
- HInstruction operand = parameters[element];
- HInstruction check = new HIdentity(target, sentinel, operand);
- add(check);
+ // Emit the equality check with the sentinel.
+ HConstant sentinel = graph.addConstant(SentinelConstant.SENTINEL);
+ Element equalsHelper = interceptors.getTripleEqualsInterceptor();
+ HInstruction target = new HStatic(equalsHelper);
+ add(target);
+ HInstruction operand = parameters[element];
+ check = new HIdentity(target, sentinel, operand);
+ add(check);
- // If the check succeeds, we must update the parameter with the
- // default value.
- handleIf(element.parseNode(compiler),
- () => stack.add(check),
- () => localsHandler.updateLocal(element, defaultValue),
- null);
+ // If the check succeeds, we must update the parameter with the
+ // default value.
+ handleIf(element.parseNode(compiler),
+ () => stack.add(check),
+ () => localsHandler.updateLocal(element, defaultValue),
+ null);
- // Create the instruction that parameter checks will use.
- check = new HNot(check);
- add(check);
+ // Create the instruction that parameter checks will use.
+ check = new HNot(check);
+ add(check);
+ }
- ClosureClassMap closureData = localsHandler.closureData;
- Element checkResultElement = closureData.parametersWithSentinel[element];
localsHandler.updateLocal(checkResultElement, check);
}
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698