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

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

Issue 614993002: Rename Constant to ConstantValue and ConstExp to ConstantExpression. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 6 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 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 /// A synthetic local variable only used with the SSA graph. 7 /// A synthetic local variable only used with the SSA graph.
8 /// 8 ///
9 /// For instance used for holding return value of function or the exception of a 9 /// For instance used for holding return value of function or the exception of a
10 /// try-catch statement. 10 /// try-catch statement.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 } 51 }
52 } else { 52 } else {
53 compiler.internalError(element, 'Unexpected element kind $kind.'); 53 compiler.internalError(element, 'Unexpected element kind $kind.');
54 } 54 }
55 assert(graph.isValid()); 55 assert(graph.isValid());
56 if (!identical(kind, ElementKind.FIELD)) { 56 if (!identical(kind, ElementKind.FIELD)) {
57 FunctionElement function = element; 57 FunctionElement function = element;
58 FunctionSignature signature = function.functionSignature; 58 FunctionSignature signature = function.functionSignature;
59 signature.forEachOptionalParameter((ParameterElement parameter) { 59 signature.forEachOptionalParameter((ParameterElement parameter) {
60 // This ensures the default value will be computed. 60 // This ensures the default value will be computed.
61 Constant constant = 61 ConstantValue constant =
62 backend.constants.getConstantForVariable(parameter).value; 62 backend.constants.getConstantForVariable(parameter).value;
63 CodegenRegistry registry = work.registry; 63 CodegenRegistry registry = work.registry;
64 registry.registerCompileTimeConstant(constant); 64 registry.registerCompileTimeConstant(constant);
65 }); 65 });
66 } 66 }
67 if (compiler.tracer.isEnabled) { 67 if (compiler.tracer.isEnabled) {
68 String name; 68 String name;
69 if (element.isClassMember) { 69 if (element.isClassMember) {
70 String className = element.enclosingClass.name; 70 String className = element.enclosingClass.name;
71 String memberName = element.name; 71 String memberName = element.name;
(...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 return compiler.withCurrentElement(element, () { 1339 return compiler.withCurrentElement(element, () {
1340 // The [sourceElementStack] contains declaration elements. 1340 // The [sourceElementStack] contains declaration elements.
1341 sourceElementStack.add(element.declaration); 1341 sourceElementStack.add(element.declaration);
1342 var result = f(); 1342 var result = f();
1343 sourceElementStack.removeLast(); 1343 sourceElementStack.removeLast();
1344 return result; 1344 return result;
1345 }); 1345 });
1346 } 1346 }
1347 1347
1348 HInstruction handleConstantForOptionalParameter(Element parameter) { 1348 HInstruction handleConstantForOptionalParameter(Element parameter) {
1349 ConstExp constant = 1349 ConstantExpression constant =
1350 backend.constants.getConstantForVariable(parameter); 1350 backend.constants.getConstantForVariable(parameter);
1351 assert(invariant(parameter, constant != null, 1351 assert(invariant(parameter, constant != null,
1352 message: 'No constant computed for $parameter')); 1352 message: 'No constant computed for $parameter'));
1353 return graph.addConstant(constant.value, compiler); 1353 return graph.addConstant(constant.value, compiler);
1354 } 1354 }
1355 1355
1356 Element get currentNonClosureClass { 1356 Element get currentNonClosureClass {
1357 ClassElement cls = sourceElement.enclosingClass; 1357 ClassElement cls = sourceElement.enclosingClass;
1358 if (cls != null && cls.isClosure) { 1358 if (cls != null && cls.isClosure) {
1359 var closureClass = cls; 1359 var closureClass = cls;
(...skipping 18 matching lines...) Expand all
1378 // types of the type variables in an environment (like the [LocalsHandler]). 1378 // types of the type variables in an environment (like the [LocalsHandler]).
1379 final List<DartType> currentInlinedInstantiations = <DartType>[]; 1379 final List<DartType> currentInlinedInstantiations = <DartType>[];
1380 1380
1381 final List<AstInliningState> inliningStack = <AstInliningState>[]; 1381 final List<AstInliningState> inliningStack = <AstInliningState>[];
1382 1382
1383 Local returnLocal; 1383 Local returnLocal;
1384 DartType returnType; 1384 DartType returnType;
1385 1385
1386 bool inTryStatement = false; 1386 bool inTryStatement = false;
1387 1387
1388 Constant getConstantForNode(ast.Node node) { 1388 ConstantValue getConstantForNode(ast.Node node) {
1389 ConstExp constant = 1389 ConstantExpression constant =
1390 backend.constants.getConstantForNode(node, elements); 1390 backend.constants.getConstantForNode(node, elements);
1391 assert(invariant(node, constant != null, 1391 assert(invariant(node, constant != null,
1392 message: 'No constant computed for $node')); 1392 message: 'No constant computed for $node'));
1393 return constant.value; 1393 return constant.value;
1394 } 1394 }
1395 1395
1396 HInstruction addConstant(ast.Node node) { 1396 HInstruction addConstant(ast.Node node) {
1397 return graph.addConstant(getConstantForNode(node), compiler); 1397 return graph.addConstant(getConstantForNode(node), compiler);
1398 } 1398 }
1399 1399
1400 bool isLazilyInitialized(VariableElement element) { 1400 bool isLazilyInitialized(VariableElement element) {
1401 ConstExp initialValue = 1401 ConstantExpression initialValue =
1402 backend.constants.getConstantForVariable(element); 1402 backend.constants.getConstantForVariable(element);
1403 return initialValue == null; 1403 return initialValue == null;
1404 } 1404 }
1405 1405
1406 TypeMask cachedTypeOfThis; 1406 TypeMask cachedTypeOfThis;
1407 1407
1408 TypeMask getTypeOfThis() { 1408 TypeMask getTypeOfThis() {
1409 TypeMask result = cachedTypeOfThis; 1409 TypeMask result = cachedTypeOfThis;
1410 if (result == null) { 1410 if (result == null) {
1411 ThisLocal local = localsHandler.closureData.thisLocal; 1411 ThisLocal local = localsHandler.closureData.thisLocal;
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
2052 remainingTypeVariables = contextClass.typeVariables.length; 2052 remainingTypeVariables = contextClass.typeVariables.length;
2053 } else { 2053 } else {
2054 assert(source == newSource); 2054 assert(source == newSource);
2055 } 2055 }
2056 // If there are no more type variables, then there are more type 2056 // If there are no more type variables, then there are more type
2057 // arguments for the new object than the source has, and it can't be 2057 // arguments for the new object than the source has, and it can't be
2058 // a copy. Otherwise remove one argument. 2058 // a copy. Otherwise remove one argument.
2059 if (remainingTypeVariables == 0) return false; 2059 if (remainingTypeVariables == 0) return false;
2060 remainingTypeVariables--; 2060 remainingTypeVariables--;
2061 // Check that the index is the one we expect. 2061 // Check that the index is the one we expect.
2062 IntConstant constant = index.constant; 2062 IntConstantValue constant = index.constant;
2063 return constant.value == expectedIndex++; 2063 return constant.primitiveValue == expectedIndex++;
2064 } 2064 }
2065 2065
2066 List<HInstruction> typeArguments = <HInstruction>[]; 2066 List<HInstruction> typeArguments = <HInstruction>[];
2067 classElement.typeVariables.forEach((TypeVariableType typeVariable) { 2067 classElement.typeVariables.forEach((TypeVariableType typeVariable) {
2068 HInstruction argument = localsHandler.readLocal( 2068 HInstruction argument = localsHandler.readLocal(
2069 localsHandler.getTypeVariableAsLocal(typeVariable)); 2069 localsHandler.getTypeVariableAsLocal(typeVariable));
2070 if (allIndexed && !isIndexedTypeArgumentGet(argument)) { 2070 if (allIndexed && !isIndexedTypeArgumentGet(argument)) {
2071 allIndexed = false; 2071 allIndexed = false;
2072 } 2072 }
2073 typeArguments.add(argument); 2073 typeArguments.add(argument);
(...skipping 11 matching lines...) Expand all
2085 HInstruction interceptor = null; 2085 HInstruction interceptor = null;
2086 for (int index = constructors.length - 1; index >= 0; index--) { 2086 for (int index = constructors.length - 1; index >= 0; index--) {
2087 FunctionElement constructor = constructors[index]; 2087 FunctionElement constructor = constructors[index];
2088 assert(invariant(functionElement, constructor.isImplementation)); 2088 assert(invariant(functionElement, constructor.isImplementation));
2089 ConstructorBodyElement body = getConstructorBody(constructor); 2089 ConstructorBodyElement body = getConstructorBody(constructor);
2090 if (body == null) continue; 2090 if (body == null) continue;
2091 2091
2092 List bodyCallInputs = <HInstruction>[]; 2092 List bodyCallInputs = <HInstruction>[];
2093 if (isNativeUpgradeFactory) { 2093 if (isNativeUpgradeFactory) {
2094 if (interceptor == null) { 2094 if (interceptor == null) {
2095 Constant constant = new InterceptorConstant(classElement.thisType); 2095 ConstantValue constant =
2096 new InterceptorConstantValue(classElement.thisType);
2096 interceptor = graph.addConstant(constant, compiler); 2097 interceptor = graph.addConstant(constant, compiler);
2097 } 2098 }
2098 bodyCallInputs.add(interceptor); 2099 bodyCallInputs.add(interceptor);
2099 } 2100 }
2100 bodyCallInputs.add(newObject); 2101 bodyCallInputs.add(newObject);
2101 ResolvedAst resolvedAst = constructor.resolvedAst; 2102 ResolvedAst resolvedAst = constructor.resolvedAst;
2102 TreeElements elements = resolvedAst.elements; 2103 TreeElements elements = resolvedAst.elements;
2103 ast.Node node = resolvedAst.node; 2104 ast.Node node = resolvedAst.node;
2104 ClosureClassMap parameterClosureData = 2105 ClosureClassMap parameterClosureData =
2105 compiler.closureToClassMapper.getMappingForNestedFunction(node); 2106 compiler.closureToClassMapper.getMappingForNestedFunction(node);
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 void visitUnary(ast.Send node, ast.Operator op) { 2993 void visitUnary(ast.Send node, ast.Operator op) {
2993 assert(node.argumentsNode is ast.Prefix); 2994 assert(node.argumentsNode is ast.Prefix);
2994 visit(node.receiver); 2995 visit(node.receiver);
2995 assert(!identical(op.token.kind, PLUS_TOKEN)); 2996 assert(!identical(op.token.kind, PLUS_TOKEN));
2996 HInstruction operand = pop(); 2997 HInstruction operand = pop();
2997 2998
2998 // See if we can constant-fold right away. This avoids rewrites later on. 2999 // See if we can constant-fold right away. This avoids rewrites later on.
2999 if (operand is HConstant) { 3000 if (operand is HConstant) {
3000 UnaryOperation operation = constantSystem.lookupUnary(op.source); 3001 UnaryOperation operation = constantSystem.lookupUnary(op.source);
3001 HConstant constant = operand; 3002 HConstant constant = operand;
3002 Constant folded = operation.fold(constant.constant); 3003 ConstantValue folded = operation.fold(constant.constant);
3003 if (folded != null) { 3004 if (folded != null) {
3004 stack.add(graph.addConstant(folded, compiler)); 3005 stack.add(graph.addConstant(folded, compiler));
3005 return; 3006 return;
3006 } 3007 }
3007 } 3008 }
3008 3009
3009 pushInvokeDynamic(node, elements.getSelector(node), [operand]); 3010 pushInvokeDynamic(node, elements.getSelector(node), [operand]);
3010 } 3011 }
3011 3012
3012 void visitBinary(HInstruction left, 3013 void visitBinary(HInstruction left,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
3075 Element helper = backend.getCheckDeferredIsLoaded(); 3076 Element helper = backend.getCheckDeferredIsLoaded();
3076 pushInvokeStatic(node, helper, [loadIdConstant, uriConstant]); 3077 pushInvokeStatic(node, helper, [loadIdConstant, uriConstant]);
3077 pop(); 3078 pop();
3078 } 3079 }
3079 } 3080 }
3080 3081
3081 void generateGetter(ast.Send send, Element element) { 3082 void generateGetter(ast.Send send, Element element) {
3082 if (element != null && element.isForeign(backend)) { 3083 if (element != null && element.isForeign(backend)) {
3083 visitForeignGetter(send); 3084 visitForeignGetter(send);
3084 } else if (Elements.isStaticOrTopLevelField(element)) { 3085 } else if (Elements.isStaticOrTopLevelField(element)) {
3085 ConstExp constant; 3086 ConstantExpression constant;
3086 if (element.isField && !element.isAssignable) { 3087 if (element.isField && !element.isAssignable) {
3087 // A static final or const. Get its constant value and inline it if 3088 // A static final or const. Get its constant value and inline it if
3088 // the value can be compiled eagerly. 3089 // the value can be compiled eagerly.
3089 constant = backend.constants.getConstantForVariable(element); 3090 constant = backend.constants.getConstantForVariable(element);
3090 } 3091 }
3091 if (constant != null) { 3092 if (constant != null) {
3092 Constant value = constant.value; 3093 ConstantValue value = constant.value;
3093 HConstant instruction; 3094 HConstant instruction;
3094 // Constants that are referred via a deferred prefix should be referred 3095 // Constants that are referred via a deferred prefix should be referred
3095 // by reference. 3096 // by reference.
3096 PrefixElement prefix = compiler.deferredLoadTask 3097 PrefixElement prefix = compiler.deferredLoadTask
3097 .deferredPrefixElement(send, elements); 3098 .deferredPrefixElement(send, elements);
3098 if (prefix != null) { 3099 if (prefix != null) {
3099 instruction = graph.addDeferredConstant(value, prefix, compiler); 3100 instruction = graph.addDeferredConstant(value, prefix, compiler);
3100 } else { 3101 } else {
3101 instruction = graph.addConstant(value, compiler); 3102 instruction = graph.addConstant(value, compiler);
3102 } 3103 }
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
3635 visit(arguments[1]); 3636 visit(arguments[1]);
3636 HInstruction globalNameHNode = pop(); 3637 HInstruction globalNameHNode = pop();
3637 if (!globalNameHNode.isConstantString()) { 3638 if (!globalNameHNode.isConstantString()) {
3638 compiler.reportError( 3639 compiler.reportError(
3639 arguments[1], MessageKind.GENERIC, 3640 arguments[1], MessageKind.GENERIC,
3640 {'text': 'Error: Expected String as second argument ' 3641 {'text': 'Error: Expected String as second argument '
3641 'to JS_EMBEDDED_GLOBAL.'}); 3642 'to JS_EMBEDDED_GLOBAL.'});
3642 return; 3643 return;
3643 } 3644 }
3644 HConstant hConstant = globalNameHNode; 3645 HConstant hConstant = globalNameHNode;
3645 StringConstant constant = hConstant.constant; 3646 StringConstantValue constant = hConstant.constant;
3646 String globalName = constant.value.slowToString(); 3647 String globalName = constant.primitiveValue.slowToString();
3647 js.Template expr = js.js.expressionTemplateYielding( 3648 js.Template expr = js.js.expressionTemplateYielding(
3648 backend.emitter.generateEmbeddedGlobalAccess(globalName)); 3649 backend.emitter.generateEmbeddedGlobalAccess(globalName));
3649 native.NativeBehavior nativeBehavior = 3650 native.NativeBehavior nativeBehavior =
3650 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); 3651 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
3651 TypeMask ssaType = 3652 TypeMask ssaType =
3652 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); 3653 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
3653 push(new HForeign(expr, ssaType, const [])); 3654 push(new HForeign(expr, ssaType, const []));
3654 } 3655 }
3655 3656
3656 void handleJsInterceptorConstant(ast.Send node) { 3657 void handleJsInterceptorConstant(ast.Send node) {
3657 // Single argument must be a TypeConstant which is converted into a 3658 // Single argument must be a TypeConstant which is converted into a
3658 // InterceptorConstant. 3659 // InterceptorConstant.
3659 if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) { 3660 if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) {
3660 ast.Node argument = node.arguments.head; 3661 ast.Node argument = node.arguments.head;
3661 visit(argument); 3662 visit(argument);
3662 HInstruction argumentInstruction = pop(); 3663 HInstruction argumentInstruction = pop();
3663 if (argumentInstruction is HConstant) { 3664 if (argumentInstruction is HConstant) {
3664 Constant argumentConstant = argumentInstruction.constant; 3665 ConstantValue argumentConstant = argumentInstruction.constant;
3665 if (argumentConstant is TypeConstant) { 3666 if (argumentConstant is TypeConstantValue) {
3666 Constant constant = 3667 ConstantValue constant =
3667 new InterceptorConstant(argumentConstant.representedType); 3668 new InterceptorConstantValue(argumentConstant.representedType);
3668 HInstruction instruction = graph.addConstant(constant, compiler); 3669 HInstruction instruction = graph.addConstant(constant, compiler);
3669 stack.add(instruction); 3670 stack.add(instruction);
3670 return; 3671 return;
3671 } 3672 }
3672 } 3673 }
3673 } 3674 }
3674 compiler.reportError(node, 3675 compiler.reportError(node,
3675 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); 3676 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
3676 stack.add(graph.addConstantNull(compiler)); 3677 stack.add(graph.addConstantNull(compiler));
3677 } 3678 }
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
3880 && element.enclosingElement.declaration != compiler.objectClass) { 3881 && element.enclosingElement.declaration != compiler.objectClass) {
3881 // Register the call as dynamic if [noSuchMethod] on the super 3882 // Register the call as dynamic if [noSuchMethod] on the super
3882 // class is _not_ the default implementation from [Object], in 3883 // class is _not_ the default implementation from [Object], in
3883 // case the [noSuchMethod] implementation calls 3884 // case the [noSuchMethod] implementation calls
3884 // [JSInvocationMirror._invokeOn]. 3885 // [JSInvocationMirror._invokeOn].
3885 registry.registerSelectorUse(selector.asUntyped); 3886 registry.registerSelectorUse(selector.asUntyped);
3886 } 3887 }
3887 String publicName = name; 3888 String publicName = name;
3888 if (selector.isSetter) publicName += '='; 3889 if (selector.isSetter) publicName += '=';
3889 3890
3890 Constant nameConstant = constantSystem.createString( 3891 ConstantValue nameConstant = constantSystem.createString(
3891 new ast.DartString.literal(publicName)); 3892 new ast.DartString.literal(publicName));
3892 3893
3893 String internalName = backend.namer.invocationName(selector); 3894 String internalName = backend.namer.invocationName(selector);
3894 Constant internalNameConstant = 3895 ConstantValue internalNameConstant =
3895 constantSystem.createString(new ast.DartString.literal(internalName)); 3896 constantSystem.createString(new ast.DartString.literal(internalName));
3896 3897
3897 Element createInvocationMirror = backend.getCreateInvocationMirror(); 3898 Element createInvocationMirror = backend.getCreateInvocationMirror();
3898 var argumentsInstruction = buildLiteralList(arguments); 3899 var argumentsInstruction = buildLiteralList(arguments);
3899 add(argumentsInstruction); 3900 add(argumentsInstruction);
3900 3901
3901 var argumentNames = new List<HInstruction>(); 3902 var argumentNames = new List<HInstruction>();
3902 for (String argumentName in selector.namedArguments) { 3903 for (String argumentName in selector.namedArguments) {
3903 Constant argumentNameConstant = 3904 ConstantValue argumentNameConstant =
3904 constantSystem.createString(new ast.DartString.literal(argumentName)); 3905 constantSystem.createString(new ast.DartString.literal(argumentName));
3905 argumentNames.add(graph.addConstant(argumentNameConstant, compiler)); 3906 argumentNames.add(graph.addConstant(argumentNameConstant, compiler));
3906 } 3907 }
3907 var argumentNamesInstruction = buildLiteralList(argumentNames); 3908 var argumentNamesInstruction = buildLiteralList(argumentNames);
3908 add(argumentNamesInstruction); 3909 add(argumentNamesInstruction);
3909 3910
3910 Constant kindConstant = 3911 ConstantValue kindConstant =
3911 constantSystem.createInt(selector.invocationMirrorKind); 3912 constantSystem.createInt(selector.invocationMirrorKind);
3912 3913
3913 pushInvokeStatic(null, 3914 pushInvokeStatic(null,
3914 createInvocationMirror, 3915 createInvocationMirror,
3915 [graph.addConstant(nameConstant, compiler), 3916 [graph.addConstant(nameConstant, compiler),
3916 graph.addConstant(internalNameConstant, compiler), 3917 graph.addConstant(internalNameConstant, compiler),
3917 graph.addConstant(kindConstant, compiler), 3918 graph.addConstant(kindConstant, compiler),
3918 argumentsInstruction, 3919 argumentsInstruction,
3919 argumentNamesInstruction], 3920 argumentNamesInstruction],
3920 backend.dynamicType); 3921 backend.dynamicType);
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
4245 inputs[0] = conversion; 4246 inputs[0] = conversion;
4246 } 4247 }
4247 js.Template code = js.js.parseForeignJS('Array(#)'); 4248 js.Template code = js.js.parseForeignJS('Array(#)');
4248 var behavior = new native.NativeBehavior(); 4249 var behavior = new native.NativeBehavior();
4249 behavior.typesReturned.add(expectedType); 4250 behavior.typesReturned.add(expectedType);
4250 // The allocation can throw only if the given length is a double 4251 // The allocation can throw only if the given length is a double
4251 // or negative. 4252 // or negative.
4252 bool canThrow = true; 4253 bool canThrow = true;
4253 if (inputs[0].isInteger(compiler) && inputs[0] is HConstant) { 4254 if (inputs[0].isInteger(compiler) && inputs[0] is HConstant) {
4254 var constant = inputs[0]; 4255 var constant = inputs[0];
4255 if (constant.constant.value >= 0) canThrow = false; 4256 if (constant.constant.primitiveValue >= 0) canThrow = false;
4256 } 4257 }
4257 HForeign foreign = new HForeign( 4258 HForeign foreign = new HForeign(
4258 code, elementType, inputs, nativeBehavior: behavior, 4259 code, elementType, inputs, nativeBehavior: behavior,
4259 canThrow: canThrow); 4260 canThrow: canThrow);
4260 push(foreign); 4261 push(foreign);
4261 TypesInferrer inferrer = compiler.typesTask.typesInferrer; 4262 TypesInferrer inferrer = compiler.typesTask.typesInferrer;
4262 if (inferrer.isFixedArrayCheckedForGrowable(send)) { 4263 if (inferrer.isFixedArrayCheckedForGrowable(send)) {
4263 js.Template code = js.js.parseForeignJS(r'#.fixed$length = init'); 4264 js.Template code = js.js.parseForeignJS(r'#.fixed$length = init');
4264 // We set the instruction as [canThrow] to avoid it being dead code. 4265 // We set the instruction as [canThrow] to avoid it being dead code.
4265 // We need a finer grained side effect. 4266 // We need a finer grained side effect.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
4434 addDynamicSendArgumentsToList(node, inputs); 4435 addDynamicSendArgumentsToList(node, inputs);
4435 Selector closureSelector = new Selector.callClosureFrom(selector); 4436 Selector closureSelector = new Selector.callClosureFrom(selector);
4436 pushWithPosition( 4437 pushWithPosition(
4437 new HInvokeClosure(closureSelector, inputs, backend.dynamicType), 4438 new HInvokeClosure(closureSelector, inputs, backend.dynamicType),
4438 node); 4439 node);
4439 } 4440 }
4440 } 4441 }
4441 4442
4442 HConstant addConstantString(String string) { 4443 HConstant addConstantString(String string) {
4443 ast.DartString dartString = new ast.DartString.literal(string); 4444 ast.DartString dartString = new ast.DartString.literal(string);
4444 Constant constant = constantSystem.createString(dartString); 4445 ConstantValue constant = constantSystem.createString(dartString);
4445 return graph.addConstant(constant, compiler); 4446 return graph.addConstant(constant, compiler);
4446 } 4447 }
4447 4448
4448 visitTypePrefixSend(ast.Send node) { 4449 visitTypePrefixSend(ast.Send node) {
4449 compiler.internalError(node, "visitTypePrefixSend should not be called."); 4450 compiler.internalError(node, "visitTypePrefixSend should not be called.");
4450 } 4451 }
4451 4452
4452 visitTypeLiteralSend(ast.Send node) { 4453 visitTypeLiteralSend(ast.Send node) {
4453 DartType type = elements.getTypeLiteralType(node); 4454 DartType type = elements.getTypeLiteralType(node);
4454 if (type.isInterfaceType || type.isTypedef || type.isDynamic) { 4455 if (type.isInterfaceType || type.isTypedef || type.isDynamic) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
4515 message, 4516 message,
4516 backend.getThrowAbstractClassInstantiationError()); 4517 backend.getThrowAbstractClassInstantiationError());
4517 } 4518 }
4518 4519
4519 void generateThrowNoSuchMethod(ast.Node diagnosticNode, 4520 void generateThrowNoSuchMethod(ast.Node diagnosticNode,
4520 String methodName, 4521 String methodName,
4521 {Link<ast.Node> argumentNodes, 4522 {Link<ast.Node> argumentNodes,
4522 List<HInstruction> argumentValues, 4523 List<HInstruction> argumentValues,
4523 List<String> existingArguments}) { 4524 List<String> existingArguments}) {
4524 Element helper = backend.getThrowNoSuchMethod(); 4525 Element helper = backend.getThrowNoSuchMethod();
4525 Constant receiverConstant = 4526 ConstantValue receiverConstant =
4526 constantSystem.createString(new ast.DartString.empty()); 4527 constantSystem.createString(new ast.DartString.empty());
4527 HInstruction receiver = graph.addConstant(receiverConstant, compiler); 4528 HInstruction receiver = graph.addConstant(receiverConstant, compiler);
4528 ast.DartString dartString = new ast.DartString.literal(methodName); 4529 ast.DartString dartString = new ast.DartString.literal(methodName);
4529 Constant nameConstant = constantSystem.createString(dartString); 4530 ConstantValue nameConstant = constantSystem.createString(dartString);
4530 HInstruction name = graph.addConstant(nameConstant, compiler); 4531 HInstruction name = graph.addConstant(nameConstant, compiler);
4531 if (argumentValues == null) { 4532 if (argumentValues == null) {
4532 argumentValues = <HInstruction>[]; 4533 argumentValues = <HInstruction>[];
4533 argumentNodes.forEach((argumentNode) { 4534 argumentNodes.forEach((argumentNode) {
4534 visit(argumentNode); 4535 visit(argumentNode);
4535 HInstruction value = pop(); 4536 HInstruction value = pop();
4536 argumentValues.add(value); 4537 argumentValues.add(value);
4537 }); 4538 });
4538 } 4539 }
4539 HInstruction arguments = buildLiteralList(argumentValues); 4540 HInstruction arguments = buildLiteralList(argumentValues);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4589 node.send, 4590 node.send,
4590 noSuchMethodTargetSymbolString(error, 'constructor'), 4591 noSuchMethodTargetSymbolString(error, 'constructor'),
4591 argumentNodes: node.send.arguments); 4592 argumentNodes: node.send.arguments);
4592 } else { 4593 } else {
4593 Message message = error.messageKind.message(error.messageArguments); 4594 Message message = error.messageKind.message(error.messageArguments);
4594 generateRuntimeError(node.send, message.toString()); 4595 generateRuntimeError(node.send, message.toString());
4595 } 4596 }
4596 } else if (node.isConst) { 4597 } else if (node.isConst) {
4597 stack.add(addConstant(node)); 4598 stack.add(addConstant(node));
4598 if (isSymbolConstructor) { 4599 if (isSymbolConstructor) {
4599 ConstructedConstant symbol = getConstantForNode(node); 4600 ConstructedConstantValue symbol = getConstantForNode(node);
4600 StringConstant stringConstant = symbol.fields.single; 4601 StringConstantValue stringConstant = symbol.fields.single;
4601 String nameString = stringConstant.toDartString().slowToString(); 4602 String nameString = stringConstant.toDartString().slowToString();
4602 registry.registerConstSymbol(nameString); 4603 registry.registerConstSymbol(nameString);
4603 } 4604 }
4604 } else { 4605 } else {
4605 handleNewSend(node); 4606 handleNewSend(node);
4606 } 4607 }
4607 } 4608 }
4608 4609
4609 void pushInvokeDynamic(ast.Node node, 4610 void pushInvokeDynamic(ast.Node node,
4610 Selector selector, 4611 Selector selector,
(...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after
5361 5362
5362 visitLiteralMapEntry(ast.LiteralMapEntry node) { 5363 visitLiteralMapEntry(ast.LiteralMapEntry node) {
5363 visit(node.value); 5364 visit(node.value);
5364 visit(node.key); 5365 visit(node.key);
5365 } 5366 }
5366 5367
5367 visitNamedArgument(ast.NamedArgument node) { 5368 visitNamedArgument(ast.NamedArgument node) {
5368 visit(node.expression); 5369 visit(node.expression);
5369 } 5370 }
5370 5371
5371 Map<ast.CaseMatch, Constant> buildSwitchCaseConstants(ast.SwitchStatement node ) { 5372 Map<ast.CaseMatch, ConstantValue> buildSwitchCaseConstants(
5372 Map<ast.CaseMatch, Constant> constants = new Map<ast.CaseMatch, Constant>(); 5373 ast.SwitchStatement node) {
5374
5375 Map<ast.CaseMatch, ConstantValue> constants =
5376 new Map<ast.CaseMatch, ConstantValue>();
5373 for (ast.SwitchCase switchCase in node.cases) { 5377 for (ast.SwitchCase switchCase in node.cases) {
5374 for (ast.Node labelOrCase in switchCase.labelsAndCases) { 5378 for (ast.Node labelOrCase in switchCase.labelsAndCases) {
5375 if (labelOrCase is ast.CaseMatch) { 5379 if (labelOrCase is ast.CaseMatch) {
5376 ast.CaseMatch match = labelOrCase; 5380 ast.CaseMatch match = labelOrCase;
5377 Constant constant = getConstantForNode(match.expression); 5381 ConstantValue constant = getConstantForNode(match.expression);
5378 constants[labelOrCase] = constant; 5382 constants[labelOrCase] = constant;
5379 } 5383 }
5380 } 5384 }
5381 } 5385 }
5382 return constants; 5386 return constants;
5383 } 5387 }
5384 5388
5385 visitSwitchStatement(ast.SwitchStatement node) { 5389 visitSwitchStatement(ast.SwitchStatement node) {
5386 Map<ast.CaseMatch, Constant> constants = buildSwitchCaseConstants(node); 5390 Map<ast.CaseMatch, ConstantValue> constants =
5391 buildSwitchCaseConstants(node);
5387 5392
5388 // The switch case indices must match those computed in 5393 // The switch case indices must match those computed in
5389 // [SwitchCaseJumpHandler]. 5394 // [SwitchCaseJumpHandler].
5390 bool hasContinue = false; 5395 bool hasContinue = false;
5391 Map<ast.SwitchCase, int> caseIndex = new Map<ast.SwitchCase, int>(); 5396 Map<ast.SwitchCase, int> caseIndex = new Map<ast.SwitchCase, int>();
5392 int switchIndex = 1; 5397 int switchIndex = 1;
5393 bool hasDefault = false; 5398 bool hasDefault = false;
5394 for (ast.SwitchCase switchCase in node.cases) { 5399 for (ast.SwitchCase switchCase in node.cases) {
5395 for (ast.Node labelOrCase in switchCase.labelsAndCases) { 5400 for (ast.Node labelOrCase in switchCase.labelsAndCases) {
5396 ast.Node label = labelOrCase.asLabel(); 5401 ast.Node label = labelOrCase.asLabel();
(...skipping 17 matching lines...) Expand all
5414 } else { 5419 } else {
5415 buildComplexSwitchStatement(node, constants, caseIndex, hasDefault); 5420 buildComplexSwitchStatement(node, constants, caseIndex, hasDefault);
5416 } 5421 }
5417 } 5422 }
5418 5423
5419 /** 5424 /**
5420 * Builds a simple switch statement which does not handle uses of continue 5425 * Builds a simple switch statement which does not handle uses of continue
5421 * statements to labeled switch cases. 5426 * statements to labeled switch cases.
5422 */ 5427 */
5423 void buildSimpleSwitchStatement(ast.SwitchStatement node, 5428 void buildSimpleSwitchStatement(ast.SwitchStatement node,
5424 Map<ast.CaseMatch, Constant> constants) { 5429 Map<ast.CaseMatch, ConstantValue> constants) {
5425 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false); 5430 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false);
5426 HInstruction buildExpression() { 5431 HInstruction buildExpression() {
5427 visit(node.expression); 5432 visit(node.expression);
5428 return pop(); 5433 return pop();
5429 } 5434 }
5430 Iterable<Constant> getConstants(ast.SwitchCase switchCase) { 5435 Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
5431 List<Constant> constantList = <Constant>[]; 5436 List<ConstantValue> constantList = <ConstantValue>[];
5432 for (ast.Node labelOrCase in switchCase.labelsAndCases) { 5437 for (ast.Node labelOrCase in switchCase.labelsAndCases) {
5433 if (labelOrCase is ast.CaseMatch) { 5438 if (labelOrCase is ast.CaseMatch) {
5434 constantList.add(constants[labelOrCase]); 5439 constantList.add(constants[labelOrCase]);
5435 } 5440 }
5436 } 5441 }
5437 return constantList; 5442 return constantList;
5438 } 5443 }
5439 bool isDefaultCase(ast.SwitchCase switchCase) { 5444 bool isDefaultCase(ast.SwitchCase switchCase) {
5440 return switchCase.isDefaultCase; 5445 return switchCase.isDefaultCase;
5441 } 5446 }
5442 void buildSwitchCase(ast.SwitchCase node) { 5447 void buildSwitchCase(ast.SwitchCase node) {
5443 visit(node.statements); 5448 visit(node.statements);
5444 } 5449 }
5445 handleSwitch(node, 5450 handleSwitch(node,
5446 jumpHandler, 5451 jumpHandler,
5447 buildExpression, 5452 buildExpression,
5448 node.cases, 5453 node.cases,
5449 getConstants, 5454 getConstants,
5450 isDefaultCase, 5455 isDefaultCase,
5451 buildSwitchCase); 5456 buildSwitchCase);
5452 jumpHandler.close(); 5457 jumpHandler.close();
5453 } 5458 }
5454 5459
5455 /** 5460 /**
5456 * Builds a switch statement that can handle arbitrary uses of continue 5461 * Builds a switch statement that can handle arbitrary uses of continue
5457 * statements to labeled switch cases. 5462 * statements to labeled switch cases.
5458 */ 5463 */
5459 void buildComplexSwitchStatement(ast.SwitchStatement node, 5464 void buildComplexSwitchStatement(ast.SwitchStatement node,
5460 Map<ast.CaseMatch, Constant> constants, 5465 Map<ast.CaseMatch, ConstantValue> constants,
5461 Map<ast.SwitchCase, int> caseIndex, 5466 Map<ast.SwitchCase, int> caseIndex,
5462 bool hasDefault) { 5467 bool hasDefault) {
5463 // If the switch statement has switch cases targeted by continue 5468 // If the switch statement has switch cases targeted by continue
5464 // statements we create the following encoding: 5469 // statements we create the following encoding:
5465 // 5470 //
5466 // switch (e) { 5471 // switch (e) {
5467 // l_1: case e0: s_1; break; 5472 // l_1: case e0: s_1; break;
5468 // l_2: case e1: s_2; continue l_i; 5473 // l_2: case e1: s_2; continue l_i;
5469 // ... 5474 // ...
5470 // l_n: default: s_n; continue l_j; 5475 // l_n: default: s_n; continue l_j;
(...skipping 26 matching lines...) Expand all
5497 if (!hasDefault) { 5502 if (!hasDefault) {
5498 // Use [:null:] as the marker for a synthetic default clause. 5503 // Use [:null:] as the marker for a synthetic default clause.
5499 // The synthetic default is added because otherwise, there would be no 5504 // The synthetic default is added because otherwise, there would be no
5500 // good place to give a default value to the local. 5505 // good place to give a default value to the local.
5501 switchCases = node.cases.nodes.toList()..add(null); 5506 switchCases = node.cases.nodes.toList()..add(null);
5502 } 5507 }
5503 HInstruction buildExpression() { 5508 HInstruction buildExpression() {
5504 visit(node.expression); 5509 visit(node.expression);
5505 return pop(); 5510 return pop();
5506 } 5511 }
5507 Iterable<Constant> getConstants(ast.SwitchCase switchCase) { 5512 Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
5508 List<Constant> constantList = <Constant>[]; 5513 List<ConstantValue> constantList = <ConstantValue>[];
5509 if (switchCase != null) { 5514 if (switchCase != null) {
5510 for (ast.Node labelOrCase in switchCase.labelsAndCases) { 5515 for (ast.Node labelOrCase in switchCase.labelsAndCases) {
5511 if (labelOrCase is ast.CaseMatch) { 5516 if (labelOrCase is ast.CaseMatch) {
5512 constantList.add(constants[labelOrCase]); 5517 constantList.add(constants[labelOrCase]);
5513 } 5518 }
5514 } 5519 }
5515 } 5520 }
5516 return constantList; 5521 return constantList;
5517 } 5522 }
5518 bool isDefaultCase(ast.SwitchCase switchCase) { 5523 bool isDefaultCase(ast.SwitchCase switchCase) {
(...skipping 21 matching lines...) Expand all
5540 buildSwitchCase); 5545 buildSwitchCase);
5541 jumpHandler.close(); 5546 jumpHandler.close();
5542 5547
5543 HInstruction buildCondition() => 5548 HInstruction buildCondition() =>
5544 graph.addConstantBool(true, compiler); 5549 graph.addConstantBool(true, compiler);
5545 5550
5546 void buildSwitch() { 5551 void buildSwitch() {
5547 HInstruction buildExpression() { 5552 HInstruction buildExpression() {
5548 return localsHandler.readLocal(switchTarget); 5553 return localsHandler.readLocal(switchTarget);
5549 } 5554 }
5550 Iterable<Constant> getConstants(ast.SwitchCase switchCase) { 5555 Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
5551 return <Constant>[constantSystem.createInt(caseIndex[switchCase])]; 5556 return <ConstantValue>[constantSystem.createInt(caseIndex[switchCase])];
5552 } 5557 }
5553 void buildSwitchCase(ast.SwitchCase switchCase) { 5558 void buildSwitchCase(ast.SwitchCase switchCase) {
5554 visit(switchCase.statements); 5559 visit(switchCase.statements);
5555 if (!isAborted()) { 5560 if (!isAborted()) {
5556 // Ensure that we break the loop if the case falls through. (This 5561 // Ensure that we break the loop if the case falls through. (This
5557 // is only possible for the last case.) 5562 // is only possible for the last case.)
5558 jumpTargets[switchTarget].generateBreak(); 5563 jumpTargets[switchTarget].generateBreak();
5559 } 5564 }
5560 } 5565 }
5561 // Pass a [NullJumpHandler] because the target for the contained break 5566 // Pass a [NullJumpHandler] because the target for the contained break
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
5596 * 5601 *
5597 * [jumpHandler] is the [JumpHandler] for the created switch statement. 5602 * [jumpHandler] is the [JumpHandler] for the created switch statement.
5598 * [buildExpression] creates the switch expression. 5603 * [buildExpression] creates the switch expression.
5599 * [switchCases] must be either an [Iterable] of [ast.SwitchCase] nodes or 5604 * [switchCases] must be either an [Iterable] of [ast.SwitchCase] nodes or
5600 * a [Link] or a [ast.NodeList] of [ast.SwitchCase] nodes. 5605 * a [Link] or a [ast.NodeList] of [ast.SwitchCase] nodes.
5601 * [getConstants] returns the set of constants for a switch case. 5606 * [getConstants] returns the set of constants for a switch case.
5602 * [isDefaultCase] returns [:true:] if the provided switch case should be 5607 * [isDefaultCase] returns [:true:] if the provided switch case should be
5603 * considered default for the created switch statement. 5608 * considered default for the created switch statement.
5604 * [buildSwitchCase] creates the statements for the switch case. 5609 * [buildSwitchCase] creates the statements for the switch case.
5605 */ 5610 */
5606 void handleSwitch(ast.Node errorNode, 5611 void handleSwitch(
5607 JumpHandler jumpHandler, 5612 ast.Node errorNode,
5608 HInstruction buildExpression(), 5613 JumpHandler jumpHandler,
5609 var switchCases, 5614 HInstruction buildExpression(),
5610 Iterable<Constant> getConstants(ast.SwitchCase switchCase), 5615 var switchCases,
5611 bool isDefaultCase(ast.SwitchCase switchCase), 5616 Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase),
5612 void buildSwitchCase(ast.SwitchCase switchCase)) { 5617 bool isDefaultCase(ast.SwitchCase switchCase),
5613 Map<ast.CaseMatch, Constant> constants = new Map<ast.CaseMatch, Constant>(); 5618 void buildSwitchCase(ast.SwitchCase switchCase)) {
5619
5620 Map<ast.CaseMatch, ConstantValue> constants =
5621 new Map<ast.CaseMatch, ConstantValue>();
5614 5622
5615 HBasicBlock expressionStart = openNewBlock(); 5623 HBasicBlock expressionStart = openNewBlock();
5616 HInstruction expression = buildExpression(); 5624 HInstruction expression = buildExpression();
5617 if (switchCases.isEmpty) { 5625 if (switchCases.isEmpty) {
5618 return; 5626 return;
5619 } 5627 }
5620 5628
5621 HSwitch switchInstruction = new HSwitch(<HInstruction>[expression]); 5629 HSwitch switchInstruction = new HSwitch(<HInstruction>[expression]);
5622 HBasicBlock expressionEnd = close(switchInstruction); 5630 HBasicBlock expressionEnd = close(switchInstruction);
5623 LocalsHandler savedLocals = localsHandler; 5631 LocalsHandler savedLocals = localsHandler;
5624 5632
5625 List<HStatementInformation> statements = <HStatementInformation>[]; 5633 List<HStatementInformation> statements = <HStatementInformation>[];
5626 bool hasDefault = false; 5634 bool hasDefault = false;
5627 Element getFallThroughErrorElement = backend.getFallThroughError(); 5635 Element getFallThroughErrorElement = backend.getFallThroughError();
5628 HasNextIterator<ast.Node> caseIterator = 5636 HasNextIterator<ast.Node> caseIterator =
5629 new HasNextIterator<ast.Node>(switchCases.iterator); 5637 new HasNextIterator<ast.Node>(switchCases.iterator);
5630 while (caseIterator.hasNext) { 5638 while (caseIterator.hasNext) {
5631 ast.SwitchCase switchCase = caseIterator.next(); 5639 ast.SwitchCase switchCase = caseIterator.next();
5632 HBasicBlock block = graph.addNewBlock(); 5640 HBasicBlock block = graph.addNewBlock();
5633 for (Constant constant in getConstants(switchCase)) { 5641 for (ConstantValue constant in getConstants(switchCase)) {
5634 HConstant hConstant = graph.addConstant(constant, compiler); 5642 HConstant hConstant = graph.addConstant(constant, compiler);
5635 switchInstruction.inputs.add(hConstant); 5643 switchInstruction.inputs.add(hConstant);
5636 hConstant.usedBy.add(switchInstruction); 5644 hConstant.usedBy.add(switchInstruction);
5637 expressionEnd.addSuccessor(block); 5645 expressionEnd.addSuccessor(block);
5638 } 5646 }
5639 5647
5640 if (isDefaultCase(switchCase)) { 5648 if (isDefaultCase(switchCase)) {
5641 // An HSwitch has n inputs and n+1 successors, the last being the 5649 // An HSwitch has n inputs and n+1 successors, the last being the
5642 // default case. 5650 // default case.
5643 expressionEnd.addSuccessor(block); 5651 expressionEnd.addSuccessor(block);
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after
6550 if (unaliased is TypedefType) throw 'unable to unalias $type'; 6558 if (unaliased is TypedefType) throw 'unable to unalias $type';
6551 unaliased.accept(this, builder); 6559 unaliased.accept(this, builder);
6552 } 6560 }
6553 6561
6554 void visitDynamicType(DynamicType type, SsaBuilder builder) { 6562 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6555 JavaScriptBackend backend = builder.compiler.backend; 6563 JavaScriptBackend backend = builder.compiler.backend;
6556 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 6564 ClassElement cls = backend.findHelper('DynamicRuntimeType');
6557 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 6565 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
6558 } 6566 }
6559 } 6567 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698