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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 1112563002: Refactor SsaBuilder.visitStaticSend and visitGetterSend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add tests. Created 5 years, 7 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
« no previous file with comments | « pkg/compiler/lib/src/resolved_visitor.dart ('k') | tests/compiler/dart2js/compiler_helper.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 class 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 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 backend.constants.getConstantForNode(node, elements); 1511 backend.constants.getConstantForNode(node, elements);
1512 assert(invariant(node, constant != null, 1512 assert(invariant(node, constant != null,
1513 message: 'No constant computed for $node')); 1513 message: 'No constant computed for $node'));
1514 return constant.value; 1514 return constant.value;
1515 } 1515 }
1516 1516
1517 HInstruction addConstant(ast.Node node) { 1517 HInstruction addConstant(ast.Node node) {
1518 return graph.addConstant(getConstantForNode(node), compiler); 1518 return graph.addConstant(getConstantForNode(node), compiler);
1519 } 1519 }
1520 1520
1521 bool isLazilyInitialized(VariableElement element) {
1522 ConstantExpression initialValue =
1523 backend.constants.getConstantForVariable(element);
1524 return initialValue == null;
1525 }
1526
1527 TypeMask cachedTypeOfThis; 1521 TypeMask cachedTypeOfThis;
1528 1522
1529 TypeMask getTypeOfThis() { 1523 TypeMask getTypeOfThis() {
1530 TypeMask result = cachedTypeOfThis; 1524 TypeMask result = cachedTypeOfThis;
1531 if (result == null) { 1525 if (result == null) {
1532 ThisLocal local = localsHandler.closureData.thisLocal; 1526 ThisLocal local = localsHandler.closureData.thisLocal;
1533 ClassElement cls = local.enclosingClass; 1527 ClassElement cls = local.enclosingClass;
1534 ClassWorld classWorld = compiler.world; 1528 ClassWorld classWorld = compiler.world;
1535 if (classWorld.isUsedAsMixin(cls)) { 1529 if (classWorld.isUsedAsMixin(cls)) {
1536 // If the enclosing class is used as a mixin, [:this:] can be 1530 // If the enclosing class is used as a mixin, [:this:] can be
(...skipping 1701 matching lines...) Expand 10 before | Expand all | Expand 10 after
3238 deferredTask.importDeferName[prefixElement.deferredImport]; 3232 deferredTask.importDeferName[prefixElement.deferredImport];
3239 HInstruction loadIdConstant = addConstantString(loadId); 3233 HInstruction loadIdConstant = addConstantString(loadId);
3240 String uri = prefixElement.deferredImport.uri.dartString.slowToString(); 3234 String uri = prefixElement.deferredImport.uri.dartString.slowToString();
3241 HInstruction uriConstant = addConstantString(uri); 3235 HInstruction uriConstant = addConstantString(uri);
3242 Element helper = backend.getCheckDeferredIsLoaded(); 3236 Element helper = backend.getCheckDeferredIsLoaded();
3243 pushInvokeStatic(node, helper, [loadIdConstant, uriConstant]); 3237 pushInvokeStatic(node, helper, [loadIdConstant, uriConstant]);
3244 pop(); 3238 pop();
3245 } 3239 }
3246 } 3240 }
3247 3241
3248 void generateGetter(ast.Send send, Element element) { 3242 /// Generate read access of an unresolved static or top level entity.
3249 if (element != null && element.isForeign(backend)) { 3243 void generateStaticUnresolvedGet(ast.Send node, Element element) {
3250 visitForeignGetter(send); 3244 if (element is ErroneousElement) {
3251 } else if (Elements.isStaticOrTopLevelField(element)) { 3245 // An erroneous element indicates an unresolved static getter.
3252 ConstantExpression constant; 3246 generateThrowNoSuchMethod(
3253 if (element.isField && !element.isAssignable) { 3247 node,
3248 noSuchMethodTargetSymbolString(element, 'get'),
3249 argumentNodes: const Link<ast.Node>());
3250 } else {
3251 // TODO(ahe): Do something like the above, that is, emit a runtime
3252 // error.
3253 stack.add(graph.addConstantNull(compiler));
karlklose 2015/04/29 10:54:23 Please add a comment on what this case is and an a
Johnni Winther 2015/04/29 11:38:09 Done.
3254 }
3255 }
3256
3257 /// Read a static or top level [field] of constant value.
3258 void generateStaticConstGet(
3259 ast.Send node,
3260 FieldElement field,
3261 ConstantExpression constant) {
3262 ConstantValue value = constant.value;
3263 HConstant instruction;
3264 // Constants that are referred via a deferred prefix should be referred
3265 // by reference.
3266 PrefixElement prefix = compiler.deferredLoadTask
3267 .deferredPrefixElement(node, elements);
3268 if (prefix != null) {
3269 instruction = graph.addDeferredConstant(value, prefix, compiler);
3270 } else {
3271 instruction = graph.addConstant(value, compiler);
3272 }
3273 stack.add(instruction);
3274 // The inferrer may have found a better type than the constant
3275 // handler in the case of lists, because the constant handler
3276 // does not look at elements in the list.
3277 TypeMask type =
3278 TypeMaskFactory.inferredTypeForElement(field, compiler);
3279 if (!type.containsAll(compiler.world) &&
3280 !instruction.isConstantNull()) {
3281 // TODO(13429): The inferrer should know that an element
3282 // cannot be null.
3283 instruction.instructionType = type.nonNullable();
3284 }
3285 }
3286
3287 /// Read a static or top level [field].
3288 void generateStaticFieldGet(ast.Send node, FieldElement field) {
3289 generateIsDeferredLoadedCheckIfNeeded(node);
3290
3291 ConstantExpression constant =
3292 backend.constants.getConstantForVariable(field);
3293 if (constant != null) {
3294 if (!field.isAssignable) {
3254 // A static final or const. Get its constant value and inline it if 3295 // A static final or const. Get its constant value and inline it if
3255 // the value can be compiled eagerly. 3296 // the value can be compiled eagerly.
3256 constant = backend.constants.getConstantForVariable(element); 3297 generateStaticConstGet(node, field, constant);
3257 } 3298 } else {
3258 if (constant != null) { 3299 // TODO(5346): Try to avoid the need for calling [declaration] before
3259 ConstantValue value = constant.value; 3300 // creating an [HStatic].
3260 HConstant instruction; 3301 HInstruction instruction = new HStatic(
3261 // Constants that are referred via a deferred prefix should be referred 3302 field.declaration,
3262 // by reference. 3303 TypeMaskFactory.inferredTypeForElement(field, compiler));
3263 PrefixElement prefix = compiler.deferredLoadTask
3264 .deferredPrefixElement(send, elements);
3265 if (prefix != null) {
3266 instruction = graph.addDeferredConstant(value, prefix, compiler);
3267 } else {
3268 instruction = graph.addConstant(value, compiler);
3269 }
3270 stack.add(instruction);
3271 // The inferrer may have found a better type than the constant
3272 // handler in the case of lists, because the constant handler
3273 // does not look at elements in the list.
3274 TypeMask type =
3275 TypeMaskFactory.inferredTypeForElement(element, compiler);
3276 if (!type.containsAll(compiler.world) &&
3277 !instruction.isConstantNull()) {
3278 // TODO(13429): The inferrer should know that an element
3279 // cannot be null.
3280 instruction.instructionType = type.nonNullable();
3281 }
3282 } else if (element.isField && isLazilyInitialized(element)) {
3283 HInstruction instruction = new HLazyStatic(
3284 element,
3285 TypeMaskFactory.inferredTypeForElement(element, compiler));
3286 push(instruction); 3304 push(instruction);
3287 } else {
3288 if (element.isGetter) {
3289 pushInvokeStatic(send, element, <HInstruction>[]);
3290 } else {
3291 // TODO(5346): Try to avoid the need for calling [declaration] before
3292 // creating an [HStatic].
3293 HInstruction instruction = new HStatic(
3294 element.declaration,
3295 TypeMaskFactory.inferredTypeForElement(element, compiler));
3296 push(instruction);
3297 }
3298 }
3299 } else if (Elements.isInstanceSend(send, elements)) {
3300 HInstruction receiver = generateInstanceSendReceiver(send);
3301 generateInstanceGetterWithCompiledReceiver(
3302 send, elements.getSelector(send), receiver);
3303 } else if (Elements.isStaticOrTopLevelFunction(element)) {
3304 // TODO(5346): Try to avoid the need for calling [declaration] before
3305 // creating an [HStatic].
3306 push(new HStatic(element.declaration, backend.nonNullType));
3307 // TODO(ahe): This should be registered in codegen.
3308 registry.registerGetOfStaticFunction(element.declaration);
3309 } else if (Elements.isErroneous(element)) {
3310 if (element is ErroneousElement) {
3311 // An erroneous element indicates an unresolved static getter.
3312 generateThrowNoSuchMethod(
3313 send,
3314 noSuchMethodTargetSymbolString(element, 'get'),
3315 argumentNodes: const Link<ast.Node>());
3316 } else {
3317 // TODO(ahe): Do something like the above, that is, emit a runtime
3318 // error.
3319 stack.add(graph.addConstantNull(compiler));
3320 } 3305 }
3321 } else { 3306 } else {
3322 if (send.asSendSet() == null) { 3307 HInstruction instruction = new HLazyStatic(
3323 internalError(send, "Unhandled local: $element"); 3308 field,
3324 } 3309 TypeMaskFactory.inferredTypeForElement(field, compiler));
3325 // TODO(johnniwinther): Remove this when [generateGetter] is no longer 3310 push(instruction);
3326 // called from [visitSendSet] (for compound assignments).
3327 handleLocalGet(element);
3328 } 3311 }
3329 } 3312 }
3330 3313
3314 /// Generate a getter invocation of the static or top level [getter].
3315 void generateStaticGetterGet(ast.Send node, MethodElement getter) {
3316 if (getter.isDeferredLoaderGetter) {
3317 generateDeferredLoaderGet(node, getter);
3318 } else {
3319 generateIsDeferredLoadedCheckIfNeeded(node);
3320 pushInvokeStatic(node, getter, <HInstruction>[]);
3321 }
3322 }
3323
3324 /// Generate a dynamic getter invocation.
3325 void generateDynamicGet(ast.Send node) {
3326 HInstruction receiver = generateInstanceSendReceiver(node);
3327 generateInstanceGetterWithCompiledReceiver(
3328 node, elements.getSelector(node), receiver);
3329 }
3330
3331 /// Generate a closurization of the static or top level [function].
3332 void generateStaticFunctionGet(ast.Send node, MethodElement function) {
3333 generateIsDeferredLoadedCheckIfNeeded(node);
3334 // TODO(5346): Try to avoid the need for calling [declaration] before
3335 // creating an [HStatic].
3336 push(new HStatic(function.declaration, backend.nonNullType));
3337 // TODO(ahe): This should be registered in codegen.
3338 registry.registerGetOfStaticFunction(function.declaration);
3339 }
3340
3331 /// Read a local variable, function or parameter. 3341 /// Read a local variable, function or parameter.
3332 void handleLocalGet(LocalElement local) { 3342 void handleLocalGet(LocalElement local) {
3333 stack.add(localsHandler.readLocal(local)); 3343 stack.add(localsHandler.readLocal(local));
3334 } 3344 }
3335 3345
3336 @override 3346 @override
3347 void visitDynamicPropertyGet(
3348 ast.Send node,
3349 ast.Node receiver,
3350 Selector selector,
3351 _) {
3352 generateDynamicGet(node);
3353 }
3354
3355 @override
3337 void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) { 3356 void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) {
3338 handleLocalGet(variable); 3357 handleLocalGet(variable);
3339 } 3358 }
3340 3359
3341 @override 3360 @override
3342 void visitParameterGet(ast.Send node, ParameterElement parameter, _) { 3361 void visitParameterGet(ast.Send node, ParameterElement parameter, _) {
3343 handleLocalGet(parameter); 3362 handleLocalGet(parameter);
3344 } 3363 }
3345 3364
3346 @override 3365 @override
3347 void visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) { 3366 void visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) {
3348 handleLocalGet(function); 3367 handleLocalGet(function);
3349 } 3368 }
3350 3369
3370 @override
3371 void visitStaticFieldGet(
3372 ast.Send node,
3373 FieldElement field,
3374 _) {
3375 generateStaticFieldGet(node, field);
3376 }
3377
3378 @override
3379 void visitStaticFunctionGet(
3380 ast.Send node,
3381 MethodElement function,
3382 _) {
3383 generateStaticFunctionGet(node, function);
3384 }
3385
3386 @override
3387 void visitStaticGetterGet(
3388 ast.Send node,
3389 FunctionElement getter,
3390 _) {
3391 generateStaticGetterGet(node, getter);
3392 }
3393
3394 @override
3395 void visitThisPropertyGet(
3396 ast.Send node,
3397 Selector selector,
3398 _) {
3399 generateDynamicGet(node);
3400 }
3401
3402 @override
3403 void visitTopLevelFieldGet(
3404 ast.Send node,
3405 FieldElement field,
3406 _) {
3407 generateStaticFieldGet(node, field);
3408 }
3409
3410 @override
3411 void visitTopLevelFunctionGet(
3412 ast.Send node,
3413 MethodElement function,
3414 _) {
3415 generateStaticFunctionGet(node, function);
3416 }
3417
3418 @override
3419 void visitTopLevelGetterGet(
3420 ast.Send node,
3421 FunctionElement getter,
3422 _) {
3423 generateStaticGetterGet(node, getter);
3424 }
3425
3351 void generateInstanceSetterWithCompiledReceiver(ast.Send send, 3426 void generateInstanceSetterWithCompiledReceiver(ast.Send send,
3352 HInstruction receiver, 3427 HInstruction receiver,
3353 HInstruction value, 3428 HInstruction value,
3354 {Selector selector, 3429 {Selector selector,
3355 ast.Node location}) { 3430 ast.Node location}) {
3356 assert(send == null || Elements.isInstanceSend(send, elements)); 3431 assert(send == null || Elements.isInstanceSend(send, elements));
3357 if (selector == null) { 3432 if (selector == null) {
3358 assert(send != null); 3433 assert(send != null);
3359 selector = elements.getSelector(send); 3434 selector = elements.getSelector(send);
3360 } 3435 }
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
4007 4082
4008 void handleForeignJsCurrentIsolate(ast.Send node) { 4083 void handleForeignJsCurrentIsolate(ast.Send node) {
4009 if (!node.arguments.isEmpty) { 4084 if (!node.arguments.isEmpty) {
4010 compiler.internalError(node.argumentsNode, 'Too many arguments.'); 4085 compiler.internalError(node.argumentsNode, 'Too many arguments.');
4011 } 4086 }
4012 push(new HForeignCode(js.js.parseForeignJS(backend.namer.currentIsolate), 4087 push(new HForeignCode(js.js.parseForeignJS(backend.namer.currentIsolate),
4013 backend.dynamicType, 4088 backend.dynamicType,
4014 <HInstruction>[])); 4089 <HInstruction>[]));
4015 } 4090 }
4016 4091
4017 visitForeignSend(ast.Send node) { 4092 void visitForeignSend(ast.Send node, FunctionElement element) {
karlklose 2015/04/29 10:54:23 Can we rename this method to handleForeignSend?
Johnni Winther 2015/04/29 11:38:09 Done.
4018 Selector selector = elements.getSelector(node); 4093 String name = element.name;
4019 String name = selector.name;
4020 if (name == 'JS') { 4094 if (name == 'JS') {
4021 handleForeignJs(node); 4095 handleForeignJs(node);
4022 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') { 4096 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
4023 handleForeignJsCurrentIsolateContext(node); 4097 handleForeignJsCurrentIsolateContext(node);
4024 } else if (name == 'JS_CALL_IN_ISOLATE') { 4098 } else if (name == 'JS_CALL_IN_ISOLATE') {
4025 handleForeignJsCallInIsolate(node); 4099 handleForeignJsCallInIsolate(node);
4026 } else if (name == 'DART_CLOSURE_TO_JS') { 4100 } else if (name == 'DART_CLOSURE_TO_JS') {
4027 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS'); 4101 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS');
4028 } else if (name == 'RAW_DART_FUNCTION_REF') { 4102 } else if (name == 'RAW_DART_FUNCTION_REF') {
4029 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); 4103 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF');
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4084 handleForeignJsBuiltin(node); 4158 handleForeignJsBuiltin(node);
4085 } else if (name == 'JS_GET_FLAG') { 4159 } else if (name == 'JS_GET_FLAG') {
4086 handleForeingJsGetFlag(node); 4160 handleForeingJsGetFlag(node);
4087 } else if (name == 'JS_EFFECT') { 4161 } else if (name == 'JS_EFFECT') {
4088 stack.add(graph.addConstantNull(compiler)); 4162 stack.add(graph.addConstantNull(compiler));
4089 } else if (name == 'JS_INTERCEPTOR_CONSTANT') { 4163 } else if (name == 'JS_INTERCEPTOR_CONSTANT') {
4090 handleJsInterceptorConstant(node); 4164 handleJsInterceptorConstant(node);
4091 } else if (name == 'JS_STRING_CONCAT') { 4165 } else if (name == 'JS_STRING_CONCAT') {
4092 handleJsStringConcat(node); 4166 handleJsStringConcat(node);
4093 } else { 4167 } else {
4094 throw "Unknown foreign: ${selector}"; 4168 throw "Unknown foreign: ${element}";
4095 } 4169 }
4096 } 4170 }
4097 4171
4098 visitForeignGetter(ast.Send node) { 4172 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader) {
4099 Element element = elements[node];
4100 // Until now we only handle these as getters. 4173 // Until now we only handle these as getters.
4101 invariant(node, element.isDeferredLoaderGetter); 4174 invariant(node, deferredLoader.isDeferredLoaderGetter);
4102 FunctionElement deferredLoader = element;
4103 Element loadFunction = compiler.loadLibraryFunction; 4175 Element loadFunction = compiler.loadLibraryFunction;
4104 PrefixElement prefixElement = deferredLoader.enclosingElement; 4176 PrefixElement prefixElement = deferredLoader.enclosingElement;
4105 String loadId = compiler.deferredLoadTask 4177 String loadId = compiler.deferredLoadTask
4106 .importDeferName[prefixElement.deferredImport]; 4178 .importDeferName[prefixElement.deferredImport];
4107 var inputs = [graph.addConstantString( 4179 var inputs = [graph.addConstantString(
4108 new ast.DartString.literal(loadId), compiler)]; 4180 new ast.DartString.literal(loadId), compiler)];
4109 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType, 4181 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType,
4110 targetCanThrow: false)); 4182 targetCanThrow: false));
4111 } 4183 }
4112 4184
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
4791 } 4863 }
4792 4864
4793 @override 4865 @override
4794 visitAssert(ast.Send node, ast.Node expression, _) { 4866 visitAssert(ast.Send node, ast.Node expression, _) {
4795 if (!compiler.enableUserAssertions) { 4867 if (!compiler.enableUserAssertions) {
4796 stack.add(graph.addConstantNull(compiler)); 4868 stack.add(graph.addConstantNull(compiler));
4797 return; 4869 return;
4798 } 4870 }
4799 assert(invariant(node, node.arguments.tail.isEmpty, 4871 assert(invariant(node, node.arguments.tail.isEmpty,
4800 message: "Invalid assertion: $node")); 4872 message: "Invalid assertion: $node"));
4801 buildStaticFunctionInvoke( 4873 generateStaticFunctionInvoke(
4802 node, backend.assertMethod, CallStructure.ONE_ARG); 4874 node, backend.assertMethod, CallStructure.ONE_ARG);
4803 } 4875 }
4804 4876
4805 visitStaticSend(ast.Send node) { 4877 visitStaticSend(ast.Send node) {
4806 CallStructure callStructure = elements.getSelector(node).callStructure; 4878 internalError(node, "Unexpected visitStaticSend");
4807 Element element = elements[node];
4808 if (elements.isAssert(node)) {
4809 element = backend.assertMethod;
4810 }
4811 if (element.isForeign(backend) && element.isFunction) {
4812 visitForeignSend(node);
4813 return;
4814 }
4815 if (element.isErroneous) {
4816 if (element is ErroneousElement) {
4817 // An erroneous element indicates that the funciton could not be
4818 // resolved (a warning has been issued).
4819 generateThrowNoSuchMethod(node,
4820 noSuchMethodTargetSymbolString(element),
4821 argumentNodes: node.arguments);
4822 } else {
4823 // TODO(ahe): Do something like [generateWrongArgumentCountError].
4824 stack.add(graph.addConstantNull(compiler));
4825 }
4826 return;
4827 }
4828 invariant(element, !element.isGenerativeConstructor);
4829 generateIsDeferredLoadedCheckIfNeeded(node);
4830 if (element.isFunction) {
4831 // TODO(5347): Try to avoid the need for calling [implementation] before
4832 // calling [makeStaticArgumentList].
4833 if (!callStructure.signatureApplies(element.implementation)) {
4834 generateWrongArgumentCountError(node, element, node.arguments);
4835 return;
4836 }
4837 buildStaticFunctionInvoke(node, element, callStructure);
4838 } else {
4839 generateGetter(node, element);
4840 List<HInstruction> inputs = <HInstruction>[pop()];
4841 addDynamicSendArgumentsToList(node, inputs);
4842 Selector closureSelector = callStructure.callSelector;
4843 pushWithPosition(
4844 new HInvokeClosure(closureSelector, inputs, backend.dynamicType),
4845 node);
4846 }
4847 } 4879 }
4848 4880
4849 void buildStaticFunctionInvoke( 4881 /// Generate an invocation to the static or top level [function].
4882 void generateStaticFunctionInvoke(
4850 ast.Send node, 4883 ast.Send node,
4851 FunctionElement element, 4884 FunctionElement function,
4852 CallStructure callStructure) { 4885 CallStructure callStructure) {
4853 List<HInstruction> inputs = makeStaticArgumentList( 4886 List<HInstruction> inputs = makeStaticArgumentList(
4854 callStructure, 4887 callStructure,
4855 node.arguments, 4888 node.arguments,
4856 element.implementation); 4889 function.implementation);
4857 4890
4858 if (element == compiler.identicalFunction) { 4891 if (function == compiler.identicalFunction) {
4859 pushWithPosition( 4892 pushWithPosition(
4860 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node); 4893 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node);
4861 return; 4894 return;
4862 } else { 4895 } else {
4863 pushInvokeStatic(node, element, inputs); 4896 pushInvokeStatic(node, function, inputs);
4864 } 4897 }
4865 } 4898 }
4866 4899
4900 /// Generate an invocation to a static or top level function with the wrong
4901 /// number of arguments.
4902 void generateStaticFunctionIncompatibleInvoke(ast.Send node,
4903 Element element) {
4904 generateWrongArgumentCountError(node, element, node.arguments);
4905 }
4906
4907 @override
4908 void visitStaticFieldInvoke(
4909 ast.Send node,
4910 FieldElement field,
4911 ast.NodeList arguments,
4912 CallStructure callStructure,
4913 _) {
4914 generateStaticFieldGet(node, field);
4915 generateCallInvoke(node, pop());
4916 }
4917
4918 @override
4919 void visitStaticFunctionInvoke(
4920 ast.Send node,
4921 MethodElement function,
4922 ast.NodeList arguments,
4923 CallStructure callStructure,
4924 _) {
4925 generateStaticFunctionInvoke(node, function, callStructure);
4926 }
4927
4928 @override
4929 void visitStaticFunctionIncompatibleInvoke(
4930 ast.Send node,
4931 MethodElement function,
4932 ast.NodeList arguments,
4933 CallStructure callStructure,
4934 _) {
4935 generateStaticFunctionIncompatibleInvoke(node, function);
4936 }
4937
4938 @override
4939 void visitStaticGetterInvoke(
4940 ast.Send node,
4941 FunctionElement getter,
4942 ast.NodeList arguments,
4943 CallStructure callStructure,
4944 _) {
4945 generateStaticGetterGet(node, getter);
4946 generateCallInvoke(node, pop());
4947 }
4948
4949 @override
4950 void visitTopLevelFieldInvoke(
4951 ast.Send node,
4952 FieldElement field,
4953 ast.NodeList arguments,
4954 CallStructure callStructure,
4955 _) {
4956 generateStaticFieldGet(node, field);
4957 generateCallInvoke(node, pop());
4958 }
4959
4960 @override
4961 void visitTopLevelFunctionInvoke(
4962 ast.Send node,
4963 MethodElement function,
4964 ast.NodeList arguments,
4965 CallStructure callStructure,
4966 _) {
4967 if (function.isForeign(backend)) {
4968 visitForeignSend(node, function);
4969 } else {
4970 generateStaticFunctionInvoke(node, function, callStructure);
4971 }
4972 }
4973
4974 @override
4975 void visitTopLevelFunctionIncompatibleInvoke(
4976 ast.Send node,
4977 MethodElement function,
4978 ast.NodeList arguments,
4979 CallStructure callStructure,
4980 _) {
4981 generateStaticFunctionIncompatibleInvoke(node, function);
4982 }
4983
4984 @override
4985 void visitTopLevelGetterInvoke(
4986 ast.Send node,
4987 FunctionElement getter,
4988 ast.NodeList arguments,
4989 CallStructure callStructure,
4990 _) {
4991 generateStaticGetterGet(node, getter);
4992 generateCallInvoke(node, pop());
4993 }
4994
4995 @override
4996 void visitUnresolvedGet(
4997 ast.Send node,
4998 Element element,
4999 _) {
5000 generateStaticUnresolvedGet(node, element);
5001 }
5002
5003 @override
5004 void visitUnresolvedInvoke(
5005 ast.Send node,
5006 Element element,
5007 ast.NodeList arguments,
5008 Selector selector,
5009 _) {
5010 if (element is ErroneousElement) {
5011 // An erroneous element indicates that the funciton could not be
5012 // resolved (a warning has been issued).
5013 generateThrowNoSuchMethod(node,
5014 noSuchMethodTargetSymbolString(element),
5015 argumentNodes: node.arguments);
5016 } else {
5017 // TODO(ahe): Do something like [generateWrongArgumentCountError].
5018 stack.add(graph.addConstantNull(compiler));
5019 }
5020 return;
5021 }
5022
4867 HConstant addConstantString(String string) { 5023 HConstant addConstantString(String string) {
4868 ast.DartString dartString = new ast.DartString.literal(string); 5024 ast.DartString dartString = new ast.DartString.literal(string);
4869 ConstantValue constant = constantSystem.createString(dartString); 5025 ConstantValue constant = constantSystem.createString(dartString);
4870 return graph.addConstant(constant, compiler); 5026 return graph.addConstant(constant, compiler);
4871 } 5027 }
4872 5028
4873 visitClassTypeLiteralGet( 5029 visitClassTypeLiteralGet(
4874 ast.Send node, 5030 ast.Send node,
4875 ConstantExpression constant, 5031 ConstantExpression constant,
4876 _) { 5032 _) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
4978 void generateCallInvoke(ast.Send node, HInstruction target) { 5134 void generateCallInvoke(ast.Send node, HInstruction target) {
4979 Selector selector = elements.getSelector(node); 5135 Selector selector = elements.getSelector(node);
4980 List<HInstruction> inputs = <HInstruction>[target]; 5136 List<HInstruction> inputs = <HInstruction>[target];
4981 addDynamicSendArgumentsToList(node, inputs); 5137 addDynamicSendArgumentsToList(node, inputs);
4982 Selector closureSelector = new Selector.callClosureFrom(selector); 5138 Selector closureSelector = new Selector.callClosureFrom(selector);
4983 pushWithPosition( 5139 pushWithPosition(
4984 new HInvokeClosure(closureSelector, inputs, backend.dynamicType), node); 5140 new HInvokeClosure(closureSelector, inputs, backend.dynamicType), node);
4985 } 5141 }
4986 5142
4987 visitGetterSend(ast.Send node) { 5143 visitGetterSend(ast.Send node) {
4988 generateIsDeferredLoadedCheckIfNeeded(node); 5144 internalError(node, "Unexpected visitGetterSend");
4989 generateGetter(node, elements[node]);
4990 } 5145 }
4991 5146
4992 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. 5147 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError.
4993 internalError(Spannable node, String reason) { 5148 internalError(Spannable node, String reason) {
4994 compiler.internalError(node, reason); 5149 compiler.internalError(node, reason);
4995 } 5150 }
4996 5151
4997 void generateError(ast.Node node, String message, Element helper) { 5152 void generateError(ast.Node node, String message, Element helper) {
4998 HInstruction errorMessage = addConstantString(message); 5153 HInstruction errorMessage = addConstantString(message);
4999 pushInvokeStatic(node, helper, [errorMessage]); 5154 pushInvokeStatic(node, helper, [errorMessage]);
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
5383 5538
5384 if (!Elements.isUnresolved(getter) && getter.impliesType) { 5539 if (!Elements.isUnresolved(getter) && getter.impliesType) {
5385 ast.Identifier selector = node.selector; 5540 ast.Identifier selector = node.selector;
5386 generateThrowNoSuchMethod(node, selector.source, 5541 generateThrowNoSuchMethod(node, selector.source,
5387 argumentNodes: node.arguments); 5542 argumentNodes: node.arguments);
5388 return; 5543 return;
5389 } else if (Elements.isInstanceSend(node, elements)) { 5544 } else if (Elements.isInstanceSend(node, elements)) {
5390 receiver = generateInstanceSendReceiver(node); 5545 receiver = generateInstanceSendReceiver(node);
5391 generateInstanceGetterWithCompiledReceiver( 5546 generateInstanceGetterWithCompiledReceiver(
5392 node, elements.getGetterSelectorInComplexSendSet(node), receiver); 5547 node, elements.getGetterSelectorInComplexSendSet(node), receiver);
5548 } else if (getter.isErroneous) {
5549 generateStaticUnresolvedGet(node, getter);
5550 } else if (getter.isField) {
5551 generateStaticFieldGet(node, getter);
5552 } else if (getter.isGetter) {
5553 generateStaticGetterGet(node, getter);
5554 } else if (getter.isFunction) {
5555 generateStaticFunctionGet(node, getter);
5556 } else if (getter.isLocal) {
5557 handleLocalGet(getter);
5393 } else { 5558 } else {
5394 generateGetter(node, getter); 5559 internalError(node, "Unexpected getter: $getter");
5395 } 5560 }
5396 HInstruction getterInstruction = pop(); 5561 HInstruction getterInstruction = pop();
5397 handleComplexOperatorSend(node, getterInstruction, node.arguments); 5562 handleComplexOperatorSend(node, getterInstruction, node.arguments);
5398 HInstruction value = pop(); 5563 HInstruction value = pop();
5399 assert(value != null); 5564 assert(value != null);
5400 if (Elements.isInstanceSend(node, elements)) { 5565 if (Elements.isInstanceSend(node, elements)) {
5401 assert(receiver != null); 5566 assert(receiver != null);
5402 generateInstanceSetterWithCompiledReceiver(node, receiver, value); 5567 generateInstanceSetterWithCompiledReceiver(node, receiver, value);
5403 } else { 5568 } else {
5404 assert(receiver == null); 5569 assert(receiver == null);
(...skipping 2015 matching lines...) Expand 10 before | Expand all | Expand 10 after
7420 if (unaliased is TypedefType) throw 'unable to unalias $type'; 7585 if (unaliased is TypedefType) throw 'unable to unalias $type';
7421 unaliased.accept(this, builder); 7586 unaliased.accept(this, builder);
7422 } 7587 }
7423 7588
7424 void visitDynamicType(DynamicType type, SsaBuilder builder) { 7589 void visitDynamicType(DynamicType type, SsaBuilder builder) {
7425 JavaScriptBackend backend = builder.compiler.backend; 7590 JavaScriptBackend backend = builder.compiler.backend;
7426 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 7591 ClassElement cls = backend.findHelper('DynamicRuntimeType');
7427 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 7592 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
7428 } 7593 }
7429 } 7594 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolved_visitor.dart ('k') | tests/compiler/dart2js/compiler_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698