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

Side by Side Diff: sdk/lib/_internal/compiler/js_lib/js_names.dart

Issue 974803002: Defer addStubs to class instantiation time. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Ensure fast prototypes and avoid polymorphic access in constructor Created 5 years, 9 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dart._js_names; 5 library dart._js_names;
6 6
7 import 'dart:_js_embedded_names' show 7 import 'dart:_js_embedded_names' show
8 MANGLED_GLOBAL_NAMES, 8 MANGLED_GLOBAL_NAMES,
9 MANGLED_NAMES; 9 MANGLED_NAMES;
10 10
11 import 'dart:_foreign_helper' show 11 import 'dart:_foreign_helper' show
12 JS, 12 JS,
13 JS_EMBEDDED_GLOBAL, 13 JS_EMBEDDED_GLOBAL,
14 JS_GET_NAME; 14 JS_GET_NAME;
15 15
16 import 'dart:_js_helper' show 16 import 'dart:_js_helper' show
17 JsCache, 17 JsCache,
18 NoInline; 18 NoInline;
19 19
20 import 'dart:_interceptors' show JSArray; 20 import 'dart:_interceptors' show JSArray;
21 21
22 /// No-op method that is called to inform the compiler that unmangled named 22 /// No-op method that is called to inform the compiler that unmangled named
23 /// must be preserved. 23 /// must be preserved.
24 preserveNames() {} 24 preserveNames() {}
25 25
26 /// A map from mangled names to "reflective" names, that is, unmangled names 26 /// A map from mangled names to "reflective" names, that is, unmangled names
27 /// with some additional information, such as, number of required arguments. 27 /// with some additional information, such as, number of required arguments.
28 /// This map is for mangled names used as instance members. 28 /// This map is for mangled names used as instance members.
29 final Map<String, String> mangledNames = 29 final _LazyMangledNamesMap mangledNames = new _LazyMangledInstanceNamesMap(
30 computeMangledNames( 30 JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES));
31 JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES),
32 false);
33 31
34 /// A map from "reflective" names to mangled names (the reverse of 32 /// A map from "reflective" names to mangled names (the reverse of
35 /// [mangledNames]). 33 /// [mangledNames]).
36 final Map<String, String> reflectiveNames = 34 final _LazyReflectiveNamesMap reflectiveNames =
37 computeReflectiveNames(mangledNames); 35 new _LazyReflectiveNamesMap(JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES),
36 true);
38 37
39 /// A map from mangled names to "reflective" names (see [mangledNames]). This 38 /// A map from mangled names to "reflective" names (see [mangledNames]). This
40 /// map is for globals, that is, static and top-level members. 39 /// map is for globals, that is, static and top-level members.
41 final Map<String, String> mangledGlobalNames = computeMangledNames( 40 final _LazyMangledNamesMap mangledGlobalNames = new _LazyMangledNamesMap(
42 JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES), 41 JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES));
43 true);
44 42
45 /// A map from "reflective" names to mangled names (the reverse of 43 /// A map from "reflective" names to mangled names (the reverse of
46 /// [mangledGlobalNames]). 44 /// [mangledGlobalNames]).
47 final Map<String, String> reflectiveGlobalNames = 45 final _LazyReflectiveNamesMap reflectiveGlobalNames =
48 computeReflectiveNames(mangledGlobalNames); 46 new _LazyReflectiveNamesMap(
47 JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES), false);
49 48
50 /// [jsMangledNames] is a JavaScript object literal. The keys are the mangled 49 /// [jsMangledNames] is a JavaScript object literal. The keys are the mangled
51 /// names, and the values are the "reflective" names. 50 /// names, and the values are the "reflective" names.
52 Map<String, String> computeMangledNames(jsMangledNames, bool isGlobal) { 51 class _LazyMangledNamesMap {
53 preserveNames(); 52 var _jsMangledNames;
54 var keys = extractKeys(jsMangledNames); 53
55 var result = <String, String>{}; 54 _LazyMangledNamesMap(this._jsMangledNames);
56 String getterPrefix = JS_GET_NAME('GETTER_PREFIX'); 55
57 int getterPrefixLength = getterPrefix.length; 56 String operator[](String key) {
58 String setterPrefix = JS_GET_NAME('SETTER_PREFIX'); 57 String result = JS('var', '#[#]', _jsMangledNames, key);
59 for (String key in keys) { 58 // Filter out all non-string values to protect against polution from
60 String value = JS('String', '#[#]', jsMangledNames, key); 59 // anciliary fields in [_jsMangledNames].
61 result[key] = value; 60 bool filter =
62 if (!isGlobal) { 61 JS('bool', '# == null || typeof # !== "string"', result, result);
sra1 2015/03/05 18:23:25 typeof is sufficient
herhut 2015/03/06 12:36:45 True, thanks!
63 if (key.startsWith(getterPrefix)) { 62 return filter ? null : result;
64 result['$setterPrefix${key.substring(getterPrefixLength)}'] = '$value='; 63 }
64 }
65
66 class _LazyMangledInstanceNamesMap extends _LazyMangledNamesMap {
67 _LazyMangledInstanceNamesMap(_jsMangledNames) : super(_jsMangledNames);
68
69 String operator[](String key) {
70 var result = super[key];
floitsch 2015/03/06 14:54:10 Use type.
herhut 2015/03/09 14:28:35 Done.
71 String setterPrefix = JS_GET_NAME('SETTER_PREFIX');
72 if (result == null && key.startsWith(setterPrefix)) {
floitsch 2015/03/06 14:54:10 Isn't this handled by the "_updateReflectiveNames
herhut 2015/03/09 14:28:35 _updateReflectiveNames is the inverse mapping. Thi
floitsch 2015/03/09 16:35:06 Explain in a comment.
73 String getterPrefix = JS_GET_NAME('GETTER_PREFIX');
74 int setterPrefixLength = getterPrefix.length;
floitsch 2015/03/09 16:35:06 getterPrefixLength
75
76 // Generate the setter name from the getter name.
77 key = '$getterPrefix${key.substring(setterPrefixLength)}';
78 result = super[key];
79 return (result != null) ? "${result}=" : null;
floitsch 2015/03/06 14:54:10 You don't need the curly braces.
herhut 2015/03/09 14:28:35 I actually find this easier to read. Unless you re
80 }
81 return result;
82 }
83 }
84
85 class _LazyReflectiveNamesMap {
86 final _jsMangledNames;
87 final bool _isInstance;
88 var _cacheLength = 0;
floitsch 2015/03/06 14:54:10 types.
herhut 2015/03/09 14:28:35 Done.
89 var _cache;
90
91 _LazyReflectiveNamesMap(this._jsMangledNames, this._isInstance);
92
93 Map<String, String> _updateReflectiveNames() {
94 preserveNames();
95 var result = <String, String>{};
floitsch 2015/03/06 14:54:10 Use types.
herhut 2015/03/09 14:28:35 Done.
96 var keys = JS('List', 'Object.keys(#)', _jsMangledNames);
97 for (String key in keys) {
98 var reflectiveName = JS('var', '#[#]', _jsMangledNames, key);
99 // Filter out all non-string values to protect against polution from
100 // anciliary fields in [_jsMangledNames].
101 bool filter = JS('bool', '# == null || typeof # !== "string"',
102 reflectiveName, reflectiveName);
103 if (filter) continue;
104 result[reflectiveName] = key;
105
106 String getterPrefix = JS_GET_NAME('GETTER_PREFIX');
107 if (_isInstance && key.startsWith(getterPrefix)) {
108 int getterPrefixLength = getterPrefix.length;
109 String setterPrefix = JS_GET_NAME('SETTER_PREFIX');
110 result['$reflectiveName='] =
111 '$setterPrefix${key.substring(getterPrefixLength)}';
65 } 112 }
66 } 113 }
114 return result;
67 } 115 }
68 return result;
69 }
70 116
71 Map<String, String> computeReflectiveNames(Map<String, String> map) { 117 int get _jsMangledNamesLength => JS('int', '#.length', _jsMangledNames);
72 preserveNames(); 118
73 var result = <String, String>{}; 119 String operator[](String key) {
74 map.forEach((String mangledName, String reflectiveName) { 120 if (_cache == null || _jsMangledNamesLength != _cacheLength) {
75 result[reflectiveName] = mangledName; 121 _cache = _updateReflectiveNames();
76 }); 122 _cacheLength = _jsMangledNamesLength;
77 return result; 123 }
124 return _cache[key];
125 }
78 } 126 }
79 127
80 @NoInline() 128 @NoInline()
81 List extractKeys(victim) { 129 List extractKeys(victim) {
82 var result = JS('', '# ? Object.keys(#) : []', victim, victim); 130 var result = JS('', '# ? Object.keys(#) : []', victim, victim);
83 return new JSArray.markFixed(result); 131 return new JSArray.markFixed(result);
84 } 132 }
85 133
86 /** 134 /**
87 * Returns the (global) unmangled version of [name]. 135 * Returns the (global) unmangled version of [name].
(...skipping 11 matching lines...) Expand all
99 return JsCache.fetch(names, name); 147 return JsCache.fetch(names, name);
100 } 148 }
101 149
102 String unmangleAllIdentifiersIfPreservedAnyways(String str) { 150 String unmangleAllIdentifiersIfPreservedAnyways(String str) {
103 return JS("String", 151 return JS("String",
104 r"(#).replace(/[^<,> ]+/g," 152 r"(#).replace(/[^<,> ]+/g,"
105 r"function(m) { return #[m] || m; })", 153 r"function(m) { return #[m] || m; })",
106 str, 154 str,
107 JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES)); 155 JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES));
108 } 156 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698