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

Unified Diff: pkg/compiler/lib/src/js_backend/codegen/codegen.dart

Issue 1525163002: dart2js cps: Use oneshot interceptors and 'instanceof' expressions. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Merge Created 5 years 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 side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/js_backend/codegen/codegen.dart
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index 15b429769df75d99d823c7632e60543b1b2aaa9f..54f2d40b0e38e9a757c5fbf38e244cddab3b4e14 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -281,29 +281,19 @@ class CodeGenerator extends tree_ir.StatementVisitor
sourceInformation: node.sourceInformation);
}
- void registerMethodInvoke(tree_ir.InvokeMethod node) {
- Selector selector = node.selector;
- TypeMask mask = node.mask;
- mask = glue.extendMaskIfReachesAll(selector, mask);
- if (selector.isGetter) {
- registry.registerDynamicUse(new DynamicUse(selector, mask));
- } else if (selector.isSetter) {
- registry.registerDynamicUse(new DynamicUse(selector, mask));
- } else {
- assert(invariant(CURRENT_ELEMENT_SPANNABLE,
- selector.isCall || selector.isOperator ||
- selector.isIndex || selector.isIndexSet,
- message: 'unexpected kind ${selector.kind}'));
+ void registerMethodInvoke(Selector selector, TypeMask receiverType) {
+ registry.registerDynamicUse(new DynamicUse(selector, receiverType));
+ if (!selector.isGetter && !selector.isSetter) {
// TODO(sigurdm): We should find a better place to register the call.
Selector call = new Selector.callClosureFrom(selector);
registry.registerDynamicUse(new DynamicUse(call, null));
- registry.registerDynamicUse(new DynamicUse(selector, mask));
}
}
@override
js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) {
- registerMethodInvoke(node);
+ TypeMask mask = glue.extendMaskIfReachesAll(node.selector, node.mask);
+ registerMethodInvoke(node.selector, mask);
return js.propertyCall(visitExpression(node.receiver),
glue.invocationName(node.selector),
visitExpressionList(node.arguments))
@@ -355,6 +345,17 @@ class CodeGenerator extends tree_ir.StatementVisitor
}
@override
+ js.Expression visitOneShotInterceptor(tree_ir.OneShotInterceptor node) {
+ registerMethodInvoke(node.selector, node.mask);
+ registry.registerUseInterceptor();
+ return js.js('#.#(#)',
+ [glue.getInterceptorLibrary(),
+ glue.registerOneShotInterceptor(node.selector),
+ visitExpressionList(node.arguments)])
+ .withSourceInformation(node.sourceInformation);
+ }
+
+ @override
js.Expression visitLiteralList(tree_ir.LiteralList node) {
registry.registerInstantiatedClass(glue.listClass);
List<js.Expression> entries = visitExpressionList(node.values);
@@ -399,6 +400,19 @@ class CodeGenerator extends tree_ir.StatementVisitor
return new js.This();
}
+ /// Ensure that 'instanceof' checks may be performed against [class_].
+ ///
+ /// Even if the class is never instantiated, a JS constructor must be emitted
+ /// so the 'instanceof' expression does not throw an exception at runtime.
+ ///
+ /// It does not help to ask the class world if the class is instantiated,
+ /// because it could still get tree-shaken if it is unused after optimization.
+ void registerInstanceofCheck(ClassElement class_) {
+ // TODO(asgerf): This is the only hook we have to ensure the JS constructor
+ // gets emitted, but it is very imprecise. We should do better.
+ registry.registerInstantiatedClass(class_);
+ }
+
@override
js.Expression visitTypeOperator(tree_ir.TypeOperator node) {
js.Expression value = visitExpression(node.value);
@@ -406,7 +420,6 @@ class CodeGenerator extends tree_ir.StatementVisitor
DartType type = node.type;
if (type is InterfaceType) {
registry.registerTypeUse(new TypeUse.isCheck(type));
- //glue.registerIsCheck(type, registry);
ClassElement clazz = type.element;
if (glue.isStringClass(clazz)) {
@@ -419,6 +432,11 @@ class CodeGenerator extends tree_ir.StatementVisitor
return js.js(r'typeof # === "boolean"', <js.Expression>[value]);
}
// TODO(sra): Implement fast cast via calling 'boolTypeCast'.
+ } else if (node.isTypeTest &&
+ node.typeArguments.isEmpty &&
+ glue.mayGenerateInstanceofCheck(type)) {
+ registerInstanceofCheck(clazz);
+ return js.js('# instanceof #', [value, glue.constructorAccess(clazz)]);
}
// The helper we use needs the JSArray class to exist, but for some
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart ('k') | pkg/compiler/lib/src/js_backend/codegen/glue.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698