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 |