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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart

Issue 1288013002: dart2js cps: Handle native functions, getters, and setters. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address comments. Created 5 years, 4 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dart2js.ir_builder; 5 library dart2js.ir_builder;
6 6
7 import '../compile_time_constants.dart' show BackendConstantEnvironment; 7 import '../compile_time_constants.dart' show BackendConstantEnvironment;
8 import '../constants/constant_system.dart'; 8 import '../constants/constant_system.dart';
9 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; 9 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
11 import '../dart2jslib.dart'; 11 import '../dart2jslib.dart';
12 import '../elements/elements.dart'; 12 import '../elements/elements.dart';
13 import '../io/source_information.dart'; 13 import '../io/source_information.dart';
14 import '../tree/tree.dart' as ast; 14 import '../tree/tree.dart' as ast;
15 import '../types/types.dart' show TypeMask; 15 import '../types/types.dart' show TypeMask;
16 import '../closure.dart' hide ClosureScope; 16 import '../closure.dart' hide ClosureScope;
17 import '../universe/universe.dart' show SelectorKind; 17 import '../universe/universe.dart' show SelectorKind;
18 import 'cps_ir_nodes.dart' as ir; 18 import 'cps_ir_nodes.dart' as ir;
19 import 'cps_ir_builder_task.dart' show DartCapturedVariables, 19 import 'cps_ir_builder_task.dart' show DartCapturedVariables,
20 GlobalProgramInformation; 20 GlobalProgramInformation;
21 21
22 import '../common.dart' as types show TypeMask; 22 import '../common.dart' as types show TypeMask;
23 import '../js/js.dart' as js show Template; 23 import '../js/js.dart' as js show Template, js, LiteralStatement;
24 import '../native/native.dart' show NativeBehavior; 24 import '../native/native.dart' show NativeBehavior;
25 25
26 /// A mapping from variable elements to their compile-time values. 26 /// A mapping from variable elements to their compile-time values.
27 /// 27 ///
28 /// Map elements denoted by parameters and local variables to the 28 /// Map elements denoted by parameters and local variables to the
29 /// [ir.Primitive] that is their value. Parameters and locals are 29 /// [ir.Primitive] that is their value. Parameters and locals are
30 /// assigned indexes which can be used to refer to them. 30 /// assigned indexes which can be used to refer to them.
31 class Environment { 31 class Environment {
32 /// A map from locals to their environment index. 32 /// A map from locals to their environment index.
33 final Map<Local, int> variable2index; 33 final Map<Local, int> variable2index;
(...skipping 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after
2018 sourceInformation: sourceInformation)); 2018 sourceInformation: sourceInformation));
2019 _current = null; 2019 _current = null;
2020 } else { 2020 } else {
2021 // Inside the try block of try/finally, all returns go to a join-point 2021 // Inside the try block of try/finally, all returns go to a join-point
2022 // continuation that contains the finally code. The return value is 2022 // continuation that contains the finally code. The return value is
2023 // passed as an extra argument. 2023 // passed as an extra argument.
2024 jumpTo(state.returnCollector, value); 2024 jumpTo(state.returnCollector, value);
2025 } 2025 }
2026 } 2026 }
2027 2027
2028 /// Build a call to the closure conversion helper for the [Function] typed
2029 /// value in [value].
2030 ir.Primitive _convertDartClosure(ir.Primitive value, FunctionType type) {
2031 ir.Constant arity = buildIntegerConstant(type.computeArity());
2032 return buildStaticFunctionInvocation(
2033 program.closureConverter,
2034 CallStructure.TWO_ARGS,
2035 <ir.Primitive>[value, arity]);
2036 }
2037
2038 /// Generate the body for a native function [function] that is annotated with
2039 /// an implementation in JavaScript (provided as string in [javaScriptCode]).
2040 void buildNativeFunctionBody(FunctionElement function,
2041 String javaScriptCode) {
2042 NativeBehavior behavior = new NativeBehavior();
2043 behavior.sideEffects.setAllSideEffects();
2044 // Generate a [ForeignCode] statement from the given native code.
2045 buildForeignCode(
2046 js.js.statementTemplateYielding(
2047 new js.LiteralStatement(javaScriptCode)),
2048 <ir.Primitive>[],
2049 behavior);
2050 }
2051
2052 /// Generate the body for a native function that redirects to a native
2053 /// JavaScript function, getter, or setter.
2054 ///
2055 /// Generates a call to the real target, which is given by [functions]'s
2056 /// `fixedBackendName`, passing all parameters as arguments. The target can
2057 /// be the JavaScript implementation of a function, getter, or setter.
2058 void buildRedirectingNativeFunctionBody(FunctionElement function,
2059 SourceInformation source) {
2060 String name = function.fixedBackendName;
2061 List<ir.Primitive> arguments = <ir.Primitive>[];
2062 NativeBehavior behavior = new NativeBehavior();
2063 behavior.sideEffects.setAllSideEffects();
2064 program.addNativeMethod(function);
2065 // Construct the access of the target element.
2066 String code = function.isInstanceMember ? '#.$name' : name;
2067 if (function.isInstanceMember) {
2068 arguments.add(state.thisParameter);
2069 }
2070 // Collect all parameters of the function and templates for them to be
2071 // inserted into the JavaScript code.
2072 List<String> argumentTemplates = <String>[];
2073 function.functionSignature.forEachParameter((ParameterElement parameter) {
2074 ir.Primitive input = environment.lookup(parameter);
2075 DartType type = program.unaliasType(parameter.type);
2076 if (type is FunctionType) {
2077 // The parameter type is a function type either directly or through
2078 // typedef(s).
2079 input = _convertDartClosure(input, type);
2080 }
2081 arguments.add(input);
2082 argumentTemplates.add('#');
2083 });
2084 // Construct the application of parameters for functions and setters.
2085 if (function.kind == ElementKind.FUNCTION) {
2086 code = "$code(${argumentTemplates.join(', ')})";
2087 } else if (function.kind == ElementKind.SETTER) {
2088 code = "$code = ${argumentTemplates.single}";
2089 } else {
2090 assert(argumentTemplates.isEmpty);
2091 assert(function.kind == ElementKind.GETTER);
2092 }
2093 // Generate the [ForeignCode] expression and a return statement to return
2094 // its value.
2095 ir.Primitive value = buildForeignCode(
2096 js.js.uncachedExpressionTemplate(code),
2097 arguments,
2098 behavior);
2099 buildReturn(value: value, sourceInformation: source);
2100 }
2101
2028 /// Create a blocks of [statements] by applying [build] to all reachable 2102 /// Create a blocks of [statements] by applying [build] to all reachable
2029 /// statements. The first statement is assumed to be reachable. 2103 /// statements. The first statement is assumed to be reachable.
2030 // TODO(johnniwinther): Type [statements] as `Iterable` when `NodeList` uses 2104 // TODO(johnniwinther): Type [statements] as `Iterable` when `NodeList` uses
2031 // `List` instead of `Link`. 2105 // `List` instead of `Link`.
2032 void buildBlock(var statements, BuildFunction build) { 2106 void buildBlock(var statements, BuildFunction build) {
2033 // Build(Block(stamements), C) = C' 2107 // Build(Block(stamements), C) = C'
2034 // where C' = statements.fold(Build, C) 2108 // where C' = statements.fold(Build, C)
2035 assert(isOpen); 2109 assert(isOpen);
2036 return buildSequence(statements, build); 2110 return buildSequence(statements, build);
2037 } 2111 }
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 2666
2593 ir.Primitive buildInvocationMirror(Selector selector, 2667 ir.Primitive buildInvocationMirror(Selector selector,
2594 List<ir.Primitive> arguments) { 2668 List<ir.Primitive> arguments) {
2595 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); 2669 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments));
2596 } 2670 }
2597 2671
2598 ir.Primitive buildForeignCode(js.Template codeTemplate, 2672 ir.Primitive buildForeignCode(js.Template codeTemplate,
2599 List<ir.Primitive> arguments, 2673 List<ir.Primitive> arguments,
2600 NativeBehavior behavior, 2674 NativeBehavior behavior,
2601 {Element dependency}) { 2675 {Element dependency}) {
2676 assert(behavior != null);
2602 types.TypeMask type = program.getTypeMaskForForeign(behavior); 2677 types.TypeMask type = program.getTypeMaskForForeign(behavior);
2603 ir.Primitive result = _continueWithExpression((k) => new ir.ForeignCode( 2678 ir.Primitive result = _continueWithExpression((k) => new ir.ForeignCode(
2604 codeTemplate, 2679 codeTemplate,
2605 type, 2680 type,
2606 arguments, 2681 arguments,
2607 behavior, 2682 behavior,
2608 k, 2683 k,
2609 dependency: dependency)); 2684 dependency: dependency));
2610 if (!codeTemplate.isExpression) { 2685 if (!codeTemplate.isExpression) {
2611 // Close the term if this is a "throw" expression. 2686 // Close the term if this is a "throw" expression or native body.
2612 add(new ir.Unreachable()); 2687 add(new ir.Unreachable());
2613 _current = null; 2688 _current = null;
2614 } 2689 }
2615 return result; 2690 return result;
2616 } 2691 }
2617 2692
2618 /// Creates a type test or type cast of [value] against [type]. 2693 /// Creates a type test or type cast of [value] against [type].
2619 ir.Primitive buildTypeOperator(ir.Primitive value, 2694 ir.Primitive buildTypeOperator(ir.Primitive value,
2620 DartType type, 2695 DartType type,
2621 {bool isTypeTest}) { 2696 {bool isTypeTest}) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2783 } 2858 }
2784 2859
2785 class SwitchCaseInfo { 2860 class SwitchCaseInfo {
2786 final List<ir.Primitive> constants = <ir.Primitive>[]; 2861 final List<ir.Primitive> constants = <ir.Primitive>[];
2787 final SubbuildFunction buildBody; 2862 final SubbuildFunction buildBody;
2788 2863
2789 SwitchCaseInfo(this.buildBody); 2864 SwitchCaseInfo(this.buildBody);
2790 2865
2791 void addConstant(ir.Primitive constant) => constants.add(constant); 2866 void addConstant(ir.Primitive constant) => constants.add(constant);
2792 } 2867 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698