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

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

Issue 2479323003: Adding check or trust type checks to builder_kernel.dart. (Closed)
Patch Set: . Created 4 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
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
9 import '../common/names.dart'; 9 import '../common/names.dart';
10 import '../common/tasks.dart' show CompilerTask; 10 import '../common/tasks.dart' show CompilerTask;
11 import '../compiler.dart'; 11 import '../compiler.dart';
12 import '../dart_types.dart'; 12 import '../dart_types.dart';
13 import '../elements/elements.dart'; 13 import '../elements/elements.dart';
14 import '../io/source_information.dart'; 14 import '../io/source_information.dart';
15 import '../js_backend/backend.dart' show JavaScriptBackend; 15 import '../js_backend/backend.dart' show JavaScriptBackend;
16 import '../kernel/kernel.dart'; 16 import '../kernel/kernel.dart';
17 import '../resolution/tree_elements.dart'; 17 import '../resolution/tree_elements.dart';
18 import '../tree/dartstring.dart'; 18 import '../tree/dartstring.dart';
19 import '../types/masks.dart'; 19 import '../types/masks.dart';
20 import '../universe/call_structure.dart' show CallStructure;
20 import '../universe/selector.dart'; 21 import '../universe/selector.dart';
22 import '../universe/use.dart' show TypeUse;
21 import 'graph_builder.dart'; 23 import 'graph_builder.dart';
22 import 'kernel_ast_adapter.dart'; 24 import 'kernel_ast_adapter.dart';
23 import 'kernel_string_builder.dart'; 25 import 'kernel_string_builder.dart';
24 import 'locals_handler.dart'; 26 import 'locals_handler.dart';
25 import 'loop_handler.dart'; 27 import 'loop_handler.dart';
26 import 'nodes.dart'; 28 import 'nodes.dart';
27 import 'ssa_branch_builder.dart'; 29 import 'ssa_branch_builder.dart';
30 import 'type_verifier.dart';
28 31
29 class SsaKernelBuilderTask extends CompilerTask { 32 class SsaKernelBuilderTask extends CompilerTask {
30 final JavaScriptBackend backend; 33 final JavaScriptBackend backend;
31 final SourceInformationStrategy sourceInformationFactory; 34 final SourceInformationStrategy sourceInformationFactory;
32 35
33 String get name => 'SSA kernel builder'; 36 String get name => 'SSA kernel builder';
34 37
35 SsaKernelBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory) 38 SsaKernelBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory)
36 : backend = backend, 39 : backend = backend,
37 super(backend.compiler.measurer); 40 super(backend.compiler.measurer);
(...skipping 17 matching lines...) Expand all
55 58
56 @override 59 @override
57 JavaScriptBackend get backend => compiler.backend; 60 JavaScriptBackend get backend => compiler.backend;
58 61
59 @override 62 @override
60 TreeElements get elements => resolvedAst.elements; 63 TreeElements get elements => resolvedAst.elements;
61 64
62 SourceInformationBuilder sourceInformationBuilder; 65 SourceInformationBuilder sourceInformationBuilder;
63 KernelAstAdapter astAdapter; 66 KernelAstAdapter astAdapter;
64 LoopHandler<ir.Node> loopHandler; 67 LoopHandler<ir.Node> loopHandler;
68 TypeVerifier typeVerifier;
65 69
66 KernelSsaBuilder( 70 KernelSsaBuilder(
67 this.targetElement, 71 this.targetElement,
68 this.resolvedAst, 72 this.resolvedAst,
69 Compiler compiler, 73 Compiler compiler,
70 this.registry, 74 this.registry,
71 SourceInformationStrategy sourceInformationFactory, 75 SourceInformationStrategy sourceInformationFactory,
72 Kernel kernel) { 76 Kernel kernel) {
73 this.compiler = compiler; 77 this.compiler = compiler;
74 this.loopHandler = new KernelLoopHandler(this); 78 this.loopHandler = new KernelLoopHandler(this);
79 typeVerifier = new TypeVerifier(this);
75 graph.element = targetElement; 80 graph.element = targetElement;
76 // TODO(het): Should sourceInformationBuilder be in GraphBuilder? 81 // TODO(het): Should sourceInformationBuilder be in GraphBuilder?
77 this.sourceInformationBuilder = 82 this.sourceInformationBuilder =
78 sourceInformationFactory.createBuilderForContext(resolvedAst); 83 sourceInformationFactory.createBuilderForContext(resolvedAst);
79 graph.sourceInformation = 84 graph.sourceInformation =
80 sourceInformationBuilder.buildVariableDeclaration(); 85 sourceInformationBuilder.buildVariableDeclaration();
81 this.localsHandler = new LocalsHandler(this, targetElement, null, compiler); 86 this.localsHandler = new LocalsHandler(this, targetElement, null, compiler);
82 this.astAdapter = new KernelAstAdapter(kernel, compiler.backend, 87 this.astAdapter = new KernelAstAdapter(kernel, compiler.backend,
83 resolvedAst, kernel.nodeToAst, kernel.nodeToElement); 88 resolvedAst, kernel.nodeToAst, kernel.nodeToElement);
84 Element originTarget = targetElement; 89 Element originTarget = targetElement;
(...skipping 26 matching lines...) Expand all
111 if (field.initializer != null) { 116 if (field.initializer != null) {
112 field.initializer.accept(this); 117 field.initializer.accept(this);
113 } else { 118 } else {
114 stack.add(graph.addConstantNull(compiler)); 119 stack.add(graph.addConstantNull(compiler));
115 } 120 }
116 HInstruction value = pop(); 121 HInstruction value = pop();
117 closeAndGotoExit(new HReturn(value, null)); 122 closeAndGotoExit(new HReturn(value, null));
118 closeFunction(); 123 closeFunction();
119 } 124 }
120 125
126
127 /// Pops the most recent instruction from the stack and 'boolifies' it.
128 ///
129 /// Boolification is checking if the value is '=== true'.
121 @override 130 @override
122 HInstruction popBoolified() { 131 HInstruction popBoolified() {
123 HInstruction value = pop(); 132 HInstruction value = pop();
124 // TODO(het): add boolean conversion type check 133 if (typeVerifier.checkOrTrustTypes) {
134 return typeVerifier.potentiallyCheckOrTrustType(
135 value, compiler.coreTypes.boolType,
136 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
137 }
125 HInstruction result = new HBoolify(value, backend.boolType); 138 HInstruction result = new HBoolify(value, backend.boolType);
126 add(result); 139 add(result);
127 return result; 140 return result;
128 } 141 }
129 142
130 void buildConstructor(ir.Constructor constructor) { 143 void buildConstructor(ir.Constructor constructor) {
131 // TODO(het): Actually handle this correctly 144 // TODO(het): Actually handle this correctly
132 HBasicBlock block = graph.addNewBlock(); 145 HBasicBlock block = graph.addNewBlock();
133 open(graph.entry); 146 open(graph.entry);
134 close(new HGoto()).addSuccessor(block); 147 close(new HGoto()).addSuccessor(block);
135 open(block); 148 open(block);
136 closeAndGotoExit(new HGoto()); 149 closeAndGotoExit(new HGoto());
137 graph.finalize(); 150 graph.finalize();
138 } 151 }
139 152
153 HTypeConversion buildFunctionTypeConversion(HInstruction original,
154 DartType type, int kind) {
155 String name =
156 kind == HTypeConversion.CAST_TYPE_CHECK ? '_asCheck' : '_assertCheck';
157
158 List<HInstruction> arguments = <HInstruction>[
159 buildFunctionType(type),
160 original
161 ];
162 _pushDynamicInvocation(null, null, arguments,
163 selector: new Selector.call(
164 new Name(name, astAdapter.jsHelperLibrary),
165 CallStructure.ONE_ARG));
166
167 return new HTypeConversion(type, kind, original.instructionType, pop());
168 }
169
140 /// Builds a SSA graph for [procedure]. 170 /// Builds a SSA graph for [procedure].
141 void buildProcedure(ir.Procedure procedure) { 171 void buildProcedure(ir.Procedure procedure) {
142 openFunction(); 172 openFunction();
143 procedure.function.body.accept(this); 173 procedure.function.body.accept(this);
144 closeFunction(); 174 closeFunction();
145 } 175 }
146 176
147 void openFunction() { 177 void openFunction() {
148 HBasicBlock block = graph.addNewBlock(); 178 HBasicBlock block = graph.addNewBlock();
149 open(graph.entry); 179 open(graph.entry);
150 localsHandler.startFunction(targetElement, resolvedAst.node); 180 localsHandler.startFunction(targetElement, resolvedAst.node);
151 close(new HGoto()).addSuccessor(block); 181 close(new HGoto()).addSuccessor(block);
152 182
153 open(block); 183 open(block);
154 } 184 }
155 185
156 void closeFunction() { 186 void closeFunction() {
157 if (!isAborted()) closeAndGotoExit(new HGoto()); 187 if (!isAborted()) closeAndGotoExit(new HGoto());
158 graph.finalize(); 188 graph.finalize();
159 } 189 }
160 190
191 /// Pushes a boolean checking [expression] against null.
192 pushCheckNull(HInstruction expression) {
193 push(new HIdentity(
194 expression, graph.addConstantNull(compiler), null, backend.boolType));
195 }
161 @override 196 @override
162 void defaultExpression(ir.Expression expression) { 197 void defaultExpression(ir.Expression expression) {
163 // TODO(het): This is only to get tests working 198 // TODO(het): This is only to get tests working
164 stack.add(graph.addConstantNull(compiler)); 199 stack.add(graph.addConstantNull(compiler));
165 } 200 }
166 201
202 /// Returns the current source element.
203 ///
204 /// The returned element is a declaration element.
205 @override
206 Element get sourceElement => astAdapter.getElement(target);
Emily Fortuna 2016/11/11 23:23:11 really not sure about this as being what sourceEle
sra1 2016/11/12 00:31:19 SourceElement is used to mark HInstructions with t
Emily Fortuna 2016/11/14 17:47:56 Hmmm what dart code should produce that compiles t
sra1 2016/11/14 18:00:20 "return s.length + s.codeUnitAt(0);" is the sugges
Emily Fortuna 2016/11/14 19:03:39 Okay. Code looks like option one, so I think we're
207
167 @override 208 @override
168 void visitBlock(ir.Block block) { 209 void visitBlock(ir.Block block) {
169 assert(!isAborted()); 210 assert(!isAborted());
170 for (ir.Statement statement in block.statements) { 211 for (ir.Statement statement in block.statements) {
171 statement.accept(this); 212 statement.accept(this);
172 if (!isReachable) { 213 if (!isReachable) {
173 // The block has been aborted by a return or a throw. 214 // The block has been aborted by a return or a throw.
174 if (stack.isNotEmpty) { 215 if (stack.isNotEmpty) {
175 compiler.reporter.internalError( 216 compiler.reporter.internalError(
176 NO_LOCATION_SPANNABLE, 'Non-empty instruction stack.'); 217 NO_LOCATION_SPANNABLE, 'Non-empty instruction stack.');
(...skipping 13 matching lines...) Expand all
190 exprStatement.expression.accept(this); 231 exprStatement.expression.accept(this);
191 pop(); 232 pop();
192 } 233 }
193 234
194 @override 235 @override
195 void visitReturnStatement(ir.ReturnStatement returnStatement) { 236 void visitReturnStatement(ir.ReturnStatement returnStatement) {
196 HInstruction value; 237 HInstruction value;
197 if (returnStatement.expression == null) { 238 if (returnStatement.expression == null) {
198 value = graph.addConstantNull(compiler); 239 value = graph.addConstantNull(compiler);
199 } else { 240 } else {
241 assert(target is ir.Procedure);
200 returnStatement.expression.accept(this); 242 returnStatement.expression.accept(this);
201 value = pop(); 243 value = typeVerifier.potentiallyCheckOrTrustType(
202 // TODO(het): Check or trust the type of value 244 pop(),
245 astAdapter.getFunctionReturnType((target as ir.Procedure).function));
203 } 246 }
204 // TODO(het): Add source information 247 // TODO(het): Add source information
205 // TODO(het): Set a return value instead of closing the function when we 248 // TODO(het): Set a return value instead of closing the function when we
206 // support inlining. 249 // support inlining.
207 closeAndGotoExit(new HReturn(value, null)); 250 closeAndGotoExit(new HReturn(value, null));
208 } 251 }
209 252
210 @override 253 @override
211 void visitForStatement(ir.ForStatement forStatement) { 254 void visitForStatement(ir.ForStatement forStatement) {
212 assert(isReachable); 255 assert(isReachable);
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 staticSet.value.accept(this); 627 staticSet.value.accept(this);
585 HInstruction value = pop(); 628 HInstruction value = pop();
586 629
587 var staticTarget = staticSet.target; 630 var staticTarget = staticSet.target;
588 if (staticTarget is ir.Procedure) { 631 if (staticTarget is ir.Procedure) {
589 // Invoke the setter 632 // Invoke the setter
590 _pushStaticInvocation(staticTarget, <HInstruction>[value], 633 _pushStaticInvocation(staticTarget, <HInstruction>[value],
591 astAdapter.returnTypeOf(staticTarget)); 634 astAdapter.returnTypeOf(staticTarget));
592 pop(); 635 pop();
593 } else { 636 } else {
594 // TODO(het): check or trust type 637 add(new HStaticStore(astAdapter.getMember(staticTarget),
595 add(new HStaticStore(astAdapter.getMember(staticTarget), value)); 638 typeVerifier.potentiallyCheckOrTrustType(value,
639 astAdapter.getDartType(staticTarget.setterType))));
596 } 640 }
597 stack.add(value); 641 stack.add(value);
598 } 642 }
599 643
600 @override 644 @override
601 void visitPropertyGet(ir.PropertyGet propertyGet) { 645 void visitPropertyGet(ir.PropertyGet propertyGet) {
602 propertyGet.receiver.accept(this); 646 propertyGet.receiver.accept(this);
603 HInstruction receiver = pop(); 647 HInstruction receiver = pop();
604 648
605 _pushDynamicInvocation(propertyGet, astAdapter.typeOfGet(propertyGet), 649 _pushDynamicInvocation(propertyGet, astAdapter.typeOfGet(propertyGet),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 void _visitLocalSetter(ir.VariableDeclaration variable, HInstruction value) { 684 void _visitLocalSetter(ir.VariableDeclaration variable, HInstruction value) {
641 // TODO(het): handle case where the variable is top-level or static 685 // TODO(het): handle case where the variable is top-level or static
642 LocalElement local = astAdapter.getElement(variable); 686 LocalElement local = astAdapter.getElement(variable);
643 687
644 // Give the value a name if it doesn't have one already. 688 // Give the value a name if it doesn't have one already.
645 if (value.sourceElement == null) { 689 if (value.sourceElement == null) {
646 value.sourceElement = local; 690 value.sourceElement = local;
647 } 691 }
648 692
649 stack.add(value); 693 stack.add(value);
650 // TODO(het): check or trust type 694 localsHandler.updateLocal(local, typeVerifier.potentiallyCheckOrTrustType(
651 localsHandler.updateLocal(local, value); 695 value, astAdapter.getDartType(variable.type)));
652 } 696 }
653 697
654 // TODO(het): Also extract type arguments 698 // TODO(het): Also extract type arguments
655 /// Extracts the list of instructions for the expressions in the arguments. 699 /// Extracts the list of instructions for the expressions in the arguments.
656 List<HInstruction> _visitArguments(ir.Arguments arguments) { 700 List<HInstruction> _visitArguments(ir.Arguments arguments) {
657 List<HInstruction> result = <HInstruction>[]; 701 List<HInstruction> result = <HInstruction>[];
658 702
659 for (ir.Expression argument in arguments.positional) { 703 for (ir.Expression argument in arguments.positional) {
660 argument.accept(this); 704 argument.accept(this);
661 result.add(pop()); 705 result.add(pop());
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 push(new HNot(popBoolified(), backend.boolType)); 861 push(new HNot(popBoolified(), backend.boolType));
818 } 862 }
819 863
820 @override 864 @override
821 void visitStringConcatenation(ir.StringConcatenation stringConcat) { 865 void visitStringConcatenation(ir.StringConcatenation stringConcat) {
822 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); 866 KernelStringBuilder stringBuilder = new KernelStringBuilder(this);
823 stringConcat.accept(stringBuilder); 867 stringConcat.accept(stringBuilder);
824 stack.add(stringBuilder.result); 868 stack.add(stringBuilder.result);
825 } 869 }
826 } 870 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698