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 GET_TYPE_FROM_NAME, | 8 GET_TYPE_FROM_NAME, |
9 GET_ISOLATE_TAG, | 9 GET_ISOLATE_TAG, |
10 INTERCEPTED_NAMES, | 10 INTERCEPTED_NAMES, |
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1036 | 1036 |
1037 return function.noSuchMethod( | 1037 return function.noSuchMethod( |
1038 createUnmangledInvocationMirror( | 1038 createUnmangledInvocationMirror( |
1039 #call, | 1039 #call, |
1040 selectorName, | 1040 selectorName, |
1041 JSInvocationMirror.METHOD, | 1041 JSInvocationMirror.METHOD, |
1042 arguments, | 1042 arguments, |
1043 namedArgumentList)); | 1043 namedArgumentList)); |
1044 } | 1044 } |
1045 | 1045 |
1046 static applyFunctionNewEmitter(Function function, | |
1047 List positionalArguments, | |
1048 Map<String, dynamic> namedArguments) { | |
1049 if (namedArguments == null) { | |
1050 int requiredParameterCount = JS('int', r'#[#]', function, | |
1051 JS_GET_NAME("REQUIRED_PARAMETER_PROPERTY")); | |
floitsch
2015/02/16 15:26:03
In another CL: JS_GET_NAME should use embedded_nam
herhut
2015/02/17 10:25:39
Acknowledged.
| |
1052 int argumentCount = positionalArguments.length; | |
1053 if (argumentCount < requiredParameterCount) { | |
1054 return functionNoSuchMethod(function, positionalArguments, null); | |
1055 } | |
1056 String selectorName = '${JS_GET_NAME("CALL_PREFIX")}\$$argumentCount'; | |
1057 var jsStub = JS('var', r'#[#]', function, selectorName); | |
1058 if (jsStub == null) { | |
1059 // Do a dynamic call. | |
1060 var interceptor = getInterceptor(function); | |
1061 var jsFunction = JS('', '#["call*"]', interceptor); | |
floitsch
2015/02/16 15:26:03
"call*" should be shared name.
herhut
2015/02/17 10:25:39
Done.
| |
1062 var defaultValues = JS('var', r'#[#]', function, | |
1063 JS_GET_NAME("DEFAULT_VALUES_PROPERTY")); | |
1064 if (!JS('bool', '# instanceof Array', defaultValues)) { | |
1065 // The function expects named arguments! | |
1066 return functionNoSuchMethod(function, positionalArguments, null); | |
1067 } | |
1068 int defaultsLength = JS('int', "#.length", defaultValues); | |
1069 int maxArguments = requiredParameterCount + defaultsLength; | |
1070 if (argumentCount > maxArguments) { | |
1071 // The function expects less arguments! | |
1072 return functionNoSuchMethod(function, positionalArguments, null); | |
1073 } | |
1074 List arguments = new List.from(positionalArguments); | |
1075 List missingDefaults = JS('JSArray', '#.slice(#)', defaultValues, | |
1076 argumentCount - requiredParameterCount); | |
1077 arguments.addAll(missingDefaults); | |
1078 return JS('var', '#.apply(#, #)', jsFunction, function, arguments); | |
1079 } | |
1080 return JS('var', '#.apply(#, #)', jsStub, function, positionalArguments); | |
1081 } else { | |
1082 var interceptor = getInterceptor(function); | |
1083 var jsFunction = JS('', '#["call*"]', interceptor); | |
1084 var defaultValues = JS('JSArray', r'#[#]', function, | |
1085 JS_GET_NAME("DEFAULT_VALUES_PROPERTY")); | |
1086 List keys = JS('JSArray', r'Object.keys(#)', defaultValues); | |
1087 List arguments = new List.from(positionalArguments); | |
1088 int used = 0; | |
1089 for (String key in keys) { | |
1090 var value = namedArguments[key]; | |
floitsch
2015/02/16 15:26:03
indendation.
herhut
2015/02/17 10:25:39
Done.
| |
1091 if (value != null) { | |
1092 used++; | |
1093 arguments.add(value); | |
1094 } else { | |
1095 arguments.add(JS('var', r'#[#]', defaultValues, key)); | |
1096 } | |
1097 } | |
1098 if (used != namedArguments.length) { | |
1099 return functionNoSuchMethod(function, positionalArguments, | |
1100 namedArguments); | |
1101 } | |
1102 return JS('var', r'#.apply(#, #)', jsFunction, function, arguments); | |
1103 } | |
1104 } | |
1105 | |
1046 static applyFunction(Function function, | 1106 static applyFunction(Function function, |
1047 List positionalArguments, | 1107 List positionalArguments, |
1048 Map<String, dynamic> namedArguments) { | 1108 Map<String, dynamic> namedArguments) { |
1049 // Dispatch on presence of named arguments to improve tree-shaking. | 1109 // Dispatch on presence of named arguments to improve tree-shaking. |
1050 // | 1110 // |
1051 // This dispatch is as simple as possible to help the compiler detect the | 1111 // This dispatch is as simple as possible to help the compiler detect the |
1052 // common case of `null` namedArguments, either via inlining or | 1112 // common case of `null` namedArguments, either via inlining or |
1053 // specialization. | 1113 // specialization. |
1054 return namedArguments == null | 1114 return namedArguments == null |
1055 ? applyFunctionWithPositionalArguments( | 1115 ? applyFunctionWithPositionalArguments( |
(...skipping 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2086 for (int i = 1; i < functions.length; i++) { | 2146 for (int i = 1; i < functions.length; i++) { |
2087 var stub = functions[i]; | 2147 var stub = functions[i]; |
2088 var stubCallName = JS('String|Null', '#.\$callName', stub); | 2148 var stubCallName = JS('String|Null', '#.\$callName', stub); |
2089 if (stubCallName != null) { | 2149 if (stubCallName != null) { |
2090 JS('', '#[#] = #', prototype, stubCallName, | 2150 JS('', '#[#] = #', prototype, stubCallName, |
2091 isStatic ? stub : forwardCallTo(receiver, stub, isIntercepted)); | 2151 isStatic ? stub : forwardCallTo(receiver, stub, isIntercepted)); |
2092 } | 2152 } |
2093 } | 2153 } |
2094 | 2154 |
2095 JS('', '#["call*"] = #', prototype, trampoline); | 2155 JS('', '#["call*"] = #', prototype, trampoline); |
2156 String reqArgProperty = JS_GET_NAME("REQUIRED_PARAMETER_PROPERTY"); | |
2157 String defValProperty = JS_GET_NAME("DEFAULT_VALUES_PROPERTY"); | |
2158 JS('', '#.# = #.#', prototype, reqArgProperty, function, reqArgProperty); | |
2159 JS('', '#.# = #.#', prototype, defValProperty, function, defValProperty); | |
2096 | 2160 |
2097 return constructor; | 2161 return constructor; |
2098 } | 2162 } |
2099 | 2163 |
2100 static cspForwardCall(int arity, bool isSuperCall, String stubName, | 2164 static cspForwardCall(int arity, bool isSuperCall, String stubName, |
2101 function) { | 2165 function) { |
2102 var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf); | 2166 var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf); |
2103 // Handle intercepted stub-names with the default slow case. | 2167 // Handle intercepted stub-names with the default slow case. |
2104 if (isSuperCall) arity = -1; | 2168 if (isSuperCall) arity = -1; |
2105 switch (arity) { | 2169 switch (arity) { |
(...skipping 1614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3720 // This is a function that will return a helper function that does the | 3784 // This is a function that will return a helper function that does the |
3721 // iteration of the sync*. | 3785 // iteration of the sync*. |
3722 // | 3786 // |
3723 // Each invocation should give a helper with fresh state. | 3787 // Each invocation should give a helper with fresh state. |
3724 final dynamic /* js function */ _outerHelper; | 3788 final dynamic /* js function */ _outerHelper; |
3725 | 3789 |
3726 SyncStarIterable(this._outerHelper); | 3790 SyncStarIterable(this._outerHelper); |
3727 | 3791 |
3728 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); | 3792 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); |
3729 } | 3793 } |
OLD | NEW |