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

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

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