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

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: Updated cf. comments. 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 // This happens when [element] has parse errors.
3252 assert(invariant(node, element.isErroneous));
3253 // TODO(ahe): Do something like the above, that is, emit a runtime
3254 // error.
3255 stack.add(graph.addConstantNull(compiler));
3256 }
3257 }
3258
3259 /// Read a static or top level [field] of constant value.
3260 void generateStaticConstGet(
3261 ast.Send node,
3262 FieldElement field,
3263 ConstantExpression constant) {
3264 ConstantValue value = constant.value;
3265 HConstant instruction;
3266 // Constants that are referred via a deferred prefix should be referred
3267 // by reference.
3268 PrefixElement prefix = compiler.deferredLoadTask
3269 .deferredPrefixElement(node, elements);
3270 if (prefix != null) {
3271 instruction = graph.addDeferredConstant(value, prefix, compiler);
3272 } else {
3273 instruction = graph.addConstant(value, compiler);
3274 }
3275 stack.add(instruction);
3276 // The inferrer may have found a better type than the constant
3277 // handler in the case of lists, because the constant handler
3278 // does not look at elements in the list.
3279 TypeMask type =
3280 TypeMaskFactory.inferredTypeForElement(field, compiler);
3281 if (!type.containsAll(compiler.world) &&
3282 !instruction.isConstantNull()) {
3283 // TODO(13429): The inferrer should know that an element
3284 // cannot be null.
3285 instruction.instructionType = type.nonNullable();
3286 }
3287 }
3288
3289 /// Read a static or top level [field].
3290 void generateStaticFieldGet(ast.Send node, FieldElement field) {
3291 generateIsDeferredLoadedCheckIfNeeded(node);
3292
3293 ConstantExpression constant =
3294 backend.constants.getConstantForVariable(field);
3295 if (constant != null) {
3296 if (!field.isAssignable) {
3254 // A static final or const. Get its constant value and inline it if 3297 // A static final or const. Get its constant value and inline it if
3255 // the value can be compiled eagerly. 3298 // the value can be compiled eagerly.
3256 constant = backend.constants.getConstantForVariable(element); 3299 generateStaticConstGet(node, field, constant);
3257 } 3300 } else {
3258 if (constant != null) { 3301 // TODO(5346): Try to avoid the need for calling [declaration] before
3259 ConstantValue value = constant.value; 3302 // creating an [HStatic].
3260 HConstant instruction; 3303 HInstruction instruction = new HStatic(
3261 // Constants that are referred via a deferred prefix should be referred 3304 field.declaration,
3262 // by reference. 3305 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); 3306 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 } 3307 }
3321 } else { 3308 } else {
3322 if (send.asSendSet() == null) { 3309 HInstruction instruction = new HLazyStatic(
3323 internalError(send, "Unhandled local: $element"); 3310 field,
3324 } 3311 TypeMaskFactory.inferredTypeForElement(field, compiler));
3325 // TODO(johnniwinther): Remove this when [generateGetter] is no longer 3312 push(instruction);
3326 // called from [visitSendSet] (for compound assignments).
3327 handleLocalGet(element);
3328 } 3313 }
3329 } 3314 }
3330 3315
3316 /// Generate a getter invocation of the static or top level [getter].
3317 void generateStaticGetterGet(ast.Send node, MethodElement getter) {
3318 if (getter.isDeferredLoaderGetter) {
3319 generateDeferredLoaderGet(node, getter);
3320 } else {
3321 generateIsDeferredLoadedCheckIfNeeded(node);
3322 pushInvokeStatic(node, getter, <HInstruction>[]);
3323 }
3324 }
3325
3326 /// Generate a dynamic getter invocation.
3327 void generateDynamicGet(ast.Send node) {
3328 HInstruction receiver = generateInstanceSendReceiver(node);
3329 generateInstanceGetterWithCompiledReceiver(
3330 node, elements.getSelector(node), receiver);
3331 }
3332
3333 /// Generate a closurization of the static or top level [function].
3334 void generateStaticFunctionGet(ast.Send node, MethodElement function) {
3335 generateIsDeferredLoadedCheckIfNeeded(node);
3336 // TODO(5346): Try to avoid the need for calling [declaration] before
3337 // creating an [HStatic].
3338 push(new HStatic(function.declaration, backend.nonNullType));
3339 // TODO(ahe): This should be registered in codegen.
3340 registry.registerGetOfStaticFunction(function.declaration);
3341 }
3342
3331 /// Read a local variable, function or parameter. 3343 /// Read a local variable, function or parameter.
3332 void handleLocalGet(LocalElement local) { 3344 void handleLocalGet(LocalElement local) {
3333 stack.add(localsHandler.readLocal(local)); 3345 stack.add(localsHandler.readLocal(local));
3334 } 3346 }
3335 3347
3336 @override 3348 @override
3349 void visitDynamicPropertyGet(
3350 ast.Send node,
3351 ast.Node receiver,
3352 Selector selector,
3353 _) {
3354 generateDynamicGet(node);
3355 }
3356
3357 @override
3337 void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) { 3358 void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) {
3338 handleLocalGet(variable); 3359 handleLocalGet(variable);
3339 } 3360 }
3340 3361
3341 @override 3362 @override
3342 void visitParameterGet(ast.Send node, ParameterElement parameter, _) { 3363 void visitParameterGet(ast.Send node, ParameterElement parameter, _) {
3343 handleLocalGet(parameter); 3364 handleLocalGet(parameter);
3344 } 3365 }
3345 3366
3346 @override 3367 @override
3347 void visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) { 3368 void visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) {
3348 handleLocalGet(function); 3369 handleLocalGet(function);
3349 } 3370 }
3350 3371
3372 @override
3373 void visitStaticFieldGet(
3374 ast.Send node,
3375 FieldElement field,
3376 _) {
3377 generateStaticFieldGet(node, field);
3378 }
3379
3380 @override
3381 void visitStaticFunctionGet(
3382 ast.Send node,
3383 MethodElement function,
3384 _) {
3385 generateStaticFunctionGet(node, function);
3386 }
3387
3388 @override
3389 void visitStaticGetterGet(
3390 ast.Send node,
3391 FunctionElement getter,
3392 _) {
3393 generateStaticGetterGet(node, getter);
3394 }
3395
3396 @override
3397 void visitThisPropertyGet(
3398 ast.Send node,
3399 Selector selector,
3400 _) {
3401 generateDynamicGet(node);
3402 }
3403
3404 @override
3405 void visitTopLevelFieldGet(
3406 ast.Send node,
3407 FieldElement field,
3408 _) {
3409 generateStaticFieldGet(node, field);
3410 }
3411
3412 @override
3413 void visitTopLevelFunctionGet(
3414 ast.Send node,
3415 MethodElement function,
3416 _) {
3417 generateStaticFunctionGet(node, function);
3418 }
3419
3420 @override
3421 void visitTopLevelGetterGet(
3422 ast.Send node,
3423 FunctionElement getter,
3424 _) {
3425 generateStaticGetterGet(node, getter);
3426 }
3427
3351 void generateInstanceSetterWithCompiledReceiver(ast.Send send, 3428 void generateInstanceSetterWithCompiledReceiver(ast.Send send,
3352 HInstruction receiver, 3429 HInstruction receiver,
3353 HInstruction value, 3430 HInstruction value,
3354 {Selector selector, 3431 {Selector selector,
3355 ast.Node location}) { 3432 ast.Node location}) {
3356 assert(send == null || Elements.isInstanceSend(send, elements)); 3433 assert(send == null || Elements.isInstanceSend(send, elements));
3357 if (selector == null) { 3434 if (selector == null) {
3358 assert(send != null); 3435 assert(send != null);
3359 selector = elements.getSelector(send); 3436 selector = elements.getSelector(send);
3360 } 3437 }
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
4007 4084
4008 void handleForeignJsCurrentIsolate(ast.Send node) { 4085 void handleForeignJsCurrentIsolate(ast.Send node) {
4009 if (!node.arguments.isEmpty) { 4086 if (!node.arguments.isEmpty) {
4010 compiler.internalError(node.argumentsNode, 'Too many arguments.'); 4087 compiler.internalError(node.argumentsNode, 'Too many arguments.');
4011 } 4088 }
4012 push(new HForeignCode(js.js.parseForeignJS(backend.namer.currentIsolate), 4089 push(new HForeignCode(js.js.parseForeignJS(backend.namer.currentIsolate),
4013 backend.dynamicType, 4090 backend.dynamicType,
4014 <HInstruction>[])); 4091 <HInstruction>[]));
4015 } 4092 }
4016 4093
4017 visitForeignSend(ast.Send node) { 4094 void handleForeignSend(ast.Send node, FunctionElement element) {
4018 Selector selector = elements.getSelector(node); 4095 String name = element.name;
4019 String name = selector.name;
4020 if (name == 'JS') { 4096 if (name == 'JS') {
4021 handleForeignJs(node); 4097 handleForeignJs(node);
4022 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') { 4098 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
4023 handleForeignJsCurrentIsolateContext(node); 4099 handleForeignJsCurrentIsolateContext(node);
4024 } else if (name == 'JS_CALL_IN_ISOLATE') { 4100 } else if (name == 'JS_CALL_IN_ISOLATE') {
4025 handleForeignJsCallInIsolate(node); 4101 handleForeignJsCallInIsolate(node);
4026 } else if (name == 'DART_CLOSURE_TO_JS') { 4102 } else if (name == 'DART_CLOSURE_TO_JS') {
4027 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS'); 4103 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS');
4028 } else if (name == 'RAW_DART_FUNCTION_REF') { 4104 } else if (name == 'RAW_DART_FUNCTION_REF') {
4029 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); 4105 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF');
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4084 handleForeignJsBuiltin(node); 4160 handleForeignJsBuiltin(node);
4085 } else if (name == 'JS_GET_FLAG') { 4161 } else if (name == 'JS_GET_FLAG') {
4086 handleForeingJsGetFlag(node); 4162 handleForeingJsGetFlag(node);
4087 } else if (name == 'JS_EFFECT') { 4163 } else if (name == 'JS_EFFECT') {
4088 stack.add(graph.addConstantNull(compiler)); 4164 stack.add(graph.addConstantNull(compiler));
4089 } else if (name == 'JS_INTERCEPTOR_CONSTANT') { 4165 } else if (name == 'JS_INTERCEPTOR_CONSTANT') {
4090 handleJsInterceptorConstant(node); 4166 handleJsInterceptorConstant(node);
4091 } else if (name == 'JS_STRING_CONCAT') { 4167 } else if (name == 'JS_STRING_CONCAT') {
4092 handleJsStringConcat(node); 4168 handleJsStringConcat(node);
4093 } else { 4169 } else {
4094 throw "Unknown foreign: ${selector}"; 4170 throw "Unknown foreign: ${element}";
4095 } 4171 }
4096 } 4172 }
4097 4173
4098 visitForeignGetter(ast.Send node) { 4174 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader) {
4099 Element element = elements[node];
4100 // Until now we only handle these as getters. 4175 // Until now we only handle these as getters.
4101 invariant(node, element.isDeferredLoaderGetter); 4176 invariant(node, deferredLoader.isDeferredLoaderGetter);
4102 FunctionElement deferredLoader = element;
4103 Element loadFunction = compiler.loadLibraryFunction; 4177 Element loadFunction = compiler.loadLibraryFunction;
4104 PrefixElement prefixElement = deferredLoader.enclosingElement; 4178 PrefixElement prefixElement = deferredLoader.enclosingElement;
4105 String loadId = compiler.deferredLoadTask 4179 String loadId = compiler.deferredLoadTask
4106 .importDeferName[prefixElement.deferredImport]; 4180 .importDeferName[prefixElement.deferredImport];
4107 var inputs = [graph.addConstantString( 4181 var inputs = [graph.addConstantString(
4108 new ast.DartString.literal(loadId), compiler)]; 4182 new ast.DartString.literal(loadId), compiler)];
4109 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType, 4183 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType,
4110 targetCanThrow: false)); 4184 targetCanThrow: false));
4111 } 4185 }
4112 4186
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
4791 } 4865 }
4792 4866
4793 @override 4867 @override
4794 visitAssert(ast.Send node, ast.Node expression, _) { 4868 visitAssert(ast.Send node, ast.Node expression, _) {
4795 if (!compiler.enableUserAssertions) { 4869 if (!compiler.enableUserAssertions) {
4796 stack.add(graph.addConstantNull(compiler)); 4870 stack.add(graph.addConstantNull(compiler));
4797 return; 4871 return;
4798 } 4872 }
4799 assert(invariant(node, node.arguments.tail.isEmpty, 4873 assert(invariant(node, node.arguments.tail.isEmpty,
4800 message: "Invalid assertion: $node")); 4874 message: "Invalid assertion: $node"));
4801 buildStaticFunctionInvoke( 4875 generateStaticFunctionInvoke(
4802 node, backend.assertMethod, CallStructure.ONE_ARG); 4876 node, backend.assertMethod, CallStructure.ONE_ARG);
4803 } 4877 }
4804 4878
4805 visitStaticSend(ast.Send node) { 4879 visitStaticSend(ast.Send node) {
4806 CallStructure callStructure = elements.getSelector(node).callStructure; 4880 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 } 4881 }
4848 4882
4849 void buildStaticFunctionInvoke( 4883 /// Generate an invocation to the static or top level [function].
4884 void generateStaticFunctionInvoke(
4850 ast.Send node, 4885 ast.Send node,
4851 FunctionElement element, 4886 FunctionElement function,
4852 CallStructure callStructure) { 4887 CallStructure callStructure) {
4853 List<HInstruction> inputs = makeStaticArgumentList( 4888 List<HInstruction> inputs = makeStaticArgumentList(
4854 callStructure, 4889 callStructure,
4855 node.arguments, 4890 node.arguments,
4856 element.implementation); 4891 function.implementation);
4857 4892
4858 if (element == compiler.identicalFunction) { 4893 if (function == compiler.identicalFunction) {
4859 pushWithPosition( 4894 pushWithPosition(
4860 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node); 4895 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node);
4861 return; 4896 return;
4862 } else { 4897 } else {
4863 pushInvokeStatic(node, element, inputs); 4898 pushInvokeStatic(node, function, inputs);
4864 } 4899 }
4865 } 4900 }
4866 4901
4902 /// Generate an invocation to a static or top level function with the wrong
4903 /// number of arguments.
4904 void generateStaticFunctionIncompatibleInvoke(ast.Send node,
4905 Element element) {
4906 generateWrongArgumentCountError(node, element, node.arguments);
4907 }
4908
4909 @override
4910 void visitStaticFieldInvoke(
4911 ast.Send node,
4912 FieldElement field,
4913 ast.NodeList arguments,
4914 CallStructure callStructure,
4915 _) {
4916 generateStaticFieldGet(node, field);
4917 generateCallInvoke(node, pop());
4918 }
4919
4920 @override
4921 void visitStaticFunctionInvoke(
4922 ast.Send node,
4923 MethodElement function,
4924 ast.NodeList arguments,
4925 CallStructure callStructure,
4926 _) {
4927 generateStaticFunctionInvoke(node, function, callStructure);
4928 }
4929
4930 @override
4931 void visitStaticFunctionIncompatibleInvoke(
4932 ast.Send node,
4933 MethodElement function,
4934 ast.NodeList arguments,
4935 CallStructure callStructure,
4936 _) {
4937 generateStaticFunctionIncompatibleInvoke(node, function);
4938 }
4939
4940 @override
4941 void visitStaticGetterInvoke(
4942 ast.Send node,
4943 FunctionElement getter,
4944 ast.NodeList arguments,
4945 CallStructure callStructure,
4946 _) {
4947 generateStaticGetterGet(node, getter);
4948 generateCallInvoke(node, pop());
4949 }
4950
4951 @override
4952 void visitTopLevelFieldInvoke(
4953 ast.Send node,
4954 FieldElement field,
4955 ast.NodeList arguments,
4956 CallStructure callStructure,
4957 _) {
4958 generateStaticFieldGet(node, field);
4959 generateCallInvoke(node, pop());
4960 }
4961
4962 @override
4963 void visitTopLevelFunctionInvoke(
4964 ast.Send node,
4965 MethodElement function,
4966 ast.NodeList arguments,
4967 CallStructure callStructure,
4968 _) {
4969 if (function.isForeign(backend)) {
4970 handleForeignSend(node, function);
4971 } else {
4972 generateStaticFunctionInvoke(node, function, callStructure);
4973 }
4974 }
4975
4976 @override
4977 void visitTopLevelFunctionIncompatibleInvoke(
4978 ast.Send node,
4979 MethodElement function,
4980 ast.NodeList arguments,
4981 CallStructure callStructure,
4982 _) {
4983 generateStaticFunctionIncompatibleInvoke(node, function);
4984 }
4985
4986 @override
4987 void visitTopLevelGetterInvoke(
4988 ast.Send node,
4989 FunctionElement getter,
4990 ast.NodeList arguments,
4991 CallStructure callStructure,
4992 _) {
4993 generateStaticGetterGet(node, getter);
4994 generateCallInvoke(node, pop());
4995 }
4996
4997 @override
4998 void visitUnresolvedGet(
4999 ast.Send node,
5000 Element element,
5001 _) {
5002 generateStaticUnresolvedGet(node, element);
5003 }
5004
5005 @override
5006 void visitUnresolvedInvoke(
5007 ast.Send node,
5008 Element element,
5009 ast.NodeList arguments,
5010 Selector selector,
5011 _) {
5012 if (element is ErroneousElement) {
5013 // An erroneous element indicates that the funciton could not be
5014 // resolved (a warning has been issued).
5015 generateThrowNoSuchMethod(node,
5016 noSuchMethodTargetSymbolString(element),
5017 argumentNodes: node.arguments);
5018 } else {
5019 // TODO(ahe): Do something like [generateWrongArgumentCountError].
5020 stack.add(graph.addConstantNull(compiler));
5021 }
5022 return;
5023 }
5024
4867 HConstant addConstantString(String string) { 5025 HConstant addConstantString(String string) {
4868 ast.DartString dartString = new ast.DartString.literal(string); 5026 ast.DartString dartString = new ast.DartString.literal(string);
4869 ConstantValue constant = constantSystem.createString(dartString); 5027 ConstantValue constant = constantSystem.createString(dartString);
4870 return graph.addConstant(constant, compiler); 5028 return graph.addConstant(constant, compiler);
4871 } 5029 }
4872 5030
4873 visitClassTypeLiteralGet( 5031 visitClassTypeLiteralGet(
4874 ast.Send node, 5032 ast.Send node,
4875 ConstantExpression constant, 5033 ConstantExpression constant,
4876 _) { 5034 _) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
4978 void generateCallInvoke(ast.Send node, HInstruction target) { 5136 void generateCallInvoke(ast.Send node, HInstruction target) {
4979 Selector selector = elements.getSelector(node); 5137 Selector selector = elements.getSelector(node);
4980 List<HInstruction> inputs = <HInstruction>[target]; 5138 List<HInstruction> inputs = <HInstruction>[target];
4981 addDynamicSendArgumentsToList(node, inputs); 5139 addDynamicSendArgumentsToList(node, inputs);
4982 Selector closureSelector = new Selector.callClosureFrom(selector); 5140 Selector closureSelector = new Selector.callClosureFrom(selector);
4983 pushWithPosition( 5141 pushWithPosition(
4984 new HInvokeClosure(closureSelector, inputs, backend.dynamicType), node); 5142 new HInvokeClosure(closureSelector, inputs, backend.dynamicType), node);
4985 } 5143 }
4986 5144
4987 visitGetterSend(ast.Send node) { 5145 visitGetterSend(ast.Send node) {
4988 generateIsDeferredLoadedCheckIfNeeded(node); 5146 internalError(node, "Unexpected visitGetterSend");
4989 generateGetter(node, elements[node]);
4990 } 5147 }
4991 5148
4992 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. 5149 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError.
4993 internalError(Spannable node, String reason) { 5150 internalError(Spannable node, String reason) {
4994 compiler.internalError(node, reason); 5151 compiler.internalError(node, reason);
4995 } 5152 }
4996 5153
4997 void generateError(ast.Node node, String message, Element helper) { 5154 void generateError(ast.Node node, String message, Element helper) {
4998 HInstruction errorMessage = addConstantString(message); 5155 HInstruction errorMessage = addConstantString(message);
4999 pushInvokeStatic(node, helper, [errorMessage]); 5156 pushInvokeStatic(node, helper, [errorMessage]);
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
5383 5540
5384 if (!Elements.isUnresolved(getter) && getter.impliesType) { 5541 if (!Elements.isUnresolved(getter) && getter.impliesType) {
5385 ast.Identifier selector = node.selector; 5542 ast.Identifier selector = node.selector;
5386 generateThrowNoSuchMethod(node, selector.source, 5543 generateThrowNoSuchMethod(node, selector.source,
5387 argumentNodes: node.arguments); 5544 argumentNodes: node.arguments);
5388 return; 5545 return;
5389 } else if (Elements.isInstanceSend(node, elements)) { 5546 } else if (Elements.isInstanceSend(node, elements)) {
5390 receiver = generateInstanceSendReceiver(node); 5547 receiver = generateInstanceSendReceiver(node);
5391 generateInstanceGetterWithCompiledReceiver( 5548 generateInstanceGetterWithCompiledReceiver(
5392 node, elements.getGetterSelectorInComplexSendSet(node), receiver); 5549 node, elements.getGetterSelectorInComplexSendSet(node), receiver);
5550 } else if (getter.isErroneous) {
5551 generateStaticUnresolvedGet(node, getter);
5552 } else if (getter.isField) {
5553 generateStaticFieldGet(node, getter);
5554 } else if (getter.isGetter) {
5555 generateStaticGetterGet(node, getter);
5556 } else if (getter.isFunction) {
5557 generateStaticFunctionGet(node, getter);
5558 } else if (getter.isLocal) {
5559 handleLocalGet(getter);
5393 } else { 5560 } else {
5394 generateGetter(node, getter); 5561 internalError(node, "Unexpected getter: $getter");
5395 } 5562 }
5396 HInstruction getterInstruction = pop(); 5563 HInstruction getterInstruction = pop();
5397 handleComplexOperatorSend(node, getterInstruction, node.arguments); 5564 handleComplexOperatorSend(node, getterInstruction, node.arguments);
5398 HInstruction value = pop(); 5565 HInstruction value = pop();
5399 assert(value != null); 5566 assert(value != null);
5400 if (Elements.isInstanceSend(node, elements)) { 5567 if (Elements.isInstanceSend(node, elements)) {
5401 assert(receiver != null); 5568 assert(receiver != null);
5402 generateInstanceSetterWithCompiledReceiver(node, receiver, value); 5569 generateInstanceSetterWithCompiledReceiver(node, receiver, value);
5403 } else { 5570 } else {
5404 assert(receiver == null); 5571 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'; 7587 if (unaliased is TypedefType) throw 'unable to unalias $type';
7421 unaliased.accept(this, builder); 7588 unaliased.accept(this, builder);
7422 } 7589 }
7423 7590
7424 void visitDynamicType(DynamicType type, SsaBuilder builder) { 7591 void visitDynamicType(DynamicType type, SsaBuilder builder) {
7425 JavaScriptBackend backend = builder.compiler.backend; 7592 JavaScriptBackend backend = builder.compiler.backend;
7426 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 7593 ClassElement cls = backend.findHelper('DynamicRuntimeType');
7427 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 7594 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
7428 } 7595 }
7429 } 7596 }
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