Index: pkg/kernel/lib/target/vm.dart |
diff --git a/pkg/kernel/lib/target/vm.dart b/pkg/kernel/lib/target/vm.dart |
index aa943031fe08b16f23934f1cf42efaff724ab890..8ad4a9d86153eaab9fe9c18f0bca3f3e4472e2a1 100644 |
--- a/pkg/kernel/lib/target/vm.dart |
+++ b/pkg/kernel/lib/target/vm.dart |
@@ -98,7 +98,7 @@ class VmTarget extends Target { |
} |
@override |
- Expression instantiateInvocation(Member target, Expression receiver, |
+ Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver, |
String name, Arguments arguments, int offset, bool isSuper) { |
// See [_InvocationMirror] |
// (../../../../runtime/lib/invocation_mirror_patch.dart). |
@@ -142,19 +142,130 @@ class VmTarget extends Target { |
new BoolLiteral(isSuper)..fileOffset = arguments.fileOffset, |
]); |
- return (target is Constructor |
- ? new ConstructorInvocation(target, constructorArguments) |
- : new StaticInvocation(target, constructorArguments)) |
+ return new ConstructorInvocation( |
+ coreTypes.invocationMirrorDefaultConstructor, constructorArguments) |
..fileOffset = offset; |
} |
- Expression _fixedLengthList(List<Expression> elements, int charOffset) { |
+ @override |
+ Expression instantiateNoSuchMethodError(CoreTypes coreTypes, |
+ Expression receiver, String name, Arguments arguments, int offset, |
+ {bool isMethod: false, |
+ bool isGetter: false, |
+ bool isSetter: false, |
+ bool isField: false, |
+ bool isLocalVariable: false, |
+ bool isDynamic: false, |
+ bool isSuper: false, |
+ bool isStatic: false, |
+ bool isConstructor: false, |
+ bool isTopLevel: false}) { |
+ int type = _invocationType( |
+ isMethod: isMethod, |
+ isGetter: isGetter, |
+ isSetter: isSetter, |
+ isField: isField, |
+ isLocalVariable: isLocalVariable, |
+ isDynamic: isDynamic, |
+ isSuper: isSuper, |
+ isStatic: isStatic, |
+ isConstructor: isConstructor, |
+ isTopLevel: isTopLevel); |
+ return new ConstructorInvocation( |
+ coreTypes.noSuchMethodErrorImplementationConstructor, |
+ new Arguments(<Expression>[ |
+ receiver, |
+ new SymbolLiteral(name)..fileOffset = offset, |
+ new IntLiteral(type)..fileOffset = offset, |
+ _fixedLengthList(arguments.positional, arguments.fileOffset), |
+ new MapLiteral(new List<MapEntry>.from( |
+ arguments.named.map((NamedExpression arg) { |
+ return new MapEntry( |
+ new SymbolLiteral(arg.name)..fileOffset = arg.fileOffset, |
+ arg.value) |
+ ..fileOffset = arg.fileOffset; |
+ }))) |
+ ..fileOffset = arguments.fileOffset, |
+ new NullLiteral() |
+ ])); |
+ } |
+ |
+ int _invocationType( |
+ {bool isMethod: false, |
+ bool isGetter: false, |
+ bool isSetter: false, |
+ bool isField: false, |
+ bool isLocalVariable: false, |
+ bool isDynamic: false, |
+ bool isSuper: false, |
+ bool isStatic: false, |
+ bool isConstructor: false, |
+ bool isTopLevel: false}) { |
+ // This is copied from [_InvocationMirror]( |
+ // ../../../../../../runtime/lib/invocation_mirror_patch.dart). |
+ |
+ // Constants describing the invocation type. |
+ // _FIELD cannot be generated by regular invocation mirrors. |
+ const int _METHOD = 0; |
+ const int _GETTER = 1; |
+ const int _SETTER = 2; |
+ const int _FIELD = 3; |
+ const int _LOCAL_VAR = 4; |
+ // ignore: UNUSED_LOCAL_VARIABLE |
+ const int _TYPE_SHIFT = 0; |
+ const int _TYPE_BITS = 3; |
+ // ignore: UNUSED_LOCAL_VARIABLE |
+ const int _TYPE_MASK = (1 << _TYPE_BITS) - 1; |
+ |
+ // These values, except _DYNAMIC and _SUPER, are only used when throwing |
+ // NoSuchMethodError for compile-time resolution failures. |
+ const int _DYNAMIC = 0; |
+ const int _SUPER = 1; |
+ const int _STATIC = 2; |
+ const int _CONSTRUCTOR = 3; |
+ const int _TOP_LEVEL = 4; |
+ const int _CALL_SHIFT = _TYPE_BITS; |
+ const int _CALL_BITS = 3; |
+ // ignore: UNUSED_LOCAL_VARIABLE |
+ const int _CALL_MASK = (1 << _CALL_BITS) - 1; |
+ |
+ int type = -1; |
+ // For convenience, [isGetter] and [isSetter] takes precedence over |
+ // [isMethod]. |
+ if (isGetter) { |
+ type = _GETTER; |
+ } else if (isSetter) { |
+ type = _SETTER; |
+ } else if (isMethod) { |
+ type = _METHOD; |
+ } else if (isField) { |
+ type = _FIELD; |
+ } else if (isLocalVariable) { |
+ type = _LOCAL_VAR; |
+ } |
+ |
+ if (isDynamic) { |
+ type |= (_DYNAMIC << _CALL_SHIFT); |
+ } else if (isSuper) { |
+ type |= (_SUPER << _CALL_SHIFT); |
+ } else if (isStatic) { |
+ type |= (_STATIC << _CALL_SHIFT); |
+ } else if (isConstructor) { |
+ type |= (_CONSTRUCTOR << _CALL_SHIFT); |
+ } else if (isTopLevel) { |
+ type |= (_TOP_LEVEL << _CALL_SHIFT); |
+ } |
+ |
+ return type; |
+ } |
+ |
+ Expression _fixedLengthList(List<Expression> elements, int offset) { |
// TODO(ahe): It's possible that it would be better to create a fixed-length |
// list first, and then populate it. That would create fewer objects. But as |
// this is currently only used in (statically resolved) no-such-method |
// handling, the current approach seems sufficient. |
return new MethodInvocation( |
- new ListLiteral(elements)..fileOffset = charOffset, |
+ new ListLiteral(elements)..fileOffset = offset, |
new Name("toList"), |
new Arguments(<Expression>[], named: <NamedExpression>[ |
new NamedExpression("growable", new BoolLiteral(false)) |