mirror of
https://github.com/dart-lang/sdk
synced 2024-10-03 23:16:55 +00:00
Delete AST-based SSA builder
Change-Id: I16aa702eae335a01163a3b79d36bf4e60561756e Reviewed-on: https://dart-review.googlesource.com/54841 Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
4fbd22c9e2
commit
049d41ee36
|
@ -8,7 +8,6 @@ export 'behavior.dart';
|
||||||
export 'enqueue.dart';
|
export 'enqueue.dart';
|
||||||
export 'js.dart';
|
export 'js.dart';
|
||||||
export 'scanner.dart';
|
export 'scanner.dart';
|
||||||
export 'ssa.dart';
|
|
||||||
|
|
||||||
const Iterable<String> _allowedDartSchemePaths = const <String>[
|
const Iterable<String> _allowedDartSchemePaths = const <String>[
|
||||||
'async',
|
'async',
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
|
||||||
// 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 '../common.dart';
|
|
||||||
import '../constants/values.dart';
|
|
||||||
import '../elements/resolution_types.dart';
|
|
||||||
import '../elements/elements.dart';
|
|
||||||
import '../js/js.dart' as js;
|
|
||||||
import '../js_emitter/js_emitter.dart' show NativeEmitter;
|
|
||||||
import '../ssa/builder.dart' show SsaAstGraphBuilder;
|
|
||||||
import '../ssa/nodes.dart' show HInstruction, HForeignCode, HReturn;
|
|
||||||
import '../tree/tree.dart';
|
|
||||||
import '../universe/side_effects.dart' show SideEffects;
|
|
||||||
|
|
||||||
final RegExp nativeRedirectionRegExp = new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$');
|
|
||||||
|
|
||||||
void handleSsaNative(SsaAstGraphBuilder builder, Expression nativeBody) {
|
|
||||||
MethodElement element = builder.target;
|
|
||||||
NativeEmitter nativeEmitter = builder.nativeEmitter;
|
|
||||||
|
|
||||||
HInstruction convertDartClosure(
|
|
||||||
ParameterElement parameter, ResolutionFunctionType type) {
|
|
||||||
HInstruction local = builder.localsHandler.readLocal(parameter);
|
|
||||||
ConstantValue arityConstant =
|
|
||||||
builder.constantSystem.createInt(type.parameterTypes.length);
|
|
||||||
HInstruction arity =
|
|
||||||
builder.graph.addConstant(arityConstant, builder.closedWorld);
|
|
||||||
// TODO(ngeoffray): For static methods, we could pass a method with a
|
|
||||||
// defined arity.
|
|
||||||
MethodElement helper = builder.commonElements.closureConverter;
|
|
||||||
builder.pushInvokeStatic(nativeBody, helper, [local, arity]);
|
|
||||||
HInstruction closure = builder.pop();
|
|
||||||
return closure;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check which pattern this native method follows:
|
|
||||||
// 1) foo() native;
|
|
||||||
// hasBody = false
|
|
||||||
// 2) foo() native "bar";
|
|
||||||
// No longer supported, this is now done with @JSName('foo') and case 1.
|
|
||||||
// 3) foo() native "return 42";
|
|
||||||
// hasBody = true
|
|
||||||
bool hasBody = false;
|
|
||||||
assert(builder.nativeData.isNativeMember(element));
|
|
||||||
String nativeMethodName = builder.nativeData.getFixedBackendName(element);
|
|
||||||
if (nativeBody != null) {
|
|
||||||
LiteralString jsCode = nativeBody.asLiteralString();
|
|
||||||
String str = jsCode.dartString.slowToString();
|
|
||||||
if (nativeRedirectionRegExp.hasMatch(str)) {
|
|
||||||
failedAt(nativeBody, "Deprecated syntax, use @JSName('name') instead.");
|
|
||||||
}
|
|
||||||
hasBody = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasBody) {
|
|
||||||
nativeEmitter.nativeMethods.add(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionSignature parameters = element.functionSignature;
|
|
||||||
if (!hasBody) {
|
|
||||||
List<String> arguments = <String>[];
|
|
||||||
List<HInstruction> inputs = <HInstruction>[];
|
|
||||||
String receiver = '';
|
|
||||||
if (element.isInstanceMember) {
|
|
||||||
receiver = '#.';
|
|
||||||
inputs.add(builder.localsHandler.readThis());
|
|
||||||
}
|
|
||||||
parameters.forEachParameter((_parameter) {
|
|
||||||
ParameterElement parameter = _parameter;
|
|
||||||
ResolutionDartType type = parameter.type.unaliased;
|
|
||||||
HInstruction input = builder.localsHandler.readLocal(parameter);
|
|
||||||
if (type is ResolutionFunctionType) {
|
|
||||||
// The parameter type is a function type either directly or through
|
|
||||||
// typedef(s).
|
|
||||||
input = convertDartClosure(parameter, type);
|
|
||||||
}
|
|
||||||
inputs.add(input);
|
|
||||||
arguments.add('#');
|
|
||||||
});
|
|
||||||
|
|
||||||
String foreignParameters = arguments.join(',');
|
|
||||||
String nativeMethodCall;
|
|
||||||
if (element.kind == ElementKind.FUNCTION) {
|
|
||||||
nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)';
|
|
||||||
} else if (element.kind == ElementKind.GETTER) {
|
|
||||||
nativeMethodCall = '$receiver$nativeMethodName';
|
|
||||||
} else if (element.kind == ElementKind.SETTER) {
|
|
||||||
nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters';
|
|
||||||
} else {
|
|
||||||
failedAt(element, 'Unexpected kind: "${element.kind}".');
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.push(new HForeignCode(
|
|
||||||
// TODO(sra): This could be cached. The number of templates should
|
|
||||||
// be proportional to the number of native methods, which is bounded
|
|
||||||
// by the dart: libraries.
|
|
||||||
js.js.uncachedExpressionTemplate(nativeMethodCall),
|
|
||||||
builder.abstractValueDomain.dynamicType,
|
|
||||||
inputs,
|
|
||||||
effects: new SideEffects()));
|
|
||||||
// TODO(johnniwinther): Provide source information.
|
|
||||||
builder
|
|
||||||
.close(new HReturn(builder.abstractValueDomain, builder.pop(), null))
|
|
||||||
.addSuccessor(builder.graph.exit);
|
|
||||||
} else {
|
|
||||||
if (parameters.parameterCount != 0) {
|
|
||||||
failedAt(
|
|
||||||
nativeBody,
|
|
||||||
'native "..." syntax is restricted to '
|
|
||||||
'functions with zero parameters.');
|
|
||||||
}
|
|
||||||
LiteralString jsCode = nativeBody.asLiteralString();
|
|
||||||
builder.push(new HForeignCode.statement(
|
|
||||||
js.js.statementTemplateYielding(
|
|
||||||
new js.LiteralStatement(jsCode.dartString.slowToString())),
|
|
||||||
<HInstruction>[],
|
|
||||||
new SideEffects(),
|
|
||||||
null,
|
|
||||||
builder.abstractValueDomain.dynamicType));
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,9 +7,7 @@ import 'package:kernel/ast.dart' as ir;
|
||||||
import '../closure.dart' show CapturedLoopScope;
|
import '../closure.dart' show CapturedLoopScope;
|
||||||
import '../elements/jumps.dart';
|
import '../elements/jumps.dart';
|
||||||
import '../io/source_information.dart';
|
import '../io/source_information.dart';
|
||||||
import '../tree/tree.dart' as ast;
|
|
||||||
|
|
||||||
import 'builder.dart';
|
|
||||||
import 'builder_kernel.dart';
|
import 'builder_kernel.dart';
|
||||||
import 'graph_builder.dart';
|
import 'graph_builder.dart';
|
||||||
import 'jump_handler.dart';
|
import 'jump_handler.dart';
|
||||||
|
@ -312,35 +310,6 @@ abstract class LoopHandler<T> {
|
||||||
{bool isLoopJump});
|
{bool isLoopJump});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A loop handler for the builder that just uses AST nodes directly.
|
|
||||||
class SsaLoopHandler extends LoopHandler<ast.Node> {
|
|
||||||
final SsaAstGraphBuilder builder;
|
|
||||||
|
|
||||||
SsaLoopHandler(SsaAstGraphBuilder builder)
|
|
||||||
: this.builder = builder,
|
|
||||||
super(builder);
|
|
||||||
|
|
||||||
@override
|
|
||||||
int loopKind(ast.Node node) => node.accept(const _SsaLoopTypeVisitor());
|
|
||||||
|
|
||||||
@override
|
|
||||||
JumpHandler createJumpHandler(ast.Node node, JumpTarget jumpTarget,
|
|
||||||
{bool isLoopJump}) =>
|
|
||||||
builder.createJumpHandler(node, jumpTarget, isLoopJump: isLoopJump);
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SsaLoopTypeVisitor extends ast.Visitor {
|
|
||||||
const _SsaLoopTypeVisitor();
|
|
||||||
int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
|
|
||||||
int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
|
|
||||||
int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
|
|
||||||
int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
|
|
||||||
int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
|
|
||||||
int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
|
|
||||||
int visitSwitchStatement(ast.SwitchStatement node) =>
|
|
||||||
HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(het): Since kernel simplifies loop breaks and continues, we should
|
// TODO(het): Since kernel simplifies loop breaks and continues, we should
|
||||||
// rewrite the loop handler from scratch to account for the simplified structure
|
// rewrite the loop handler from scratch to account for the simplified structure
|
||||||
class KernelLoopHandler extends LoopHandler<ir.TreeNode> {
|
class KernelLoopHandler extends LoopHandler<ir.TreeNode> {
|
||||||
|
|
Loading…
Reference in a new issue