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:
Stephen Adams 2016-10-13 19:02:41 -07:00
parent a897bc3832
commit 476ffbda5e
3 changed files with 4 additions and 435 deletions

View file

@ -1930,7 +1930,7 @@ class KernelVisitor extends Object
@override
ir.Expression handleStaticFieldGet(Send node, FieldElement field, _) {
return associateNode(buildStaticGet(field), node);
return buildStaticGet(field);
}
@override
@ -2137,8 +2137,7 @@ class KernelVisitor extends Object
NodeList arguments,
CallStructure callStructure,
_) {
return associateNode(
buildStaticInvoke(function, arguments, isConst: false), node);
return buildStaticInvoke(function, arguments, isConst: false);
}
@override
@ -2763,7 +2762,7 @@ class KernelVisitor extends Object
FieldElement field = currentElement;
return field.isMalformed
? new ir.InvalidExpression()
: associateNode(visitForValue(field.initializer), field.initializer);
: visitForValue(field.initializer);
});
}
}

View file

@ -9,19 +9,15 @@ import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
import '../common/names.dart';
import '../common/tasks.dart' show CompilerTask;
import '../compiler.dart';
import '../constants/values.dart' show StringConstantValue;
import '../dart_types.dart';
import '../elements/elements.dart';
import '../io/source_information.dart';
import '../js/js.dart' as js;
import '../js_backend/backend.dart' show JavaScriptBackend;
import '../kernel/kernel.dart';
import '../native/native.dart' as native;
import '../resolution/tree_elements.dart';
import '../tree/dartstring.dart';
import '../types/masks.dart';
import '../universe/selector.dart';
import '../universe/side_effects.dart' show SideEffects;
import 'graph_builder.dart';
import 'kernel_ast_adapter.dart';
import 'kernel_string_builder.dart';
@ -571,16 +567,12 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
@override
void visitStaticGet(ir.StaticGet staticGet) {
ir.Member staticTarget = staticGet.target;
var staticTarget = staticGet.target;
if (staticTarget is ir.Procedure &&
staticTarget.kind == ir.ProcedureKind.Getter) {
// Invoke the getter
_pushStaticInvocation(staticTarget, const <HInstruction>[],
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 {
Element element = astAdapter.getElement(staticTarget).declaration;
push(new HStatic(element, astAdapter.inferredTypeOf(staticTarget)));
@ -679,10 +671,6 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
@override
void visitStaticInvocation(ir.StaticInvocation invocation) {
ir.Procedure target = invocation.target;
if (astAdapter.isInForeignLibrary(target)) {
handleInvokeStaticForeign(invocation, target);
return;
}
TypeMask typeMask = astAdapter.returnTypeOf(target);
List<HInstruction> arguments = _visitArguments(invocation.arguments);
@ -690,378 +678,6 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
_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(
ir.Node target, List<HInstruction> arguments, TypeMask typeMask) {
HInstruction instruction = new HInvokeStatic(

View file

@ -2,7 +2,6 @@
// 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.
import 'package:js_runtime/shared/embedded_names.dart';
import 'package:kernel/ast.dart' as ir;
import '../common.dart';
@ -11,10 +10,8 @@ import '../compiler.dart';
import '../constants/values.dart';
import '../dart_types.dart';
import '../elements/elements.dart';
import '../js/js.dart' as js;
import '../js_backend/js_backend.dart';
import '../kernel/kernel.dart';
import '../native/native.dart' as native;
import '../resolution/tree_elements.dart';
import '../tree/tree.dart' as ast;
import '../types/masks.dart';
@ -223,10 +220,6 @@ class KernelAstAdapter {
return TypeMaskFactory.inferredTypeForSelector(selector, mask, _compiler);
}
TypeMask typeFromNativeBehavior(native.NativeBehavior nativeBehavior) {
return TypeMaskFactory.fromNativeBehavior(nativeBehavior, _compiler);
}
ConstantValue getConstantFor(ir.Node node) {
ConstantValue constantValue =
_backend.constants.getConstantValueForNode(getNode(node), elements);
@ -279,45 +272,6 @@ class KernelAstAdapter {
TypeMask get assertThrowReturnType => TypeMaskFactory
.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) {
return type.accept(_typeConverter);
}