Index: sdk/lib/_internal/compiler/js_lib/js_helper.dart |
diff --git a/sdk/lib/_internal/compiler/js_lib/js_helper.dart b/sdk/lib/_internal/compiler/js_lib/js_helper.dart |
index b1705388bd0b3cd0032f832cf4e66c74dea001a6..b3065f24a7eda8f02283048851e0bebf0c4ded03 100644 |
--- a/sdk/lib/_internal/compiler/js_lib/js_helper.dart |
+++ b/sdk/lib/_internal/compiler/js_lib/js_helper.dart |
@@ -1043,6 +1043,66 @@ class Primitives { |
namedArgumentList)); |
} |
+ static applyFunctionNewEmitter(Function function, |
+ List positionalArguments, |
+ Map<String, dynamic> namedArguments) { |
+ if (namedArguments == null) { |
+ int requiredParameterCount = JS('int', r'#[#]', function, |
+ 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.
|
+ int argumentCount = positionalArguments.length; |
+ if (argumentCount < requiredParameterCount) { |
+ return functionNoSuchMethod(function, positionalArguments, null); |
+ } |
+ String selectorName = '${JS_GET_NAME("CALL_PREFIX")}\$$argumentCount'; |
+ var jsStub = JS('var', r'#[#]', function, selectorName); |
+ if (jsStub == null) { |
+ // Do a dynamic call. |
+ var interceptor = getInterceptor(function); |
+ 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.
|
+ var defaultValues = JS('var', r'#[#]', function, |
+ JS_GET_NAME("DEFAULT_VALUES_PROPERTY")); |
+ if (!JS('bool', '# instanceof Array', defaultValues)) { |
+ // The function expects named arguments! |
+ return functionNoSuchMethod(function, positionalArguments, null); |
+ } |
+ int defaultsLength = JS('int', "#.length", defaultValues); |
+ int maxArguments = requiredParameterCount + defaultsLength; |
+ if (argumentCount > maxArguments) { |
+ // The function expects less arguments! |
+ return functionNoSuchMethod(function, positionalArguments, null); |
+ } |
+ List arguments = new List.from(positionalArguments); |
+ List missingDefaults = JS('JSArray', '#.slice(#)', defaultValues, |
+ argumentCount - requiredParameterCount); |
+ arguments.addAll(missingDefaults); |
+ return JS('var', '#.apply(#, #)', jsFunction, function, arguments); |
+ } |
+ return JS('var', '#.apply(#, #)', jsStub, function, positionalArguments); |
+ } else { |
+ var interceptor = getInterceptor(function); |
+ var jsFunction = JS('', '#["call*"]', interceptor); |
+ var defaultValues = JS('JSArray', r'#[#]', function, |
+ JS_GET_NAME("DEFAULT_VALUES_PROPERTY")); |
+ List keys = JS('JSArray', r'Object.keys(#)', defaultValues); |
+ List arguments = new List.from(positionalArguments); |
+ int used = 0; |
+ for (String key in keys) { |
+ var value = namedArguments[key]; |
floitsch
2015/02/16 15:26:03
indendation.
herhut
2015/02/17 10:25:39
Done.
|
+ if (value != null) { |
+ used++; |
+ arguments.add(value); |
+ } else { |
+ arguments.add(JS('var', r'#[#]', defaultValues, key)); |
+ } |
+ } |
+ if (used != namedArguments.length) { |
+ return functionNoSuchMethod(function, positionalArguments, |
+ namedArguments); |
+ } |
+ return JS('var', r'#.apply(#, #)', jsFunction, function, arguments); |
+ } |
+ } |
+ |
static applyFunction(Function function, |
List positionalArguments, |
Map<String, dynamic> namedArguments) { |
@@ -2093,6 +2153,10 @@ abstract class Closure implements Function { |
} |
JS('', '#["call*"] = #', prototype, trampoline); |
+ String reqArgProperty = JS_GET_NAME("REQUIRED_PARAMETER_PROPERTY"); |
+ String defValProperty = JS_GET_NAME("DEFAULT_VALUES_PROPERTY"); |
+ JS('', '#.# = #.#', prototype, reqArgProperty, function, reqArgProperty); |
+ JS('', '#.# = #.#', prototype, defValProperty, function, defValProperty); |
return constructor; |
} |