OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |