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

Side by Side Diff: lib/runtime/dart_runtime.js

Issue 1100633006: Generate static calls for Object fields and methods (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Better static dispatch check Created 5 years, 8 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 var dart, _js_helper; 5 var dart, _js_helper;
6 (function (dart) { 6 (function (dart) {
7 'use strict'; 7 'use strict';
8 8
9 let defineProperty = Object.defineProperty; 9 let defineProperty = Object.defineProperty;
10 let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; 10 let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 89
90 function dsend(obj, method/*, ...args*/) { 90 function dsend(obj, method/*, ...args*/) {
91 let args = Array.prototype.slice.call(arguments, 2); 91 let args = Array.prototype.slice.call(arguments, 2);
92 return checkAndCall(obj[method], obj, args, method); 92 return checkAndCall(obj[method], obj, args, method);
93 } 93 }
94 dart.dsend = dsend; 94 dart.dsend = dsend;
95 95
96 function dindex(obj, index) { 96 function dindex(obj, index) {
97 // TODO(jmesserly): remove this special case once Array extensions are 97 // TODO(jmesserly): remove this special case once Array extensions are
98 // hooked up. 98 // hooked up.
99 if (obj instanceof Array && getRuntimeType(index) == core.int) { 99 if (obj instanceof Array && realRuntimeType(index) == core.int) {
100 return obj[index]; 100 return obj[index];
101 } 101 }
102 return checkAndCall(obj.get, obj, [index], '[]'); 102 return checkAndCall(obj.get, obj, [index], '[]');
103 } 103 }
104 dart.dindex = dindex; 104 dart.dindex = dindex;
105 105
106 function dsetindex(obj, index, value) { 106 function dsetindex(obj, index, value) {
107 return checkAndCall(obj.set, obj, [index, value], '[]='); 107 return checkAndCall(obj.set, obj, [index, value], '[]=');
108 } 108 }
109 dart.dsetindex = dsetindex; 109 dart.dsetindex = dsetindex;
110 110
111 /** 111 /**
112 * Returns bound `method`. 112 * Returns bound `method`.
113 * This helper function avoids needing a temp for `obj`. 113 * This helper function avoids needing a temp for `obj`.
114 */ 114 */
115 function bind(obj, method) { 115 function bind(obj, method) {
116 // This is a static bind (dynamic would use `dload`) so no need to check 116 // This is a static bind (dynamic would use `dload`) so no need to check
117 // if `method` is really there on `obj`.` 117 // if `method` is really there on `obj`.`
118 return obj[method].bind(obj); 118 return obj[method].bind(obj);
119 } 119 }
120 dart.bind = bind; 120 dart.bind = bind;
121 121
122 function cast(obj, type) { 122 function cast(obj, type) {
123 // TODO(vsm): handle non-nullable types 123 // TODO(vsm): handle non-nullable types
124 if (obj == null) return obj; 124 if (obj == null) return obj;
125 let actual = getRuntimeType(obj); 125 let actual = realRuntimeType(obj);
126 if (isSubtype(actual, type)) return obj; 126 if (isSubtype(actual, type)) return obj;
127 throw new _js_helper.CastErrorImplementation(actual, type); 127 throw new _js_helper.CastErrorImplementation(actual, type);
128 } 128 }
129 dart.as = cast; 129 dart.as = cast;
130 130
131 131
132 // TODO(vsm): How should we encode the runtime type? 132 // TODO(vsm): How should we encode the runtime type?
133 let runtimeType = Symbol('runtimeType'); 133 let _runtimeType = Symbol('_runtimeType');
134 134
135 /** 135 function checkPrimitiveType(obj) {
136 * Returns the runtime type of obj. This is the same as `obj.runtimeType`
137 * but will not call an overridden getter.
138 *
139 * Currently this will return null for non-Dart objects.
140 */
141 function getRuntimeType(obj) {
142 switch (typeof obj) { 136 switch (typeof obj) {
143 case "undefined": 137 case "undefined":
144 return core.Null; 138 return core.Null;
145 case "number": 139 case "number":
146 return Math.floor(obj) == obj ? core.int : core.double; 140 return Math.floor(obj) == obj ? core.int : core.double;
147 case "boolean": 141 case "boolean":
148 return core.bool; 142 return core.bool;
149 case "string": 143 case "string":
150 return core.String; 144 return core.String;
151 case "symbol": 145 case "symbol":
152 return Symbol; 146 return Symbol;
153 } 147 }
154 // Undefined is handled above. For historical reasons, 148 // Undefined is handled above. For historical reasons,
155 // typeof null == "object" in JS. 149 // typeof null == "object" in JS.
156 if (obj === null) return core.Null; 150 if (obj === null) return core.Null;
151 return null;
152 }
153
154 /**
155 * Returns the runtime type of obj. This is the same as `obj.realRuntimeType`
156 * but will not call an overridden getter.
157 *
158 * Currently this will return null for non-Dart objects.
159 */
160 function realRuntimeType(obj) {
161 var result = checkPrimitiveType(obj);
162 if (result !== null) return result;
157 // TODO(vsm): Should we treat Dart and JS objects differently here? 163 // TODO(vsm): Should we treat Dart and JS objects differently here?
158 // E.g., we can check if obj instanceof core.Object to differentiate. 164 // E.g., we can check if obj instanceof core.Object to differentiate.
159 var result = obj[runtimeType]; 165 result = obj[_runtimeType];
160 if (result) return result; 166 if (result) return result;
161 result = obj.constructor; 167 result = obj.constructor;
162 if (result == Function) { 168 if (result == Function) {
163 return getFunctionType(obj); 169 return getFunctionType(obj);
164 } 170 }
165 return result; 171 return result;
166 } 172 }
167 dart.getRuntimeType = getRuntimeType; 173 dart.realRuntimeType = realRuntimeType;
168 174
169 function instanceOf(obj, type) { 175 function instanceOf(obj, type) {
170 return isSubtype(getRuntimeType(obj), type); 176 return isSubtype(realRuntimeType(obj), type);
171 } 177 }
172 dart.is = instanceOf; 178 dart.is = instanceOf;
173 179
174 /** 180 /**
175 * Computes the canonical type. 181 * Computes the canonical type.
176 * This maps JS types onto their corresponding Dart Type. 182 * This maps JS types onto their corresponding Dart Type.
177 */ 183 */
178 // TODO(jmesserly): lots more needs to be done here. 184 // TODO(jmesserly): lots more needs to be done here.
179 function canonicalType(t) { 185 function canonicalType(t) {
180 if (t === Object) return core.Object; 186 if (t === Object) return core.Object;
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 let constants = new Map(); 831 let constants = new Map();
826 832
827 /** 833 /**
828 * Canonicalize a constant object. 834 * Canonicalize a constant object.
829 * 835 *
830 * Preconditions: 836 * Preconditions:
831 * - `obj` is an objects or array, not a primitive. 837 * - `obj` is an objects or array, not a primitive.
832 * - nested values of the object are themselves already canonicalized. 838 * - nested values of the object are themselves already canonicalized.
833 */ 839 */
834 function constant(obj) { 840 function constant(obj) {
835 let objectKey = [getRuntimeType(obj)]; 841 let objectKey = [realRuntimeType(obj)];
836 // There's no guarantee in JS that names/symbols are returned in the same 842 // There's no guarantee in JS that names/symbols are returned in the same
837 // order. We could probably get the same order if we're judicious about 843 // order. We could probably get the same order if we're judicious about
838 // initializing them, but easier to not depend on that. 844 // initializing them, but easier to not depend on that.
839 for (let name of getOwnNamesAndSymbols(obj)) { 845 for (let name of getOwnNamesAndSymbols(obj)) {
840 // TODO(jmesserly): we can make this faster if needed. 846 // TODO(jmesserly): we can make this faster if needed.
841 objectKey.push(name); 847 objectKey.push(name);
842 objectKey.push(obj[name]); 848 objectKey.push(obj[name]);
843 } 849 }
844 return multiKeyPutIfAbsent(constants, objectKey, () => obj); 850 return multiKeyPutIfAbsent(constants, objectKey, () => obj);
845 } 851 }
846 dart.const = constant; 852 dart.const = constant;
847 853
848 /** Sets the runtime type of `obj` to be `type` */ 854 /** Sets the runtime type of `obj` to be `type` */
849 function setType(obj, type) { 855 function setType(obj, type) {
850 obj[runtimeType] = type; 856 obj[_runtimeType] = type;
851 } 857 }
852 dart.setType = setType; 858 dart.setType = setType;
853 859
860 // The following are helpers for Object methods when the receiver
861 // may be null or primitive. These should only be generated by
862 // the compiler.
863 function hashCode(obj) {
864 if (obj == null) {
865 return 0;
866 }
867 // TODO(vsm): What should we do for primitives and non-Dart objects?
868 switch (typeof obj) {
869 case "number":
870 case "boolean":
871 return obj & 0x1FFFFFFF;
872 case "string":
873 // TODO(vsm): Call the JSString hashCode?
874 return obj.length;
875 }
876 return obj.hashCode;
877 }
878 dart.hashCode = hashCode;
879
880 function runtimeType(obj) {
881 var result = checkPrimitiveType(obj);
882 if (result !== null) return result;
883 return obj.runtimeType;
884 }
885 dart.runtimeType = runtimeType;
886
887 function toString(obj) {
888 if (obj == null) {
889 return "null";
890 }
891 return obj.toString();
892 }
893 dart.toString = toString;
894
895 function noSuchMethod(obj, invocation) {
896 if (obj == null) {
897 throw new core.NoSuchMethodError(obj, invocation.memberName,
Jennifer Messerly 2015/04/23 21:09:30 could this be like: return core.Object.noSuch
vsm 2015/04/23 21:23:29 This feels mildly dangerous ... depending on how O
898 invocation.positionalArguments, invocation.namedArguments);
899 }
900 switch (typeof obj) {
901 case "number":
902 case "boolean":
903 case "string":
904 throw new core.NoSuchMethodError(obj, invocation.memberName,
Jennifer Messerly 2015/04/23 21:09:30 this too
905 invocation.positionalArguments, invocation.namedArguments);
906 }
907 return obj.noSuchMethod(invocation);
908 }
909 dart.noSuchMethod = noSuchMethod;
910
854 // TODO(jmesserly): right now this is a sentinel. It should be a type object 911 // TODO(jmesserly): right now this is a sentinel. It should be a type object
855 // of some sort, assuming we keep around `dynamic` at runtime. 912 // of some sort, assuming we keep around `dynamic` at runtime.
856 dart.dynamic = { toString() { return 'dynamic'; } }; 913 dart.dynamic = { toString() { return 'dynamic'; } };
857 dart.void = { toString() { return 'void'; } }; 914 dart.void = { toString() { return 'void'; } };
858 dart.bottom = { toString() { return 'bottom'; } }; 915 dart.bottom = { toString() { return 'bottom'; } };
859 916
860 dart.global = window || global; 917 dart.global = window || global;
861 dart.JsSymbol = Symbol; 918 dart.JsSymbol = Symbol;
862 919
863 // TODO(jmesserly): hack to bootstrap the SDK 920 // TODO(jmesserly): hack to bootstrap the SDK
864 _js_helper = _js_helper || {}; 921 _js_helper = _js_helper || {};
865 _js_helper.checkNum = notNull; 922 _js_helper.checkNum = notNull;
866 923
867 })(dart || (dart = {})); 924 })(dart || (dart = {}));
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698