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

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

Issue 11361060: Support checked mode for return type. (Closed) Base URL: http://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 ssa; 5 part of ssa;
6 6
7 class Interceptors { 7 class Interceptors {
8 Compiler compiler; 8 Compiler compiler;
9 Interceptors(Compiler this.compiler); 9 Interceptors(Compiler this.compiler);
10 10
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 sourceElementStack = <Element>[work.element], 917 sourceElementStack = <Element>[work.element],
918 inliningStack = <InliningState>[], 918 inliningStack = <InliningState>[],
919 rti = builder.compiler.codegenWorld.rti, 919 rti = builder.compiler.codegenWorld.rti,
920 super(work.resolutionTree) { 920 super(work.resolutionTree) {
921 localsHandler = new LocalsHandler(this); 921 localsHandler = new LocalsHandler(this);
922 } 922 }
923 923
924 static const MAX_INLINING_DEPTH = 3; 924 static const MAX_INLINING_DEPTH = 3;
925 static const MAX_INLINING_SOURCE_SIZE = 128; 925 static const MAX_INLINING_SOURCE_SIZE = 128;
926 List<InliningState> inliningStack; 926 List<InliningState> inliningStack;
927 Element returnElement = null; 927 Element returnElement;
928 DartType returnType;
928 929
929 void disableMethodInterception() { 930 void disableMethodInterception() {
930 assert(methodInterceptionEnabled); 931 assert(methodInterceptionEnabled);
931 methodInterceptionEnabled = false; 932 methodInterceptionEnabled = false;
932 } 933 }
933 934
934 void enableMethodInterception() { 935 void enableMethodInterception() {
935 assert(!methodInterceptionEnabled); 936 assert(!methodInterceptionEnabled);
936 methodInterceptionEnabled = true; 937 methodInterceptionEnabled = true;
937 } 938 }
(...skipping 14 matching lines...) Expand all
952 return closeFunction(); 953 return closeFunction();
953 } 954 }
954 955
955 HGraph buildLazyInitializer(VariableElement variable) { 956 HGraph buildLazyInitializer(VariableElement variable) {
956 SendSet node = variable.parseNode(compiler); 957 SendSet node = variable.parseNode(compiler);
957 openFunction(variable, node); 958 openFunction(variable, node);
958 Link<Node> link = node.arguments; 959 Link<Node> link = node.arguments;
959 assert(!link.isEmpty && link.tail.isEmpty); 960 assert(!link.isEmpty && link.tail.isEmpty);
960 visit(link.head); 961 visit(link.head);
961 HInstruction value = pop(); 962 HInstruction value = pop();
962 value = potentiallyCheckType(value, variable); 963 value = potentiallyCheckType(value, variable.computeType(compiler));
963 close(new HReturn(value)).addSuccessor(graph.exit); 964 close(new HReturn(value)).addSuccessor(graph.exit);
964 return closeFunction(); 965 return closeFunction();
965 } 966 }
966 967
967 /** 968 /**
968 * Returns the constructor body associated with the given constructor or 969 * Returns the constructor body associated with the given constructor or
969 * creates a new constructor body, if none can be found. 970 * creates a new constructor body, if none can be found.
970 * 971 *
971 * Returns [:null:] if the constructor does not have a body. 972 * Returns [:null:] if the constructor does not have a body.
972 */ 973 */
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 // Once we start to compile the arguments we must be sure that we don't 1030 // Once we start to compile the arguments we must be sure that we don't
1030 // abort. 1031 // abort.
1031 List<HInstruction> compiledArguments = new List<HInstruction>(); 1032 List<HInstruction> compiledArguments = new List<HInstruction>();
1032 bool succeeded = addStaticSendArgumentsToList(selector, 1033 bool succeeded = addStaticSendArgumentsToList(selector,
1033 arguments, 1034 arguments,
1034 function, 1035 function,
1035 compiledArguments); 1036 compiledArguments);
1036 assert(succeeded); 1037 assert(succeeded);
1037 1038
1038 InliningState state = 1039 InliningState state =
1039 new InliningState(function, returnElement, elements, stack); 1040 new InliningState(function, returnElement, returnType, elements, stack);
1040 inliningStack.add(state); 1041 inliningStack.add(state);
1041 sourceElementStack.add(function); 1042 sourceElementStack.add(function);
1042 stack = <HInstruction>[]; 1043 stack = <HInstruction>[];
1043 returnElement = new Element(const SourceString("result"), 1044 returnElement = new Element(const SourceString("result"),
1044 ElementKind.VARIABLE, 1045 ElementKind.VARIABLE,
1045 function); 1046 function);
1046 localsHandler.updateLocal(returnElement, 1047 localsHandler.updateLocal(returnElement,
1047 graph.addConstantNull(constantSystem)); 1048 graph.addConstantNull(constantSystem));
1048 elements = compiler.enqueuer.resolution.getCachedElements(function); 1049 elements = compiler.enqueuer.resolution.getCachedElements(function);
1049 assert(elements != null); 1050 assert(elements != null);
1050 FunctionSignature signature = function.computeSignature(compiler); 1051 FunctionSignature signature = function.computeSignature(compiler);
1052 returnType = signature.returnType;
1051 int index = 0; 1053 int index = 0;
1052 signature.orderedForEachParameter((Element parameter) { 1054 signature.orderedForEachParameter((Element parameter) {
1053 HInstruction argument = compiledArguments[index++]; 1055 HInstruction argument = compiledArguments[index++];
1054 localsHandler.updateLocal(parameter, argument); 1056 localsHandler.updateLocal(parameter, argument);
1055 potentiallyCheckType(argument, parameter); 1057 potentiallyCheckType(argument, parameter.computeType(compiler));
1056 }); 1058 });
1057 return state; 1059 return state;
1058 } 1060 }
1059 1061
1060 void leaveInlinedMethod(InliningState state) { 1062 void leaveInlinedMethod(InliningState state) {
1061 InliningState poppedState = inliningStack.removeLast(); 1063 InliningState poppedState = inliningStack.removeLast();
1062 assert(state == poppedState); 1064 assert(state == poppedState);
1063 FunctionElement poppedElement = sourceElementStack.removeLast(); 1065 FunctionElement poppedElement = sourceElementStack.removeLast();
1064 assert(poppedElement == poppedState.function); 1066 assert(poppedElement == poppedState.function);
1065 elements = state.oldElements; 1067 elements = state.oldElements;
1066 stack.add(localsHandler.readLocal(returnElement)); 1068 stack.add(localsHandler.readLocal(returnElement));
1067 returnElement = state.oldReturnElement; 1069 returnElement = state.oldReturnElement;
1070 returnType = state.oldReturnType;
1068 assert(stack.length == 1); 1071 assert(stack.length == 1);
1069 state.oldStack.add(stack[0]); 1072 state.oldStack.add(stack[0]);
1070 stack = state.oldStack; 1073 stack = state.oldStack;
1071 } 1074 }
1072 1075
1073 /** 1076 /**
1074 * Documentation wanted -- johnniwinther 1077 * Documentation wanted -- johnniwinther
1075 */ 1078 */
1076 bool tryInlineMethod(Element element, 1079 bool tryInlineMethod(Element element,
1077 Selector selector, 1080 Selector selector,
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 1342
1340 // Analyze the constructor and all referenced constructors and collect 1343 // Analyze the constructor and all referenced constructors and collect
1341 // initializers and constructor bodies. 1344 // initializers and constructor bodies.
1342 List<FunctionElement> constructors = <FunctionElement>[functionElement]; 1345 List<FunctionElement> constructors = <FunctionElement>[functionElement];
1343 buildInitializers(functionElement, constructors, fieldValues); 1346 buildInitializers(functionElement, constructors, fieldValues);
1344 1347
1345 // Call the JavaScript constructor with the fields as argument. 1348 // Call the JavaScript constructor with the fields as argument.
1346 List<HInstruction> constructorArguments = <HInstruction>[]; 1349 List<HInstruction> constructorArguments = <HInstruction>[];
1347 classElement.forEachInstanceField( 1350 classElement.forEachInstanceField(
1348 (ClassElement enclosingClass, Element member) { 1351 (ClassElement enclosingClass, Element member) {
1349 constructorArguments.add( 1352 constructorArguments.add(potentiallyCheckType(
1350 potentiallyCheckType(fieldValues[member], member)); 1353 fieldValues[member], member.computeType(compiler)));
1351 }, 1354 },
1352 includeBackendMembers: true, 1355 includeBackendMembers: true,
1353 includeSuperMembers: true); 1356 includeSuperMembers: true);
1354 1357
1355 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); 1358 HForeignNew newObject = new HForeignNew(classElement, constructorArguments);
1356 add(newObject); 1359 add(newObject);
1357 1360
1358 // Create the runtime type information, if needed. 1361 // Create the runtime type information, if needed.
1359 InterfaceType type = classElement.computeType(compiler); 1362 InterfaceType type = classElement.computeType(compiler);
1360 List<HInstruction> inputs = <HInstruction>[]; 1363 List<HInstruction> inputs = <HInstruction>[];
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 HBasicBlock block = graph.addNewBlock(); 1492 HBasicBlock block = graph.addNewBlock();
1490 open(graph.entry); 1493 open(graph.entry);
1491 1494
1492 localsHandler.startFunction(element, node); 1495 localsHandler.startFunction(element, node);
1493 close(new HGoto()).addSuccessor(block); 1496 close(new HGoto()).addSuccessor(block);
1494 1497
1495 open(block); 1498 open(block);
1496 1499
1497 if (element is FunctionElement) { 1500 if (element is FunctionElement) {
1498 FunctionElement functionElement = element; 1501 FunctionElement functionElement = element;
1499 FunctionSignature params = functionElement.computeSignature(compiler); 1502 FunctionSignature signature = functionElement.computeSignature(compiler);
1500 params.orderedForEachParameter((Element parameterElement) { 1503 signature.orderedForEachParameter((Element parameterElement) {
1501 if (elements.isParameterChecked(parameterElement)) { 1504 if (elements.isParameterChecked(parameterElement)) {
1502 addParameterCheckInstruction(parameterElement); 1505 addParameterCheckInstruction(parameterElement);
1503 } 1506 }
1504 }); 1507 });
1505 1508
1506 // Put the type checks in the first successor of the entry, 1509 // Put the type checks in the first successor of the entry,
1507 // because that is where the type guards will also be inserted. 1510 // because that is where the type guards will also be inserted.
1508 // This way we ensure that a type guard will dominate the type 1511 // This way we ensure that a type guard will dominate the type
1509 // check. 1512 // check.
1510 params.orderedForEachParameter((Element element) { 1513 signature.orderedForEachParameter((Element element) {
1511 HInstruction newParameter = potentiallyCheckType( 1514 HInstruction newParameter = potentiallyCheckType(
1512 localsHandler.directLocals[element], element); 1515 localsHandler.directLocals[element],
1516 element.computeType(compiler));
1513 localsHandler.directLocals[element] = newParameter; 1517 localsHandler.directLocals[element] = newParameter;
1514 }); 1518 });
1519
1520 returnType = signature.returnType;
1515 } else { 1521 } else {
1516 // Otherwise it is a lazy initializer which does not have parameters. 1522 // Otherwise it is a lazy initializer which does not have parameters.
1517 assert(element is VariableElement); 1523 assert(element is VariableElement);
1518 } 1524 }
1519 1525
1520 // Add the type parameters of the class as parameters of this 1526 // Add the type parameters of the class as parameters of this
1521 // method. 1527 // method.
1522 var enclosing = element.enclosingElement; 1528 var enclosing = element.enclosingElement;
1523 if (element.isConstructor() && compiler.world.needsRti(enclosing)) { 1529 if (element.isConstructor() && compiler.world.needsRti(enclosing)) {
1524 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { 1530 enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
1525 HParameterValue param = new HParameterValue(typeVariable.element); 1531 HParameterValue param = new HParameterValue(typeVariable.element);
1526 add(param); 1532 add(param);
1527 localsHandler.directLocals[typeVariable.element] = param; 1533 localsHandler.directLocals[typeVariable.element] = param;
1528 }); 1534 });
1529 } 1535 }
1530 } 1536 }
1531 1537
1532 HInstruction potentiallyCheckType( 1538 HInstruction potentiallyCheckType(
1533 HInstruction original, Element sourceElement, 1539 HInstruction original, DartType type,
1534 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { 1540 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
1535 if (!compiler.enableTypeAssertions) return original; 1541 if (!compiler.enableTypeAssertions) return original;
1536 HInstruction other = original.convertType(compiler, sourceElement, kind); 1542 HInstruction other = original.convertType(compiler, type, kind);
1537 if (other != original) add(other); 1543 if (other != original) add(other);
1538 return other; 1544 return other;
1539 } 1545 }
1540 1546
1541 HGraph closeFunction() { 1547 HGraph closeFunction() {
1542 // TODO(kasperl): Make this goto an implicit return. 1548 // TODO(kasperl): Make this goto an implicit return.
1543 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit); 1549 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit);
1544 graph.finalize(); 1550 graph.finalize();
1545 return graph; 1551 return graph;
1546 } 1552 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 1614
1609 void dup() { 1615 void dup() {
1610 stack.add(stack.last); 1616 stack.add(stack.last);
1611 } 1617 }
1612 1618
1613 HInstruction popBoolified() { 1619 HInstruction popBoolified() {
1614 HInstruction value = pop(); 1620 HInstruction value = pop();
1615 if (compiler.enableTypeAssertions) { 1621 if (compiler.enableTypeAssertions) {
1616 return potentiallyCheckType( 1622 return potentiallyCheckType(
1617 value, 1623 value,
1618 compiler.boolClass, 1624 compiler.boolClass.computeType(compiler),
1619 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); 1625 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
1620 } 1626 }
1621 HInstruction result = new HBoolify(value); 1627 HInstruction result = new HBoolify(value);
1622 add(result); 1628 add(result);
1623 return result; 1629 return result;
1624 } 1630 }
1625 1631
1626 HInstruction attachPosition(HInstruction target, Node node) { 1632 HInstruction attachPosition(HInstruction target, Node node) {
1627 target.sourcePosition = sourceFileLocationForBeginToken(node); 1633 target.sourcePosition = sourceFileLocationForBeginToken(node);
1628 return target; 1634 return target;
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 stack.add(value); 2297 stack.add(value);
2292 } 2298 }
2293 2299
2294 void generateSetter(SendSet send, Element element, HInstruction value) { 2300 void generateSetter(SendSet send, Element element, HInstruction value) {
2295 if (Elements.isStaticOrTopLevelField(element)) { 2301 if (Elements.isStaticOrTopLevelField(element)) {
2296 if (element.isSetter()) { 2302 if (element.isSetter()) {
2297 HStatic target = new HStatic(element); 2303 HStatic target = new HStatic(element);
2298 add(target); 2304 add(target);
2299 addWithPosition(new HInvokeStatic(<HInstruction>[target, value]), send); 2305 addWithPosition(new HInvokeStatic(<HInstruction>[target, value]), send);
2300 } else { 2306 } else {
2301 value = potentiallyCheckType(value, element); 2307 value = potentiallyCheckType(value, element.computeType(compiler));
2302 addWithPosition(new HStaticStore(element, value), send); 2308 addWithPosition(new HStaticStore(element, value), send);
2303 } 2309 }
2304 stack.add(value); 2310 stack.add(value);
2305 } else if (element == null || Elements.isInstanceField(element)) { 2311 } else if (element == null || Elements.isInstanceField(element)) {
2306 HInstruction receiver = generateInstanceSendReceiver(send); 2312 HInstruction receiver = generateInstanceSendReceiver(send);
2307 generateInstanceSetterWithCompiledReceiver(send, receiver, value); 2313 generateInstanceSetterWithCompiledReceiver(send, receiver, value);
2308 } else if (Elements.isErroneousElement(element)) { 2314 } else if (Elements.isErroneousElement(element)) {
2309 // An erroneous element indicates an unresolved static setter. 2315 // An erroneous element indicates an unresolved static setter.
2310 generateThrowNoSuchMethod(send, 2316 generateThrowNoSuchMethod(send,
2311 getTargetName(element, 'set'), 2317 getTargetName(element, 'set'),
2312 argumentNodes: send.arguments); 2318 argumentNodes: send.arguments);
2313 } else { 2319 } else {
2314 stack.add(value); 2320 stack.add(value);
2315 // If the value does not already have a name, give it here. 2321 // If the value does not already have a name, give it here.
2316 if (value.sourceElement == null) { 2322 if (value.sourceElement == null) {
2317 value.sourceElement = element; 2323 value.sourceElement = element;
2318 } 2324 }
2319 HInstruction checked = potentiallyCheckType(value, element); 2325 HInstruction checked = potentiallyCheckType(
2326 value, element.computeType(compiler));
2320 if (!identical(checked, value)) { 2327 if (!identical(checked, value)) {
2321 pop(); 2328 pop();
2322 stack.add(checked); 2329 stack.add(checked);
2323 } 2330 }
2324 localsHandler.updateLocal(element, checked); 2331 localsHandler.updateLocal(element, checked);
2325 } 2332 }
2326 } 2333 }
2327 2334
2328 void pushInvokeHelper0(Element helper) { 2335 void pushInvokeHelper0(Element helper) {
2329 HInstruction reference = new HStatic(helper); 2336 HInstruction reference = new HStatic(helper);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2427 } 2434 }
2428 push(instruction); 2435 push(instruction);
2429 } 2436 }
2430 } else if (const SourceString("as") == op.source) { 2437 } else if (const SourceString("as") == op.source) {
2431 visit(node.receiver); 2438 visit(node.receiver);
2432 HInstruction expression = pop(); 2439 HInstruction expression = pop();
2433 Node argument = node.arguments.head; 2440 Node argument = node.arguments.head;
2434 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); 2441 TypeAnnotation typeAnnotation = argument.asTypeAnnotation();
2435 DartType type = elements.getType(typeAnnotation); 2442 DartType type = elements.getType(typeAnnotation);
2436 HInstruction converted = expression.convertType( 2443 HInstruction converted = expression.convertType(
2437 compiler, type.element, HTypeConversion.CAST_TYPE_CHECK); 2444 compiler, type, HTypeConversion.CAST_TYPE_CHECK);
2438 if (converted != expression) add(converted); 2445 if (converted != expression) add(converted);
2439 stack.add(converted); 2446 stack.add(converted);
2440 } else { 2447 } else {
2441 visit(node.receiver); 2448 visit(node.receiver);
2442 visit(node.argumentsNode); 2449 visit(node.argumentsNode);
2443 var right = pop(); 2450 var right = pop();
2444 var left = pop(); 2451 var left = pop();
2445 visitBinary(left, op, right); 2452 visitBinary(left, op, right);
2446 } 2453 }
2447 } 2454 }
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
3445 if (node.isRedirectingFactoryBody) { 3452 if (node.isRedirectingFactoryBody) {
3446 compiler.internalError("Unimplemented: Redirecting factory constructor", 3453 compiler.internalError("Unimplemented: Redirecting factory constructor",
3447 node: node); 3454 node: node);
3448 } 3455 }
3449 HInstruction value; 3456 HInstruction value;
3450 if (node.expression == null) { 3457 if (node.expression == null) {
3451 value = graph.addConstantNull(constantSystem); 3458 value = graph.addConstantNull(constantSystem);
3452 } else { 3459 } else {
3453 visit(node.expression); 3460 visit(node.expression);
3454 value = pop(); 3461 value = pop();
3462 value = potentiallyCheckType(value, returnType);
3455 } 3463 }
3456 if (!inliningStack.isEmpty) { 3464 if (!inliningStack.isEmpty) {
3457 localsHandler.updateLocal(returnElement, value); 3465 localsHandler.updateLocal(returnElement, value);
3458 } else { 3466 } else {
3459 close(attachPosition(new HReturn(value), node)).addSuccessor(graph.exit); 3467 close(attachPosition(new HReturn(value), node)).addSuccessor(graph.exit);
3460 } 3468 }
3461 } 3469 }
3462 3470
3463 visitThrow(Throw node) { 3471 visitThrow(Throw node) {
3464 if (node.expression == null) { 3472 if (node.expression == null) {
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
4419 } 4427 }
4420 4428
4421 class InliningState { 4429 class InliningState {
4422 /** 4430 /**
4423 * Documentation wanted -- johnniwinther 4431 * Documentation wanted -- johnniwinther
4424 * 4432 *
4425 * Invariant: [function] must be an implementation element. 4433 * Invariant: [function] must be an implementation element.
4426 */ 4434 */
4427 final PartialFunctionElement function; 4435 final PartialFunctionElement function;
4428 final Element oldReturnElement; 4436 final Element oldReturnElement;
4437 final DartType oldReturnType;
4429 final TreeElements oldElements; 4438 final TreeElements oldElements;
4430 final List<HInstruction> oldStack; 4439 final List<HInstruction> oldStack;
4431 4440
4432 InliningState(this.function, 4441 InliningState(this.function,
4433 this.oldReturnElement, 4442 this.oldReturnElement,
4443 this.oldReturnType,
4434 this.oldElements, 4444 this.oldElements,
4435 this.oldStack) { 4445 this.oldStack) {
4436 assert(function.isImplementation); 4446 assert(function.isImplementation);
4437 } 4447 }
4438 } 4448 }
4439 4449
4440 class SsaBranch { 4450 class SsaBranch {
4441 final SsaBranchBuilder branchBuilder; 4451 final SsaBranchBuilder branchBuilder;
4442 final HBasicBlock block; 4452 final HBasicBlock block;
4443 LocalsHandler startLocals; 4453 LocalsHandler startLocals;
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
4665 new HSubGraphBlockInformation(elseBranch.graph)); 4675 new HSubGraphBlockInformation(elseBranch.graph));
4666 4676
4667 HBasicBlock conditionStartBlock = conditionBranch.block; 4677 HBasicBlock conditionStartBlock = conditionBranch.block;
4668 conditionStartBlock.setBlockFlow(info, joinBlock); 4678 conditionStartBlock.setBlockFlow(info, joinBlock);
4669 SubGraph conditionGraph = conditionBranch.graph; 4679 SubGraph conditionGraph = conditionBranch.graph;
4670 HIf branch = conditionGraph.end.last; 4680 HIf branch = conditionGraph.end.last;
4671 assert(branch is HIf); 4681 assert(branch is HIf);
4672 branch.blockInformation = conditionStartBlock.blockFlow; 4682 branch.blockInformation = conditionStartBlock.blockFlow;
4673 } 4683 }
4674 } 4684 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/lib/js_helper.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698