| 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 class Interceptors { | 5 class Interceptors { |
| 6 Compiler compiler; | 6 Compiler compiler; |
| 7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
| 8 | 8 |
| 9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
| 10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 // Inside closure redirect references to itself to [:this:]. | 351 // Inside closure redirect references to itself to [:this:]. |
| 352 HInstruction thisInstruction = new HThis(); | 352 HInstruction thisInstruction = new HThis(); |
| 353 builder.add(thisInstruction); | 353 builder.add(thisInstruction); |
| 354 updateLocal(closureData.closureElement, thisInstruction); | 354 updateLocal(closureData.closureElement, thisInstruction); |
| 355 } else if (function.isInstanceMember() | 355 } else if (function.isInstanceMember() |
| 356 || function.isGenerativeConstructor()) { | 356 || function.isGenerativeConstructor()) { |
| 357 // Once closures have been mapped to classes their instance members might | 357 // Once closures have been mapped to classes their instance members might |
| 358 // not have any thisElement if the closure was created inside a static | 358 // not have any thisElement if the closure was created inside a static |
| 359 // context. | 359 // context. |
| 360 ClassElement cls = function.getEnclosingClass(); | 360 ClassElement cls = function.getEnclosingClass(); |
| 361 Type type = cls.computeType(builder.compiler); | 361 DartType type = cls.computeType(builder.compiler); |
| 362 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); | 362 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); |
| 363 builder.add(thisInstruction); | 363 builder.add(thisInstruction); |
| 364 directLocals[closureData.thisElement] = thisInstruction; | 364 directLocals[closureData.thisElement] = thisInstruction; |
| 365 } | 365 } |
| 366 } | 366 } |
| 367 | 367 |
| 368 bool hasValueForDirectLocal(Element element) { | 368 bool hasValueForDirectLocal(Element element) { |
| 369 assert(element !== null); | 369 assert(element !== null); |
| 370 assert(isAccessedDirectly(element)); | 370 assert(isAccessedDirectly(element)); |
| 371 return directLocals[element] !== null; | 371 return directLocals[element] !== null; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 | 444 |
| 445 HType cachedTypeOfThis; | 445 HType cachedTypeOfThis; |
| 446 | 446 |
| 447 HInstruction readThis() { | 447 HInstruction readThis() { |
| 448 HInstruction res = readLocal(closureData.thisElement); | 448 HInstruction res = readLocal(closureData.thisElement); |
| 449 if (res.guaranteedType === null) { | 449 if (res.guaranteedType === null) { |
| 450 if (cachedTypeOfThis === null) { | 450 if (cachedTypeOfThis === null) { |
| 451 assert(closureData.isClosure()); | 451 assert(closureData.isClosure()); |
| 452 Element element = closureData.thisElement; | 452 Element element = closureData.thisElement; |
| 453 ClassElement cls = element.enclosingElement.getEnclosingClass(); | 453 ClassElement cls = element.enclosingElement.getEnclosingClass(); |
| 454 Type type = cls.computeType(builder.compiler); | 454 DartType type = cls.computeType(builder.compiler); |
| 455 cachedTypeOfThis = new HBoundedType.nonNull(type); | 455 cachedTypeOfThis = new HBoundedType.nonNull(type); |
| 456 } | 456 } |
| 457 res.guaranteedType = cachedTypeOfThis; | 457 res.guaranteedType = cachedTypeOfThis; |
| 458 } | 458 } |
| 459 return res; | 459 return res; |
| 460 } | 460 } |
| 461 | 461 |
| 462 HLocalValue getLocal(Element element) { | 462 HLocalValue getLocal(Element element) { |
| 463 // If the element is a parameter, we already have a | 463 // If the element is a parameter, we already have a |
| 464 // HParameterValue for it. We cannot create another one because | 464 // HParameterValue for it. We cannot create another one because |
| (...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1264 HInstruction potentiallyCheckType(HInstruction original, | 1264 HInstruction potentiallyCheckType(HInstruction original, |
| 1265 Element sourceElement) { | 1265 Element sourceElement) { |
| 1266 if (!compiler.enableTypeAssertions) return original; | 1266 if (!compiler.enableTypeAssertions) return original; |
| 1267 return convertType(original, sourceElement, | 1267 return convertType(original, sourceElement, |
| 1268 HTypeConversion.CHECKED_MODE_CHECK); | 1268 HTypeConversion.CHECKED_MODE_CHECK); |
| 1269 } | 1269 } |
| 1270 | 1270 |
| 1271 HInstruction convertType(HInstruction original, | 1271 HInstruction convertType(HInstruction original, |
| 1272 Element sourceElement, | 1272 Element sourceElement, |
| 1273 int kind) { | 1273 int kind) { |
| 1274 Type type = sourceElement.computeType(compiler); | 1274 DartType type = sourceElement.computeType(compiler); |
| 1275 if (type === null) return original; | 1275 if (type === null) return original; |
| 1276 if (type.element === compiler.dynamicClass) return original; | 1276 if (type.element === compiler.dynamicClass) return original; |
| 1277 if (type.element === compiler.objectClass) return original; | 1277 if (type.element === compiler.objectClass) return original; |
| 1278 | 1278 |
| 1279 // If the original can't be null, type conversion also can't produce null. | 1279 // If the original can't be null, type conversion also can't produce null. |
| 1280 bool canBeNull = original.guaranteedType.canBeNull(); | 1280 bool canBeNull = original.guaranteedType.canBeNull(); |
| 1281 HType convertedType = | 1281 HType convertedType = |
| 1282 new HType.fromBoundedType(type, compiler, canBeNull); | 1282 new HType.fromBoundedType(type, compiler, canBeNull); |
| 1283 | 1283 |
| 1284 // No need to convert if we know the instruction has | 1284 // No need to convert if we know the instruction has |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2064 Node argument = node.arguments.head; | 2064 Node argument = node.arguments.head; |
| 2065 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); | 2065 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); |
| 2066 bool isNot = false; | 2066 bool isNot = false; |
| 2067 // TODO(ngeoffray): Duplicating pattern in resolver. We should | 2067 // TODO(ngeoffray): Duplicating pattern in resolver. We should |
| 2068 // add a new kind of node. | 2068 // add a new kind of node. |
| 2069 if (typeAnnotation == null) { | 2069 if (typeAnnotation == null) { |
| 2070 typeAnnotation = argument.asSend().receiver; | 2070 typeAnnotation = argument.asSend().receiver; |
| 2071 isNot = true; | 2071 isNot = true; |
| 2072 } | 2072 } |
| 2073 | 2073 |
| 2074 Type type = elements.getType(typeAnnotation); | 2074 DartType type = elements.getType(typeAnnotation); |
| 2075 HInstruction typeInfo = null; | 2075 HInstruction typeInfo = null; |
| 2076 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { | 2076 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { |
| 2077 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); | 2077 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); |
| 2078 typeInfo = pop(); | 2078 typeInfo = pop(); |
| 2079 } | 2079 } |
| 2080 if (type.element.kind === ElementKind.TYPE_VARIABLE) { | 2080 if (type.element.kind === ElementKind.TYPE_VARIABLE) { |
| 2081 // TODO(karlklose): We emulate the behavior of the old frog | 2081 // TODO(karlklose): We emulate the behavior of the old frog |
| 2082 // compiler and answer true to any is check involving a type variable | 2082 // compiler and answer true to any is check involving a type variable |
| 2083 // -- both is T and is !T -- until we have a proper implementation of | 2083 // -- both is T and is !T -- until we have a proper implementation of |
| 2084 // reified generics. | 2084 // reified generics. |
| 2085 stack.add(graph.addConstantBool(true)); | 2085 stack.add(graph.addConstantBool(true)); |
| 2086 } else { | 2086 } else { |
| 2087 HInstruction instruction; | 2087 HInstruction instruction; |
| 2088 if (typeInfo !== null) { | 2088 if (typeInfo !== null) { |
| 2089 instruction = new HIs.withTypeInfoCall(type, expression, typeInfo); | 2089 instruction = new HIs.withTypeInfoCall(type, expression, typeInfo); |
| 2090 } else { | 2090 } else { |
| 2091 instruction = new HIs(type, expression); | 2091 instruction = new HIs(type, expression); |
| 2092 } | 2092 } |
| 2093 if (isNot) { | 2093 if (isNot) { |
| 2094 add(instruction); | 2094 add(instruction); |
| 2095 instruction = new HNot(instruction); | 2095 instruction = new HNot(instruction); |
| 2096 } | 2096 } |
| 2097 push(instruction); | 2097 push(instruction); |
| 2098 } | 2098 } |
| 2099 } else if (const SourceString("as") == op.source) { | 2099 } else if (const SourceString("as") == op.source) { |
| 2100 visit(node.receiver); | 2100 visit(node.receiver); |
| 2101 HInstruction expression = pop(); | 2101 HInstruction expression = pop(); |
| 2102 Node argument = node.arguments.head; | 2102 Node argument = node.arguments.head; |
| 2103 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); | 2103 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); |
| 2104 Type type = elements.getType(typeAnnotation); | 2104 DartType type = elements.getType(typeAnnotation); |
| 2105 HInstruction converted = convertType(expression, type.element, | 2105 HInstruction converted = convertType(expression, type.element, |
| 2106 HTypeConversion.CAST_TYPE_CHECK); | 2106 HTypeConversion.CAST_TYPE_CHECK); |
| 2107 stack.add(converted); | 2107 stack.add(converted); |
| 2108 } else { | 2108 } else { |
| 2109 visit(node.receiver); | 2109 visit(node.receiver); |
| 2110 visit(node.argumentsNode); | 2110 visit(node.argumentsNode); |
| 2111 var right = pop(); | 2111 var right = pop(); |
| 2112 var left = pop(); | 2112 var left = pop(); |
| 2113 visitBinary(left, op, right); | 2113 visitBinary(left, op, right); |
| 2114 } | 2114 } |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2449 push(new HInvokeSuper(inputs)); | 2449 push(new HInvokeSuper(inputs)); |
| 2450 } else { | 2450 } else { |
| 2451 target = new HInvokeSuper(inputs); | 2451 target = new HInvokeSuper(inputs); |
| 2452 add(target); | 2452 add(target); |
| 2453 inputs = <HInstruction>[target]; | 2453 inputs = <HInstruction>[target]; |
| 2454 addDynamicSendArgumentsToList(node, inputs); | 2454 addDynamicSendArgumentsToList(node, inputs); |
| 2455 push(new HInvokeClosure(selector, inputs)); | 2455 push(new HInvokeClosure(selector, inputs)); |
| 2456 } | 2456 } |
| 2457 } | 2457 } |
| 2458 | 2458 |
| 2459 HInstruction analyzeTypeArgument(Type argument, Node currentNode) { | 2459 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { |
| 2460 if (argument.element.isTypeVariable()) { | 2460 if (argument.element.isTypeVariable()) { |
| 2461 if (work.element.isFactoryConstructor() | 2461 if (work.element.isFactoryConstructor() |
| 2462 || work.element.isGenerativeConstructor()) { | 2462 || work.element.isGenerativeConstructor()) { |
| 2463 // The type variable is stored in a parameter of the | 2463 // The type variable is stored in a parameter of the |
| 2464 // factory. | 2464 // factory. |
| 2465 return localsHandler.readLocal(argument.element); | 2465 return localsHandler.readLocal(argument.element); |
| 2466 } else if (work.element.isInstanceMember()) { | 2466 } else if (work.element.isInstanceMember()) { |
| 2467 // The type variable is stored in [this]. | 2467 // The type variable is stored in [this]. |
| 2468 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), | 2468 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), |
| 2469 localsHandler.readThis()); | 2469 localsHandler.readThis()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2517 inputs.add(target); | 2517 inputs.add(target); |
| 2518 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 2518 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| 2519 constructor, inputs); | 2519 constructor, inputs); |
| 2520 if (!succeeded) { | 2520 if (!succeeded) { |
| 2521 // TODO(ngeoffray): Match the VM behavior and throw an | 2521 // TODO(ngeoffray): Match the VM behavior and throw an |
| 2522 // exception at runtime. | 2522 // exception at runtime. |
| 2523 compiler.cancel('Unimplemented non-matching static call', node: node); | 2523 compiler.cancel('Unimplemented non-matching static call', node: node); |
| 2524 } | 2524 } |
| 2525 | 2525 |
| 2526 TypeAnnotation annotation = getTypeAnnotationFromSend(node); | 2526 TypeAnnotation annotation = getTypeAnnotationFromSend(node); |
| 2527 elements.getType(annotation).arguments.forEach((Type argument) { | 2527 elements.getType(annotation).arguments.forEach((DartType argument) { |
| 2528 inputs.add(analyzeTypeArgument(argument, node)); | 2528 inputs.add(analyzeTypeArgument(argument, node)); |
| 2529 }); | 2529 }); |
| 2530 | 2530 |
| 2531 HType elementType = computeType(constructor); | 2531 HType elementType = computeType(constructor); |
| 2532 HInstruction newInstance = new HInvokeStatic(inputs, elementType); | 2532 HInstruction newInstance = new HInvokeStatic(inputs, elementType); |
| 2533 pushWithPosition(newInstance, node); | 2533 pushWithPosition(newInstance, node); |
| 2534 } | 2534 } |
| 2535 | 2535 |
| 2536 visitStaticSend(Send node) { | 2536 visitStaticSend(Send node) { |
| 2537 Selector selector = elements.getSelector(node); | 2537 Selector selector = elements.getSelector(node); |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3440 HInstruction oldRethrowableException = rethrowableException; | 3440 HInstruction oldRethrowableException = rethrowableException; |
| 3441 rethrowableException = exception; | 3441 rethrowableException = exception; |
| 3442 | 3442 |
| 3443 pushInvokeHelper1(interceptors.getExceptionUnwrapper(), exception); | 3443 pushInvokeHelper1(interceptors.getExceptionUnwrapper(), exception); |
| 3444 HInvokeStatic unwrappedException = pop(); | 3444 HInvokeStatic unwrappedException = pop(); |
| 3445 tryInstruction.exception = exception; | 3445 tryInstruction.exception = exception; |
| 3446 Link<Node> link = node.catchBlocks.nodes; | 3446 Link<Node> link = node.catchBlocks.nodes; |
| 3447 | 3447 |
| 3448 void pushCondition(CatchBlock catchBlock) { | 3448 void pushCondition(CatchBlock catchBlock) { |
| 3449 if (catchBlock.onKeyword != null) { | 3449 if (catchBlock.onKeyword != null) { |
| 3450 Type type = elements.getType(catchBlock.type); | 3450 DartType type = elements.getType(catchBlock.type); |
| 3451 if (type == null) { | 3451 if (type == null) { |
| 3452 compiler.cancel('On with unresolved type', | 3452 compiler.cancel('On with unresolved type', |
| 3453 node: catchBlock.type); | 3453 node: catchBlock.type); |
| 3454 } | 3454 } |
| 3455 HInstruction condition = new HIs(type, unwrappedException); | 3455 HInstruction condition = new HIs(type, unwrappedException); |
| 3456 push(condition); | 3456 push(condition); |
| 3457 } | 3457 } |
| 3458 else { | 3458 else { |
| 3459 VariableDefinitions declaration = catchBlock.formals.nodes.head; | 3459 VariableDefinitions declaration = catchBlock.formals.nodes.head; |
| 3460 HInstruction condition = null; | 3460 HInstruction condition = null; |
| 3461 if (declaration.type == null) { | 3461 if (declaration.type == null) { |
| 3462 condition = graph.addConstantBool(true); | 3462 condition = graph.addConstantBool(true); |
| 3463 stack.add(condition); | 3463 stack.add(condition); |
| 3464 } else { | 3464 } else { |
| 3465 // TODO(aprelev@gmail.com): Once old catch syntax is removed | 3465 // TODO(aprelev@gmail.com): Once old catch syntax is removed |
| 3466 // "if" condition above and this "else" branch should be deleted as | 3466 // "if" condition above and this "else" branch should be deleted as |
| 3467 // type of declared variable won't matter for the catch | 3467 // type of declared variable won't matter for the catch |
| 3468 // condition | 3468 // condition |
| 3469 Type type = elements.getType(declaration.type); | 3469 DartType type = elements.getType(declaration.type); |
| 3470 if (type == null) { | 3470 if (type == null) { |
| 3471 compiler.cancel('Catch with unresolved type', node: catchBlock); | 3471 compiler.cancel('Catch with unresolved type', node: catchBlock); |
| 3472 } | 3472 } |
| 3473 condition = new HIs(type, unwrappedException, nullOk: true); | 3473 condition = new HIs(type, unwrappedException, nullOk: true); |
| 3474 push(condition); | 3474 push(condition); |
| 3475 } | 3475 } |
| 3476 } | 3476 } |
| 3477 } | 3477 } |
| 3478 | 3478 |
| 3479 void visitThen() { | 3479 void visitThen() { |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3939 new HSubGraphBlockInformation(elseBranch.graph)); | 3939 new HSubGraphBlockInformation(elseBranch.graph)); |
| 3940 | 3940 |
| 3941 HBasicBlock conditionStartBlock = conditionBranch.block; | 3941 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 3942 conditionStartBlock.setBlockFlow(info, joinBlock); | 3942 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 3943 SubGraph conditionGraph = conditionBranch.graph; | 3943 SubGraph conditionGraph = conditionBranch.graph; |
| 3944 HIf branch = conditionGraph.end.last; | 3944 HIf branch = conditionGraph.end.last; |
| 3945 assert(branch is HIf); | 3945 assert(branch is HIf); |
| 3946 branch.blockInformation = conditionStartBlock.blockFlow; | 3946 branch.blockInformation = conditionStartBlock.blockFlow; |
| 3947 } | 3947 } |
| 3948 } | 3948 } |
| OLD | NEW |