| 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 the association between runtime objects and | 5 /// This library defines the association between runtime objects and |
| 6 /// runtime types. | 6 /// runtime types. |
| 7 part of dart._runtime; | 7 part of dart._runtime; |
| 8 | 8 |
| 9 /// | 9 /// |
| 10 /// Runtime type information. This module defines the mapping from | 10 /// Runtime type information. This module defines the mapping from |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 /// constructor field. | 30 /// constructor field. |
| 31 /// | 31 /// |
| 32 /// - Types objects, which are represented as described in the types | 32 /// - Types objects, which are represented as described in the types |
| 33 /// module. Types always have a _runtimeType property attached to | 33 /// module. Types always have a _runtimeType property attached to |
| 34 /// them with the appropriate rtti. The rtti for these is always | 34 /// them with the appropriate rtti. The rtti for these is always |
| 35 /// core.Type. TODO(leafp): consider the possibility that we can | 35 /// core.Type. TODO(leafp): consider the possibility that we can |
| 36 /// reliably recognize type objects and map directly to core.Type | 36 /// reliably recognize type objects and map directly to core.Type |
| 37 /// rather than attaching this property everywhere. | 37 /// rather than attaching this property everywhere. |
| 38 /// | 38 /// |
| 39 /// | 39 /// |
| 40 | 40 /// Tag a closure with a type, using one of two forms: |
| 41 /// | 41 /// |
| 42 ///Tag a closure with a type, using one of three forms: | 42 /// `dart.fn(cls)` marks cls has having no optional or named |
| 43 /// dart.fn(cls) marks cls has having no optional or named | 43 /// parameters, with all argument and return types as dynamic. |
| 44 /// parameters, with all argument and return types as dynamic | 44 /// |
| 45 /// dart.fn(cls, func) marks cls with the lazily computed | 45 /// `dart.fn(cls, rType, argsT, extras)` marks cls as having the |
| 46 /// runtime type as computed by func() | 46 /// runtime type dart.functionType(rType, argsT, extras). |
| 47 /// dart.fn(cls, rType, argsT, extras) marks cls as having the | |
| 48 /// runtime type dart.functionType(rType, argsT, extras) | |
| 49 /// | 47 /// |
| 50 /// Note that since we are producing a type for a concrete function, | 48 /// Note that since we are producing a type for a concrete function, |
| 51 /// it is sound to use the definite arrow type. | 49 /// it is sound to use the definite arrow type. |
| 52 /// | 50 /// |
| 53 fn(closure, @rest args) => JS('', '''(() => { | 51 fn(closure, rType, argsT, extras) { |
| 54 // Closure and a lazy type constructor | 52 var t; |
| 55 if ($args.length == 1) { | 53 if (rType == null) { |
| 56 $defineLazyProperty($closure, $_runtimeType, {get : $args[0]}); | |
| 57 return $closure; | |
| 58 } | |
| 59 let t; | |
| 60 if ($args.length == 0) { | |
| 61 // No type arguments, it's all dynamic | 54 // No type arguments, it's all dynamic |
| 62 t = $definiteFunctionType( | 55 t = definiteFunctionType( |
| 63 $dynamicR, Array($closure.length).fill($dynamicR)); | 56 dynamicR, |
| 57 JS('', 'Array(#.length).fill(#)', closure, dynamicR), |
| 58 JS('', 'void 0')); |
| 64 } else { | 59 } else { |
| 65 // We're passed the piecewise components of the function type, | 60 // We're passed the piecewise components of the function type, |
| 66 // construct it. | 61 // construct it. |
| 67 t = $definiteFunctionType.apply(null, $args); | 62 t = definiteFunctionType(rType, argsT, extras); |
| 68 } | 63 } |
| 69 $tag($closure, t); | 64 tag(closure, t); |
| 70 return $closure; | 65 return closure; |
| 71 })()'''); | 66 } |
| 67 |
| 68 lazyFn(closure, computeTypeParts) { |
| 69 tagLazy(closure, JS('', '''() => { |
| 70 let parts = #(); |
| 71 return #(parts[0], parts[1], parts[2]); |
| 72 }''', computeTypeParts, definiteFunctionType)); |
| 73 return closure; |
| 74 } |
| 72 | 75 |
| 73 // TODO(vsm): How should we encode the runtime type? | 76 // TODO(vsm): How should we encode the runtime type? |
| 74 final _runtimeType = JS('', 'Symbol("_runtimeType")'); | 77 final _runtimeType = JS('', 'Symbol("_runtimeType")'); |
| 75 | 78 |
| 76 checkPrimitiveType(obj) => JS('', '''(() => { | 79 checkPrimitiveType(obj) => JS('', '''(() => { |
| 77 switch (typeof $obj) { | 80 switch (typeof $obj) { |
| 78 case "undefined": | 81 case "undefined": |
| 79 return $Null; | 82 return $Null; |
| 80 case "number": | 83 case "number": |
| 81 return Math.floor($obj) == $obj ? $int : $double; | 84 return Math.floor($obj) == $obj ? $int : $double; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 return result; | 148 return result; |
| 146 })()'''); | 149 })()'''); |
| 147 | 150 |
| 148 read(value) => JS('', '#[#]', value, _runtimeType); | 151 read(value) => JS('', '#[#]', value, _runtimeType); |
| 149 | 152 |
| 150 /// Tag the runtime type of [value] to be type [t]. | 153 /// Tag the runtime type of [value] to be type [t]. |
| 151 void tag(value, t) { | 154 void tag(value, t) { |
| 152 JS('', '#[#] = #', value, _runtimeType, t); | 155 JS('', '#[#] = #', value, _runtimeType, t); |
| 153 } | 156 } |
| 154 | 157 |
| 155 tagComputed(value, compute) { | 158 void tagComputed(value, compute) { |
| 156 JS('', '#(#, #, { get: # })', defineProperty, value, _runtimeType, compute); | 159 JS('', '#(#, #, { get: # })', defineProperty, value, _runtimeType, compute); |
| 157 } | 160 } |
| 158 | 161 |
| 159 tagMemoized(value, compute) => JS('', '''(() => { | 162 void tagLazy(value, compute) { |
| 160 let cache = null; | 163 JS('', '#(#, #, { get: # })', |
| 161 function getter() { | 164 defineLazyProperty, value, _runtimeType, compute); |
| 162 if ($compute == null) return cache; | 165 } |
| 163 cache = $compute(); | |
| 164 $compute = null; | |
| 165 return cache; | |
| 166 } | |
| 167 $tagComputed($value, getter); | |
| 168 })()'''); | |
| OLD | NEW |