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:_js_embedded_names' show | 7 import 'dart:_js_embedded_names' show |
| 8 JsGetName, |
8 GET_TYPE_FROM_NAME, | 9 GET_TYPE_FROM_NAME, |
9 GET_ISOLATE_TAG, | 10 GET_ISOLATE_TAG, |
10 INTERCEPTED_NAMES, | 11 INTERCEPTED_NAMES, |
11 INTERCEPTORS_BY_TAG, | 12 INTERCEPTORS_BY_TAG, |
12 LEAF_TAGS, | 13 LEAF_TAGS, |
13 METADATA, | 14 METADATA, |
14 DEFERRED_LIBRARY_URIS, | 15 DEFERRED_LIBRARY_URIS, |
15 DEFERRED_LIBRARY_HASHES, | 16 DEFERRED_LIBRARY_HASHES, |
16 INITIALIZE_LOADED_HUNK, | 17 INITIALIZE_LOADED_HUNK, |
17 IS_HUNK_LOADED, | 18 IS_HUNK_LOADED, |
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 if (namedArguments != null && !namedArguments.isEmpty) { | 1026 if (namedArguments != null && !namedArguments.isEmpty) { |
1026 namedArguments.forEach((String name, argument) { | 1027 namedArguments.forEach((String name, argument) { |
1027 names = '$names\$$name'; | 1028 names = '$names\$$name'; |
1028 namedArgumentList.add(name); | 1029 namedArgumentList.add(name); |
1029 arguments.add(argument); | 1030 arguments.add(argument); |
1030 argumentCount++; | 1031 argumentCount++; |
1031 }); | 1032 }); |
1032 } | 1033 } |
1033 | 1034 |
1034 String selectorName = | 1035 String selectorName = |
1035 '${JS_GET_NAME("CALL_PREFIX")}\$$argumentCount$names'; | 1036 '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount$names'; |
1036 | 1037 |
1037 return function.noSuchMethod( | 1038 return function.noSuchMethod( |
1038 createUnmangledInvocationMirror( | 1039 createUnmangledInvocationMirror( |
1039 #call, | 1040 #call, |
1040 selectorName, | 1041 selectorName, |
1041 JSInvocationMirror.METHOD, | 1042 JSInvocationMirror.METHOD, |
1042 arguments, | 1043 arguments, |
1043 namedArgumentList)); | 1044 namedArgumentList)); |
1044 } | 1045 } |
1045 | 1046 |
1046 static applyFunctionNewEmitter(Function function, | 1047 static applyFunctionNewEmitter(Function function, |
1047 List positionalArguments, | 1048 List positionalArguments, |
1048 Map<String, dynamic> namedArguments) { | 1049 Map<String, dynamic> namedArguments) { |
1049 if (namedArguments == null) { | 1050 if (namedArguments == null) { |
1050 int requiredParameterCount = JS('int', r'#[#]', function, | 1051 int requiredParameterCount = JS('int', r'#[#]', function, |
1051 JS_GET_NAME("REQUIRED_PARAMETER_PROPERTY")); | 1052 JS_GET_NAME(JsGetName.REQUIRED_PARAMETER_PROPERTY)); |
1052 int argumentCount = positionalArguments.length; | 1053 int argumentCount = positionalArguments.length; |
1053 if (argumentCount < requiredParameterCount) { | 1054 if (argumentCount < requiredParameterCount) { |
1054 return functionNoSuchMethod(function, positionalArguments, null); | 1055 return functionNoSuchMethod(function, positionalArguments, null); |
1055 } | 1056 } |
1056 String selectorName = '${JS_GET_NAME("CALL_PREFIX")}\$$argumentCount'; | 1057 String selectorName = |
| 1058 '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount'; |
1057 var jsStub = JS('var', r'#[#]', function, selectorName); | 1059 var jsStub = JS('var', r'#[#]', function, selectorName); |
1058 if (jsStub == null) { | 1060 if (jsStub == null) { |
1059 // Do a dynamic call. | 1061 // Do a dynamic call. |
1060 var interceptor = getInterceptor(function); | 1062 var interceptor = getInterceptor(function); |
1061 var jsFunction = JS('', '#[#]', interceptor, | 1063 var jsFunction = JS('', '#[#]', interceptor, |
1062 JS_GET_NAME('CALL_CATCH_ALL')); | 1064 JS_GET_NAME(JsGetName.CALL_CATCH_ALL)); |
1063 var defaultValues = JS('var', r'#[#]', function, | 1065 var defaultValues = JS('var', r'#[#]', function, |
1064 JS_GET_NAME("DEFAULT_VALUES_PROPERTY")); | 1066 JS_GET_NAME(JsGetName.DEFAULT_VALUES_PROPERTY)); |
1065 if (!JS('bool', '# instanceof Array', defaultValues)) { | 1067 if (!JS('bool', '# instanceof Array', defaultValues)) { |
1066 // The function expects named arguments! | 1068 // The function expects named arguments! |
1067 return functionNoSuchMethod(function, positionalArguments, null); | 1069 return functionNoSuchMethod(function, positionalArguments, null); |
1068 } | 1070 } |
1069 int defaultsLength = JS('int', "#.length", defaultValues); | 1071 int defaultsLength = JS('int', "#.length", defaultValues); |
1070 int maxArguments = requiredParameterCount + defaultsLength; | 1072 int maxArguments = requiredParameterCount + defaultsLength; |
1071 if (argumentCount > maxArguments) { | 1073 if (argumentCount > maxArguments) { |
1072 // The function expects less arguments! | 1074 // The function expects less arguments! |
1073 return functionNoSuchMethod(function, positionalArguments, null); | 1075 return functionNoSuchMethod(function, positionalArguments, null); |
1074 } | 1076 } |
1075 List arguments = new List.from(positionalArguments); | 1077 List arguments = new List.from(positionalArguments); |
1076 List missingDefaults = JS('JSArray', '#.slice(#)', defaultValues, | 1078 List missingDefaults = JS('JSArray', '#.slice(#)', defaultValues, |
1077 argumentCount - requiredParameterCount); | 1079 argumentCount - requiredParameterCount); |
1078 arguments.addAll(missingDefaults); | 1080 arguments.addAll(missingDefaults); |
1079 return JS('var', '#.apply(#, #)', jsFunction, function, arguments); | 1081 return JS('var', '#.apply(#, #)', jsFunction, function, arguments); |
1080 } | 1082 } |
1081 return JS('var', '#.apply(#, #)', jsStub, function, positionalArguments); | 1083 return JS('var', '#.apply(#, #)', jsStub, function, positionalArguments); |
1082 } else { | 1084 } else { |
1083 var interceptor = getInterceptor(function); | 1085 var interceptor = getInterceptor(function); |
1084 var jsFunction = JS('', '#[#]', interceptor, | 1086 var jsFunction = JS('', '#[#]', interceptor, |
1085 JS_GET_NAME('CALL_CATCH_ALL')); | 1087 JS_GET_NAME(JsGetName.CALL_CATCH_ALL)); |
1086 var defaultValues = JS('JSArray', r'#[#]', function, | 1088 var defaultValues = JS('JSArray', r'#[#]', function, |
1087 JS_GET_NAME("DEFAULT_VALUES_PROPERTY")); | 1089 JS_GET_NAME(JsGetName.DEFAULT_VALUES_PROPERTY)); |
1088 List keys = JS('JSArray', r'Object.keys(#)', defaultValues); | 1090 List keys = JS('JSArray', r'Object.keys(#)', defaultValues); |
1089 List arguments = new List.from(positionalArguments); | 1091 List arguments = new List.from(positionalArguments); |
1090 int used = 0; | 1092 int used = 0; |
1091 for (String key in keys) { | 1093 for (String key in keys) { |
1092 var value = namedArguments[key]; | 1094 var value = namedArguments[key]; |
1093 if (value != null) { | 1095 if (value != null) { |
1094 used++; | 1096 used++; |
1095 arguments.add(value); | 1097 arguments.add(value); |
1096 } else { | 1098 } else { |
1097 arguments.add(JS('var', r'#[#]', defaultValues, key)); | 1099 arguments.add(JS('var', r'#[#]', defaultValues, key)); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 if (JS('bool', '# instanceof Array', positionalArguments)) { | 1131 if (JS('bool', '# instanceof Array', positionalArguments)) { |
1130 arguments = positionalArguments; | 1132 arguments = positionalArguments; |
1131 } else { | 1133 } else { |
1132 arguments = new List.from(positionalArguments); | 1134 arguments = new List.from(positionalArguments); |
1133 } | 1135 } |
1134 argumentCount = JS('int', '#.length', arguments); | 1136 argumentCount = JS('int', '#.length', arguments); |
1135 } else { | 1137 } else { |
1136 arguments = []; | 1138 arguments = []; |
1137 } | 1139 } |
1138 | 1140 |
1139 String selectorName = '${JS_GET_NAME("CALL_PREFIX")}\$$argumentCount'; | 1141 String selectorName = |
| 1142 '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount'; |
1140 var jsFunction = JS('var', '#[#]', function, selectorName); | 1143 var jsFunction = JS('var', '#[#]', function, selectorName); |
1141 if (jsFunction == null) { | 1144 if (jsFunction == null) { |
1142 var interceptor = getInterceptor(function); | 1145 var interceptor = getInterceptor(function); |
1143 jsFunction = JS('', '#["call*"]', interceptor); | 1146 jsFunction = JS('', '#["call*"]', interceptor); |
1144 | 1147 |
1145 if (jsFunction == null) { | 1148 if (jsFunction == null) { |
1146 return functionNoSuchMethod(function, positionalArguments, null); | 1149 return functionNoSuchMethod(function, positionalArguments, null); |
1147 } | 1150 } |
1148 ReflectionInfo info = new ReflectionInfo(jsFunction); | 1151 ReflectionInfo info = new ReflectionInfo(jsFunction); |
1149 int maxArgumentCount = info.requiredParameterCount + | 1152 int maxArgumentCount = info.requiredParameterCount + |
(...skipping 15 matching lines...) Expand all Loading... |
1165 static applyFunctionWithNamedArguments(Function function, | 1168 static applyFunctionWithNamedArguments(Function function, |
1166 List positionalArguments, | 1169 List positionalArguments, |
1167 Map<String, dynamic> namedArguments) { | 1170 Map<String, dynamic> namedArguments) { |
1168 if (namedArguments.isEmpty) { | 1171 if (namedArguments.isEmpty) { |
1169 return applyFunctionWithPositionalArguments( | 1172 return applyFunctionWithPositionalArguments( |
1170 function, positionalArguments); | 1173 function, positionalArguments); |
1171 } | 1174 } |
1172 // TODO(ahe): The following code can be shared with | 1175 // TODO(ahe): The following code can be shared with |
1173 // JsInstanceMirror.invoke. | 1176 // JsInstanceMirror.invoke. |
1174 var interceptor = getInterceptor(function); | 1177 var interceptor = getInterceptor(function); |
1175 var jsFunction = JS('', '#[#]', interceptor, JS_GET_NAME('CALL_CATCH_ALL')); | 1178 var jsFunction = JS('', '#[#]', interceptor, |
| 1179 JS_GET_NAME(JsGetName.CALL_CATCH_ALL)); |
1176 | 1180 |
1177 if (jsFunction == null) { | 1181 if (jsFunction == null) { |
1178 return functionNoSuchMethod( | 1182 return functionNoSuchMethod( |
1179 function, positionalArguments, namedArguments); | 1183 function, positionalArguments, namedArguments); |
1180 } | 1184 } |
1181 ReflectionInfo info = new ReflectionInfo(jsFunction); | 1185 ReflectionInfo info = new ReflectionInfo(jsFunction); |
1182 if (info == null || !info.areOptionalParametersNamed) { | 1186 if (info == null || !info.areOptionalParametersNamed) { |
1183 return functionNoSuchMethod( | 1187 return functionNoSuchMethod( |
1184 function, positionalArguments, namedArguments); | 1188 function, positionalArguments, namedArguments); |
1185 } | 1189 } |
(...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2050 String propertyName) { | 2054 String propertyName) { |
2051 JS_EFFECT(() { | 2055 JS_EFFECT(() { |
2052 BoundClosure.receiverOf(JS('BoundClosure', 'void 0')); | 2056 BoundClosure.receiverOf(JS('BoundClosure', 'void 0')); |
2053 BoundClosure.selfOf(JS('BoundClosure', 'void 0')); | 2057 BoundClosure.selfOf(JS('BoundClosure', 'void 0')); |
2054 }); | 2058 }); |
2055 // TODO(ahe): All the place below using \$ should be rewritten to go | 2059 // TODO(ahe): All the place below using \$ should be rewritten to go |
2056 // through the namer. | 2060 // through the namer. |
2057 var function = JS('', '#[#]', functions, 0); | 2061 var function = JS('', '#[#]', functions, 0); |
2058 String name = JS('String|Null', '#.\$stubName', function); | 2062 String name = JS('String|Null', '#.\$stubName', function); |
2059 String callName = JS('String|Null', '#[#]', function, | 2063 String callName = JS('String|Null', '#[#]', function, |
2060 JS_GET_NAME("CALL_NAME_PROPERTY")); | 2064 JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY)); |
2061 | 2065 |
2062 var functionType; | 2066 var functionType; |
2063 if (reflectionInfo is List) { | 2067 if (reflectionInfo is List) { |
2064 JS('', '#.\$reflectionInfo = #', function, reflectionInfo); | 2068 JS('', '#.\$reflectionInfo = #', function, reflectionInfo); |
2065 ReflectionInfo info = new ReflectionInfo(function); | 2069 ReflectionInfo info = new ReflectionInfo(function); |
2066 functionType = info.functionType; | 2070 functionType = info.functionType; |
2067 } else { | 2071 } else { |
2068 functionType = reflectionInfo; | 2072 functionType = reflectionInfo; |
2069 } | 2073 } |
2070 | 2074 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2153 } else { | 2157 } else { |
2154 throw 'Error in reflectionInfo.'; | 2158 throw 'Error in reflectionInfo.'; |
2155 } | 2159 } |
2156 | 2160 |
2157 JS('', '#[#] = #', prototype, JS_SIGNATURE_NAME(), signatureFunction); | 2161 JS('', '#[#] = #', prototype, JS_SIGNATURE_NAME(), signatureFunction); |
2158 | 2162 |
2159 JS('', '#[#] = #', prototype, callName, trampoline); | 2163 JS('', '#[#] = #', prototype, callName, trampoline); |
2160 for (int i = 1; i < functions.length; i++) { | 2164 for (int i = 1; i < functions.length; i++) { |
2161 var stub = functions[i]; | 2165 var stub = functions[i]; |
2162 var stubCallName = JS('String|Null', '#[#]', stub, | 2166 var stubCallName = JS('String|Null', '#[#]', stub, |
2163 JS_GET_NAME("CALL_NAME_PROPERTY")); | 2167 JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY)); |
2164 if (stubCallName != null) { | 2168 if (stubCallName != null) { |
2165 JS('', '#[#] = #', prototype, stubCallName, | 2169 JS('', '#[#] = #', prototype, stubCallName, |
2166 isStatic ? stub : forwardCallTo(receiver, stub, isIntercepted)); | 2170 isStatic ? stub : forwardCallTo(receiver, stub, isIntercepted)); |
2167 } | 2171 } |
2168 } | 2172 } |
2169 | 2173 |
2170 JS('', '#[#] = #', prototype, JS_GET_NAME('CALL_CATCH_ALL'), trampoline); | 2174 JS('', '#[#] = #', prototype, JS_GET_NAME(JsGetName.CALL_CATCH_ALL), |
2171 String reqArgProperty = JS_GET_NAME("REQUIRED_PARAMETER_PROPERTY"); | 2175 trampoline); |
2172 String defValProperty = JS_GET_NAME("DEFAULT_VALUES_PROPERTY"); | 2176 String reqArgProperty = JS_GET_NAME(JsGetName.REQUIRED_PARAMETER_PROPERTY); |
| 2177 String defValProperty = JS_GET_NAME(JsGetName.DEFAULT_VALUES_PROPERTY); |
2173 JS('', '#.# = #.#', prototype, reqArgProperty, function, reqArgProperty); | 2178 JS('', '#.# = #.#', prototype, reqArgProperty, function, reqArgProperty); |
2174 JS('', '#.# = #.#', prototype, defValProperty, function, defValProperty); | 2179 JS('', '#.# = #.#', prototype, defValProperty, function, defValProperty); |
2175 | 2180 |
2176 return constructor; | 2181 return constructor; |
2177 } | 2182 } |
2178 | 2183 |
2179 static cspForwardCall(int arity, bool isSuperCall, String stubName, | 2184 static cspForwardCall(int arity, bool isSuperCall, String stubName, |
2180 function) { | 2185 function) { |
2181 var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf); | 2186 var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf); |
2182 // Handle intercepted stub-names with the default slow case. | 2187 // Handle intercepted stub-names with the default slow case. |
(...skipping 1616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3799 // This is a function that will return a helper function that does the | 3804 // This is a function that will return a helper function that does the |
3800 // iteration of the sync*. | 3805 // iteration of the sync*. |
3801 // | 3806 // |
3802 // Each invocation should give a helper with fresh state. | 3807 // Each invocation should give a helper with fresh state. |
3803 final dynamic /* js function */ _outerHelper; | 3808 final dynamic /* js function */ _outerHelper; |
3804 | 3809 |
3805 SyncStarIterable(this._outerHelper); | 3810 SyncStarIterable(this._outerHelper); |
3806 | 3811 |
3807 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); | 3812 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); |
3808 } | 3813 } |
OLD | NEW |