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

Side by Side Diff: lib/compiler/implementation/ssa/builder.dart

Issue 10888003: Change how runtime type information is being set in the backend. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 3 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
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 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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/lib/js_helper.dart ('k') | lib/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698