mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 01:10:27 +00:00
Revert "Build CFG for various JS() foreign methods"
TBR=het@google.com BUG= Review URL: https://codereview.chromium.org/2411793007 .
This commit is contained in:
parent
a897bc3832
commit
476ffbda5e
|
@ -1930,7 +1930,7 @@ class KernelVisitor extends Object
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ir.Expression handleStaticFieldGet(Send node, FieldElement field, _) {
|
ir.Expression handleStaticFieldGet(Send node, FieldElement field, _) {
|
||||||
return associateNode(buildStaticGet(field), node);
|
return buildStaticGet(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -2137,8 +2137,7 @@ class KernelVisitor extends Object
|
||||||
NodeList arguments,
|
NodeList arguments,
|
||||||
CallStructure callStructure,
|
CallStructure callStructure,
|
||||||
_) {
|
_) {
|
||||||
return associateNode(
|
return buildStaticInvoke(function, arguments, isConst: false);
|
||||||
buildStaticInvoke(function, arguments, isConst: false), node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -2763,7 +2762,7 @@ class KernelVisitor extends Object
|
||||||
FieldElement field = currentElement;
|
FieldElement field = currentElement;
|
||||||
return field.isMalformed
|
return field.isMalformed
|
||||||
? new ir.InvalidExpression()
|
? new ir.InvalidExpression()
|
||||||
: associateNode(visitForValue(field.initializer), field.initializer);
|
: visitForValue(field.initializer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,19 +9,15 @@ import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
|
||||||
import '../common/names.dart';
|
import '../common/names.dart';
|
||||||
import '../common/tasks.dart' show CompilerTask;
|
import '../common/tasks.dart' show CompilerTask;
|
||||||
import '../compiler.dart';
|
import '../compiler.dart';
|
||||||
import '../constants/values.dart' show StringConstantValue;
|
|
||||||
import '../dart_types.dart';
|
import '../dart_types.dart';
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../io/source_information.dart';
|
import '../io/source_information.dart';
|
||||||
import '../js/js.dart' as js;
|
|
||||||
import '../js_backend/backend.dart' show JavaScriptBackend;
|
import '../js_backend/backend.dart' show JavaScriptBackend;
|
||||||
import '../kernel/kernel.dart';
|
import '../kernel/kernel.dart';
|
||||||
import '../native/native.dart' as native;
|
|
||||||
import '../resolution/tree_elements.dart';
|
import '../resolution/tree_elements.dart';
|
||||||
import '../tree/dartstring.dart';
|
import '../tree/dartstring.dart';
|
||||||
import '../types/masks.dart';
|
import '../types/masks.dart';
|
||||||
import '../universe/selector.dart';
|
import '../universe/selector.dart';
|
||||||
import '../universe/side_effects.dart' show SideEffects;
|
|
||||||
import 'graph_builder.dart';
|
import 'graph_builder.dart';
|
||||||
import 'kernel_ast_adapter.dart';
|
import 'kernel_ast_adapter.dart';
|
||||||
import 'kernel_string_builder.dart';
|
import 'kernel_string_builder.dart';
|
||||||
|
@ -571,16 +567,12 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitStaticGet(ir.StaticGet staticGet) {
|
void visitStaticGet(ir.StaticGet staticGet) {
|
||||||
ir.Member staticTarget = staticGet.target;
|
var staticTarget = staticGet.target;
|
||||||
if (staticTarget is ir.Procedure &&
|
if (staticTarget is ir.Procedure &&
|
||||||
staticTarget.kind == ir.ProcedureKind.Getter) {
|
staticTarget.kind == ir.ProcedureKind.Getter) {
|
||||||
// Invoke the getter
|
// Invoke the getter
|
||||||
_pushStaticInvocation(staticTarget, const <HInstruction>[],
|
_pushStaticInvocation(staticTarget, const <HInstruction>[],
|
||||||
astAdapter.returnTypeOf(staticTarget));
|
astAdapter.returnTypeOf(staticTarget));
|
||||||
} else if (staticTarget is ir.Field && staticTarget.isConst) {
|
|
||||||
assert(staticTarget.initializer != null);
|
|
||||||
stack.add(graph.addConstant(
|
|
||||||
astAdapter.getConstantFor(staticTarget.initializer), compiler));
|
|
||||||
} else {
|
} else {
|
||||||
Element element = astAdapter.getElement(staticTarget).declaration;
|
Element element = astAdapter.getElement(staticTarget).declaration;
|
||||||
push(new HStatic(element, astAdapter.inferredTypeOf(staticTarget)));
|
push(new HStatic(element, astAdapter.inferredTypeOf(staticTarget)));
|
||||||
|
@ -679,10 +671,6 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
|
||||||
@override
|
@override
|
||||||
void visitStaticInvocation(ir.StaticInvocation invocation) {
|
void visitStaticInvocation(ir.StaticInvocation invocation) {
|
||||||
ir.Procedure target = invocation.target;
|
ir.Procedure target = invocation.target;
|
||||||
if (astAdapter.isInForeignLibrary(target)) {
|
|
||||||
handleInvokeStaticForeign(invocation, target);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
TypeMask typeMask = astAdapter.returnTypeOf(target);
|
TypeMask typeMask = astAdapter.returnTypeOf(target);
|
||||||
|
|
||||||
List<HInstruction> arguments = _visitArguments(invocation.arguments);
|
List<HInstruction> arguments = _visitArguments(invocation.arguments);
|
||||||
|
@ -690,378 +678,6 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
|
||||||
_pushStaticInvocation(target, arguments, typeMask);
|
_pushStaticInvocation(target, arguments, typeMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleInvokeStaticForeign(
|
|
||||||
ir.StaticInvocation invocation, ir.Procedure target) {
|
|
||||||
String name = target.name.name;
|
|
||||||
if (name == 'JS') {
|
|
||||||
handleForeignJs(invocation);
|
|
||||||
} else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
|
|
||||||
handleForeignJsCurrentIsolateContext(invocation);
|
|
||||||
} else if (name == 'JS_CALL_IN_ISOLATE') {
|
|
||||||
handleForeignJsCallInIsolate(invocation);
|
|
||||||
} else if (name == 'DART_CLOSURE_TO_JS') {
|
|
||||||
handleForeignDartClosureToJs(invocation, 'DART_CLOSURE_TO_JS');
|
|
||||||
} else if (name == 'RAW_DART_FUNCTION_REF') {
|
|
||||||
handleForeignRawFunctionRef(invocation, 'RAW_DART_FUNCTION_REF');
|
|
||||||
} else if (name == 'JS_SET_STATIC_STATE') {
|
|
||||||
handleForeignJsSetStaticState(invocation);
|
|
||||||
} else if (name == 'JS_GET_STATIC_STATE') {
|
|
||||||
handleForeignJsGetStaticState(invocation);
|
|
||||||
} else if (name == 'JS_GET_NAME') {
|
|
||||||
handleForeignJsGetName(invocation);
|
|
||||||
} else if (name == 'JS_EMBEDDED_GLOBAL') {
|
|
||||||
handleForeignJsEmbeddedGlobal(invocation);
|
|
||||||
} else if (name == 'JS_BUILTIN') {
|
|
||||||
handleForeignJsBuiltin(invocation);
|
|
||||||
} else if (name == 'JS_GET_FLAG') {
|
|
||||||
handleForeignJsGetFlag(invocation);
|
|
||||||
} else if (name == 'JS_EFFECT') {
|
|
||||||
stack.add(graph.addConstantNull(compiler));
|
|
||||||
} else if (name == 'JS_INTERCEPTOR_CONSTANT') {
|
|
||||||
handleJsInterceptorConstant(invocation);
|
|
||||||
} else if (name == 'JS_STRING_CONCAT') {
|
|
||||||
handleJsStringConcat(invocation);
|
|
||||||
} else {
|
|
||||||
compiler.reporter.internalError(
|
|
||||||
astAdapter.getNode(invocation), "Unknown foreign: ${name}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _unexpectedForeignArguments(
|
|
||||||
ir.StaticInvocation invocation, int minPositional, [int maxPositional]) {
|
|
||||||
|
|
||||||
String pluralizeArguments(int count) {
|
|
||||||
if (count == 0) return 'no arguments';
|
|
||||||
if (count == 1) return 'one argument';
|
|
||||||
if (count == 2) return 'two arguments';
|
|
||||||
return '$count arguments';
|
|
||||||
}
|
|
||||||
String name() => invocation.target.name.name;
|
|
||||||
|
|
||||||
|
|
||||||
ir.Arguments arguments = invocation.arguments;
|
|
||||||
bool bad = false;
|
|
||||||
if (arguments.types.isNotEmpty) {
|
|
||||||
compiler.reporter.reportErrorMessage(
|
|
||||||
astAdapter.getNode(invocation),
|
|
||||||
MessageKind.GENERIC,
|
|
||||||
{'text': "Error: '${name()}' does not take type arguments."});
|
|
||||||
bad = true;
|
|
||||||
}
|
|
||||||
if (arguments.positional.length < minPositional) {
|
|
||||||
String phrase = pluralizeArguments(minPositional);
|
|
||||||
if (maxPositional != minPositional) phrase = 'at least $phrase';
|
|
||||||
compiler.reporter.reportErrorMessage(
|
|
||||||
astAdapter.getNode(invocation),
|
|
||||||
MessageKind.GENERIC,
|
|
||||||
{'text': "Error: Too few arguments. '${name()}' takes $phrase."});
|
|
||||||
bad = true;
|
|
||||||
}
|
|
||||||
if (maxPositional != null && arguments.positional.length > maxPositional) {
|
|
||||||
String phrase = pluralizeArguments(maxPositional);
|
|
||||||
if (maxPositional != minPositional) phrase = 'at most $phrase';
|
|
||||||
compiler.reporter.reportErrorMessage(
|
|
||||||
astAdapter.getNode(invocation),
|
|
||||||
MessageKind.GENERIC,
|
|
||||||
{'text': "Error: Too many arguments. '${name()}' takes $phrase."});
|
|
||||||
bad = true;
|
|
||||||
}
|
|
||||||
if (arguments.named.isNotEmpty) {
|
|
||||||
compiler.reporter.reportErrorMessage(
|
|
||||||
astAdapter.getNode(invocation),
|
|
||||||
MessageKind.GENERIC,
|
|
||||||
{'text': "Error: '${name()}' does not take named arguments."});
|
|
||||||
bad = true;
|
|
||||||
}
|
|
||||||
return bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the value of the string argument. The argument must evaluate to a
|
|
||||||
/// constant. If there is an error, the error is reported and `null` is
|
|
||||||
/// returned.
|
|
||||||
String _foreignConstantStringArgument(
|
|
||||||
ir.StaticInvocation invocation, int position, String methodName,
|
|
||||||
[String adjective = '']) {
|
|
||||||
ir.Expression argument = invocation.arguments.positional[position];
|
|
||||||
argument.accept(this);
|
|
||||||
HInstruction instruction = pop();
|
|
||||||
|
|
||||||
if (!instruction.isConstantString()) {
|
|
||||||
compiler.reporter.reportErrorMessage(
|
|
||||||
astAdapter.getNode(argument), MessageKind.GENERIC, {
|
|
||||||
'text': "Error: Expected String constant as ${adjective}argument "
|
|
||||||
"to '$methodName'."
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
HConstant hConstant = instruction;
|
|
||||||
StringConstantValue stringConstant = hConstant.constant;
|
|
||||||
return stringConstant.primitiveValue.slowToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(sra): Remove when handleInvokeStaticForeign fully implemented.
|
|
||||||
void unhandledForeign(ir.StaticInvocation invocation) {
|
|
||||||
ir.Procedure target = invocation.target;
|
|
||||||
TypeMask typeMask = astAdapter.returnTypeOf(target);
|
|
||||||
List<HInstruction> arguments = _visitArguments(invocation.arguments);
|
|
||||||
_pushStaticInvocation(target, arguments, typeMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignJsCurrentIsolateContext(ir.StaticInvocation invocation) {
|
|
||||||
if (_unexpectedForeignArguments(invocation, 0, 0)) {
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!compiler.hasIsolateSupport) {
|
|
||||||
// If the isolate library is not used, we just generate code
|
|
||||||
// to fetch the static state.
|
|
||||||
String name = backend.namer.staticStateHolder;
|
|
||||||
push(new HForeignCode(
|
|
||||||
js.js.parseForeignJS(name), backend.dynamicType, <HInstruction>[],
|
|
||||||
nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
|
|
||||||
} else {
|
|
||||||
// Call a helper method from the isolate library. The isolate library uses
|
|
||||||
// its own isolate structure that encapsulates the isolate structure used
|
|
||||||
// for binding to methods.
|
|
||||||
ir.Procedure target = astAdapter.currentIsolate;
|
|
||||||
Element element = helpers.currentIsolate;
|
|
||||||
if (target == null) {
|
|
||||||
compiler.reporter.internalError(node, 'Isolate library and compiler mismatch.');
|
|
||||||
}
|
|
||||||
_pushStaticInvocation(target, <HInstruction>[], backend.dynamicType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (!node.arguments.isEmpty) {
|
|
||||||
reporter.internalError(
|
|
||||||
node, 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!compiler.hasIsolateSupport) {
|
|
||||||
// If the isolate library is not used, we just generate code
|
|
||||||
// to fetch the static state.
|
|
||||||
String name = backend.namer.staticStateHolder;
|
|
||||||
push(new HForeignCode(
|
|
||||||
js.js.parseForeignJS(name), backend.dynamicType, <HInstruction>[],
|
|
||||||
nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
|
|
||||||
} else {
|
|
||||||
// Call a helper method from the isolate library. The isolate
|
|
||||||
// library uses its own isolate structure, that encapsulates
|
|
||||||
// Leg's isolate.
|
|
||||||
Element element = helpers.currentIsolate;
|
|
||||||
if (element == null) {
|
|
||||||
reporter.internalError(node, 'Isolate library and compiler mismatch.');
|
|
||||||
}
|
|
||||||
pushInvokeStatic(null, element, [], typeMask: backend.dynamicType);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignJsCallInIsolate(ir.StaticInvocation invocation) {
|
|
||||||
unhandledForeign(invocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignDartClosureToJs(
|
|
||||||
ir.StaticInvocation invocation, String name) {
|
|
||||||
unhandledForeign(invocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignRawFunctionRef(
|
|
||||||
ir.StaticInvocation invocation, String name) {
|
|
||||||
unhandledForeign(invocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignJsSetStaticState(ir.StaticInvocation invocation) {
|
|
||||||
if (_unexpectedForeignArguments(invocation, 0, 0)) {
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_visitArguments(invocation.arguments);
|
|
||||||
String isolateName = backend.namer.staticStateHolder;
|
|
||||||
SideEffects sideEffects = new SideEffects.empty();
|
|
||||||
sideEffects.setAllSideEffects();
|
|
||||||
push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"),
|
|
||||||
backend.dynamicType, <HInstruction>[pop()],
|
|
||||||
nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
|
|
||||||
effects: sideEffects));
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignJsGetStaticState(ir.StaticInvocation invocation) {
|
|
||||||
if (_unexpectedForeignArguments(invocation, 0, 0)) {
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
push(new HForeignCode(js.js.parseForeignJS(backend.namer.staticStateHolder),
|
|
||||||
backend.dynamicType, <HInstruction>[],
|
|
||||||
nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignJsGetName(ir.StaticInvocation invocation) {
|
|
||||||
if (_unexpectedForeignArguments(invocation, 1, 1)) {
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ir.Node argument = invocation.arguments.positional.first;
|
|
||||||
argument.accept(this);
|
|
||||||
HInstruction instruction = pop();
|
|
||||||
|
|
||||||
if (instruction is HConstant) {
|
|
||||||
js.Name name =
|
|
||||||
astAdapter.getNameForJsGetName(argument, instruction.constant);
|
|
||||||
stack.add(graph.addConstantStringFromName(name, compiler));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
compiler.reporter.reportErrorMessage(
|
|
||||||
astAdapter.getNode(argument),
|
|
||||||
MessageKind.GENERIC,
|
|
||||||
{'text': 'Error: Expected a JsGetName enum value.'});
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignJsEmbeddedGlobal(ir.StaticInvocation invocation) {
|
|
||||||
if (_unexpectedForeignArguments(invocation, 2, 2)) {
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String globalName = _foreignConstantStringArgument(
|
|
||||||
invocation, 1, 'JS_EMBEDDED_GLOBAL', 'second ');
|
|
||||||
js.Template expr = js.js.expressionTemplateYielding(
|
|
||||||
backend.emitter.generateEmbeddedGlobalAccess(globalName));
|
|
||||||
|
|
||||||
native.NativeBehavior nativeBehavior =
|
|
||||||
astAdapter.getNativeBehavior(invocation);
|
|
||||||
assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null,
|
|
||||||
message: "No NativeBehavior for $invocation"));
|
|
||||||
|
|
||||||
TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior);
|
|
||||||
push(new HForeignCode(expr, ssaType, const <HInstruction>[],
|
|
||||||
nativeBehavior: nativeBehavior));
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignJsBuiltin(ir.StaticInvocation invocation) {
|
|
||||||
if (_unexpectedForeignArguments(invocation, 2)) {
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ir.Expression> arguments = invocation.arguments.positional;
|
|
||||||
ir.Expression nameArgument = arguments[1];
|
|
||||||
|
|
||||||
nameArgument.accept(this);
|
|
||||||
HInstruction instruction = pop();
|
|
||||||
|
|
||||||
js.Template template;
|
|
||||||
if (instruction is HConstant) {
|
|
||||||
template = astAdapter.getJsBuiltinTemplate(instruction.constant);
|
|
||||||
}
|
|
||||||
if (template == null) {
|
|
||||||
compiler.reporter.reportErrorMessage(
|
|
||||||
astAdapter.getNode(nameArgument),
|
|
||||||
MessageKind.GENERIC,
|
|
||||||
{'text': 'Error: Expected a JsBuiltin enum value.'});
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<HInstruction> inputs = <HInstruction>[];
|
|
||||||
for (ir.Expression argument in arguments.skip(2)) {
|
|
||||||
argument.accept(this);
|
|
||||||
inputs.add(pop());
|
|
||||||
}
|
|
||||||
|
|
||||||
native.NativeBehavior nativeBehavior =
|
|
||||||
astAdapter.getNativeBehavior(invocation);
|
|
||||||
assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null,
|
|
||||||
message: "No NativeBehavior for $invocation"));
|
|
||||||
|
|
||||||
TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior);
|
|
||||||
push(new HForeignCode(template, ssaType, inputs,
|
|
||||||
nativeBehavior: nativeBehavior));
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignJsGetFlag(ir.StaticInvocation invocation) {
|
|
||||||
if (_unexpectedForeignArguments(invocation, 1, 1)) {
|
|
||||||
stack.add(
|
|
||||||
graph.addConstantBool(false, compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String name = _foreignConstantStringArgument(invocation, 0, 'JS_GET_FLAG');
|
|
||||||
bool value = false;
|
|
||||||
switch (name) {
|
|
||||||
case 'MUST_RETAIN_METADATA':
|
|
||||||
value = backend.mustRetainMetadata;
|
|
||||||
break;
|
|
||||||
case 'USE_CONTENT_SECURITY_POLICY':
|
|
||||||
value = compiler.options.useContentSecurityPolicy;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
compiler.reporter.reportErrorMessage(
|
|
||||||
astAdapter.getNode(invocation),
|
|
||||||
MessageKind.GENERIC,
|
|
||||||
{'text': 'Error: Unknown internal flag "$name".'});
|
|
||||||
}
|
|
||||||
stack.add(graph.addConstantBool(value, compiler));
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleJsInterceptorConstant(ir.StaticInvocation invocation) {
|
|
||||||
unhandledForeign(invocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleForeignJs(ir.StaticInvocation invocation) {
|
|
||||||
if (_unexpectedForeignArguments(invocation, 2)) {
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
native.NativeBehavior nativeBehavior =
|
|
||||||
astAdapter.getNativeBehavior(invocation);
|
|
||||||
assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null,
|
|
||||||
message: "No NativeBehavior for $invocation"));
|
|
||||||
|
|
||||||
List<HInstruction> inputs = <HInstruction>[];
|
|
||||||
for (ir.Expression argument in invocation.arguments.positional.skip(2)) {
|
|
||||||
argument.accept(this);
|
|
||||||
inputs.add(pop());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) {
|
|
||||||
compiler.reporter.reportErrorMessage(
|
|
||||||
astAdapter.getNode(invocation), MessageKind.GENERIC, {
|
|
||||||
'text': 'Mismatch between number of placeholders'
|
|
||||||
' and number of arguments.'
|
|
||||||
});
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) {
|
|
||||||
compiler.reporter.reportErrorMessage(
|
|
||||||
astAdapter.getNode(invocation), MessageKind.JS_PLACEHOLDER_CAPTURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior);
|
|
||||||
|
|
||||||
SourceInformation sourceInformation = null;
|
|
||||||
push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs,
|
|
||||||
isStatement: !nativeBehavior.codeTemplate.isExpression,
|
|
||||||
effects: nativeBehavior.sideEffects,
|
|
||||||
nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleJsStringConcat(ir.StaticInvocation invocation) {
|
|
||||||
if (_unexpectedForeignArguments(invocation, 2, 2)) {
|
|
||||||
stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<HInstruction> inputs = _visitArguments(invocation.arguments);
|
|
||||||
push(new HStringConcat(inputs[0], inputs[1], backend.stringType));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _pushStaticInvocation(
|
void _pushStaticInvocation(
|
||||||
ir.Node target, List<HInstruction> arguments, TypeMask typeMask) {
|
ir.Node target, List<HInstruction> arguments, TypeMask typeMask) {
|
||||||
HInstruction instruction = new HInvokeStatic(
|
HInstruction instruction = new HInvokeStatic(
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:js_runtime/shared/embedded_names.dart';
|
|
||||||
import 'package:kernel/ast.dart' as ir;
|
import 'package:kernel/ast.dart' as ir;
|
||||||
|
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
|
@ -11,10 +10,8 @@ import '../compiler.dart';
|
||||||
import '../constants/values.dart';
|
import '../constants/values.dart';
|
||||||
import '../dart_types.dart';
|
import '../dart_types.dart';
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../js/js.dart' as js;
|
|
||||||
import '../js_backend/js_backend.dart';
|
import '../js_backend/js_backend.dart';
|
||||||
import '../kernel/kernel.dart';
|
import '../kernel/kernel.dart';
|
||||||
import '../native/native.dart' as native;
|
|
||||||
import '../resolution/tree_elements.dart';
|
import '../resolution/tree_elements.dart';
|
||||||
import '../tree/tree.dart' as ast;
|
import '../tree/tree.dart' as ast;
|
||||||
import '../types/masks.dart';
|
import '../types/masks.dart';
|
||||||
|
@ -223,10 +220,6 @@ class KernelAstAdapter {
|
||||||
return TypeMaskFactory.inferredTypeForSelector(selector, mask, _compiler);
|
return TypeMaskFactory.inferredTypeForSelector(selector, mask, _compiler);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeMask typeFromNativeBehavior(native.NativeBehavior nativeBehavior) {
|
|
||||||
return TypeMaskFactory.fromNativeBehavior(nativeBehavior, _compiler);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstantValue getConstantFor(ir.Node node) {
|
ConstantValue getConstantFor(ir.Node node) {
|
||||||
ConstantValue constantValue =
|
ConstantValue constantValue =
|
||||||
_backend.constants.getConstantValueForNode(getNode(node), elements);
|
_backend.constants.getConstantValueForNode(getNode(node), elements);
|
||||||
|
@ -279,45 +272,6 @@ class KernelAstAdapter {
|
||||||
TypeMask get assertThrowReturnType => TypeMaskFactory
|
TypeMask get assertThrowReturnType => TypeMaskFactory
|
||||||
.inferredReturnTypeForElement(_backend.helpers.assertThrow, _compiler);
|
.inferredReturnTypeForElement(_backend.helpers.assertThrow, _compiler);
|
||||||
|
|
||||||
ir.Procedure get currentIsolate =>
|
|
||||||
kernel.functions[_backend.helpers.currentIsolate];
|
|
||||||
|
|
||||||
bool isInForeignLibrary(ir.Member member) =>
|
|
||||||
_backend.isForeign(getElement(member));
|
|
||||||
|
|
||||||
native.NativeBehavior getNativeBehavior(ir.Node node) {
|
|
||||||
return elements.getNativeData(getNode(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
js.Name getNameForJsGetName(ir.Node argument, ConstantValue constant) {
|
|
||||||
int index = _extractEnumIndexFromConstantValue(
|
|
||||||
constant, _backend.helpers.jsGetNameEnum);
|
|
||||||
if (index == null) return null;
|
|
||||||
return _backend.namer
|
|
||||||
.getNameForJsGetName(getNode(argument), JsGetName.values[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
js.Template getJsBuiltinTemplate(ConstantValue constant) {
|
|
||||||
int index = _extractEnumIndexFromConstantValue(
|
|
||||||
constant, _backend.helpers.jsBuiltinEnum);
|
|
||||||
if (index == null) return null;
|
|
||||||
return _backend.emitter.builtinTemplateFor(JsBuiltin.values[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _extractEnumIndexFromConstantValue(
|
|
||||||
ConstantValue constant, Element classElement) {
|
|
||||||
if (constant is ConstructedConstantValue) {
|
|
||||||
if (constant.type.element == classElement) {
|
|
||||||
assert(constant.fields.length == 1);
|
|
||||||
ConstantValue indexConstant = constant.fields.values.single;
|
|
||||||
if (indexConstant is IntConstantValue) {
|
|
||||||
return indexConstant.primitiveValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
DartType getDartType(ir.DartType type) {
|
DartType getDartType(ir.DartType type) {
|
||||||
return type.accept(_typeConverter);
|
return type.accept(_typeConverter);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue