OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 // VM-specific implementation of the dart:mirrors library. | 5 // VM-specific implementation of the dart:mirrors library. |
6 | 6 |
7 import "dart:collection"; | 7 import "dart:collection"; |
8 | 8 |
9 final emptyList = new UnmodifiableListView([]); | 9 final emptyList = new UnmodifiableListView([]); |
10 final emptyMap = new _UnmodifiableMapView({}); | 10 final emptyMap = new _UnmodifiableMapView({}); |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
325 } | 325 } |
326 } | 326 } |
327 if (!found) { | 327 if (!found) { |
328 throw new ArgumentError( | 328 throw new ArgumentError( |
329 "${MirrorSystem.getName(type.simpleName)} has no instance method " | 329 "${MirrorSystem.getName(type.simpleName)} has no instance method " |
330 "${MirrorSystem.getName(selector)}"); | 330 "${MirrorSystem.getName(selector)}"); |
331 } | 331 } |
332 return new _InvocationTrampoline(this, selector); | 332 return new _InvocationTrampoline(this, selector); |
333 } | 333 } |
334 | 334 |
335 // TODO(16539): Make these weak or soft. | |
336 static var _getFieldClosures = new HashMap(); | |
337 static var _setFieldClosures = new HashMap(); | |
338 static var _getFieldCallCounts = new HashMap(); | |
339 static var _setFieldCallCounts = new HashMap(); | |
340 | |
341 _getFieldSlow(unwrapped) { | |
342 // Slow path factored out to give the fast path a better chance at being | |
343 // inlined. | |
344 var callCount = _getFieldCallCounts[unwrapped]; | |
345 if (callCount == null) { | |
346 callCount = 0; | |
347 } | |
348 if (callCount == 20) { | |
Ivan Posva
2014/02/05 22:23:44
How about naming this arbitrary constant and pulli
rmacnak
2014/02/05 22:56:31
Done.
| |
349 // We've seen a success getter invocation a few times: time to invest in a | |
350 // closure. | |
351 var f; | |
352 var atPosition = unwrapped.indexOf('@'); | |
353 if (atPosition == -1) { | |
354 // Public symbol. | |
355 f = _eval('(x) => x.$unwrapped', null); | |
356 } else { | |
357 // Private symbol. | |
358 var withoutKey = unwrapped.substring(0, atPosition); | |
359 var privateKey = unwrapped.substring(atPosition); | |
360 f = _eval('(x) => x.$withoutKey', privateKey); | |
361 } | |
362 _getFieldClosures[unwrapped] = f; | |
363 _getFieldCallCounts.remove(unwrapped); // We won't look for this again. | |
364 return reflect(f(_reflectee)); | |
365 } | |
366 var result = reflect(_invokeGetter(_reflectee, unwrapped)); | |
367 // Only update call count if we don't throw to avoid creating closures for | |
368 // non-existent getters. | |
369 _getFieldCallCounts[unwrapped] = callCount + 1; | |
370 return result; | |
371 } | |
372 | |
373 InstanceMirror getField(Symbol memberName) { | |
374 var unwrapped = _n(memberName); | |
375 var f = _getFieldClosures[unwrapped]; | |
376 return (f == null) | |
Ivan Posva
2014/02/05 22:23:44
return (f == null) ?
_getFieldSlow(unwrapped
rmacnak
2014/02/05 22:56:31
Done.
| |
377 ? _getFieldSlow(unwrapped) | |
378 : reflect(f(_reflectee)); | |
379 } | |
380 | |
381 _setFieldSlow(unwrapped, arg) { | |
382 // Slow path factored out to give the fast path a better chance at being | |
383 // inlined. | |
384 var callCount = _setFieldCallCounts[unwrapped]; | |
385 if (callCount == null) { | |
386 callCount = 0; | |
387 } | |
388 if (callCount == 20) { | |
389 // We've seen a success getter invocation a few times: time to invest in a | |
390 // closure. | |
391 var f; | |
392 var atPosition = unwrapped.indexOf('@'); | |
393 if (atPosition == -1) { | |
394 // Public symbol. | |
395 f = _eval('(x, v) => x.$unwrapped = v', null); | |
396 } else { | |
397 // Private symbol. | |
398 var withoutKey = unwrapped.substring(0, atPosition); | |
399 var privateKey = unwrapped.substring(atPosition); | |
400 f = _eval('(x, v) => x.$withoutKey = v', privateKey); | |
401 } | |
402 _setFieldClosures[unwrapped] = f; | |
403 _setFieldCallCounts.remove(unwrapped); | |
404 return reflect(f(_reflectee, arg)); | |
405 } | |
406 _invokeSetter(_reflectee, unwrapped, arg); | |
407 var result = reflect(arg); | |
408 // Only update call count if we don't throw to avoid creating closures for | |
409 // non-existent setters. | |
410 _setFieldCallCounts[unwrapped] = callCount + 1; | |
411 return result; | |
412 } | |
413 | |
414 InstanceMirror setField(Symbol memberName, arg) { | |
415 var unwrapped = _n(memberName); | |
416 var f = _setFieldClosures[unwrapped]; | |
417 return (f == null) | |
418 ? _setFieldSlow(unwrapped, arg) | |
419 : reflect(f(_reflectee, arg)); | |
420 } | |
421 | |
422 static _eval(expression, privateKey) | |
423 native "Mirrors_evalInLibraryWithPrivateKey"; | |
424 | |
335 // Override to include the receiver in the arguments. | 425 // Override to include the receiver in the arguments. |
336 InstanceMirror invoke(Symbol memberName, | 426 InstanceMirror invoke(Symbol memberName, |
337 List positionalArguments, | 427 List positionalArguments, |
338 [Map<Symbol, dynamic> namedArguments]) { | 428 [Map<Symbol, dynamic> namedArguments]) { |
339 int numPositionalArguments = positionalArguments.length + 1; // Receiver. | 429 int numPositionalArguments = positionalArguments.length + 1; // Receiver. |
340 int numNamedArguments = namedArguments != null ? namedArguments.length : 0; | 430 int numNamedArguments = namedArguments != null ? namedArguments.length : 0; |
341 int numArguments = numPositionalArguments + numNamedArguments; | 431 int numArguments = numPositionalArguments + numNamedArguments; |
342 List arguments = new List(numArguments); | 432 List arguments = new List(numArguments); |
343 arguments[0] = _reflectee; // Receiver. | 433 arguments[0] = _reflectee; // Receiver. |
344 arguments.setRange(1, numPositionalArguments, positionalArguments); | 434 arguments.setRange(1, numPositionalArguments, positionalArguments); |
(...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1492 if (typeMirror == null) { | 1582 if (typeMirror == null) { |
1493 typeMirror = makeLocalTypeMirror(key); | 1583 typeMirror = makeLocalTypeMirror(key); |
1494 _instanitationCache[key] = typeMirror; | 1584 _instanitationCache[key] = typeMirror; |
1495 if (typeMirror is ClassMirror && !typeMirror._isGeneric) { | 1585 if (typeMirror is ClassMirror && !typeMirror._isGeneric) { |
1496 _declarationCache[key] = typeMirror; | 1586 _declarationCache[key] = typeMirror; |
1497 } | 1587 } |
1498 } | 1588 } |
1499 return typeMirror; | 1589 return typeMirror; |
1500 } | 1590 } |
1501 } | 1591 } |
OLD | NEW |