| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 /// This library defines runtime operations on objects used by the code | 5 /// This library defines runtime operations on objects used by the code |
| 6 /// generator. | 6 /// generator. |
| 7 part of dart._runtime; | 7 part of dart._runtime; |
| 8 | 8 |
| 9 _canonicalFieldName(obj, name, args, displayName) => JS('', '''(() => { | 9 _canonicalFieldName(obj, name, args, displayName) => JS('', '''(() => { |
| 10 $name = $canonicalMember($obj, $name); | 10 $name = $canonicalMember($obj, $name); |
| 11 if ($name) return $name; | 11 if ($name) return $name; |
| 12 // TODO(jmesserly): in the future we might have types that "overlay" Dart | 12 // TODO(jmesserly): in the future we might have types that "overlay" Dart |
| 13 // methods while also exposing the full native API, e.g. dart:html vs | 13 // methods while also exposing the full native API, e.g. dart:html vs |
| 14 // dart:dom. To support that we'd need to fall back to the normal name | 14 // dart:dom. To support that we'd need to fall back to the normal name |
| 15 // if an extension method wasn't found. | 15 // if an extension method wasn't found. |
| 16 $throwNoSuchMethodFunc($obj, $displayName, $args); | 16 $throwNoSuchMethodFunc($obj, $displayName, $args); |
| 17 })()'''); | 17 })()'''); |
| 18 | 18 |
| 19 dload(obj, field) => JS('', '''(() => { | 19 dload(obj, field) => JS('', '''(() => { |
| 20 $field = $_canonicalFieldName($obj, $field, [], $field); | 20 $field = $_canonicalFieldName($obj, $field, [], $field); |
| 21 $_trackCall(obj, $field); |
| 21 if ($hasMethod($obj, $field)) { | 22 if ($hasMethod($obj, $field)) { |
| 22 return $bind($obj, $field); | 23 return $bind($obj, $field); |
| 23 } | 24 } |
| 24 // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain | 25 // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain |
| 25 // types. hasOwnProperty doesn't chase the proto chain. | 26 // types. hasOwnProperty doesn't chase the proto chain. |
| 26 // Also, do we want an NSM on regular JS objects? | 27 // Also, do we want an NSM on regular JS objects? |
| 27 // See: https://github.com/dart-lang/dev_compiler/issues/169 | 28 // See: https://github.com/dart-lang/dev_compiler/issues/169 |
| 28 let result = $obj[$field]; | 29 let result = $obj[$field]; |
| 29 return result; | 30 return result; |
| 30 })()'''); | 31 })()'''); |
| 31 | 32 |
| 32 dput(obj, field, value) => JS('', '''(() => { | 33 dput(obj, field, value) => JS('', '''(() => { |
| 33 $field = $_canonicalFieldName($obj, $field, [$value], $field); | 34 $field = $_canonicalFieldName($obj, $field, [$value], $field); |
| 35 $_trackCall(obj, $field); |
| 36 |
| 34 // TODO(vsm): Implement NSM and type checks. | 37 // TODO(vsm): Implement NSM and type checks. |
| 35 // See: https://github.com/dart-lang/dev_compiler/issues/170 | 38 // See: https://github.com/dart-lang/dev_compiler/issues/170 |
| 36 $obj[$field] = $value; | 39 $obj[$field] = $value; |
| 37 return $value; | 40 return $value; |
| 38 })()'''); | 41 })()'''); |
| 39 | 42 |
| 40 /// Check that a function of a given type can be applied to | 43 /// Check that a function of a given type can be applied to |
| 41 /// actuals. | 44 /// actuals. |
| 42 _checkApply(type, actuals) => JS('', '''(() => { | 45 _checkApply(type, actuals) => JS('', '''(() => { |
| 43 if ($actuals.length < $type.args.length) return false; | 46 if ($actuals.length < $type.args.length) return false; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 throwNoSuchMethod(obj, name, pArgs, nArgs, extras) => JS('', '''(() => { | 84 throwNoSuchMethod(obj, name, pArgs, nArgs, extras) => JS('', '''(() => { |
| 82 $throw_(new $NoSuchMethodError($obj, $_dartSymbol($name), $pArgs, $nArgs, $ext
ras)); | 85 $throw_(new $NoSuchMethodError($obj, $_dartSymbol($name), $pArgs, $nArgs, $ext
ras)); |
| 83 })()'''); | 86 })()'''); |
| 84 | 87 |
| 85 throwNoSuchMethodFunc(obj, name, pArgs, opt_func) => JS('', '''(() => { | 88 throwNoSuchMethodFunc(obj, name, pArgs, opt_func) => JS('', '''(() => { |
| 86 if ($obj === void 0) $obj = $opt_func; | 89 if ($obj === void 0) $obj = $opt_func; |
| 87 $throwNoSuchMethod($obj, $name, $pArgs); | 90 $throwNoSuchMethod($obj, $name, $pArgs); |
| 88 })()'''); | 91 })()'''); |
| 89 | 92 |
| 90 _checkAndCall(f, ftype, obj, typeArgs, args, name) => JS('', '''(() => { | 93 _checkAndCall(f, ftype, obj, typeArgs, args, name) => JS('', '''(() => { |
| 94 $_trackCall(obj, name); |
| 95 |
| 91 let originalFunction = $f; | 96 let originalFunction = $f; |
| 92 if (!($f instanceof Function)) { | 97 if (!($f instanceof Function)) { |
| 93 // We're not a function (and hence not a method either) | 98 // We're not a function (and hence not a method either) |
| 94 // Grab the `call` method if it's not a function. | 99 // Grab the `call` method if it's not a function. |
| 95 if ($f != null) { | 100 if ($f != null) { |
| 96 $ftype = $getMethodType($f, 'call'); | 101 $ftype = $getMethodType($f, 'call'); |
| 97 $f = $f.call; | 102 $f = $f.call; |
| 98 } | 103 } |
| 99 if (!($f instanceof Function)) { | 104 if (!($f instanceof Function)) { |
| 100 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); | 105 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); | 155 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); |
| 151 })()'''); | 156 })()'''); |
| 152 | 157 |
| 153 dcall(f, @rest args) => _checkAndCall( | 158 dcall(f, @rest args) => _checkAndCall( |
| 154 f, _getRuntimeType(f), JS('', 'void 0'), null, args, 'call'); | 159 f, _getRuntimeType(f), JS('', 'void 0'), null, args, 'call'); |
| 155 | 160 |
| 156 | 161 |
| 157 dgcall(f, typeArgs, @rest args) => _checkAndCall( | 162 dgcall(f, typeArgs, @rest args) => _checkAndCall( |
| 158 f, _getRuntimeType(f), JS('', 'void 0'), typeArgs, args, 'call'); | 163 f, _getRuntimeType(f), JS('', 'void 0'), typeArgs, args, 'call'); |
| 159 | 164 |
| 165 Map<String, int> _callMethodStats = new Map(); |
| 166 |
| 167 class ProfileEntry { |
| 168 final String key; |
| 169 final num count; |
| 170 |
| 171 ProfileEntry(this.key, this.count); |
| 172 } |
| 173 |
| 174 List<ProfileEntry> getDynamicStats() { |
| 175 List<ProfileEntry> ret = new List(); |
| 176 |
| 177 var keys = _callMethodStats.keys.toList(); |
| 178 |
| 179 keys.sort((a, b) => _callMethodStats[b].compareTo(_callMethodStats[a])); |
| 180 for (var key in keys) { |
| 181 int count = _callMethodStats[key]; |
| 182 ret.add(new ProfileEntry(key, count)); |
| 183 } |
| 184 |
| 185 return ret; |
| 186 } |
| 187 |
| 188 clearDynamicStats() { |
| 189 _callMethodStats.clear(); |
| 190 } |
| 191 |
| 192 _trackCall(obj, name) { |
| 193 if(JS('bool', '!window.trackDdcProfile')) return; |
| 194 |
| 195 var actual = getReifiedType(obj); |
| 196 String stackStr = JS('String', "new Error().stack"); |
| 197 var stack = stackStr.split('\n at '); |
| 198 var src = ''; |
| 199 for (int i = 2; i < stack.length; ++i) { |
| 200 var frame = stack[i]; |
| 201 if (!frame.contains('dev_compiler/lib/runtime/dart_sdk.js')) { |
| 202 src = frame; |
| 203 break; |
| 204 } |
| 205 } |
| 206 |
| 207 name = "${typeName(actual)}.$name <$src>"; |
| 208 if (_callMethodStats.containsKey(name)) { |
| 209 _callMethodStats[name] = _callMethodStats[name] + 1; |
| 210 } else { |
| 211 _callMethodStats[name] = 1; |
| 212 } |
| 213 } |
| 160 | 214 |
| 161 /// Shared code for dsend, dindex, and dsetindex. | 215 /// Shared code for dsend, dindex, and dsetindex. |
| 162 _callMethod(obj, name, typeArgs, args, displayName) { | 216 _callMethod(obj, name, typeArgs, args, displayName) { |
| 163 var symbol = _canonicalFieldName(obj, name, args, displayName); | 217 var symbol = _canonicalFieldName(obj, name, args, displayName); |
| 164 var f = obj != null ? JS('', '#[#]', obj, symbol) : null; | 218 var f = obj != null ? JS('', '#[#]', obj, symbol) : null; |
| 165 var ftype = getMethodType(obj, symbol); | 219 var ftype = getMethodType(obj, symbol); |
| 166 return _checkAndCall(f, ftype, obj, typeArgs, args, displayName); | 220 return _checkAndCall(f, ftype, obj, typeArgs, args, displayName); |
| 167 } | 221 } |
| 168 | 222 |
| 169 dsend(obj, method, @rest args) => _callMethod(obj, method, null, args, method); | 223 dsend(obj, method, @rest args) => _callMethod(obj, method, null, args, method); |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 constructor(dartIterator) { | 641 constructor(dartIterator) { |
| 588 this.dartIterator = dartIterator; | 642 this.dartIterator = dartIterator; |
| 589 } | 643 } |
| 590 next() { | 644 next() { |
| 591 let i = this.dartIterator; | 645 let i = this.dartIterator; |
| 592 let done = !i.moveNext(); | 646 let done = !i.moveNext(); |
| 593 return { done: done, value: done ? void 0 : i.current }; | 647 return { done: done, value: done ? void 0 : i.current }; |
| 594 } | 648 } |
| 595 } | 649 } |
| 596 '''); | 650 '''); |
| OLD | NEW |