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

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

Issue 712093002: Revert "dart2js: Trust type annotations more often with --trust-type-annotation." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | « no previous file | pkg/compiler/lib/src/ssa/codegen.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 /// A synthetic local variable only used with the SSA graph. 7 /// A synthetic local variable only used with the SSA graph.
8 /// 8 ///
9 /// For instance used for holding return value of function or the exception of a 9 /// For instance used for holding return value of function or the exception of a
10 /// try-catch statement. 10 /// try-catch statement.
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 999
1000 CodegenRegistry get registry => work.registry; 1000 CodegenRegistry get registry => work.registry;
1001 1001
1002 /// Returns the current source element. 1002 /// Returns the current source element.
1003 /// 1003 ///
1004 /// The returned element is a declaration element. 1004 /// The returned element is a declaration element.
1005 // TODO(johnniwinther): Check that all usages of sourceElement agree on 1005 // TODO(johnniwinther): Check that all usages of sourceElement agree on
1006 // implementation/declaration distinction. 1006 // implementation/declaration distinction.
1007 Element get sourceElement => sourceElementStack.last; 1007 Element get sourceElement => sourceElementStack.last;
1008 1008
1009 bool get _checkOrTrustTypes =>
1010 compiler.enableTypeAssertions || compiler.trustTypeAnnotations;
1011
1012 HBasicBlock addNewBlock() { 1009 HBasicBlock addNewBlock() {
1013 HBasicBlock block = graph.addNewBlock(); 1010 HBasicBlock block = graph.addNewBlock();
1014 // If adding a new block during building of an expression, it is due to 1011 // If adding a new block during building of an expression, it is due to
1015 // conditional expressions or short-circuit logical operators. 1012 // conditional expressions or short-circuit logical operators.
1016 return block; 1013 return block;
1017 } 1014 }
1018 1015
1019 void open(HBasicBlock block) { 1016 void open(HBasicBlock block) {
1020 block.open(); 1017 block.open();
1021 current = block; 1018 current = block;
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 HGraph buildCheckedSetter(VariableElement field) { 1476 HGraph buildCheckedSetter(VariableElement field) {
1480 openFunction(field, field.node); 1477 openFunction(field, field.node);
1481 HInstruction thisInstruction = localsHandler.readThis(); 1478 HInstruction thisInstruction = localsHandler.readThis();
1482 // Use dynamic type because the type computed by the inferrer is 1479 // Use dynamic type because the type computed by the inferrer is
1483 // narrowed to the type annotation. 1480 // narrowed to the type annotation.
1484 HInstruction parameter = new HParameterValue(field, backend.dynamicType); 1481 HInstruction parameter = new HParameterValue(field, backend.dynamicType);
1485 // Add the parameter as the last instruction of the entry block. 1482 // Add the parameter as the last instruction of the entry block.
1486 // If the method is intercepted, we want the actual receiver 1483 // If the method is intercepted, we want the actual receiver
1487 // to be the first parameter. 1484 // to be the first parameter.
1488 graph.entry.addBefore(graph.entry.last, parameter); 1485 graph.entry.addBefore(graph.entry.last, parameter);
1489 HInstruction value = potentiallyCheckOrTrustType(parameter, field.type); 1486 HInstruction value =
1487 potentiallyCheckType(parameter, field.type);
1490 add(new HFieldSet(field, thisInstruction, value)); 1488 add(new HFieldSet(field, thisInstruction, value));
1491 return closeFunction(); 1489 return closeFunction();
1492 } 1490 }
1493 1491
1494 HGraph buildLazyInitializer(VariableElement variable) { 1492 HGraph buildLazyInitializer(VariableElement variable) {
1495 ast.Node node = variable.node; 1493 ast.Node node = variable.node;
1496 openFunction(variable, node); 1494 openFunction(variable, node);
1497 assert(variable.initializer != null); 1495 assert(variable.initializer != null);
1498 visit(variable.initializer); 1496 visit(variable.initializer);
1499 HInstruction value = pop(); 1497 HInstruction value = pop();
1500 value = potentiallyCheckOrTrustType(value, variable.type); 1498 value = potentiallyCheckType(value, variable.type);
1501 closeAndGotoExit(new HReturn(value)); 1499 closeAndGotoExit(new HReturn(value));
1502 return closeFunction(); 1500 return closeFunction();
1503 } 1501 }
1504 1502
1505 /** 1503 /**
1506 * Returns the constructor body associated with the given constructor or 1504 * Returns the constructor body associated with the given constructor or
1507 * creates a new constructor body, if none can be found. 1505 * creates a new constructor body, if none can be found.
1508 * 1506 *
1509 * Returns [:null:] if the constructor does not have a body. 1507 * Returns [:null:] if the constructor does not have a body.
1510 */ 1508 */
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1653 * [visitForIn]. 1651 * [visitForIn].
1654 */ 1652 */
1655 return currentNode.asForIn() != null; 1653 return currentNode.asForIn() != null;
1656 } 1654 }
1657 1655
1658 /** 1656 /**
1659 * In checked mode, generate type tests for the parameters of the inlined 1657 * In checked mode, generate type tests for the parameters of the inlined
1660 * function. 1658 * function.
1661 */ 1659 */
1662 void potentiallyCheckInlinedParameterTypes(FunctionElement function) { 1660 void potentiallyCheckInlinedParameterTypes(FunctionElement function) {
1663 if (!_checkOrTrustTypes) return; 1661 if (!compiler.enableTypeAssertions) return;
1664 1662
1665 FunctionSignature signature = function.functionSignature; 1663 FunctionSignature signature = function.functionSignature;
1666 signature.orderedForEachParameter((ParameterElement parameter) { 1664 signature.orderedForEachParameter((ParameterElement parameter) {
1667 HInstruction argument = localsHandler.readLocal(parameter); 1665 HInstruction argument = localsHandler.readLocal(parameter);
1668 potentiallyCheckOrTrustType(argument, parameter.type); 1666 potentiallyCheckType(argument, parameter.type);
1669 }); 1667 });
1670 } 1668 }
1671 1669
1672 /** 1670 /**
1673 * Documentation wanted -- johnniwinther 1671 * Documentation wanted -- johnniwinther
1674 * 1672 *
1675 * Invariant: [constructors] must contain only implementation elements. 1673 * Invariant: [constructors] must contain only implementation elements.
1676 */ 1674 */
1677 void inlineSuperOrRedirect(FunctionElement callee, 1675 void inlineSuperOrRedirect(FunctionElement callee,
1678 List<HInstruction> compiledArguments, 1676 List<HInstruction> compiledArguments,
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 classElement.forEachInstanceField( 1967 classElement.forEachInstanceField(
1970 (ClassElement enclosingClass, VariableElement member) { 1968 (ClassElement enclosingClass, VariableElement member) {
1971 HInstruction value = fieldValues[member]; 1969 HInstruction value = fieldValues[member];
1972 if (value == null) { 1970 if (value == null) {
1973 // Uninitialized native fields are pre-initialized by the native 1971 // Uninitialized native fields are pre-initialized by the native
1974 // implementation. 1972 // implementation.
1975 assert(isNativeUpgradeFactory); 1973 assert(isNativeUpgradeFactory);
1976 } else { 1974 } else {
1977 fields.add(member); 1975 fields.add(member);
1978 DartType type = localsHandler.substInContext(member.type); 1976 DartType type = localsHandler.substInContext(member.type);
1979 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); 1977 constructorArguments.add(potentiallyCheckType(value, type));
1980 } 1978 }
1981 }, 1979 },
1982 includeSuperAndInjectedMembers: true); 1980 includeSuperAndInjectedMembers: true);
1983 1981
1984 InterfaceType type = classElement.thisType; 1982 InterfaceType type = classElement.thisType;
1985 TypeMask ssaType = 1983 TypeMask ssaType =
1986 new TypeMask.nonNullExact(classElement.declaration, compiler.world); 1984 new TypeMask.nonNullExact(classElement.declaration, compiler.world);
1987 List<DartType> instantiatedTypes; 1985 List<DartType> instantiatedTypes;
1988 addInlinedInstantiation(type); 1986 addInlinedInstantiation(type);
1989 if (!currentInlinedInstantiations.isEmpty) { 1987 if (!currentInlinedInstantiations.isEmpty) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 // class A { 2212 // class A {
2215 // A(String foo) = A.b; 2213 // A(String foo) = A.b;
2216 // A(int foo) { print(foo); } 2214 // A(int foo) { print(foo); }
2217 // } 2215 // }
2218 // main() { 2216 // main() {
2219 // new A(499); // valid even in checked mode. 2217 // new A(499); // valid even in checked mode.
2220 // new A("foo"); // invalid in checked mode. 2218 // new A("foo"); // invalid in checked mode.
2221 // 2219 //
2222 // Only the final target is allowed to check for the argument types. 2220 // Only the final target is allowed to check for the argument types.
2223 newParameter = 2221 newParameter =
2224 potentiallyCheckOrTrustType(newParameter, parameterElement.type); 2222 potentiallyCheckType(newParameter, parameterElement.type);
2225 } 2223 }
2226 localsHandler.directLocals[parameterElement] = newParameter; 2224 localsHandler.directLocals[parameterElement] = newParameter;
2227 }); 2225 });
2228 2226
2229 returnType = signature.type.returnType; 2227 returnType = signature.type.returnType;
2230 } else { 2228 } else {
2231 // Otherwise it is a lazy initializer which does not have parameters. 2229 // Otherwise it is a lazy initializer which does not have parameters.
2232 assert(element is VariableElement); 2230 assert(element is VariableElement);
2233 } 2231 }
2234 2232
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 null, 2289 null,
2292 new Selector.call(name, backend.jsHelperLibrary, 1), 2290 new Selector.call(name, backend.jsHelperLibrary, 1),
2293 arguments); 2291 arguments);
2294 2292
2295 return new HTypeConversion(type, kind, original.instructionType, pop()); 2293 return new HTypeConversion(type, kind, original.instructionType, pop());
2296 } else { 2294 } else {
2297 return original.convertType(compiler, type, kind); 2295 return original.convertType(compiler, type, kind);
2298 } 2296 }
2299 } 2297 }
2300 2298
2301 HInstruction _trustType(HInstruction original, DartType type) { 2299 HInstruction potentiallyBuildTypeHint(HInstruction original, DartType type) {
2302 assert(compiler.trustTypeAnnotations); 2300 if (!compiler.trustTypeAnnotations || type == null) return original;
2303 assert(type != null);
2304 type = localsHandler.substInContext(type); 2301 type = localsHandler.substInContext(type);
2305 type = type.unalias(compiler);
2306 if (type.isDynamic) return original;
2307 if (!type.isInterfaceType) return original; 2302 if (!type.isInterfaceType) return original;
2308 // The type element is either a class or the void element. 2303 TypeMask mask = new TypeMask.subtype(type.element, compiler.world);
2309 Element element = type.element; 2304 var result = new HTypeKnown.pinned(mask, original);
2310 if (element == compiler.objectClass) return original; 2305 return result;
2311 TypeMask mask = new TypeMask.subtype(element, compiler.world);
2312 return new HTypeKnown.pinned(mask, original);
2313 } 2306 }
2314 2307
2315 HInstruction _checkType(HInstruction original, DartType type, int kind) { 2308 HInstruction potentiallyCheckType(HInstruction original, DartType type,
2316 assert(compiler.enableTypeAssertions); 2309 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
2317 assert(type != null); 2310 if (!compiler.enableTypeAssertions) return original;
2318 type = localsHandler.substInContext(type); 2311 type = localsHandler.substInContext(type);
2319 HInstruction other = buildTypeConversion(original, type, kind); 2312 HInstruction other = buildTypeConversion(original, type, kind);
2313 if (other != original) add(other);
2320 registry.registerIsCheck(type); 2314 registry.registerIsCheck(type);
2321 return other; 2315 return other;
2322 } 2316 }
2323 2317
2324 HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type,
2325 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
2326 if (type == null) return original;
2327 HInstruction checkedOrTrusted = original;
2328 if (compiler.trustTypeAnnotations) {
2329 checkedOrTrusted = _trustType(original, type);
2330 } else if (compiler.enableTypeAssertions) {
2331 checkedOrTrusted = _checkType(original, type, kind);
2332 }
2333 if (checkedOrTrusted == original) return original;
2334 add(checkedOrTrusted);
2335 return checkedOrTrusted;
2336 }
2337
2338 void assertIsSubtype(ast.Node node, DartType subtype, DartType supertype, 2318 void assertIsSubtype(ast.Node node, DartType subtype, DartType supertype,
2339 String message) { 2319 String message) {
2340 HInstruction subtypeInstruction = 2320 HInstruction subtypeInstruction =
2341 analyzeTypeArgument(localsHandler.substInContext(subtype)); 2321 analyzeTypeArgument(localsHandler.substInContext(subtype));
2342 HInstruction supertypeInstruction = 2322 HInstruction supertypeInstruction =
2343 analyzeTypeArgument(localsHandler.substInContext(supertype)); 2323 analyzeTypeArgument(localsHandler.substInContext(supertype));
2344 HInstruction messageInstruction = 2324 HInstruction messageInstruction =
2345 graph.addConstantString(new ast.DartString.literal(message), compiler); 2325 graph.addConstantString(new ast.DartString.literal(message), compiler);
2346 Element element = backend.getAssertIsSubtype(); 2326 Element element = backend.getAssertIsSubtype();
2347 var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction, 2327 var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction,
(...skipping 23 matching lines...) Expand all
2371 HInstruction pop() { 2351 HInstruction pop() {
2372 return stack.removeLast(); 2352 return stack.removeLast();
2373 } 2353 }
2374 2354
2375 void dup() { 2355 void dup() {
2376 stack.add(stack.last); 2356 stack.add(stack.last);
2377 } 2357 }
2378 2358
2379 HInstruction popBoolified() { 2359 HInstruction popBoolified() {
2380 HInstruction value = pop(); 2360 HInstruction value = pop();
2381 if (_checkOrTrustTypes) { 2361 if (compiler.enableTypeAssertions) {
2382 return potentiallyCheckOrTrustType( 2362 return potentiallyCheckType(
2383 value, 2363 value,
2384 compiler.boolClass.rawType, 2364 compiler.boolClass.rawType,
2385 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); 2365 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
2386 } 2366 }
2387 HInstruction result = new HBoolify(value, backend.boolType); 2367 HInstruction result = new HBoolify(value, backend.boolType);
2388 add(result); 2368 add(result);
2389 return result; 2369 return result;
2390 } 2370 }
2391 2371
2392 HInstruction attachPosition(HInstruction target, ast.Node node) { 2372 HInstruction attachPosition(HInstruction target, ast.Node node) {
(...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after
3199 if (location == null) { 3179 if (location == null) {
3200 assert(send != null); 3180 assert(send != null);
3201 location = send; 3181 location = send;
3202 } 3182 }
3203 if (Elements.isStaticOrTopLevelField(element)) { 3183 if (Elements.isStaticOrTopLevelField(element)) {
3204 if (element.isSetter) { 3184 if (element.isSetter) {
3205 pushInvokeStatic(location, element, <HInstruction>[value]); 3185 pushInvokeStatic(location, element, <HInstruction>[value]);
3206 pop(); 3186 pop();
3207 } else { 3187 } else {
3208 VariableElement field = element; 3188 VariableElement field = element;
3209 value = potentiallyCheckOrTrustType(value, field.type); 3189 value =
3190 potentiallyCheckType(value, field.type);
3210 addWithPosition(new HStaticStore(element, value), location); 3191 addWithPosition(new HStaticStore(element, value), location);
3211 } 3192 }
3212 stack.add(value); 3193 stack.add(value);
3213 } else if (Elements.isErroneousElement(element)) { 3194 } else if (Elements.isErroneousElement(element)) {
3214 List<HInstruction> arguments = 3195 List<HInstruction> arguments =
3215 send == null ? const <HInstruction>[] : <HInstruction>[value]; 3196 send == null ? const <HInstruction>[] : <HInstruction>[value];
3216 // An erroneous element indicates an unresolved static setter. 3197 // An erroneous element indicates an unresolved static setter.
3217 generateThrowNoSuchMethod(location, 3198 generateThrowNoSuchMethod(location,
3218 noSuchMethodTargetSymbolString(element, 'set'), 3199 noSuchMethodTargetSymbolString(element, 'set'),
3219 argumentValues: arguments); 3200 argumentValues: arguments);
3220 } else { 3201 } else {
3221 stack.add(value); 3202 stack.add(value);
3222 LocalElement local = element; 3203 LocalElement local = element;
3223 // If the value does not already have a name, give it here. 3204 // If the value does not already have a name, give it here.
3224 if (value.sourceElement == null) { 3205 if (value.sourceElement == null) {
3225 value.sourceElement = local; 3206 value.sourceElement = local;
3226 } 3207 }
3227 HInstruction checkedOrTrusted = 3208 HInstruction checked =
3228 potentiallyCheckOrTrustType(value, local.type); 3209 potentiallyCheckType(value, local.type);
3229 if (!identical(checkedOrTrusted, value)) { 3210 if (!identical(checked, value)) {
3230 pop(); 3211 pop();
3231 stack.add(checkedOrTrusted); 3212 stack.add(checked);
3213 }
3214 HInstruction trusted =
3215 potentiallyBuildTypeHint(checked, local.type);
3216 if (!identical(trusted, checked)) {
3217 pop();
3218 push(trusted);
3232 } 3219 }
3233 3220
3234 localsHandler.updateLocal(local, checkedOrTrusted); 3221 localsHandler.updateLocal(local, trusted);
3235 } 3222 }
3236 } 3223 }
3237 3224
3238 HInstruction invokeInterceptor(HInstruction receiver) { 3225 HInstruction invokeInterceptor(HInstruction receiver) {
3239 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType); 3226 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType);
3240 add(interceptor); 3227 add(interceptor);
3241 return interceptor; 3228 return interceptor;
3242 } 3229 }
3243 3230
3244 HForeign createForeign(js.Template code, 3231 HForeign createForeign(js.Template code,
(...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after
4310 // the 'new' is done. 4297 // the 'new' is done.
4311 if (backend.classNeedsRti(compiler.listClass) && 4298 if (backend.classNeedsRti(compiler.listClass) &&
4312 (isFixedListConstructorCall || isGrowableListConstructorCall || 4299 (isFixedListConstructorCall || isGrowableListConstructorCall ||
4313 isJSArrayTypedConstructor)) { 4300 isJSArrayTypedConstructor)) {
4314 newInstance = handleListConstructor(type, send, pop()); 4301 newInstance = handleListConstructor(type, send, pop());
4315 stack.add(newInstance); 4302 stack.add(newInstance);
4316 } 4303 }
4317 4304
4318 // Finally, if we called a redirecting factory constructor, check the type. 4305 // Finally, if we called a redirecting factory constructor, check the type.
4319 if (isRedirected) { 4306 if (isRedirected) {
4320 HInstruction checked = potentiallyCheckOrTrustType(newInstance, type); 4307 HInstruction checked = potentiallyCheckType(newInstance, type);
4321 if (checked != newInstance) { 4308 if (checked != newInstance) {
4322 pop(); 4309 pop();
4323 stack.add(checked); 4310 stack.add(checked);
4324 } 4311 }
4325 } 4312 }
4326 } 4313 }
4327 4314
4328 void potentiallyAddTypeArguments(List<HInstruction> inputs, ClassElement cls, 4315 void potentiallyAddTypeArguments(List<HInstruction> inputs, ClassElement cls,
4329 InterfaceType expectedType) { 4316 InterfaceType expectedType) {
4330 if (!backend.classNeedsRti(cls)) return; 4317 if (!backend.classNeedsRti(cls)) return;
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after
5048 if (identical(node.beginToken.stringValue, 'native')) { 5035 if (identical(node.beginToken.stringValue, 'native')) {
5049 native.handleSsaNative(this, node.expression); 5036 native.handleSsaNative(this, node.expression);
5050 return; 5037 return;
5051 } 5038 }
5052 HInstruction value; 5039 HInstruction value;
5053 if (node.expression == null) { 5040 if (node.expression == null) {
5054 value = graph.addConstantNull(compiler); 5041 value = graph.addConstantNull(compiler);
5055 } else { 5042 } else {
5056 visit(node.expression); 5043 visit(node.expression);
5057 value = pop(); 5044 value = pop();
5058 value = potentiallyCheckOrTrustType(value, returnType); 5045 value = potentiallyCheckType(value, returnType);
5059 } 5046 }
5060 5047
5061 handleInTryStatement(); 5048 handleInTryStatement();
5062 emitReturn(value, node); 5049 emitReturn(value, node);
5063 } 5050 }
5064 5051
5065 visitThrow(ast.Throw node) { 5052 visitThrow(ast.Throw node) {
5066 visitThrowExpression(node.expression); 5053 visitThrowExpression(node.expression);
5067 if (isReachable) { 5054 if (isReachable) {
5068 handleInTryStatement(); 5055 handleInTryStatement();
(...skipping 1513 matching lines...) Expand 10 before | Expand all | Expand 10 after
6582 if (unaliased is TypedefType) throw 'unable to unalias $type'; 6569 if (unaliased is TypedefType) throw 'unable to unalias $type';
6583 unaliased.accept(this, builder); 6570 unaliased.accept(this, builder);
6584 } 6571 }
6585 6572
6586 void visitDynamicType(DynamicType type, SsaBuilder builder) { 6573 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6587 JavaScriptBackend backend = builder.compiler.backend; 6574 JavaScriptBackend backend = builder.compiler.backend;
6588 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 6575 ClassElement cls = backend.findHelper('DynamicRuntimeType');
6589 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 6576 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
6590 } 6577 }
6591 } 6578 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698