Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit f3cec06

Browse files
rakudramacommit-bot@chromium.org
authored andcommitted
Capture type variables in global NSM stubs
- Add a type argument count to JSInvocationMirror. - Change stubs to pass the argument count. Change-Id: I448dbee9a2aa0be17c24ae79eae0c89e7574fa7c Reviewed-on: https://dart-review.googlesource.com/49820 Commit-Queue: Stephen Adams <[email protected]> Reviewed-by: Sigmund Cherem <[email protected]>
1 parent 2247843 commit f3cec06

File tree

6 files changed

+59
-16
lines changed

6 files changed

+59
-16
lines changed

pkg/compiler/lib/src/js_emitter/class_stub_generator.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ class ClassStubGenerator {
183183
// Values match JSInvocationMirror in js-helper library.
184184
int type = selector.invocationMirrorKind;
185185
List<String> parameterNames =
186-
new List.generate(selector.argumentCount, (i) => '\$$i');
186+
new List.generate(selector.argumentCount, (i) => '\$$i') +
187+
new List.generate(selector.typeArgumentCount, (i) => '\$T${i + 1}');
187188

188189
List<jsAst.Expression> argNames = selector.callStructure
189190
.getOrderedNamedArguments()
@@ -200,7 +201,8 @@ class ClassStubGenerator {
200201
#internalName,
201202
#type,
202203
#arguments,
203-
#namedArguments))''', {
204+
#namedArguments,
205+
#typeArgumentCount))''', {
204206
'receiver': isIntercepted ? r'$receiver' : 'this',
205207
'noSuchMethodName': _namer.noSuchMethodName,
206208
'createInvocationMirror':
@@ -210,7 +212,8 @@ class ClassStubGenerator {
210212
'internalName': js.quoteName(internalName),
211213
'type': js.number(type),
212214
'arguments': new jsAst.ArrayInitializer(parameterNames.map(js).toList()),
213-
'namedArguments': new jsAst.ArrayInitializer(argNames)
215+
'namedArguments': new jsAst.ArrayInitializer(argNames),
216+
'typeArgumentCount': js.number(selector.typeArgumentCount)
214217
});
215218

216219
jsAst.Expression function;

pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class NsmEmitter extends CodeEmitterHelper {
8989
if (!generateTrivialNsmHandlers) return false;
9090
// Check for named arguments.
9191
if (argNames.length != 0) return false;
92+
if (selector.typeArgumentCount > 0) return false;
9293
// Check for unexpected name (this doesn't really happen).
9394
if (internalName is GetterName) return type == 1;
9495
if (internalName is SetterName) return type == 2;
@@ -261,7 +262,7 @@ class NsmEmitter extends CodeEmitterHelper {
261262
// Generate call to:
262263
//
263264
// createInvocationMirror(String name, internalName, type,
264-
// arguments, argumentNames)
265+
// arguments, argumentNames, typeArgumentCount)
265266
//
266267
267268
// This 'if' is either a static choice or dynamic choice depending on
@@ -276,7 +277,8 @@ class NsmEmitter extends CodeEmitterHelper {
276277
// Create proper Array with all arguments except first
277278
// (receiver).
278279
Array.prototype.slice.call(arguments, 1),
279-
[]));
280+
[],
281+
0));
280282
}
281283
})(#names[j], shortName, type);
282284
} else {
@@ -290,7 +292,8 @@ class NsmEmitter extends CodeEmitterHelper {
290292
#createInvocationMirror(name, shortName, type,
291293
// Create proper Array with all arguments.
292294
Array.prototype.slice.call(arguments, 0),
293-
[]));
295+
[],
296+
0));
294297
}
295298
})(#names[j], shortName, type);
296299
}

pkg/compiler/lib/src/ssa/builder.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3198,7 +3198,8 @@ class SsaAstGraphBuilder extends ast.Visitor
31983198
graph.addConstantStringFromName(internalName, closedWorld),
31993199
graph.addConstant(kindConstant, closedWorld),
32003200
argumentsInstruction,
3201-
argumentNamesInstruction
3201+
argumentNamesInstruction,
3202+
graph.addConstantInt(0, closedWorld), // type argument count.
32023203
],
32033204
typeMask: commonMasks.dynamicType);
32043205

pkg/compiler/lib/src/ssa/builder_kernel.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4114,7 +4114,8 @@ class KernelSsaGraphBuilder extends ir.Visitor
41144114
graph.addConstantStringFromName(internalName, closedWorld),
41154115
graph.addConstant(kindConstant, closedWorld),
41164116
argumentsInstruction,
4117-
argumentNamesInstruction
4117+
argumentNamesInstruction,
4118+
graph.addConstantInt(typeArguments.length, closedWorld),
41184119
],
41194120
commonMasks.dynamicType,
41204121
typeArguments);

sdk/lib/_internal/js_runtime/lib/js_helper.dart

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,16 +262,19 @@ String S(value) {
262262
return res;
263263
}
264264

265+
// Called from generated code.
265266
createInvocationMirror(
266-
String name, internalName, kind, arguments, argumentNames) {
267+
String name, internalName, kind, arguments, argumentNames, types) {
268+
// TODO(sra): [types] (the number of type arguments) could be omitted in the
269+
// generated stub code to save an argument. Then we would use `types ?? 0`.
267270
return new JSInvocationMirror(
268-
name, internalName, kind, arguments, argumentNames);
271+
name, internalName, kind, arguments, argumentNames, types);
269272
}
270273

271274
createUnmangledInvocationMirror(
272275
Symbol symbol, internalName, kind, arguments, argumentNames) {
273276
return new JSInvocationMirror(
274-
symbol, internalName, kind, arguments, argumentNames);
277+
symbol, internalName, kind, arguments, argumentNames, 0);
275278
}
276279

277280
void throwInvalidReflectionError(String memberName) {
@@ -333,11 +336,12 @@ class JSInvocationMirror implements Invocation {
333336
final List<Type> _typeArguments;
334337
final List _arguments;
335338
final List _namedArgumentNames;
339+
final int _typeArgumentCount;
336340
/** Map from argument name to index in _arguments. */
337341
Map<String, dynamic> _namedIndices = null;
338342

339343
JSInvocationMirror(this._memberName, this._internalName, this._kind,
340-
this._arguments, this._namedArgumentNames);
344+
this._arguments, this._namedArgumentNames, this._typeArgumentCount);
341345

342346
Symbol get memberName {
343347
if (_memberName is Symbol) return _memberName;
@@ -361,13 +365,20 @@ class JSInvocationMirror implements Invocation {
361365
bool get isAccessor => _kind != METHOD;
362366

363367
List<Type> get typeArguments {
364-
// UNIMPLEMENTED
365-
return const <Type>[];
368+
if (_typeArgumentCount == 0) return const <Type>[];
369+
int start = _arguments.length - _typeArgumentCount;
370+
var list = <Type>[];
371+
for (int index = 0; index < _typeArgumentCount; index++) {
372+
list.add(
373+
createRuntimeType(runtimeTypeToString(_arguments[start + index])));
374+
}
375+
return list;
366376
}
367377

368378
List get positionalArguments {
369379
if (isGetter) return const [];
370-
var argumentCount = _arguments.length - _namedArgumentNames.length;
380+
var argumentCount =
381+
_arguments.length - _namedArgumentNames.length - _typeArgumentCount;
371382
if (argumentCount == 0) return const [];
372383
var list = [];
373384
for (var index = 0; index < argumentCount; index++) {
@@ -379,7 +390,8 @@ class JSInvocationMirror implements Invocation {
379390
Map<Symbol, dynamic> get namedArguments {
380391
if (isAccessor) return const <Symbol, dynamic>{};
381392
int namedArgumentCount = _namedArgumentNames.length;
382-
int namedArgumentsStartIndex = _arguments.length - namedArgumentCount;
393+
int namedArgumentsStartIndex =
394+
_arguments.length - namedArgumentCount - _typeArgumentCount;
383395
if (namedArgumentCount == 0) return const <Symbol, dynamic>{};
384396
var map = new Map<Symbol, dynamic>();
385397
for (int i = 0; i < namedArgumentCount; i++) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
// dart2jsOptions=--disable-rti-optimization
5+
6+
// Dart test program testing that type arguments are captured by the Invocation
7+
// passed to noSuchMethod from a dynamic call.
8+
9+
import "package:expect/expect.dart";
10+
11+
class Mock {
12+
noSuchMethod(i) => i.typeArguments;
13+
}
14+
15+
void main() {
16+
var g = new Mock();
17+
18+
Expect.listEquals(
19+
[String, int], (g as dynamic).hurrah<String, int>(moose: 42, duck: 12));
20+
21+
// map has interceptor calling convention in dart2js.
22+
Expect.listEquals([String, int], (g as dynamic).map<String, int>());
23+
}

0 commit comments

Comments
 (0)