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

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

Issue 3003613002: improve DDC's type checks (Closed)
Patch Set: format Created 3 years, 3 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 lazyFn(closure, computeType) { 68 lazyFn(closure, computeType) {
69 tagLazy(closure, computeType); 69 tagLazy(closure, computeType);
70 return closure; 70 return closure;
71 } 71 }
72 72
73 // TODO(vsm): How should we encode the runtime type? 73 // TODO(vsm): How should we encode the runtime type?
74 final _runtimeType = JS('', 'Symbol("_runtimeType")'); 74 final _runtimeType = JS('', 'Symbol("_runtimeType")');
75 75
76 final _moduleName = JS('', 'Symbol("_moduleName")'); 76 final _moduleName = JS('', 'Symbol("_moduleName")');
77 77
78 _checkPrimitiveType(obj) {
79 // TODO(jmesserly): JS is used to prevent type literal wrapping. Is there a
80 // better way we can handle this? (sra: It is super dodgy that the values
81 // passed to JS are different to the values passed to a regular function - the
82 // semantics are not longer that of calling an interpreter. dart2js has other
83 // special functions, we could do the same.)
84
85 // Check for null and undefined
86 if (obj == null) return JS('', '#', Null);
87
88 if (JS('bool', 'typeof # == "number"', obj)) {
89 if (JS('bool', 'Math.floor(#) == #', obj, obj)) {
90 return JS('', '#', int);
91 }
92 return JS('', '#', double);
93 }
94
95 if (JS('bool', 'typeof # == "boolean"', obj)) {
96 return JS('', '#', bool);
97 }
98
99 if (JS('bool', 'typeof # == "string"', obj)) {
100 return JS('', '#', String);
101 }
102
103 if (JS('bool', 'typeof # == "symbol"', obj)) {
104 // Note: this is a JS Symbol, not a Dart one.
105 return JS('', '#', jsobject);
106 }
107
108 return null;
109 }
110
111 getFunctionType(obj) { 78 getFunctionType(obj) {
112 // TODO(vsm): Encode this properly on the function for Dart-generated code. 79 // TODO(vsm): Encode this properly on the function for Dart-generated code.
113 var args = JS('List', 'Array(#.length).fill(#)', obj, dynamic); 80 var args = JS('List', 'Array(#.length).fill(#)', obj, dynamic);
114 return fnType(bottom, args, JS('', 'void 0')); 81 return fnType(bottom, args, JS('', 'void 0'));
115 } 82 }
116 83
117 /// Returns the runtime representation of the type of obj. 84 /// Returns the runtime representation of the type of obj.
118 /// 85 ///
119 /// The resulting object is used internally for runtime type checking. This is 86 /// The resulting object is used internally for runtime type checking. This is
120 /// different from the user-visible Type object returned by calling 87 /// different from the user-visible Type object returned by calling
121 /// `runtimeType` on some Dart object. 88 /// `runtimeType` on some Dart object.
122 getReifiedType(obj) { 89 getReifiedType(obj) {
123 var result = _checkPrimitiveType(obj); 90 switch (JS('String', 'typeof #', obj)) {
Leaf 2017/08/24 17:19:39 Will V8 make this code fast, even when the `typeof
Jennifer Messerly 2017/08/24 18:26:37 Yup. I was skeptical too, but this code was the re
124 if (result != null) return result; 91 case "object":
125 return _nonPrimitiveRuntimeType(obj); 92 if (obj == null) return JS('', '#', Null);
126 } 93 if (JS('bool', '# instanceof #', obj, Object)) {
127 94 return JS('', '#.constructor', obj);
128 /// Assumes that obj is non-null 95 }
129 _nonPrimitiveRuntimeType(obj) { 96 var result = JS('', '#[#]', obj, _extensionType);
130 // Lookup recorded *real* type (not user definable runtimeType) 97 if (result == null) return JS('', '#', jsobject);
Jennifer Messerly 2017/08/23 23:36:01 FYI -- there's one subtle difference from the old
Leaf 2017/08/24 17:19:39 Acknowledged.
131 // TODO(vsm): Should we treat Dart and JS objects differently here? 98 return result;
132 // E.g., we can check if obj instanceof core.Object to differentiate. 99 case "function":
133 var result = _getRuntimeType(obj); 100 // All Dart functions and callable classes must set _runtimeType
134 if (result != null) return result; 101 var result = JS('', '#[#]', obj, _runtimeType);
135 102 if (result != null) return result;
136 // Lookup extension type 103 return JS('', '#', jsobject);
137 result = getExtensionType(obj); 104 case "undefined":
138 if (result != null) return result; 105 return JS('', '#', Null);
139 106 case "number":
140 // Fallback on constructor for class types 107 return JS('', 'Math.floor(#) == # ? # : #', obj, obj, int, double);
141 result = JS('', '#.constructor', obj); 108 case "boolean":
142 if (JS('bool', '# === Function', result)) { 109 return JS('', '#', bool);
143 // An undecorated Function should have come from JavaScript. 110 case "string":
144 // Treat as untyped. 111 return JS('', '#', String);
145 return JS('', '#', jsobject); 112 case "symbol":
113 default:
114 return JS('', '#', jsobject);
146 } 115 }
147 if (result == null) {
148 return JS('', '#', jsobject);
149 }
150 return result;
151 } 116 }
152 117
153 /// Given an internal runtime type object, wraps it in a `WrappedType` object 118 /// Given an internal runtime type object, wraps it in a `WrappedType` object
154 /// that implements the dart:core Type interface. 119 /// that implements the dart:core Type interface.
155 Type wrapType(type) { 120 Type wrapType(type) {
156 // If we've already wrapped this type once, use the previous wrapper. This 121 // If we've already wrapped this type once, use the previous wrapper. This
157 // way, multiple references to the same type return an identical Type. 122 // way, multiple references to the same type return an identical Type.
158 if (JS('bool', '#.hasOwnProperty(#)', type, _typeObject)) { 123 if (JS('bool', '#.hasOwnProperty(#)', type, _typeObject)) {
159 return JS('', '#[#]', type, _typeObject); 124 return JS('', '#[#]', type, _typeObject);
160 } 125 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 if (module == null) return null; 165 if (module == null) return null;
201 JS('', '#[#] = #', module, _moduleName, name); 166 JS('', '#[#] = #', module, _moduleName, name);
202 return module; 167 return module;
203 } 168 }
204 169
205 /// Track all libraries 170 /// Track all libraries
206 void trackLibraries(String moduleName, libraries, sourceMap) { 171 void trackLibraries(String moduleName, libraries, sourceMap) {
207 JS('', '#.set(#, #)', _loadedSourceMaps, moduleName, sourceMap); 172 JS('', '#.set(#, #)', _loadedSourceMaps, moduleName, sourceMap);
208 JS('', '#.set(#, #)', _loadedModules, moduleName, libraries); 173 JS('', '#.set(#, #)', _loadedModules, moduleName, libraries);
209 } 174 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698