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

Side by Side Diff: tool/input_sdk/private/ddc_runtime/rtti.dart

Issue 1962823002: fix #552, Object members on native types (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 7 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
OLDNEW
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 /// Runtime type information. This module defines the mapping from 9 /// Runtime type information. This module defines the mapping from
10 /// runtime objects to their runtime type information. See the types 10 /// runtime objects to their runtime type information. See the types
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 /// runtime type dart.functionType(rType, argsT, extras). 53 /// runtime type dart.functionType(rType, argsT, extras).
54 /// 54 ///
55 /// Note that since we are producing a type for a concrete function, 55 /// Note that since we are producing a type for a concrete function,
56 /// it is sound to use the definite arrow type. 56 /// it is sound to use the definite arrow type.
57 /// 57 ///
58 fn(closure, rType, argsT, extras) { 58 fn(closure, rType, argsT, extras) {
59 var t; 59 var t;
60 if (rType == null) { 60 if (rType == null) {
61 // No type arguments, it's all dynamic 61 // No type arguments, it's all dynamic
62 t = definiteFunctionType( 62 t = definiteFunctionType(
63 dynamicR, 63 JS('', '#', dynamic),
64 JS('', 'Array(#.length).fill(#)', closure, dynamicR), 64 JS('', 'Array(#.length).fill(#)', closure, dynamic),
65 JS('', 'void 0')); 65 JS('', 'void 0'));
66 } else { 66 } else {
67 // We're passed the piecewise components of the function type, 67 // We're passed the piecewise components of the function type,
68 // construct it. 68 // construct it.
69 t = definiteFunctionType(rType, argsT, extras); 69 t = definiteFunctionType(rType, argsT, extras);
70 } 70 }
71 tag(closure, t); 71 tag(closure, t);
72 return closure; 72 return closure;
73 } 73 }
74 74
75 lazyFn(closure, computeTypeParts) { 75 lazyFn(closure, computeTypeParts) {
76 tagLazy(closure, JS('', '''() => { 76 tagLazy(closure, JS('', '''() => {
77 let parts = #(); 77 let parts = #();
78 return #(parts[0], parts[1], parts[2]); 78 return #(parts[0], parts[1], parts[2]);
79 }''', computeTypeParts, definiteFunctionType)); 79 }''', computeTypeParts, definiteFunctionType));
80 return closure; 80 return closure;
81 } 81 }
82 82
83 // TODO(vsm): How should we encode the runtime type? 83 // TODO(vsm): How should we encode the runtime type?
84 final _runtimeType = JS('', 'Symbol("_runtimeType")'); 84 final _runtimeType = JS('', 'Symbol("_runtimeType")');
85 85
86 checkPrimitiveType(obj) => JS('', '''(() => { 86 _checkPrimitiveType(obj) {
87 switch (typeof $obj) { 87 // TODO(jmesserly): JS is used to prevent type literal wrapping.
88 case "undefined": 88 // Is there a better way we can handle this?
89 return $Null; 89
90 // Check for null and undefined
91 if (obj == null) return JS('', '#', Null);
92 switch (JS('String', 'typeof #', obj)) {
90 case "number": 93 case "number":
91 return Math.floor($obj) == $obj ? $int : $double; 94 return JS('bool', 'Math.floor(#) == # ? # : #', obj, obj, int, double);
92 case "boolean": 95 case "boolean":
93 return $bool; 96 return JS('', '#', bool);
94 case "string": 97 case "string":
95 return $String; 98 return JS('', '#', String);
96 case "symbol": 99 case "symbol":
97 return Symbol; 100 // Note: this is a JS Symbol, not a Dart one.
101 return JS('', '#', jsobject);
98 } 102 }
99 // Undefined is handled above. For historical reasons,
100 // typeof null == "object" in JS.
101 if ($obj === null) return $Null;
102 return null; 103 return null;
103 })()'''); 104 }
104 105
105 runtimeType(obj) => JS('', '''(() => { 106 getFunctionType(obj) {
106 // Handle primitives where the method isn't on the object.
107 let result = $checkPrimitiveType($obj);
108 if (result !== null) return $wrapType(result);
109
110 // Delegate to the actual method on the object.
111 return $obj.runtimeType;
112 })()''');
113
114 getFunctionType(obj) => JS('', '''(() => {
115 // TODO(vsm): Encode this properly on the function for Dart-generated code. 107 // TODO(vsm): Encode this properly on the function for Dart-generated code.
116 let args = Array($obj.length).fill($dynamicR); 108 var args = JS('', 'Array(#.length).fill(#)', obj, dynamic);
117 return $definiteFunctionType($bottom, args); 109 return definiteFunctionType(bottom, args, JS('', 'void 0'));
118 })()'''); 110 }
119
120 /// The base implementation of Object.runtimeType.
121 objectRuntimeType(obj) => wrapType(getReifiedType(obj));
122 111
123 /// Returns an the runtime representation of the type of obj. 112 /// Returns an the runtime representation of the type of obj.
124 /// 113 ///
125 /// The resulting object is used internally for runtime type checking. This is 114 /// The resulting object is used internally for runtime type checking. This is
126 /// different from the user-visible Type object returned by calling 115 /// different from the user-visible Type object returned by calling
127 /// `runtimeType` on some Dart object. 116 /// `runtimeType` on some Dart object.
128 getReifiedType(obj) { 117 getReifiedType(obj) {
129 var result = checkPrimitiveType(obj); 118 var result = _checkPrimitiveType(obj);
130 if (result != null) return result; 119 if (result != null) return result;
131 return _nonPrimitiveRuntimeType(obj); 120 return _nonPrimitiveRuntimeType(obj);
132 } 121 }
133 122
134 _nonPrimitiveRuntimeType(obj) => JS('', '''(() => { 123 _nonPrimitiveRuntimeType(obj) {
135 // Lookup recorded *real* type (not user definable runtimeType) 124 // Lookup recorded *real* type (not user definable runtimeType)
136 // TODO(vsm): Should we treat Dart and JS objects differently here? 125 // TODO(vsm): Should we treat Dart and JS objects differently here?
137 // E.g., we can check if obj instanceof core.Object to differentiate. 126 // E.g., we can check if obj instanceof core.Object to differentiate.
138 let result = $obj[$_runtimeType]; 127 var result = _getRuntimeType(obj);
139 if (result) return result; 128 if (result != null) return result;
140 129
141 // Lookup extension type 130 // Lookup extension type
142 result = $obj[$_extensionType]; 131 result = getExtensionType(obj);
143 if (result) return result; 132 if (result != null) return result;
144 133
145 // Fallback on constructor for class types 134 // Fallback on constructor for class types
146 result = $obj.constructor; 135 result = JS('', '#.constructor', obj);
147 if (result == Function) { 136 if (JS('bool', '# === Function', result)) {
148 // An undecorated Function should have come from 137 // An undecorated Function should have come from JavaScript.
149 // JavaScript. Treat as untyped. 138 // Treat as untyped.
150 return $jsobject; 139 return JS('', '#', jsobject);
151 } 140 }
152 return result; 141 return result;
153 })()'''); 142 }
154 143
155 /// Given an internal runtime type object, wraps it in a `WrappedType` object 144 /// Given an internal runtime type object, wraps it in a `WrappedType` object
156 /// that implements the dart:core Type interface. 145 /// that implements the dart:core Type interface.
157 wrapType(type) { 146 wrapType(type) {
158 // If we've already wrapped this type once, use the previous wrapper. This 147 // If we've already wrapped this type once, use the previous wrapper. This
159 // way, multiple references to the same type return an identical Type. 148 // way, multiple references to the same type return an identical Type.
160 if (JS('bool', '#.hasOwnProperty(#)', type, _typeObject)) { 149 if (JS('bool', '#.hasOwnProperty(#)', type, _typeObject)) {
161 return JS('', '#[#]', type, _typeObject); 150 return JS('', '#[#]', type, _typeObject);
162 } 151 }
163 return JS('', '#[#] = new #(#)', type, _typeObject, WrappedType, type); 152 return JS('', '#[#] = new #(#)', type, _typeObject, WrappedType, type);
164 } 153 }
165 154
166 _getRuntimeType(value) => JS('', '#[#]', value, _runtimeType); 155 _getRuntimeType(value) => JS('', '#[#]', value, _runtimeType);
167 156
168 /// Tag the runtime type of [value] to be type [t]. 157 /// Tag the runtime type of [value] to be type [t].
169 void tag(value, t) { 158 void tag(value, t) {
170 JS('', '#[#] = #', value, _runtimeType, t); 159 JS('', '#[#] = #', value, _runtimeType, t);
171 } 160 }
172 161
173 void tagComputed(value, compute) { 162 void tagComputed(value, compute) {
174 JS('', '#(#, #, { get: # })', defineProperty, value, _runtimeType, compute); 163 JS('', '#(#, #, { get: # })', defineProperty, value, _runtimeType, compute);
175 } 164 }
176 165
177 void tagLazy(value, compute) { 166 void tagLazy(value, compute) {
178 JS('', '#(#, #, { get: # })', 167 JS('', '#(#, #, { get: # })',
179 defineLazyProperty, value, _runtimeType, compute); 168 defineLazyProperty, value, _runtimeType, compute);
180 } 169 }
OLDNEW
« no previous file with comments | « tool/input_sdk/private/ddc_runtime/operations.dart ('k') | tool/input_sdk/private/ddc_runtime/types.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698