| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 class SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
| 8 SsaCodeGeneratorTask generator; | 8 SsaCodeGeneratorTask generator; |
| 9 SsaBuilderTask builder; | 9 SsaBuilderTask builder; |
| 10 SsaOptimizerTask optimizer; | 10 SsaOptimizerTask optimizer; |
| 11 | 11 |
| 12 SsaFunctionCompiler(JavaScriptBackend backend) | 12 SsaFunctionCompiler(JavaScriptBackend backend, bool generateSourceMap) |
| 13 : generator = new SsaCodeGeneratorTask(backend), | 13 : generator = new SsaCodeGeneratorTask(backend), |
| 14 builder = new SsaBuilderTask(backend), | 14 builder = new SsaBuilderTask(backend, generateSourceMap), |
| 15 optimizer = new SsaOptimizerTask(backend); | 15 optimizer = new SsaOptimizerTask(backend); |
| 16 | 16 |
| 17 /// Generates JavaScript code for `work.element`. | 17 /// Generates JavaScript code for `work.element`. |
| 18 /// Using the ssa builder, optimizer and codegenerator. | 18 /// Using the ssa builder, optimizer and codegenerator. |
| 19 js.Fun compile(CodegenWorkItem work) { | 19 js.Fun compile(CodegenWorkItem work) { |
| 20 HGraph graph = builder.build(work); | 20 HGraph graph = builder.build(work); |
| 21 optimizer.optimize(work, graph); | 21 optimizer.optimize(work, graph); |
| 22 return generator.generateCode(work, graph); | 22 return generator.generateCode(work, graph); |
| 23 } | 23 } |
| 24 | 24 |
| 25 Iterable<CompilerTask> get tasks { | 25 Iterable<CompilerTask> get tasks { |
| 26 return <CompilerTask>[builder, optimizer, generator]; | 26 return <CompilerTask>[builder, optimizer, generator]; |
| 27 } | 27 } |
| 28 } | 28 } |
| 29 | 29 |
| 30 /// A synthetic local variable only used with the SSA graph. | 30 /// A synthetic local variable only used with the SSA graph. |
| 31 /// | 31 /// |
| 32 /// For instance used for holding return value of function or the exception of a | 32 /// For instance used for holding return value of function or the exception of a |
| 33 /// try-catch statement. | 33 /// try-catch statement. |
| 34 class SyntheticLocal extends Local { | 34 class SyntheticLocal extends Local { |
| 35 final String name; | 35 final String name; |
| 36 final ExecutableElement executableContext; | 36 final ExecutableElement executableContext; |
| 37 | 37 |
| 38 SyntheticLocal(this.name, this.executableContext); | 38 SyntheticLocal(this.name, this.executableContext); |
| 39 } | 39 } |
| 40 | 40 |
| 41 class SsaBuilderTask extends CompilerTask { | 41 class SsaBuilderTask extends CompilerTask { |
| 42 final CodeEmitterTask emitter; | 42 final CodeEmitterTask emitter; |
| 43 final JavaScriptBackend backend; | 43 final JavaScriptBackend backend; |
| 44 final bool generateSourceMap; |
| 44 | 45 |
| 45 String get name => 'SSA builder'; | 46 String get name => 'SSA builder'; |
| 46 | 47 |
| 47 SsaBuilderTask(JavaScriptBackend backend) | 48 SsaBuilderTask(JavaScriptBackend backend, this.generateSourceMap) |
| 48 : emitter = backend.emitter, | 49 : emitter = backend.emitter, |
| 49 backend = backend, | 50 backend = backend, |
| 50 super(backend.compiler); | 51 super(backend.compiler); |
| 51 | 52 |
| 52 HGraph build(CodegenWorkItem work) { | 53 HGraph build(CodegenWorkItem work) { |
| 53 return measure(() { | 54 return measure(() { |
| 54 Element element = work.element.implementation; | 55 Element element = work.element.implementation; |
| 55 return compiler.withCurrentElement(element, () { | 56 return compiler.withCurrentElement(element, () { |
| 56 HInstruction.idCounter = 0; | 57 HInstruction.idCounter = 0; |
| 57 SsaBuilder builder = | 58 SsaBuilder builder = |
| 58 new SsaBuilder(backend, work, emitter.nativeEmitter); | 59 new SsaBuilder( |
| 60 backend, work, emitter.nativeEmitter, generateSourceMap); |
| 59 HGraph graph; | 61 HGraph graph; |
| 60 ElementKind kind = element.kind; | 62 ElementKind kind = element.kind; |
| 61 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) { | 63 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) { |
| 62 graph = compileConstructor(builder, work); | 64 graph = compileConstructor(builder, work); |
| 63 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY || | 65 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY || |
| 64 kind == ElementKind.FUNCTION || | 66 kind == ElementKind.FUNCTION || |
| 65 kind == ElementKind.GETTER || | 67 kind == ElementKind.GETTER || |
| 66 kind == ElementKind.SETTER) { | 68 kind == ElementKind.SETTER) { |
| 67 graph = builder.buildMethod(element); | 69 graph = builder.buildMethod(element); |
| 68 } else if (kind == ElementKind.FIELD) { | 70 } else if (kind == ElementKind.FIELD) { |
| (...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 924 | 926 |
| 925 /** | 927 /** |
| 926 * This class builds SSA nodes for functions represented in AST. | 928 * This class builds SSA nodes for functions represented in AST. |
| 927 */ | 929 */ |
| 928 class SsaBuilder extends ResolvedVisitor { | 930 class SsaBuilder extends ResolvedVisitor { |
| 929 final Compiler compiler; | 931 final Compiler compiler; |
| 930 final JavaScriptBackend backend; | 932 final JavaScriptBackend backend; |
| 931 final ConstantSystem constantSystem; | 933 final ConstantSystem constantSystem; |
| 932 final CodegenWorkItem work; | 934 final CodegenWorkItem work; |
| 933 final RuntimeTypes rti; | 935 final RuntimeTypes rti; |
| 936 final bool generateSourceMap; |
| 934 | 937 |
| 935 /* This field is used by the native handler. */ | 938 /* This field is used by the native handler. */ |
| 936 final NativeEmitter nativeEmitter; | 939 final NativeEmitter nativeEmitter; |
| 937 | 940 |
| 938 final HGraph graph = new HGraph(); | 941 final HGraph graph = new HGraph(); |
| 939 | 942 |
| 940 /** | 943 /** |
| 941 * The current block to add instructions to. Might be null, if we are | 944 * The current block to add instructions to. Might be null, if we are |
| 942 * visiting dead code, but see [isReachable]. | 945 * visiting dead code, but see [isReachable]. |
| 943 */ | 946 */ |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1002 * accessed indirectly through [HLocalGet] and [HLocalSet]. | 1005 * accessed indirectly through [HLocalGet] and [HLocalSet]. |
| 1003 */ | 1006 */ |
| 1004 Map<Local, HLocalValue> activationVariables = | 1007 Map<Local, HLocalValue> activationVariables = |
| 1005 <Local, HLocalValue>{}; | 1008 <Local, HLocalValue>{}; |
| 1006 | 1009 |
| 1007 // We build the Ssa graph by simulating a stack machine. | 1010 // We build the Ssa graph by simulating a stack machine. |
| 1008 List<HInstruction> stack = <HInstruction>[]; | 1011 List<HInstruction> stack = <HInstruction>[]; |
| 1009 | 1012 |
| 1010 SsaBuilder(JavaScriptBackend backend, | 1013 SsaBuilder(JavaScriptBackend backend, |
| 1011 CodegenWorkItem work, | 1014 CodegenWorkItem work, |
| 1012 this.nativeEmitter) | 1015 this.nativeEmitter, |
| 1016 this.generateSourceMap) |
| 1013 : this.compiler = backend.compiler, | 1017 : this.compiler = backend.compiler, |
| 1014 this.backend = backend, | 1018 this.backend = backend, |
| 1015 this.constantSystem = backend.constantSystem, | 1019 this.constantSystem = backend.constantSystem, |
| 1016 this.work = work, | 1020 this.work = work, |
| 1017 this.rti = backend.rti, | 1021 this.rti = backend.rti, |
| 1018 super(work.resolutionTree) { | 1022 super(work.resolutionTree) { |
| 1019 localsHandler = new LocalsHandler(this, work.element); | 1023 localsHandler = new LocalsHandler(this, work.element); |
| 1020 sourceElementStack.add(work.element); | 1024 sourceElementStack.add(work.element); |
| 1021 } | 1025 } |
| 1022 | 1026 |
| (...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2407 value, | 2411 value, |
| 2408 compiler.boolClass.rawType, | 2412 compiler.boolClass.rawType, |
| 2409 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); | 2413 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); |
| 2410 } | 2414 } |
| 2411 HInstruction result = new HBoolify(value, backend.boolType); | 2415 HInstruction result = new HBoolify(value, backend.boolType); |
| 2412 add(result); | 2416 add(result); |
| 2413 return result; | 2417 return result; |
| 2414 } | 2418 } |
| 2415 | 2419 |
| 2416 HInstruction attachPosition(HInstruction target, ast.Node node) { | 2420 HInstruction attachPosition(HInstruction target, ast.Node node) { |
| 2417 if (node != null) { | 2421 if (generateSourceMap && node != null) { |
| 2418 target.sourcePosition = sourceFileLocationForBeginToken(node); | 2422 target.sourcePosition = sourceFileLocationForBeginToken(node); |
| 2419 } | 2423 } |
| 2420 return target; | 2424 return target; |
| 2421 } | 2425 } |
| 2422 | 2426 |
| 2423 SourceFileLocation sourceFileLocationForBeginToken(ast.Node node) => | 2427 SourceFileLocation sourceFileLocationForBeginToken(ast.Node node) => |
| 2424 sourceFileLocationForToken(node, node.getBeginToken()); | 2428 sourceFileLocationForToken(node, node.getBeginToken()); |
| 2425 | 2429 |
| 2426 SourceFileLocation sourceFileLocationForEndToken(ast.Node node) => | 2430 SourceFileLocation sourceFileLocationForEndToken(ast.Node node) => |
| 2427 sourceFileLocationForToken(node, node.getEndToken()); | 2431 sourceFileLocationForToken(node, node.getEndToken()); |
| (...skipping 4178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6606 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6610 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 6607 unaliased.accept(this, builder); | 6611 unaliased.accept(this, builder); |
| 6608 } | 6612 } |
| 6609 | 6613 |
| 6610 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6614 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 6611 JavaScriptBackend backend = builder.compiler.backend; | 6615 JavaScriptBackend backend = builder.compiler.backend; |
| 6612 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 6616 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
| 6613 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 6617 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
| 6614 } | 6618 } |
| 6615 } | 6619 } |
| OLD | NEW |