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 class SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
8 SsaCodeGeneratorTask generator; | 8 SsaCodeGeneratorTask generator; |
9 SsaBuilderTask builder; | 9 SsaBuilderTask builder; |
10 SsaOptimizerTask optimizer; | 10 SsaOptimizerTask optimizer; |
(...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1237 * void foo(a, {b, d, c}) | 1237 * void foo(a, {b, d, c}) |
1238 * foo(0, d = 1, b = 2) | 1238 * foo(0, d = 1, b = 2) |
1239 * | 1239 * |
1240 * providedArguments = [0, 2, 1] | 1240 * providedArguments = [0, 2, 1] |
1241 * selectorArgumentNames = [b, d] | 1241 * selectorArgumentNames = [b, d] |
1242 * signature.orderedOptionalParameters = [b, c, d] | 1242 * signature.orderedOptionalParameters = [b, c, d] |
1243 * | 1243 * |
1244 * For each parameter name in the signature, if the argument name matches | 1244 * For each parameter name in the signature, if the argument name matches |
1245 * we use the next provided argument, otherwise we get the default. | 1245 * we use the next provided argument, otherwise we get the default. |
1246 */ | 1246 */ |
1247 List<String> selectorArgumentNames = selector.getOrderedNamedArguments(); | 1247 List<String> selectorArgumentNames = |
| 1248 selector.callStructure.getOrderedNamedArguments(); |
1248 int namedArgumentIndex = 0; | 1249 int namedArgumentIndex = 0; |
1249 int firstProvidedNamedArgument = index; | 1250 int firstProvidedNamedArgument = index; |
1250 signature.orderedOptionalParameters.forEach((element) { | 1251 signature.orderedOptionalParameters.forEach((element) { |
1251 if (namedArgumentIndex < selectorArgumentNames.length && | 1252 if (namedArgumentIndex < selectorArgumentNames.length && |
1252 element.name == selectorArgumentNames[namedArgumentIndex]) { | 1253 element.name == selectorArgumentNames[namedArgumentIndex]) { |
1253 // The named argument was provided in the function invocation. | 1254 // The named argument was provided in the function invocation. |
1254 compiledArguments[index] = providedArguments[ | 1255 compiledArguments[index] = providedArguments[ |
1255 firstProvidedNamedArgument + namedArgumentIndex++]; | 1256 firstProvidedNamedArgument + namedArgumentIndex++]; |
1256 } else { | 1257 } else { |
1257 compiledArguments[index] = | 1258 compiledArguments[index] = |
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1886 List<FunctionElement> constructors, | 1887 List<FunctionElement> constructors, |
1887 Map<Element, HInstruction> fieldValues) { | 1888 Map<Element, HInstruction> fieldValues) { |
1888 assert(invariant(constructor, constructor.isImplementation)); | 1889 assert(invariant(constructor, constructor.isImplementation)); |
1889 if (constructor.isSynthesized) { | 1890 if (constructor.isSynthesized) { |
1890 List<HInstruction> arguments = <HInstruction>[]; | 1891 List<HInstruction> arguments = <HInstruction>[]; |
1891 HInstruction compileArgument(ParameterElement parameter) { | 1892 HInstruction compileArgument(ParameterElement parameter) { |
1892 return localsHandler.readLocal(parameter); | 1893 return localsHandler.readLocal(parameter); |
1893 } | 1894 } |
1894 | 1895 |
1895 Element target = constructor.definingConstructor.implementation; | 1896 Element target = constructor.definingConstructor.implementation; |
1896 bool match = Selector.addForwardingElementArgumentsToList( | 1897 bool match = CallStructure.addForwardingElementArgumentsToList( |
1897 constructor, | 1898 constructor, |
1898 arguments, | 1899 arguments, |
1899 target, | 1900 target, |
1900 compileArgument, | 1901 compileArgument, |
1901 handleConstantForOptionalParameter, | 1902 handleConstantForOptionalParameter); |
1902 compiler.world); | |
1903 if (!match) { | 1903 if (!match) { |
1904 if (compiler.elementHasCompileTimeError(constructor)) { | 1904 if (compiler.elementHasCompileTimeError(constructor)) { |
1905 return; | 1905 return; |
1906 } | 1906 } |
1907 // If this fails, the selector we constructed for the call to a | 1907 // If this fails, the selector we constructed for the call to a |
1908 // forwarding constructor in a mixin application did not match the | 1908 // forwarding constructor in a mixin application did not match the |
1909 // constructor (which, for example, may happen when the libraries are | 1909 // constructor (which, for example, may happen when the libraries are |
1910 // not compatible for private names, see issue 20394). | 1910 // not compatible for private names, see issue 20394). |
1911 compiler.internalError(constructor, | 1911 compiler.internalError(constructor, |
1912 'forwarding constructor call does not match'); | 1912 'forwarding constructor call does not match'); |
(...skipping 13 matching lines...) Expand all Loading... |
1926 Link<ast.Node> initializers = functionNode.initializers.nodes; | 1926 Link<ast.Node> initializers = functionNode.initializers.nodes; |
1927 for (Link<ast.Node> link = initializers; !link.isEmpty; link = link.tail)
{ | 1927 for (Link<ast.Node> link = initializers; !link.isEmpty; link = link.tail)
{ |
1928 assert(link.head is ast.Send); | 1928 assert(link.head is ast.Send); |
1929 if (link.head is !ast.SendSet) { | 1929 if (link.head is !ast.SendSet) { |
1930 // A super initializer or constructor redirection. | 1930 // A super initializer or constructor redirection. |
1931 foundSuperOrRedirect = true; | 1931 foundSuperOrRedirect = true; |
1932 ast.Send call = link.head; | 1932 ast.Send call = link.head; |
1933 assert(ast.Initializers.isSuperConstructorCall(call) || | 1933 assert(ast.Initializers.isSuperConstructorCall(call) || |
1934 ast.Initializers.isConstructorRedirect(call)); | 1934 ast.Initializers.isConstructorRedirect(call)); |
1935 FunctionElement target = elements[call].implementation; | 1935 FunctionElement target = elements[call].implementation; |
1936 Selector selector = elements.getSelector(call); | 1936 CallStructure callStructure = |
| 1937 elements.getSelector(call).callStructure; |
1937 Link<ast.Node> arguments = call.arguments; | 1938 Link<ast.Node> arguments = call.arguments; |
1938 List<HInstruction> compiledArguments; | 1939 List<HInstruction> compiledArguments; |
1939 inlinedFrom(constructor, () { | 1940 inlinedFrom(constructor, () { |
1940 compiledArguments = | 1941 compiledArguments = |
1941 makeStaticArgumentList(selector, arguments, target); | 1942 makeStaticArgumentList(callStructure, arguments, target); |
1942 }); | 1943 }); |
1943 inlineSuperOrRedirect(target, | 1944 inlineSuperOrRedirect(target, |
1944 compiledArguments, | 1945 compiledArguments, |
1945 constructors, | 1946 constructors, |
1946 fieldValues, | 1947 fieldValues, |
1947 constructor); | 1948 constructor); |
1948 } else { | 1949 } else { |
1949 // A field initializer. | 1950 // A field initializer. |
1950 ast.SendSet init = link.head; | 1951 ast.SendSet init = link.head; |
1951 Link<ast.Node> arguments = init.arguments; | 1952 Link<ast.Node> arguments = init.arguments; |
(...skipping 13 matching lines...) Expand all Loading... |
1965 ClassElement superClass = enclosingClass.superclass; | 1966 ClassElement superClass = enclosingClass.superclass; |
1966 if (!enclosingClass.isObject) { | 1967 if (!enclosingClass.isObject) { |
1967 assert(superClass != null); | 1968 assert(superClass != null); |
1968 assert(superClass.resolutionState == STATE_DONE); | 1969 assert(superClass.resolutionState == STATE_DONE); |
1969 // TODO(johnniwinther): Should we find injected constructors as well? | 1970 // TODO(johnniwinther): Should we find injected constructors as well? |
1970 FunctionElement target = superClass.lookupDefaultConstructor(); | 1971 FunctionElement target = superClass.lookupDefaultConstructor(); |
1971 if (target == null) { | 1972 if (target == null) { |
1972 compiler.internalError(superClass, | 1973 compiler.internalError(superClass, |
1973 "No default constructor available."); | 1974 "No default constructor available."); |
1974 } | 1975 } |
1975 Selector selector = new Selector.callDefaultConstructor(); | |
1976 List<HInstruction> arguments = | 1976 List<HInstruction> arguments = |
1977 selector.makeArgumentsList(const Link<ast.Node>(), | 1977 CallStructure.NO_ARGS.makeArgumentsList( |
1978 target.implementation, | 1978 const Link<ast.Node>(), |
1979 null, | 1979 target.implementation, |
1980 handleConstantForOptionalParameter); | 1980 null, |
| 1981 handleConstantForOptionalParameter); |
1981 inlineSuperOrRedirect(target, | 1982 inlineSuperOrRedirect(target, |
1982 arguments, | 1983 arguments, |
1983 constructors, | 1984 constructors, |
1984 fieldValues, | 1985 fieldValues, |
1985 constructor); | 1986 constructor); |
1986 } | 1987 } |
1987 } | 1988 } |
1988 } | 1989 } |
1989 | 1990 |
1990 /** | 1991 /** |
(...skipping 1524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3515 type, expression, invokeInterceptor(expression), backend.boolType); | 3516 type, expression, invokeInterceptor(expression), backend.boolType); |
3516 } | 3517 } |
3517 } | 3518 } |
3518 | 3519 |
3519 HInstruction buildFunctionType(FunctionType type) { | 3520 HInstruction buildFunctionType(FunctionType type) { |
3520 type.accept(new TypeBuilder(compiler.world), this); | 3521 type.accept(new TypeBuilder(compiler.world), this); |
3521 return pop(); | 3522 return pop(); |
3522 } | 3523 } |
3523 | 3524 |
3524 void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) { | 3525 void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) { |
3525 Selector selector = elements.getSelector(node); | 3526 CallStructure callStructure = elements.getSelector(node).callStructure; |
3526 if (selector.namedArgumentCount == 0) { | 3527 if (callStructure.namedArgumentCount == 0) { |
3527 addGenericSendArgumentsToList(node.arguments, list); | 3528 addGenericSendArgumentsToList(node.arguments, list); |
3528 } else { | 3529 } else { |
3529 // Visit positional arguments and add them to the list. | 3530 // Visit positional arguments and add them to the list. |
3530 Link<ast.Node> arguments = node.arguments; | 3531 Link<ast.Node> arguments = node.arguments; |
3531 int positionalArgumentCount = selector.positionalArgumentCount; | 3532 int positionalArgumentCount = callStructure.positionalArgumentCount; |
3532 for (int i = 0; | 3533 for (int i = 0; |
3533 i < positionalArgumentCount; | 3534 i < positionalArgumentCount; |
3534 arguments = arguments.tail, i++) { | 3535 arguments = arguments.tail, i++) { |
3535 visit(arguments.head); | 3536 visit(arguments.head); |
3536 list.add(pop()); | 3537 list.add(pop()); |
3537 } | 3538 } |
3538 | 3539 |
3539 // Visit named arguments and add them into a temporary map. | 3540 // Visit named arguments and add them into a temporary map. |
3540 Map<String, HInstruction> instructions = | 3541 Map<String, HInstruction> instructions = |
3541 new Map<String, HInstruction>(); | 3542 new Map<String, HInstruction>(); |
3542 List<String> namedArguments = selector.namedArguments; | 3543 List<String> namedArguments = callStructure.namedArguments; |
3543 int nameIndex = 0; | 3544 int nameIndex = 0; |
3544 for (; !arguments.isEmpty; arguments = arguments.tail) { | 3545 for (; !arguments.isEmpty; arguments = arguments.tail) { |
3545 visit(arguments.head); | 3546 visit(arguments.head); |
3546 instructions[namedArguments[nameIndex++]] = pop(); | 3547 instructions[namedArguments[nameIndex++]] = pop(); |
3547 } | 3548 } |
3548 | 3549 |
3549 // Iterate through the named arguments to add them to the list | 3550 // Iterate through the named arguments to add them to the list |
3550 // of instructions, in an order that can be shared with | 3551 // of instructions, in an order that can be shared with |
3551 // selectors with the same named arguments. | 3552 // selectors with the same named arguments. |
3552 List<String> orderedNames = selector.getOrderedNamedArguments(); | 3553 List<String> orderedNames = callStructure.getOrderedNamedArguments(); |
3553 for (String name in orderedNames) { | 3554 for (String name in orderedNames) { |
3554 list.add(instructions[name]); | 3555 list.add(instructions[name]); |
3555 } | 3556 } |
3556 } | 3557 } |
3557 } | 3558 } |
3558 | 3559 |
3559 /** | 3560 /** |
3560 * Returns a list with the evaluated [arguments] in the normalized order. | 3561 * Returns a list with the evaluated [arguments] in the normalized order. |
3561 * | 3562 * |
3562 * Precondition: `this.applies(element, world)`. | 3563 * Precondition: `this.applies(element, world)`. |
3563 * Invariant: [element] must be an implementation element. | 3564 * Invariant: [element] must be an implementation element. |
3564 */ | 3565 */ |
3565 List<HInstruction> makeStaticArgumentList(Selector selector, | 3566 List<HInstruction> makeStaticArgumentList(CallStructure callStructure, |
3566 Link<ast.Node> arguments, | 3567 Link<ast.Node> arguments, |
3567 FunctionElement element) { | 3568 FunctionElement element) { |
3568 assert(invariant(element, element.isImplementation)); | 3569 assert(invariant(element, element.isImplementation)); |
3569 | 3570 |
3570 HInstruction compileArgument(ast.Node argument) { | 3571 HInstruction compileArgument(ast.Node argument) { |
3571 visit(argument); | 3572 visit(argument); |
3572 return pop(); | 3573 return pop(); |
3573 } | 3574 } |
3574 | 3575 |
3575 return selector.makeArgumentsList(arguments, | 3576 return callStructure.makeArgumentsList( |
3576 element, | 3577 arguments, |
3577 compileArgument, | 3578 element, |
3578 handleConstantForOptionalParameter); | 3579 compileArgument, |
| 3580 handleConstantForOptionalParameter); |
3579 } | 3581 } |
3580 | 3582 |
3581 void addGenericSendArgumentsToList(Link<ast.Node> link, List<HInstruction> lis
t) { | 3583 void addGenericSendArgumentsToList(Link<ast.Node> link, List<HInstruction> lis
t) { |
3582 for (; !link.isEmpty; link = link.tail) { | 3584 for (; !link.isEmpty; link = link.tail) { |
3583 visit(link.head); | 3585 visit(link.head); |
3584 list.add(pop()); | 3586 list.add(pop()); |
3585 } | 3587 } |
3586 } | 3588 } |
3587 | 3589 |
3588 visitDynamicSend(ast.Send node) { | 3590 visitDynamicSend(ast.Send node) { |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4096 } | 4098 } |
4097 List<HInstruction> inputs = <HInstruction>[]; | 4099 List<HInstruction> inputs = <HInstruction>[]; |
4098 if (node.isPropertyAccess) { | 4100 if (node.isPropertyAccess) { |
4099 push(buildInvokeSuper(selector, element, inputs)); | 4101 push(buildInvokeSuper(selector, element, inputs)); |
4100 } else if (element.isFunction || element.isGenerativeConstructor) { | 4102 } else if (element.isFunction || element.isGenerativeConstructor) { |
4101 if (selector.applies(element, compiler.world)) { | 4103 if (selector.applies(element, compiler.world)) { |
4102 // TODO(5347): Try to avoid the need for calling [implementation] before | 4104 // TODO(5347): Try to avoid the need for calling [implementation] before |
4103 // calling [makeStaticArgumentList]. | 4105 // calling [makeStaticArgumentList]. |
4104 FunctionElement function = element.implementation; | 4106 FunctionElement function = element.implementation; |
4105 assert(selector.applies(function, compiler.world)); | 4107 assert(selector.applies(function, compiler.world)); |
4106 inputs = makeStaticArgumentList(selector, | 4108 inputs = makeStaticArgumentList(selector.callStructure, |
4107 node.arguments, | 4109 node.arguments, |
4108 function); | 4110 function); |
4109 push(buildInvokeSuper(selector, element, inputs)); | 4111 push(buildInvokeSuper(selector, element, inputs)); |
4110 } else if (element.isGenerativeConstructor) { | 4112 } else if (element.isGenerativeConstructor) { |
4111 generateWrongArgumentCountError(node, element, node.arguments); | 4113 generateWrongArgumentCountError(node, element, node.arguments); |
4112 } else { | 4114 } else { |
4113 addGenericSendArgumentsToList(node.arguments, inputs); | 4115 addGenericSendArgumentsToList(node.arguments, inputs); |
4114 generateSuperNoSuchMethodSend(node, selector, inputs); | 4116 generateSuperNoSuchMethodSend(node, selector, inputs); |
4115 } | 4117 } |
4116 } else { | 4118 } else { |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4340 } else if (element.isGenerativeConstructor) { | 4342 } else if (element.isGenerativeConstructor) { |
4341 ClassElement cls = element.enclosingClass; | 4343 ClassElement cls = element.enclosingClass; |
4342 return new TypeMask.nonNullExact(cls.thisType.element, compiler.world); | 4344 return new TypeMask.nonNullExact(cls.thisType.element, compiler.world); |
4343 } else { | 4345 } else { |
4344 return TypeMaskFactory.inferredReturnTypeForElement( | 4346 return TypeMaskFactory.inferredReturnTypeForElement( |
4345 originalElement, compiler); | 4347 originalElement, compiler); |
4346 } | 4348 } |
4347 } | 4349 } |
4348 | 4350 |
4349 Element constructor = elements[send]; | 4351 Element constructor = elements[send]; |
4350 Selector selector = elements.getSelector(send); | 4352 CallStructure callStructure = elements.getSelector(send).callStructure; |
4351 ConstructorElement constructorDeclaration = constructor; | 4353 ConstructorElement constructorDeclaration = constructor; |
4352 ConstructorElement constructorImplementation = constructor.implementation; | 4354 ConstructorElement constructorImplementation = constructor.implementation; |
4353 constructor = constructorImplementation.effectiveTarget; | 4355 constructor = constructorImplementation.effectiveTarget; |
4354 | 4356 |
4355 final bool isSymbolConstructor = | 4357 final bool isSymbolConstructor = |
4356 constructorDeclaration == compiler.symbolConstructor; | 4358 constructorDeclaration == compiler.symbolConstructor; |
4357 final bool isJSArrayTypedConstructor = | 4359 final bool isJSArrayTypedConstructor = |
4358 constructorDeclaration == backend.jsArrayTypedConstructor; | 4360 constructorDeclaration == backend.jsArrayTypedConstructor; |
4359 | 4361 |
4360 if (isSymbolConstructor) { | 4362 if (isSymbolConstructor) { |
4361 constructor = compiler.symbolValidatedConstructor; | 4363 constructor = compiler.symbolValidatedConstructor; |
4362 assert(invariant(send, constructor != null, | 4364 assert(invariant(send, constructor != null, |
4363 message: 'Constructor Symbol.validated is missing')); | 4365 message: 'Constructor Symbol.validated is missing')); |
4364 selector = compiler.symbolValidatedConstructorSelector; | 4366 callStructure = compiler.symbolValidatedConstructorSelector.callStructure; |
4365 assert(invariant(send, selector != null, | 4367 assert(invariant(send, callStructure != null, |
4366 message: 'Constructor Symbol.validated is missing')); | 4368 message: 'Constructor Symbol.validated is missing')); |
4367 } | 4369 } |
4368 | 4370 |
4369 bool isRedirected = constructorDeclaration.isRedirectingFactory; | 4371 bool isRedirected = constructorDeclaration.isRedirectingFactory; |
4370 InterfaceType type = elements.getType(node); | 4372 InterfaceType type = elements.getType(node); |
4371 InterfaceType expectedType = | 4373 InterfaceType expectedType = |
4372 constructorDeclaration.computeEffectiveTargetType(type); | 4374 constructorDeclaration.computeEffectiveTargetType(type); |
4373 expectedType = localsHandler.substInContext(expectedType); | 4375 expectedType = localsHandler.substInContext(expectedType); |
4374 | 4376 |
4375 if (compiler.elementHasCompileTimeError(constructor)) { | 4377 if (compiler.elementHasCompileTimeError(constructor)) { |
4376 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 4378 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
4377 stack.add(graph.addConstantNull(compiler)); | 4379 stack.add(graph.addConstantNull(compiler)); |
4378 return; | 4380 return; |
4379 } | 4381 } |
4380 if (checkTypeVariableBounds(node, type)) return; | 4382 if (checkTypeVariableBounds(node, type)) return; |
4381 | 4383 |
4382 var inputs = <HInstruction>[]; | 4384 var inputs = <HInstruction>[]; |
4383 if (constructor.isGenerativeConstructor && | 4385 if (constructor.isGenerativeConstructor && |
4384 Elements.isNativeOrExtendsNative(constructor.enclosingClass)) { | 4386 Elements.isNativeOrExtendsNative(constructor.enclosingClass)) { |
4385 // Native class generative constructors take a pre-constructed object. | 4387 // Native class generative constructors take a pre-constructed object. |
4386 inputs.add(graph.addConstantNull(compiler)); | 4388 inputs.add(graph.addConstantNull(compiler)); |
4387 } | 4389 } |
4388 // TODO(5347): Try to avoid the need for calling [implementation] before | 4390 // TODO(5347): Try to avoid the need for calling [implementation] before |
4389 // calling [makeStaticArgumentList]. | 4391 // calling [makeStaticArgumentList]. |
4390 if (!selector.applies(constructor.implementation, compiler.world)) { | 4392 if (!callStructure.signatureApplies(constructor.implementation)) { |
4391 generateWrongArgumentCountError(send, constructor, send.arguments); | 4393 generateWrongArgumentCountError(send, constructor, send.arguments); |
4392 return; | 4394 return; |
4393 } | 4395 } |
4394 inputs.addAll(makeStaticArgumentList(selector, | 4396 inputs.addAll(makeStaticArgumentList(callStructure, |
4395 send.arguments, | 4397 send.arguments, |
4396 constructor.implementation)); | 4398 constructor.implementation)); |
4397 | 4399 |
4398 TypeMask elementType = computeType(constructor); | 4400 TypeMask elementType = computeType(constructor); |
4399 if (isFixedListConstructorCall) { | 4401 if (isFixedListConstructorCall) { |
4400 if (!inputs[0].isNumber(compiler)) { | 4402 if (!inputs[0].isNumber(compiler)) { |
4401 HTypeConversion conversion = new HTypeConversion( | 4403 HTypeConversion conversion = new HTypeConversion( |
4402 null, HTypeConversion.ARGUMENT_TYPE_CHECK, backend.numType, | 4404 null, HTypeConversion.ARGUMENT_TYPE_CHECK, backend.numType, |
4403 inputs[0], null); | 4405 inputs[0], null); |
4404 add(conversion); | 4406 add(conversion); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4543 return; | 4545 return; |
4544 } | 4546 } |
4545 // TODO(johnniwinther): Don't handle assert like a regular static call. | 4547 // TODO(johnniwinther): Don't handle assert like a regular static call. |
4546 // It breaks the selector name check since the assert helper method cannot | 4548 // It breaks the selector name check since the assert helper method cannot |
4547 // be called `assert` and therefore does not match the selector like a | 4549 // be called `assert` and therefore does not match the selector like a |
4548 // regular method. | 4550 // regular method. |
4549 visitStaticSend(node); | 4551 visitStaticSend(node); |
4550 } | 4552 } |
4551 | 4553 |
4552 visitStaticSend(ast.Send node) { | 4554 visitStaticSend(ast.Send node) { |
4553 Selector selector = elements.getSelector(node); | 4555 CallStructure callStructure = elements.getSelector(node).callStructure; |
4554 Element element = elements[node]; | 4556 Element element = elements[node]; |
4555 if (elements.isAssert(node)) { | 4557 if (elements.isAssert(node)) { |
4556 element = backend.assertMethod; | 4558 element = backend.assertMethod; |
4557 } | 4559 } |
4558 if (element.isForeign(backend) && element.isFunction) { | 4560 if (element.isForeign(backend) && element.isFunction) { |
4559 visitForeignSend(node); | 4561 visitForeignSend(node); |
4560 return; | 4562 return; |
4561 } | 4563 } |
4562 if (element.isErroneous) { | 4564 if (element.isErroneous) { |
4563 if (element is ErroneousElement) { | 4565 if (element is ErroneousElement) { |
4564 // An erroneous element indicates that the funciton could not be | 4566 // An erroneous element indicates that the funciton could not be |
4565 // resolved (a warning has been issued). | 4567 // resolved (a warning has been issued). |
4566 generateThrowNoSuchMethod(node, | 4568 generateThrowNoSuchMethod(node, |
4567 noSuchMethodTargetSymbolString(element), | 4569 noSuchMethodTargetSymbolString(element), |
4568 argumentNodes: node.arguments); | 4570 argumentNodes: node.arguments); |
4569 } else { | 4571 } else { |
4570 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 4572 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
4571 stack.add(graph.addConstantNull(compiler)); | 4573 stack.add(graph.addConstantNull(compiler)); |
4572 } | 4574 } |
4573 return; | 4575 return; |
4574 } | 4576 } |
4575 invariant(element, !element.isGenerativeConstructor); | 4577 invariant(element, !element.isGenerativeConstructor); |
4576 generateIsDeferredLoadedCheckIfNeeded(node); | 4578 generateIsDeferredLoadedCheckIfNeeded(node); |
4577 if (element.isFunction) { | 4579 if (element.isFunction) { |
4578 // TODO(5347): Try to avoid the need for calling [implementation] before | 4580 // TODO(5347): Try to avoid the need for calling [implementation] before |
4579 // calling [makeStaticArgumentList]. | 4581 // calling [makeStaticArgumentList]. |
4580 if (!selector.applies(element.implementation, compiler.world)) { | 4582 if (!callStructure.signatureApplies(element.implementation)) { |
4581 generateWrongArgumentCountError(node, element, node.arguments); | 4583 generateWrongArgumentCountError(node, element, node.arguments); |
4582 return; | 4584 return; |
4583 } | 4585 } |
4584 | 4586 |
4585 List<HInstruction> inputs = | 4587 List<HInstruction> inputs = |
4586 makeStaticArgumentList(selector, | 4588 makeStaticArgumentList(callStructure, |
4587 node.arguments, | 4589 node.arguments, |
4588 element.implementation); | 4590 element.implementation); |
4589 | 4591 |
4590 if (element == compiler.identicalFunction) { | 4592 if (element == compiler.identicalFunction) { |
4591 pushWithPosition( | 4593 pushWithPosition( |
4592 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node); | 4594 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node); |
4593 return; | 4595 return; |
4594 } | 4596 } |
4595 | 4597 |
4596 pushInvokeStatic(node, element, inputs); | 4598 pushInvokeStatic(node, element, inputs); |
4597 } else { | 4599 } else { |
4598 generateGetter(node, element); | 4600 generateGetter(node, element); |
4599 List<HInstruction> inputs = <HInstruction>[pop()]; | 4601 List<HInstruction> inputs = <HInstruction>[pop()]; |
4600 addDynamicSendArgumentsToList(node, inputs); | 4602 addDynamicSendArgumentsToList(node, inputs); |
4601 Selector closureSelector = new Selector.callClosureFrom(selector); | 4603 Selector closureSelector = callStructure.callSelector; |
4602 pushWithPosition( | 4604 pushWithPosition( |
4603 new HInvokeClosure(closureSelector, inputs, backend.dynamicType), | 4605 new HInvokeClosure(closureSelector, inputs, backend.dynamicType), |
4604 node); | 4606 node); |
4605 } | 4607 } |
4606 } | 4608 } |
4607 | 4609 |
4608 HConstant addConstantString(String string) { | 4610 HConstant addConstantString(String string) { |
4609 ast.DartString dartString = new ast.DartString.literal(string); | 4611 ast.DartString dartString = new ast.DartString.literal(string); |
4610 ConstantValue constant = constantSystem.createString(dartString); | 4612 ConstantValue constant = constantSystem.createString(dartString); |
4611 return graph.addConstant(constant, compiler); | 4613 return graph.addConstant(constant, compiler); |
(...skipping 2335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6947 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6949 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
6948 unaliased.accept(this, builder); | 6950 unaliased.accept(this, builder); |
6949 } | 6951 } |
6950 | 6952 |
6951 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6953 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
6952 JavaScriptBackend backend = builder.compiler.backend; | 6954 JavaScriptBackend backend = builder.compiler.backend; |
6953 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 6955 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
6954 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 6956 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
6955 } | 6957 } |
6956 } | 6958 } |
OLD | NEW |