| 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 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 List<HInstruction> constructorArguments = <HInstruction>[]; | 1175 List<HInstruction> constructorArguments = <HInstruction>[]; |
| 1176 classElement.forEachInstanceField( | 1176 classElement.forEachInstanceField( |
| 1177 includeBackendMembers: true, | 1177 includeBackendMembers: true, |
| 1178 includeSuperMembers: true, | 1178 includeSuperMembers: true, |
| 1179 f: (ClassElement enclosingClass, Element member) { | 1179 f: (ClassElement enclosingClass, Element member) { |
| 1180 constructorArguments.add(fieldValues[member]); | 1180 constructorArguments.add(fieldValues[member]); |
| 1181 }); | 1181 }); |
| 1182 | 1182 |
| 1183 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); | 1183 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); |
| 1184 add(newObject); | 1184 add(newObject); |
| 1185 |
| 1186 // If the class has type variables, create the runtime type |
| 1187 // information with the type parameters provided. |
| 1188 if (!classElement.typeVariables.isEmpty()) { |
| 1189 List<String> typeVariables = <String>[]; |
| 1190 List<HInstruction> rtiInputs = <HInstruction>[]; |
| 1191 classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
| 1192 typeVariables.add("'$typeVariable': #"); |
| 1193 rtiInputs.add(localsHandler.directLocals[typeVariable.element]); |
| 1194 }); |
| 1195 String jsCode = '{ ${Strings.join(typeVariables, ', ')} }'; |
| 1196 HInstruction typeInfo = new HForeign(new LiteralDartString(jsCode), |
| 1197 new LiteralDartString('Object'), |
| 1198 rtiInputs); |
| 1199 add(typeInfo); |
| 1200 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); |
| 1201 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); |
| 1202 add(typeInfoSetter); |
| 1203 add(new HInvokeStatic( |
| 1204 <HInstruction>[typeInfoSetter, newObject, typeInfo])); |
| 1205 } |
| 1206 |
| 1185 // Generate calls to the constructor bodies. | 1207 // Generate calls to the constructor bodies. |
| 1186 for (int index = constructors.length - 1; index >= 0; index--) { | 1208 for (int index = constructors.length - 1; index >= 0; index--) { |
| 1187 FunctionElement constructor = constructors[index]; | 1209 FunctionElement constructor = constructors[index]; |
| 1188 ConstructorBodyElement body = getConstructorBody(constructor); | 1210 ConstructorBodyElement body = getConstructorBody(constructor); |
| 1189 if (body === null) continue; | 1211 if (body === null) continue; |
| 1190 List bodyCallInputs = <HInstruction>[]; | 1212 List bodyCallInputs = <HInstruction>[]; |
| 1191 bodyCallInputs.add(newObject); | 1213 bodyCallInputs.add(newObject); |
| 1192 int arity = body.functionSignature.parameterCount; | 1214 int arity = body.functionSignature.parameterCount; |
| 1193 body.functionSignature.forEachParameter((parameter) { | 1215 body.functionSignature.forEachParameter((parameter) { |
| 1194 bodyCallInputs.add(localsHandler.readLocal(parameter)); | 1216 bodyCallInputs.add(localsHandler.readLocal(parameter)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1221 // Put the type checks in the first successor of the entry, | 1243 // Put the type checks in the first successor of the entry, |
| 1222 // because that is where the type guards will also be inserted. | 1244 // because that is where the type guards will also be inserted. |
| 1223 // This way we ensure that a type guard will dominate the type | 1245 // This way we ensure that a type guard will dominate the type |
| 1224 // check. | 1246 // check. |
| 1225 FunctionSignature params = functionElement.computeSignature(compiler); | 1247 FunctionSignature params = functionElement.computeSignature(compiler); |
| 1226 params.forEachParameter((Element element) { | 1248 params.forEachParameter((Element element) { |
| 1227 HInstruction newParameter = potentiallyCheckType( | 1249 HInstruction newParameter = potentiallyCheckType( |
| 1228 localsHandler.directLocals[element], element); | 1250 localsHandler.directLocals[element], element); |
| 1229 localsHandler.directLocals[element] = newParameter; | 1251 localsHandler.directLocals[element] = newParameter; |
| 1230 }); | 1252 }); |
| 1253 |
| 1254 // Add the type parameters of the class as parameters of this |
| 1255 // method. |
| 1256 if (functionElement.isFactoryConstructor() |
| 1257 || functionElement.isGenerativeConstructor()) { |
| 1258 ClassElement cls = functionElement.enclosingElement; |
| 1259 cls.typeVariables.forEach((TypeVariableType typeVariable) { |
| 1260 HParameterValue param = new HParameterValue(typeVariable.element); |
| 1261 add(param); |
| 1262 localsHandler.directLocals[typeVariable.element] = param; |
| 1263 }); |
| 1264 } |
| 1231 } | 1265 } |
| 1232 | 1266 |
| 1233 HInstruction potentiallyCheckType(HInstruction original, | 1267 HInstruction potentiallyCheckType(HInstruction original, |
| 1234 Element sourceElement) { | 1268 Element sourceElement) { |
| 1235 if (!compiler.enableTypeAssertions) return original; | 1269 if (!compiler.enableTypeAssertions) return original; |
| 1236 return convertType(original, sourceElement, | 1270 return convertType(original, sourceElement, |
| 1237 HTypeConversion.CHECKED_MODE_CHECK); | 1271 HTypeConversion.CHECKED_MODE_CHECK); |
| 1238 } | 1272 } |
| 1239 | 1273 |
| 1240 HInstruction convertType(HInstruction original, | 1274 HInstruction convertType(HInstruction original, |
| (...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2421 push(new HInvokeSuper(inputs)); | 2455 push(new HInvokeSuper(inputs)); |
| 2422 } else { | 2456 } else { |
| 2423 target = new HInvokeSuper(inputs); | 2457 target = new HInvokeSuper(inputs); |
| 2424 add(target); | 2458 add(target); |
| 2425 inputs = <HInstruction>[target]; | 2459 inputs = <HInstruction>[target]; |
| 2426 addDynamicSendArgumentsToList(node, inputs); | 2460 addDynamicSendArgumentsToList(node, inputs); |
| 2427 push(new HInvokeClosure(selector, inputs)); | 2461 push(new HInvokeClosure(selector, inputs)); |
| 2428 } | 2462 } |
| 2429 } | 2463 } |
| 2430 | 2464 |
| 2465 HInstruction analyzeTypeArgument(Type argument, Node currentNode) { |
| 2466 if (argument.element.isTypeVariable()) { |
| 2467 if (work.element.isFactoryConstructor() |
| 2468 || work.element.isGenerativeConstructor()) { |
| 2469 // The type variable is stored in a parameter of the |
| 2470 // factory. |
| 2471 return localsHandler.readLocal(argument.element); |
| 2472 } else if (work.element.isInstanceMember()) { |
| 2473 // The type variable is stored in [this]. |
| 2474 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), |
| 2475 localsHandler.readThis()); |
| 2476 HInstruction typeInfo = pop(); |
| 2477 HInstruction foreign = new HForeign( |
| 2478 new LiteralDartString('#.$argument'), |
| 2479 new LiteralDartString('String'), |
| 2480 <HInstruction>[typeInfo]); |
| 2481 add(foreign); |
| 2482 return foreign; |
| 2483 } else { |
| 2484 // TODO(ngeoffray): Match the VM behavior and throw an |
| 2485 // exception at runtime. |
| 2486 compiler.cancel('Unimplemented unresolved type variable', |
| 2487 node: currentNode); |
| 2488 } |
| 2489 } else { |
| 2490 // The type variable is a type (e.g. int). |
| 2491 return graph.addConstantString( |
| 2492 new LiteralDartString('$argument'), currentNode); |
| 2493 } |
| 2494 } |
| 2495 |
| 2431 visitNewSend(Send node) { | 2496 visitNewSend(Send node) { |
| 2432 computeType(element) { | 2497 computeType(element) { |
| 2433 Element originalElement = elements[node]; | 2498 Element originalElement = elements[node]; |
| 2434 if (originalElement.getEnclosingClass() === compiler.listClass) { | 2499 if (originalElement.getEnclosingClass() === compiler.listClass) { |
| 2435 if (node.arguments.isEmpty()) { | 2500 if (node.arguments.isEmpty()) { |
| 2436 return HType.EXTENDABLE_ARRAY; | 2501 return HType.EXTENDABLE_ARRAY; |
| 2437 } else { | 2502 } else { |
| 2438 return HType.MUTABLE_ARRAY; | 2503 return HType.MUTABLE_ARRAY; |
| 2439 } | 2504 } |
| 2440 } else if (element.isGenerativeConstructor()) { | 2505 } else if (element.isGenerativeConstructor()) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2457 var inputs = <HInstruction>[]; | 2522 var inputs = <HInstruction>[]; |
| 2458 inputs.add(target); | 2523 inputs.add(target); |
| 2459 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 2524 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| 2460 element, inputs); | 2525 element, inputs); |
| 2461 if (!succeeded) { | 2526 if (!succeeded) { |
| 2462 // TODO(ngeoffray): Match the VM behavior and throw an | 2527 // TODO(ngeoffray): Match the VM behavior and throw an |
| 2463 // exception at runtime. | 2528 // exception at runtime. |
| 2464 compiler.cancel('Unimplemented non-matching static call', node: node); | 2529 compiler.cancel('Unimplemented non-matching static call', node: node); |
| 2465 } | 2530 } |
| 2466 | 2531 |
| 2532 TypeAnnotation annotation = getTypeAnnotationFromSend(node); |
| 2533 elements.getType(annotation).arguments.forEach((Type argument) { |
| 2534 inputs.add(analyzeTypeArgument(argument, node)); |
| 2535 }); |
| 2536 |
| 2467 HType elementType = computeType(element); | 2537 HType elementType = computeType(element); |
| 2468 HInstruction newInstance = new HInvokeStatic(inputs, elementType); | 2538 HInstruction newInstance = new HInvokeStatic(inputs, elementType); |
| 2469 pushWithPosition(newInstance, node); | 2539 pushWithPosition(newInstance, node); |
| 2470 | |
| 2471 TypeAnnotation annotation = getTypeAnnotationFromSend(node); | |
| 2472 Type type = elements.getType(annotation); | |
| 2473 generateSetRuntimeTypeInformation(newInstance, type); | |
| 2474 } | |
| 2475 | |
| 2476 generateSetRuntimeTypeInformation(HInstruction instance, Type type) { | |
| 2477 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { | |
| 2478 String typeString = compiler.codegenWorld.rti.asJsString(type); | |
| 2479 HInstruction typeInfo = new HForeign(new LiteralDartString(typeString), | |
| 2480 new LiteralDartString('Object'), | |
| 2481 <HInstruction>[]); | |
| 2482 add(typeInfo); | |
| 2483 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); | |
| 2484 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); | |
| 2485 add(typeInfoSetter); | |
| 2486 var inputs = <HInstruction>[typeInfoSetter, instance, typeInfo]; | |
| 2487 add(new HInvokeStatic(inputs)); | |
| 2488 } | |
| 2489 } | 2540 } |
| 2490 | 2541 |
| 2491 visitStaticSend(Send node) { | 2542 visitStaticSend(Send node) { |
| 2492 Selector selector = elements.getSelector(node); | 2543 Selector selector = elements.getSelector(node); |
| 2493 Element element = elements[node]; | 2544 Element element = elements[node]; |
| 2494 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { | 2545 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { |
| 2495 stack.add(graph.addConstantNull()); | 2546 stack.add(graph.addConstantNull()); |
| 2496 return; | 2547 return; |
| 2497 } | 2548 } |
| 2498 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR); | 2549 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR); |
| (...skipping 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3885 new HSubGraphBlockInformation(elseBranch.graph)); | 3936 new HSubGraphBlockInformation(elseBranch.graph)); |
| 3886 | 3937 |
| 3887 HBasicBlock conditionStartBlock = conditionBranch.block; | 3938 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 3888 conditionStartBlock.setBlockFlow(info, joinBlock); | 3939 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 3889 SubGraph conditionGraph = conditionBranch.graph; | 3940 SubGraph conditionGraph = conditionBranch.graph; |
| 3890 HIf branch = conditionGraph.end.last; | 3941 HIf branch = conditionGraph.end.last; |
| 3891 assert(branch is HIf); | 3942 assert(branch is HIf); |
| 3892 branch.blockInformation = conditionStartBlock.blockFlow; | 3943 branch.blockInformation = conditionStartBlock.blockFlow; |
| 3893 } | 3944 } |
| 3894 } | 3945 } |
| OLD | NEW |