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

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

Issue 10911062: Codegen support for the argument definition test. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 3 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 | « lib/compiler/implementation/resolver.dart ('k') | 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 11813)
+++ lib/compiler/implementation/ssa/builder.dart (working copy)
@@ -812,7 +812,7 @@
/**
* Variables stored in the current activation. These variables are
* being updated in try/catch blocks, and should be
- * accessed indirectly through HFieldGet and HFieldSet.
+ * accessed indirectly through [HLocalGet] and [HLocalSet].
*/
Map<Element, HLocalValue> activationVariables;
@@ -1226,6 +1226,52 @@
return closeFunction();
}
+ 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);
+ // }
+
+ // Fetch the original default value of [element];
+ ConstantHandler handler = compiler.constantHandler;
+ Constant constant = handler.compileVariable(element);
+ HConstant defaultValue = constant == null
+ ? graph.addConstantNull()
+ : 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);
+
+ // 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);
+
+ ClosureClassMap closureData = localsHandler.closureData;
+ Element checkResultElement = closureData.parametersWithSentinel[element];
+ localsHandler.updateLocal(checkResultElement, check);
+ }
+
void openFunction(FunctionElement functionElement,
FunctionExpression node) {
HBasicBlock block = graph.addNewBlock();
@@ -1236,11 +1282,17 @@
open(block);
+ FunctionSignature params = functionElement.computeSignature(compiler);
+ params.forEachParameter((Element element) {
+ if (elements.isParameterChecked(element)) {
+ addParameterCheckInstruction(element);
+ }
+ });
+
// Put the type checks in the first successor of the entry,
// because that is where the type guards will also be inserted.
// This way we ensure that a type guard will dominate the type
// check.
- FunctionSignature params = functionElement.computeSignature(compiler);
params.forEachParameter((Element element) {
HInstruction newParameter = potentiallyCheckType(
localsHandler.directLocals[element], element);
@@ -1778,10 +1830,14 @@
}
void visitUnary(Send node, Operator op) {
- String value = op.source.stringValue;
- if (value === '?') {
- // TODO(ahe): Implement argument definition test.
- stack.add(graph.addConstantBool(true));
+ if (node.isParameterCheck) {
+ Element element = elements[node.receiver];
+ Node function = element.enclosingElement.parseNode(compiler);
+ ClosureClassMap parameterClosureData =
+ compiler.closureToClassMapper.getMappingForNestedFunction(function);
+ Element fieldCheck =
+ parameterClosureData.parametersWithSentinel[element];
+ stack.add(localsHandler.readLocal(fieldCheck));
return;
}
assert(node.argumentsNode is Prefix);
@@ -1793,6 +1849,7 @@
new HStatic(interceptors.getPrefixOperatorInterceptor(op));
add(target);
HInvokeUnary result;
+ String value = op.source.stringValue;
switch (value) {
case "-": result = new HNegate(target, operand); break;
case "~": result = new HBitNot(target, operand); break;
@@ -2165,8 +2222,15 @@
return pop();
}
- HInstruction compileConstant(Element constantElement) {
- Constant constant = compiler.compileVariable(constantElement);
+ HInstruction compileConstant(Element parameter) {
+ Constant constant;
+ TreeElements calleeElements =
+ compiler.enqueuer.resolution.getCachedElements(element);
+ if (calleeElements.isParameterChecked(parameter)) {
+ constant = SentinelConstant.SENTINEL;
+ } else {
+ constant = compiler.compileVariable(parameter);
+ }
return graph.addConstant(constant);
}
@@ -3669,7 +3733,11 @@
tooDifficult = true;
}
- void visitSend(Node node) {
+ void visitSend(Send node) {
+ if (node.isParameterCheck) {
+ tooDifficult = true;
+ return;
+ }
node.visitChildren(this);
}
« no previous file with comments | « lib/compiler/implementation/resolver.dart ('k') | lib/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698