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

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

Issue 1196443002: Revert "cps-ir: Support foreign code." (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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
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_task; 5 library dart2js.ir_builder_task;
6 6
7 import '../closure.dart' as closurelib; 7 import '../closure.dart' as closurelib;
8 import '../closure.dart' hide ClosureScope; 8 import '../closure.dart' hide ClosureScope;
9 import '../constants/expressions.dart'; 9 import '../constants/expressions.dart';
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 '../elements/modelx.dart' show SynthesizedConstructorElementX, 13 import '../elements/modelx.dart' show SynthesizedConstructorElementX,
14 ConstructorBodyElementX, FunctionSignatureX; 14 ConstructorBodyElementX, FunctionSignatureX;
15 import '../io/source_information.dart'; 15 import '../io/source_information.dart';
16 import '../js_backend/js_backend.dart' show JavaScriptBackend; 16 import '../js_backend/js_backend.dart' show JavaScriptBackend;
17 import '../resolution/semantic_visitor.dart'; 17 import '../resolution/semantic_visitor.dart';
18 import '../resolution/operators.dart' as op; 18 import '../resolution/operators.dart' as op;
19 import '../tree/tree.dart' as ast; 19 import '../tree/tree.dart' as ast;
20 import '../types/types.dart' show TypeMask; 20 import '../types/types.dart' show TypeMask;
21 import '../universe/universe.dart' show SelectorKind, CallStructure; 21 import '../universe/universe.dart' show SelectorKind, CallStructure;
22 import 'cps_ir_nodes.dart' as ir; 22 import 'cps_ir_nodes.dart' as ir;
23 import 'cps_ir_builder.dart'; 23 import 'cps_ir_builder.dart';
24 import '../native/native.dart' show NativeBehavior;
25
26 // TODO(karlklose): remove.
27 import '../js/js.dart' as js show js, Template, Expression;
28 import '../ssa/ssa.dart' show TypeMaskFactory;
29 import '../types/types.dart' show TypeMask;
30 import '../util/util.dart';
31
32 import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
33 show JsBuiltin, JsGetName;
34 import '../constants/values.dart';
35 24
36 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode); 25 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode);
37 26
38 /// This task provides the interface to build IR nodes from [ast.Node]s, which 27 /// This task provides the interface to build IR nodes from [ast.Node]s, which
39 /// is used from the [CpsFunctionCompiler] to generate code. 28 /// is used from the [CpsFunctionCompiler] to generate code.
40 /// 29 ///
41 /// This class is mainly there to correctly measure how long building the IR 30 /// This class is mainly there to correctly measure how long building the IR
42 /// takes. 31 /// takes.
43 class IrBuilderTask extends CompilerTask { 32 class IrBuilderTask extends CompilerTask {
44 final SourceInformationFactory sourceInformationFactory; 33 final SourceInformationFactory sourceInformationFactory;
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 callStructure, 977 callStructure,
989 translateDynamicArguments(arguments, callStructure)); 978 translateDynamicArguments(arguments, callStructure));
990 } 979 }
991 980
992 @override 981 @override
993 ir.Primitive handleStaticFunctionInvoke( 982 ir.Primitive handleStaticFunctionInvoke(
994 ast.Send node, 983 ast.Send node,
995 MethodElement function, 984 MethodElement function,
996 ast.NodeList arguments, 985 ast.NodeList arguments,
997 CallStructure callStructure, 986 CallStructure callStructure,
998 _); 987 _) {
988 // TODO(karlklose): support foreign functions.
989 if (compiler.backend.isForeign(function)) {
990 return giveup(node, 'handleStaticFunctionInvoke: foreign: $function');
991 }
992 return irBuilder.buildStaticFunctionInvocation(function, callStructure,
993 translateStaticArguments(arguments, function, callStructure),
994 sourceInformation: sourceInformationBuilder.buildCall(node));
995 }
999 996
1000 @override 997 @override
1001 ir.Primitive handleStaticFunctionIncompatibleInvoke( 998 ir.Primitive handleStaticFunctionIncompatibleInvoke(
1002 ast.Send node, 999 ast.Send node,
1003 MethodElement function, 1000 MethodElement function,
1004 ast.NodeList arguments, 1001 ast.NodeList arguments,
1005 CallStructure callStructure, _) { 1002 CallStructure callStructure, _) {
1006 return buildStaticNoSuchMethod( 1003 return buildStaticNoSuchMethod(
1007 elements.getSelector(node), 1004 elements.getSelector(node),
1008 arguments.nodes.mapToList(visit)); 1005 arguments.nodes.mapToList(visit));
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after
1879 try { 1876 try {
1880 return action(); 1877 return action();
1881 } catch(e) { 1878 } catch(e) {
1882 if (e == ABORT_IRNODE_BUILDER) { 1879 if (e == ABORT_IRNODE_BUILDER) {
1883 return null; 1880 return null;
1884 } 1881 }
1885 rethrow; 1882 rethrow;
1886 } 1883 }
1887 } 1884 }
1888 1885
1889 internalError(ast.Node node, String message) { 1886 void internalError(ast.Node node, String message) {
1890 giveup(node, message); 1887 giveup(node, message);
1891 } 1888 }
1892 1889
1893 @override 1890 @override
1894 visitNode(ast.Node node) { 1891 visitNode(ast.Node node) {
1895 internalError(node, "Unhandled node"); 1892 internalError(node, "Unhandled node");
1896 } 1893 }
1897 1894
1898 dynamic giveup(ast.Node node, [String reason]) { 1895 dynamic giveup(ast.Node node, [String reason]) {
1899 bailoutMessage = '($node): $reason'; 1896 bailoutMessage = '($node): $reason';
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2074 /// arguments for the class [cls] are never used in the program. 2071 /// arguments for the class [cls] are never used in the program.
2075 bool requiresRuntimeTypesFor(ClassElement cls) { 2072 bool requiresRuntimeTypesFor(ClassElement cls) {
2076 return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls); 2073 return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls);
2077 } 2074 }
2078 2075
2079 FunctionElement get throwTypeErrorHelper => _backend.getThrowTypeError(); 2076 FunctionElement get throwTypeErrorHelper => _backend.getThrowTypeError();
2080 2077
2081 ClassElement get nullClass => _compiler.nullClass; 2078 ClassElement get nullClass => _compiler.nullClass;
2082 2079
2083 DartType unaliasType(DartType type) => type.unalias(_compiler); 2080 DartType unaliasType(DartType type) => type.unalias(_compiler);
2084
2085 TypeMask getTypeMaskForForeign(NativeBehavior behavior) {
2086 return TypeMaskFactory.fromNativeBehavior(behavior, _compiler);
2087 }
2088 } 2081 }
2089 2082
2090 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. 2083 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder].
2091 class JsIrBuilderVisitor extends IrBuilderVisitor { 2084 class JsIrBuilderVisitor extends IrBuilderVisitor {
2092 /// Promote the type of [irBuilder] to [JsIrBuilder]. 2085 /// Promote the type of [irBuilder] to [JsIrBuilder].
2093 JsIrBuilder get irBuilder => super.irBuilder; 2086 JsIrBuilder get irBuilder => super.irBuilder;
2094 2087
2095 JavaScriptBackend get backend => compiler.backend; 2088 JavaScriptBackend get backend => compiler.backend;
2096 2089
2097 /// Result of closure conversion for the current body of code. 2090 /// Result of closure conversion for the current body of code.
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
2831 ConstantExpression constant = 2824 ConstantExpression constant =
2832 backend.constants.getConstantForVariable(field); 2825 backend.constants.getConstantForVariable(field);
2833 if (constant != null && !field.isAssignable) { 2826 if (constant != null && !field.isAssignable) {
2834 return buildConstant(constant); 2827 return buildConstant(constant);
2835 } else if (backend.constants.lazyStatics.contains(field)) { 2828 } else if (backend.constants.lazyStatics.contains(field)) {
2836 return irBuilder.buildStaticFieldLazyGet(field, src); 2829 return irBuilder.buildStaticFieldLazyGet(field, src);
2837 } else { 2830 } else {
2838 return irBuilder.buildStaticFieldGet(field, src); 2831 return irBuilder.buildStaticFieldGet(field, src);
2839 } 2832 }
2840 } 2833 }
2841
2842 /// Build code to handle foreign code, that is, native JavaScript code, or
2843 /// builtin values and operations of the backend.
2844 ir.Primitive handleForeignCode(ast.Send node,
2845 MethodElement function,
2846 ast.NodeList argumentList,
2847 CallStructure callStructure) {
2848
2849 void validateArgumentCount({int minimum, int exactly}) {
2850 assert((minimum == null) != (exactly == null));
2851 int count = 0;
2852 int maximum;
2853 if (exactly != null) {
2854 minimum = exactly;
2855 maximum = exactly;
2856 }
2857 for (ast.Node argument in argumentList) {
2858 count++;
2859 if (maximum != null && count > maximum) {
2860 internalError(argument, 'Additional argument.');
2861 }
2862 }
2863 if (count < minimum) {
2864 internalError(node, 'Expected at least $minimum arguments.');
2865 }
2866 }
2867
2868 /// Call a helper method from the isolate library. The isolate library uses
2869 /// its own isolate structure, that encapsulates dart2js's isolate.
2870 ir.Primitive buildIsolateHelperInvocation(String helperName,
2871 CallStructure callStructure) {
2872 Element element = backend.isolateHelperLibrary.find(helperName);
2873 if (element == null) {
2874 compiler.internalError(node,
2875 'Isolate library and compiler mismatch.');
2876 }
2877 List<ir.Primitive> arguments = translateStaticArguments(argumentList,
2878 element, CallStructure.TWO_ARGS);
2879 return irBuilder.buildStaticFunctionInvocation(element,
2880 CallStructure.TWO_ARGS, arguments,
2881 sourceInformation: sourceInformationBuilder.buildCall(node));
2882 }
2883
2884 /// Lookup the value of the enum described by [node].
2885 getEnumValue(ast.Node node, EnumClassElement enumClass, List values) {
2886 Element element = elements[node];
2887 if (element is! FieldElement || element.enclosingClass != enumClass) {
2888 internalError(node, 'expected a JsBuiltin enum value');
2889 }
2890
2891 int index = enumClass.enumValues.indexOf(element);
2892 return values[index];
2893 }
2894
2895 /// Returns the String the node evaluates to, or throws an error if the
2896 /// result is not a string constant.
2897 String expectStringConstant(ast.Node node) {
2898 ir.Primitive nameValue = visit(node);
2899 if (nameValue is ir.Constant && nameValue.value.isString) {
2900 StringConstantValue constantValue = nameValue.value;
2901 return constantValue.primitiveValue.slowToString();
2902 } else {
2903 return internalError(node, 'expected a literal string');
2904 }
2905 }
2906
2907 Link<ast.Node> argumentNodes = argumentList.nodes;
2908 NativeBehavior behavior =
2909 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
2910 switch (function.name) {
2911 case 'JS':
2912 validateArgumentCount(minimum: 2);
2913 // The first two arguments are the type and the foreign code template,
2914 // which already have been analyzed by the resolver and can be retrieved
2915 // using [NativeBehavior]. We can ignore these arguments in the backend.
2916 List<ir.Primitive> arguments =
2917 argumentNodes.skip(2).mapToList(visit, growable: false);
2918 return irBuilder.buildForeignCode(behavior.codeTemplate, arguments,
2919 behavior);
2920
2921 case 'DART_CLOSURE_TO_JS':
2922 // TODO(ahe): This should probably take care to wrap the closure in
2923 // another closure that saves the current isolate.
2924 case 'RAW_DART_FUNCTION_REF':
2925 validateArgumentCount(exactly: 1);
2926
2927 ast.Node argument = node.arguments.single;
2928 FunctionElement closure = elements[argument].implementation;
2929 if (!Elements.isStaticOrTopLevelFunction(closure)) {
2930 internalError(argument,
2931 'only static or toplevel function supported');
2932 }
2933 if (closure.functionSignature.hasOptionalParameters) {
2934 internalError(argument,
2935 'closures with optional parameters not supported');
2936 }
2937 return irBuilder.buildForeignCode(
2938 js.js.expressionTemplateYielding(
2939 backend.emitter.staticFunctionAccess(function)),
2940 <ir.Primitive>[],
2941 NativeBehavior.PURE,
2942 dependency: closure);
2943
2944 case 'JS_BUILTIN':
2945 // The first argument is a description of the type and effect of the
2946 // builtin, which has already been analyzed in the frontend. The second
2947 // argument must be a [JsBuiltin] value. All other arguments are
2948 // values used by the JavaScript template that is associated with the
2949 // builtin.
2950 validateArgumentCount(minimum: 2);
2951
2952 ast.Node builtin = argumentNodes.tail.head;
2953 JsBuiltin value = getEnumValue(argumentNodes.tail.head,
2954 backend.jsBuiltinEnum, JsBuiltin.values);
2955 js.Template template = backend.emitter.builtinTemplateFor(value);
2956 List<ir.Primitive> arguments =
2957 argumentNodes.skip(2).mapToList(visit, growable: false);
2958 return irBuilder.buildForeignCode(template, arguments, behavior);
2959
2960 case 'JS_EMBEDDED_GLOBAL':
2961 validateArgumentCount(exactly: 2);
2962
2963 String name = expectStringConstant(argumentNodes.tail.head);
2964 js.Expression access =
2965 backend.emitter.generateEmbeddedGlobalAccess(name);
2966 js.Template template = js.js.expressionTemplateYielding(access);
2967 return irBuilder.buildForeignCode(template, <ir.Primitive>[], behavior);
2968
2969 case 'JS_INTERCEPTOR_CONSTANT':
2970 validateArgumentCount(exactly: 1);
2971
2972 ast.Node argument = argumentNodes.head;
2973 ir.Primitive argumentValue = visit(argument);
2974 if (argumentValue is ir.Constant && argumentValue.value.isType) {
2975 TypeConstantValue constant = argumentValue.value;
2976 ConstantValue interceptorValue =
2977 new InterceptorConstantValue(constant.representedType);
2978 return irBuilder.buildConstant(argumentValue.expression,
2979 interceptorValue);
2980 } else {
2981 internalError(argument, 'expected Type as argument');
2982 }
2983 break;
2984
2985 case 'JS_EFFECT':
2986 return irBuilder.buildNullConstant();
2987
2988 case 'JS_GET_NAME':
2989 validateArgumentCount(exactly: 1);
2990
2991 ast.Node argument = argumentNodes.head;
2992 JsGetName id = getEnumValue(argument, backend.jsGetNameEnum,
2993 JsGetName.values);
2994 String name = backend.namer.getNameForJsGetName(argument, id);
2995 return irBuilder.buildStringConstant(name);
2996
2997 case 'JS_GET_FLAG':
2998 validateArgumentCount(exactly: 1);
2999
3000 String name = expectStringConstant(argumentNodes.first);
3001 bool value = false;
3002 switch (name) {
3003 case 'MUST_RETAIN_METADATA':
3004 value = backend.mustRetainMetadata;
3005 break;
3006 case 'USE_CONTENT_SECURITY_POLICY':
3007 value = compiler.useContentSecurityPolicy;
3008 break;
3009 default:
3010 internalError(node, 'Unknown internal flag "$name".');
3011 }
3012 return irBuilder.buildBooleanConstant(value);
3013
3014 case 'JS_STRING_CONCAT':
3015 validateArgumentCount(exactly: 2);
3016 List<ir.Primitive> arguments = argumentNodes.mapToList(visit);
3017 return irBuilder.buildStringConcatenation(arguments);
3018
3019 case 'JS_CURRENT_ISOLATE_CONTEXT':
3020 validateArgumentCount(exactly: 0);
3021
3022 if (!compiler.hasIsolateSupport) {
3023 // If the isolate library is not used, we just generate code
3024 // to fetch the current isolate.
3025 String name = backend.namer.currentIsolate;
3026 return irBuilder.buildForeignCode(js.js.parseForeignJS(name),
3027 const <ir.Primitive>[], NativeBehavior.PURE);
3028 } else {
3029 return buildIsolateHelperInvocation('_currentIsolate',
3030 CallStructure.NO_ARGS);
3031 }
3032 break;
3033
3034 case 'JS_CALL_IN_ISOLATE':
3035 validateArgumentCount(exactly: 2);
3036
3037 if (!compiler.hasIsolateSupport) {
3038 ir.Primitive closure = visit(argumentNodes.tail.head);
3039 return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS,
3040 const <ir.Primitive>[]);
3041 } else {
3042 return buildIsolateHelperInvocation('_callInIsolate',
3043 CallStructure.TWO_ARGS);
3044 }
3045 break;
3046
3047 default:
3048 giveup(node, 'unplemented native construct: ${function.name}');
3049 break;
3050 }
3051 }
3052
3053 @override
3054 ir.Primitive handleStaticFunctionInvoke(ast.Send node,
3055 MethodElement function,
3056 ast.NodeList argumentList,
3057 CallStructure callStructure,
3058 _) {
3059 if (compiler.backend.isForeign(function)) {
3060 return handleForeignCode(node, function, argumentList, callStructure);
3061 } else {
3062 return irBuilder.buildStaticFunctionInvocation(function, callStructure,
3063 translateStaticArguments(argumentList, function, callStructure),
3064 sourceInformation: sourceInformationBuilder.buildCall(node));
3065 }
3066 }
3067 } 2834 }
3068 2835
3069 /// Perform simple post-processing on the initial CPS-translated root term. 2836 /// Perform simple post-processing on the initial CPS-translated root term.
3070 /// 2837 ///
3071 /// This pass performs backend-independent post-processing on the translated 2838 /// This pass performs backend-independent post-processing on the translated
3072 /// term. It is implemented separately from the optimization passes because 2839 /// term. It is implemented separately from the optimization passes because
3073 /// it is required for correctness of the implementation. 2840 /// it is required for correctness of the implementation.
3074 /// 2841 ///
3075 /// It performs the following translations: 2842 /// It performs the following translations:
3076 /// - Replace [ir.LetPrim] binding a [ir.NonTailThrow] with a [ir.Throw] 2843 /// - Replace [ir.LetPrim] binding a [ir.NonTailThrow] with a [ir.Throw]
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3116 } 2883 }
3117 2884
3118 processSetStatic(ir.SetStatic node) { 2885 processSetStatic(ir.SetStatic node) {
3119 node.body = replacementFor(node.body); 2886 node.body = replacementFor(node.body);
3120 } 2887 }
3121 2888
3122 processContinuation(ir.Continuation node) { 2889 processContinuation(ir.Continuation node) {
3123 node.body = replacementFor(node.body); 2890 node.body = replacementFor(node.body);
3124 } 2891 }
3125 } 2892 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698