Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
index 6d364895aacebadf4e0f9010a32f37c36b603fd4..b29c9c7823550ebfe6e5084313a63f3a1097fd50 100644 |
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
@@ -21,17 +21,6 @@ import '../types/types.dart' show TypeMask; |
import '../universe/universe.dart' show SelectorKind, CallStructure; |
import 'cps_ir_nodes.dart' as ir; |
import 'cps_ir_builder.dart'; |
-import '../native/native.dart' show NativeBehavior; |
- |
-// TODO(karlklose): remove. |
-import '../js/js.dart' as js show js, Template, Expression; |
-import '../ssa/ssa.dart' show TypeMaskFactory; |
-import '../types/types.dart' show TypeMask; |
-import '../util/util.dart'; |
- |
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' |
- show JsBuiltin, JsGetName; |
-import '../constants/values.dart'; |
typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode); |
@@ -995,7 +984,15 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
MethodElement function, |
ast.NodeList arguments, |
CallStructure callStructure, |
- _); |
+ _) { |
+ // TODO(karlklose): support foreign functions. |
+ if (compiler.backend.isForeign(function)) { |
+ return giveup(node, 'handleStaticFunctionInvoke: foreign: $function'); |
+ } |
+ return irBuilder.buildStaticFunctionInvocation(function, callStructure, |
+ translateStaticArguments(arguments, function, callStructure), |
+ sourceInformation: sourceInformationBuilder.buildCall(node)); |
+ } |
@override |
ir.Primitive handleStaticFunctionIncompatibleInvoke( |
@@ -1886,7 +1883,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
} |
} |
- internalError(ast.Node node, String message) { |
+ void internalError(ast.Node node, String message) { |
giveup(node, message); |
} |
@@ -2081,10 +2078,6 @@ class GlobalProgramInformation { |
ClassElement get nullClass => _compiler.nullClass; |
DartType unaliasType(DartType type) => type.unalias(_compiler); |
- |
- TypeMask getTypeMaskForForeign(NativeBehavior behavior) { |
- return TypeMaskFactory.fromNativeBehavior(behavior, _compiler); |
- } |
} |
/// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. |
@@ -2838,232 +2831,6 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
return irBuilder.buildStaticFieldGet(field, src); |
} |
} |
- |
- /// Build code to handle foreign code, that is, native JavaScript code, or |
- /// builtin values and operations of the backend. |
- ir.Primitive handleForeignCode(ast.Send node, |
- MethodElement function, |
- ast.NodeList argumentList, |
- CallStructure callStructure) { |
- |
- void validateArgumentCount({int minimum, int exactly}) { |
- assert((minimum == null) != (exactly == null)); |
- int count = 0; |
- int maximum; |
- if (exactly != null) { |
- minimum = exactly; |
- maximum = exactly; |
- } |
- for (ast.Node argument in argumentList) { |
- count++; |
- if (maximum != null && count > maximum) { |
- internalError(argument, 'Additional argument.'); |
- } |
- } |
- if (count < minimum) { |
- internalError(node, 'Expected at least $minimum arguments.'); |
- } |
- } |
- |
- /// Call a helper method from the isolate library. The isolate library uses |
- /// its own isolate structure, that encapsulates dart2js's isolate. |
- ir.Primitive buildIsolateHelperInvocation(String helperName, |
- CallStructure callStructure) { |
- Element element = backend.isolateHelperLibrary.find(helperName); |
- if (element == null) { |
- compiler.internalError(node, |
- 'Isolate library and compiler mismatch.'); |
- } |
- List<ir.Primitive> arguments = translateStaticArguments(argumentList, |
- element, CallStructure.TWO_ARGS); |
- return irBuilder.buildStaticFunctionInvocation(element, |
- CallStructure.TWO_ARGS, arguments, |
- sourceInformation: sourceInformationBuilder.buildCall(node)); |
- } |
- |
- /// Lookup the value of the enum described by [node]. |
- getEnumValue(ast.Node node, EnumClassElement enumClass, List values) { |
- Element element = elements[node]; |
- if (element is! FieldElement || element.enclosingClass != enumClass) { |
- internalError(node, 'expected a JsBuiltin enum value'); |
- } |
- |
- int index = enumClass.enumValues.indexOf(element); |
- return values[index]; |
- } |
- |
- /// Returns the String the node evaluates to, or throws an error if the |
- /// result is not a string constant. |
- String expectStringConstant(ast.Node node) { |
- ir.Primitive nameValue = visit(node); |
- if (nameValue is ir.Constant && nameValue.value.isString) { |
- StringConstantValue constantValue = nameValue.value; |
- return constantValue.primitiveValue.slowToString(); |
- } else { |
- return internalError(node, 'expected a literal string'); |
- } |
- } |
- |
- Link<ast.Node> argumentNodes = argumentList.nodes; |
- NativeBehavior behavior = |
- compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); |
- switch (function.name) { |
- case 'JS': |
- validateArgumentCount(minimum: 2); |
- // The first two arguments are the type and the foreign code template, |
- // which already have been analyzed by the resolver and can be retrieved |
- // using [NativeBehavior]. We can ignore these arguments in the backend. |
- List<ir.Primitive> arguments = |
- argumentNodes.skip(2).mapToList(visit, growable: false); |
- return irBuilder.buildForeignCode(behavior.codeTemplate, arguments, |
- behavior); |
- |
- case 'DART_CLOSURE_TO_JS': |
- // TODO(ahe): This should probably take care to wrap the closure in |
- // another closure that saves the current isolate. |
- case 'RAW_DART_FUNCTION_REF': |
- validateArgumentCount(exactly: 1); |
- |
- ast.Node argument = node.arguments.single; |
- FunctionElement closure = elements[argument].implementation; |
- if (!Elements.isStaticOrTopLevelFunction(closure)) { |
- internalError(argument, |
- 'only static or toplevel function supported'); |
- } |
- if (closure.functionSignature.hasOptionalParameters) { |
- internalError(argument, |
- 'closures with optional parameters not supported'); |
- } |
- return irBuilder.buildForeignCode( |
- js.js.expressionTemplateYielding( |
- backend.emitter.staticFunctionAccess(function)), |
- <ir.Primitive>[], |
- NativeBehavior.PURE, |
- dependency: closure); |
- |
- case 'JS_BUILTIN': |
- // The first argument is a description of the type and effect of the |
- // builtin, which has already been analyzed in the frontend. The second |
- // argument must be a [JsBuiltin] value. All other arguments are |
- // values used by the JavaScript template that is associated with the |
- // builtin. |
- validateArgumentCount(minimum: 2); |
- |
- ast.Node builtin = argumentNodes.tail.head; |
- JsBuiltin value = getEnumValue(argumentNodes.tail.head, |
- backend.jsBuiltinEnum, JsBuiltin.values); |
- js.Template template = backend.emitter.builtinTemplateFor(value); |
- List<ir.Primitive> arguments = |
- argumentNodes.skip(2).mapToList(visit, growable: false); |
- return irBuilder.buildForeignCode(template, arguments, behavior); |
- |
- case 'JS_EMBEDDED_GLOBAL': |
- validateArgumentCount(exactly: 2); |
- |
- String name = expectStringConstant(argumentNodes.tail.head); |
- js.Expression access = |
- backend.emitter.generateEmbeddedGlobalAccess(name); |
- js.Template template = js.js.expressionTemplateYielding(access); |
- return irBuilder.buildForeignCode(template, <ir.Primitive>[], behavior); |
- |
- case 'JS_INTERCEPTOR_CONSTANT': |
- validateArgumentCount(exactly: 1); |
- |
- ast.Node argument = argumentNodes.head; |
- ir.Primitive argumentValue = visit(argument); |
- if (argumentValue is ir.Constant && argumentValue.value.isType) { |
- TypeConstantValue constant = argumentValue.value; |
- ConstantValue interceptorValue = |
- new InterceptorConstantValue(constant.representedType); |
- return irBuilder.buildConstant(argumentValue.expression, |
- interceptorValue); |
- } else { |
- internalError(argument, 'expected Type as argument'); |
- } |
- break; |
- |
- case 'JS_EFFECT': |
- return irBuilder.buildNullConstant(); |
- |
- case 'JS_GET_NAME': |
- validateArgumentCount(exactly: 1); |
- |
- ast.Node argument = argumentNodes.head; |
- JsGetName id = getEnumValue(argument, backend.jsGetNameEnum, |
- JsGetName.values); |
- String name = backend.namer.getNameForJsGetName(argument, id); |
- return irBuilder.buildStringConstant(name); |
- |
- case 'JS_GET_FLAG': |
- validateArgumentCount(exactly: 1); |
- |
- String name = expectStringConstant(argumentNodes.first); |
- bool value = false; |
- switch (name) { |
- case 'MUST_RETAIN_METADATA': |
- value = backend.mustRetainMetadata; |
- break; |
- case 'USE_CONTENT_SECURITY_POLICY': |
- value = compiler.useContentSecurityPolicy; |
- break; |
- default: |
- internalError(node, 'Unknown internal flag "$name".'); |
- } |
- return irBuilder.buildBooleanConstant(value); |
- |
- case 'JS_STRING_CONCAT': |
- validateArgumentCount(exactly: 2); |
- List<ir.Primitive> arguments = argumentNodes.mapToList(visit); |
- return irBuilder.buildStringConcatenation(arguments); |
- |
- case 'JS_CURRENT_ISOLATE_CONTEXT': |
- validateArgumentCount(exactly: 0); |
- |
- if (!compiler.hasIsolateSupport) { |
- // If the isolate library is not used, we just generate code |
- // to fetch the current isolate. |
- String name = backend.namer.currentIsolate; |
- return irBuilder.buildForeignCode(js.js.parseForeignJS(name), |
- const <ir.Primitive>[], NativeBehavior.PURE); |
- } else { |
- return buildIsolateHelperInvocation('_currentIsolate', |
- CallStructure.NO_ARGS); |
- } |
- break; |
- |
- case 'JS_CALL_IN_ISOLATE': |
- validateArgumentCount(exactly: 2); |
- |
- if (!compiler.hasIsolateSupport) { |
- ir.Primitive closure = visit(argumentNodes.tail.head); |
- return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS, |
- const <ir.Primitive>[]); |
- } else { |
- return buildIsolateHelperInvocation('_callInIsolate', |
- CallStructure.TWO_ARGS); |
- } |
- break; |
- |
- default: |
- giveup(node, 'unplemented native construct: ${function.name}'); |
- break; |
- } |
- } |
- |
- @override |
- ir.Primitive handleStaticFunctionInvoke(ast.Send node, |
- MethodElement function, |
- ast.NodeList argumentList, |
- CallStructure callStructure, |
- _) { |
- if (compiler.backend.isForeign(function)) { |
- return handleForeignCode(node, function, argumentList, callStructure); |
- } else { |
- return irBuilder.buildStaticFunctionInvocation(function, callStructure, |
- translateStaticArguments(argumentList, function, callStructure), |
- sourceInformation: sourceInformationBuilder.buildCall(node)); |
- } |
- } |
} |
/// Perform simple post-processing on the initial CPS-translated root term. |