Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library _js_helper; | 5 library _js_helper; |
| 6 | 6 |
| 7 import 'dart:_async_await_error_codes' as async_error_codes; | 7 import 'dart:_async_await_error_codes' as async_error_codes; |
| 8 | 8 |
| 9 import 'dart:_js_embedded_names' show | 9 import 'dart:_js_embedded_names' show |
| 10 DEFERRED_LIBRARY_URIS, | 10 DEFERRED_LIBRARY_URIS, |
| (...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1139 // specialization. | 1139 // specialization. |
| 1140 return namedArguments == null | 1140 return namedArguments == null |
| 1141 ? applyFunctionWithPositionalArguments( | 1141 ? applyFunctionWithPositionalArguments( |
| 1142 function, positionalArguments) | 1142 function, positionalArguments) |
| 1143 : applyFunctionWithNamedArguments( | 1143 : applyFunctionWithNamedArguments( |
| 1144 function, positionalArguments, namedArguments); | 1144 function, positionalArguments, namedArguments); |
| 1145 } | 1145 } |
| 1146 | 1146 |
| 1147 static applyFunctionWithPositionalArguments(Function function, | 1147 static applyFunctionWithPositionalArguments(Function function, |
| 1148 List positionalArguments) { | 1148 List positionalArguments) { |
| 1149 int argumentCount = 0; | |
| 1150 List arguments; | 1149 List arguments; |
| 1151 | 1150 |
| 1152 if (positionalArguments != null) { | 1151 if (positionalArguments != null) { |
| 1153 if (JS('bool', '# instanceof Array', positionalArguments)) { | 1152 if (JS('bool', '# instanceof Array', positionalArguments)) { |
| 1154 arguments = positionalArguments; | 1153 arguments = JS('JSArray', '#', positionalArguments); |
| 1155 } else { | 1154 } else { |
| 1156 arguments = new List.from(positionalArguments); | 1155 arguments = new List.from(positionalArguments); |
| 1157 } | 1156 } |
| 1158 argumentCount = JS('int', '#.length', arguments); | |
| 1159 } else { | 1157 } else { |
| 1160 arguments = []; | 1158 arguments = []; |
| 1161 } | 1159 } |
| 1162 | 1160 |
| 1161 if (arguments.length == 0) { | |
| 1162 String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX0); | |
| 1163 if (JS('bool', '!!#[#]', function, selectorName)) { | |
| 1164 return JS('', '#[#]()', function, selectorName); | |
| 1165 } | |
| 1166 } else if (arguments.length == 1) { | |
| 1167 String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX1); | |
| 1168 if (JS('bool', '!!#[#]', function, selectorName)) { | |
| 1169 return JS('', '#[#](#)', function, selectorName, arguments[0]); | |
| 1170 } | |
| 1171 } else if (arguments.length == 2) { | |
| 1172 String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX2); | |
| 1173 if (JS('bool', '!!#[#]', function, selectorName)) { | |
| 1174 return JS('', '#[#](#,#)', function, selectorName, | |
| 1175 arguments[0], arguments[1]); | |
| 1176 } | |
| 1177 } else if (arguments.length == 3) { | |
| 1178 String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX3); | |
| 1179 if (JS('bool', '!!#[#]', function, selectorName)) { | |
| 1180 return JS('', '#[#](#,#,#)', function, selectorName, | |
| 1181 arguments[0], arguments[1], arguments[2]); | |
|
sra1
2015/03/25 03:16:29
I would not surprise me if the array bounds checks
floitsch
2015/03/25 22:58:30
I was sure I had tested it, but you are (unfortuna
| |
| 1182 } | |
| 1183 } | |
| 1184 return _genericApplyFunctionWithPositionalArguments(function, arguments); | |
| 1185 } | |
| 1186 | |
| 1187 static _genericApplyFunctionWithPositionalArguments(Function function, | |
| 1188 List arguments) { | |
| 1189 int argumentCount = arguments.length; | |
| 1163 String selectorName = | 1190 String selectorName = |
| 1164 '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount'; | 1191 '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount'; |
| 1165 var jsFunction = JS('var', '#[#]', function, selectorName); | 1192 var jsFunction = JS('var', '#[#]', function, selectorName); |
| 1166 if (jsFunction == null) { | 1193 if (jsFunction == null) { |
| 1167 var interceptor = getInterceptor(function); | 1194 var interceptor = getInterceptor(function); |
| 1168 jsFunction = JS('', '#["call*"]', interceptor); | 1195 jsFunction = JS('', '#["call*"]', interceptor); |
| 1169 | 1196 |
| 1170 if (jsFunction == null) { | 1197 if (jsFunction == null) { |
| 1171 return functionNoSuchMethod(function, positionalArguments, null); | 1198 return functionNoSuchMethod(function, arguments, null); |
| 1172 } | 1199 } |
| 1173 ReflectionInfo info = new ReflectionInfo(jsFunction); | 1200 ReflectionInfo info = new ReflectionInfo(jsFunction); |
| 1174 int maxArgumentCount = info.requiredParameterCount + | 1201 int maxArgumentCount = info.requiredParameterCount + |
| 1175 info.optionalParameterCount; | 1202 info.optionalParameterCount; |
| 1176 if (info.areOptionalParametersNamed || maxArgumentCount < argumentCount) { | 1203 if (info.areOptionalParametersNamed || maxArgumentCount < argumentCount) { |
| 1177 return functionNoSuchMethod(function, positionalArguments, null); | 1204 return functionNoSuchMethod(function, arguments, null); |
| 1178 } | 1205 } |
| 1179 arguments = new List.from(arguments); | 1206 arguments = new List.from(arguments); |
| 1180 for (int pos = argumentCount; pos < maxArgumentCount; pos++) { | 1207 for (int pos = argumentCount; pos < maxArgumentCount; pos++) { |
| 1181 arguments.add(info.defaultValue(pos)); | 1208 arguments.add(info.defaultValue(pos)); |
| 1182 } | 1209 } |
| 1183 } | 1210 } |
| 1184 // We bound 'this' to [function] because of how we compile | 1211 // We bound 'this' to [function] because of how we compile |
| 1185 // closures: escaped local variables are stored and accessed through | 1212 // closures: escaped local variables are stored and accessed through |
| 1186 // [function]. | 1213 // [function]. |
| 1187 return JS('var', '#.apply(#, #)', jsFunction, function, arguments); | 1214 return JS('var', '#.apply(#, #)', jsFunction, function, arguments); |
| (...skipping 2693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3881 // This is a function that will return a helper function that does the | 3908 // This is a function that will return a helper function that does the |
| 3882 // iteration of the sync*. | 3909 // iteration of the sync*. |
| 3883 // | 3910 // |
| 3884 // Each invocation should give a body with fresh state. | 3911 // Each invocation should give a body with fresh state. |
| 3885 final dynamic /* js function */ _outerHelper; | 3912 final dynamic /* js function */ _outerHelper; |
| 3886 | 3913 |
| 3887 SyncStarIterable(this._outerHelper); | 3914 SyncStarIterable(this._outerHelper); |
| 3888 | 3915 |
| 3889 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); | 3916 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); |
| 3890 } | 3917 } |
| OLD | NEW |