mirror of
https://github.com/dart-lang/sdk
synced 2024-09-22 03:28:40 +00:00
dart2js: use Es6 maps when available.
R=herhut@google.com Review URL: https://codereview.chromium.org//1032783003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@45105 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
1e264887c4
commit
dbc6ae91ab
|
@ -245,6 +245,9 @@ class Namer {
|
|||
// next-generation plugin, this results in starting a new Java process.
|
||||
"java", "Packages", "netscape", "sun", "JavaObject", "JavaClass",
|
||||
"JavaArray", "JavaMember",
|
||||
|
||||
// ES6 collections.
|
||||
"Map",
|
||||
];
|
||||
|
||||
static const List<String> reservedGlobalObjectNames = const <String>[
|
||||
|
|
|
@ -386,6 +386,7 @@ class _CustomHashMap<K, V> extends _HashMap<K, V> {
|
|||
final _Equality<K> _equals;
|
||||
final _Hasher<K> _hashCode;
|
||||
final _Predicate _validKey;
|
||||
|
||||
_CustomHashMap(this._equals, this._hashCode, bool validKey(potentialKey))
|
||||
: _validKey = (validKey != null) ? validKey : ((v) => v is K);
|
||||
|
||||
|
@ -492,7 +493,7 @@ class LinkedHashMap<K, V> {
|
|||
if (isValidKey == null) {
|
||||
if (hashCode == null) {
|
||||
if (equals == null) {
|
||||
return new JsLinkedHashMap<K, V>();
|
||||
return new JsLinkedHashMap<K, V>.es6();
|
||||
}
|
||||
hashCode = _defaultHashCode;
|
||||
} else {
|
||||
|
@ -521,16 +522,17 @@ class LinkedHashMap<K, V> {
|
|||
// Private factory constructor called by generated code for map literals.
|
||||
@NoInline()
|
||||
factory LinkedHashMap._literal(List keyValuePairs) {
|
||||
return fillLiteralMap(keyValuePairs, new JsLinkedHashMap<K, V>());
|
||||
return fillLiteralMap(keyValuePairs, new JsLinkedHashMap<K, V>.es6());
|
||||
}
|
||||
|
||||
// Private factory constructor called by generated code for map literals.
|
||||
@NoThrows() @NoInline()
|
||||
factory LinkedHashMap._empty() {
|
||||
return new JsLinkedHashMap<K, V>();
|
||||
return new JsLinkedHashMap<K, V>.es6();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(floitsch): use ES6 Maps when available.
|
||||
class _LinkedIdentityHashMap<K, V> extends JsLinkedHashMap<K, V> {
|
||||
int internalComputeHashCode(var key) {
|
||||
// We force the hash codes to be unsigned 30-bit integers to avoid
|
||||
|
@ -550,10 +552,12 @@ class _LinkedIdentityHashMap<K, V> extends JsLinkedHashMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO(floitsch): use ES6 maps when available.
|
||||
class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> {
|
||||
final _Equality<K> _equals;
|
||||
final _Hasher<K> _hashCode;
|
||||
final _Predicate _validKey;
|
||||
|
||||
_LinkedCustomHashMap(this._equals, this._hashCode,
|
||||
bool validKey(potentialKey))
|
||||
: _validKey = (validKey != null) ? validKey : ((v) => v is K);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
part of _js_helper;
|
||||
|
||||
const _USE_ES6_MAPS = const bool.fromEnvironment("dart2js.use.es6.maps");
|
||||
|
||||
class JsLinkedHashMap<K, V> implements LinkedHashMap<K, V>, InternalMap {
|
||||
int _length = 0;
|
||||
|
||||
|
@ -32,8 +34,21 @@ class JsLinkedHashMap<K, V> implements LinkedHashMap<K, V>, InternalMap {
|
|||
// iterated over.
|
||||
int _modifications = 0;
|
||||
|
||||
static bool get _supportsEs6Maps {
|
||||
return JS('returns:bool;depends:none;effects:none;',
|
||||
'typeof Map != "undefined"');
|
||||
}
|
||||
|
||||
JsLinkedHashMap();
|
||||
|
||||
/// If ES6 Maps are available returns a linked hash-map backed by an ES6 Map.
|
||||
factory JsLinkedHashMap.es6() {
|
||||
if (_USE_ES6_MAPS && JsLinkedHashMap._supportsEs6Maps) {
|
||||
return new Es6LinkedHashMap<K, V>();
|
||||
} else {
|
||||
return new JsLinkedHashMap<K, V>();
|
||||
}
|
||||
}
|
||||
|
||||
int get length => _length;
|
||||
bool get isEmpty => _length == 0;
|
||||
|
@ -51,13 +66,11 @@ class JsLinkedHashMap<K, V> implements LinkedHashMap<K, V>, InternalMap {
|
|||
if (_isStringKey(key)) {
|
||||
var strings = _strings;
|
||||
if (strings == null) return false;
|
||||
LinkedHashMapCell cell = _getTableEntry(strings, key);
|
||||
return cell != null;
|
||||
return _containsTableEntry(strings, key);
|
||||
} else if (_isNumericKey(key)) {
|
||||
var nums = _nums;
|
||||
if (nums == null) return false;
|
||||
LinkedHashMapCell cell = _getTableEntry(nums, key);
|
||||
return cell != null;
|
||||
return _containsTableEntry(nums, key);
|
||||
} else {
|
||||
return internalContainsKey(key);
|
||||
}
|
||||
|
@ -124,7 +137,7 @@ class JsLinkedHashMap<K, V> implements LinkedHashMap<K, V>, InternalMap {
|
|||
var rest = _rest;
|
||||
if (rest == null) _rest = rest = _newHashTable();
|
||||
var hash = internalComputeHashCode(key);
|
||||
var bucket = JS('var', '#[#]', rest, hash);
|
||||
var bucket = _getTableEntry(rest, hash);
|
||||
if (bucket == null) {
|
||||
LinkedHashMapCell cell = _newLinkedCell(key, value);
|
||||
_setTableEntry(rest, hash, JS('var', '[#]', cell));
|
||||
|
@ -253,7 +266,7 @@ class JsLinkedHashMap<K, V> implements LinkedHashMap<K, V>, InternalMap {
|
|||
}
|
||||
|
||||
static bool _isStringKey(var key) {
|
||||
return key is String && key != '__proto__';
|
||||
return key is String;
|
||||
}
|
||||
|
||||
static bool _isNumericKey(var key) {
|
||||
|
@ -270,22 +283,9 @@ class JsLinkedHashMap<K, V> implements LinkedHashMap<K, V>, InternalMap {
|
|||
return JS('int', '# & 0x3ffffff', key.hashCode);
|
||||
}
|
||||
|
||||
static _getTableEntry(var table, var key) {
|
||||
return JS('var', '#[#]', table, key);
|
||||
}
|
||||
|
||||
static void _setTableEntry(var table, var key, var value) {
|
||||
assert(value != null);
|
||||
JS('void', '#[#] = #', table, key, value);
|
||||
}
|
||||
|
||||
static void _deleteTableEntry(var table, var key) {
|
||||
JS('void', 'delete #[#]', table, key);
|
||||
}
|
||||
|
||||
List _getBucket(var table, var key) {
|
||||
var hash = internalComputeHashCode(key);
|
||||
return JS('var', '#[#]', table, hash);
|
||||
return _getTableEntry(table, hash);
|
||||
}
|
||||
|
||||
int internalFindBucketIndex(var bucket, var key) {
|
||||
|
@ -298,7 +298,27 @@ class JsLinkedHashMap<K, V> implements LinkedHashMap<K, V>, InternalMap {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static _newHashTable() {
|
||||
String toString() => Maps.mapToString(this);
|
||||
|
||||
_getTableEntry(var table, var key) {
|
||||
return JS('var', '#[#]', table, key);
|
||||
}
|
||||
|
||||
void _setTableEntry(var table, var key, var value) {
|
||||
assert(value != null);
|
||||
JS('void', '#[#] = #', table, key, value);
|
||||
}
|
||||
|
||||
void _deleteTableEntry(var table, var key) {
|
||||
JS('void', 'delete #[#]', table, key);
|
||||
}
|
||||
|
||||
bool _containsTableEntry(var table, var key) {
|
||||
LinkedHashMapCell cell = _getTableEntry(table, key);
|
||||
return cell != null;
|
||||
}
|
||||
|
||||
_newHashTable() {
|
||||
// Create a new JavaScript object to be used as a hash table. Use
|
||||
// Object.create to avoid the properties on Object.prototype
|
||||
// showing up as entries.
|
||||
|
@ -310,8 +330,34 @@ class JsLinkedHashMap<K, V> implements LinkedHashMap<K, V>, InternalMap {
|
|||
_deleteTableEntry(table, temporaryKey);
|
||||
return table;
|
||||
}
|
||||
}
|
||||
|
||||
String toString() => Maps.mapToString(this);
|
||||
class Es6LinkedHashMap<K, V> extends JsLinkedHashMap<K, V> {
|
||||
|
||||
@override
|
||||
_getTableEntry(var table, var key) {
|
||||
return JS('var', '#.get(#)', table, key);
|
||||
}
|
||||
|
||||
@override
|
||||
void _setTableEntry(var table, var key, var value) {
|
||||
JS('void', '#.set(#, #)', table, key, value);
|
||||
}
|
||||
|
||||
@override
|
||||
void _deleteTableEntry(var table, var key) {
|
||||
JS('void', '#.delete(#)', table, key);
|
||||
}
|
||||
|
||||
@override
|
||||
bool _containsTableEntry(var table, var key) {
|
||||
return JS('bool', '#.has(#)', table, key);
|
||||
}
|
||||
|
||||
@override
|
||||
_newHashTable() {
|
||||
return JS('var', 'new Map()');
|
||||
}
|
||||
}
|
||||
|
||||
class LinkedHashMapCell {
|
||||
|
|
Loading…
Reference in a new issue