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..ee44c7f421063c5c9da1ec68031f0aec905e2ad3 100644 |
--- a/sdk/lib/_internal/compiler/js_lib/js_helper.dart |
+++ b/sdk/lib/_internal/compiler/js_lib/js_helper.dart |
@@ -1043,6 +1043,68 @@ 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")); |
+ 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('', '#[#]', interceptor, |
+ JS_GET_NAME('CALL_CATCH_ALL')); |
+ 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('', '#[#]', interceptor, |
+ JS_GET_NAME('CALL_CATCH_ALL')); |
+ 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]; |
+ 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) { |
@@ -1099,7 +1161,7 @@ class Primitives { |
// TODO(ahe): The following code can be shared with |
// JsInstanceMirror.invoke. |
var interceptor = getInterceptor(function); |
- var jsFunction = JS('', '#["call*"]', interceptor); |
+ var jsFunction = JS('', '#[#]', interceptor, JS_GET_NAME('CALL_CATCH_ALL')); |
if (jsFunction == null) { |
return functionNoSuchMethod( |
@@ -1983,7 +2045,8 @@ abstract class Closure implements Function { |
// through the namer. |
var function = JS('', '#[#]', functions, 0); |
String name = JS('String|Null', '#.\$stubName', function); |
- String callName = JS('String|Null', '#.\$callName', function); |
+ String callName = JS('String|Null', '#[#]', function, |
+ JS_GET_NAME("CALL_NAME_PROPERTY")); |
var functionType; |
if (reflectionInfo is List) { |
@@ -2085,14 +2148,19 @@ abstract class Closure implements Function { |
JS('', '#[#] = #', prototype, callName, trampoline); |
for (int i = 1; i < functions.length; i++) { |
var stub = functions[i]; |
- var stubCallName = JS('String|Null', '#.\$callName', stub); |
+ var stubCallName = JS('String|Null', '#[#]', stub, |
+ JS_GET_NAME("CALL_NAME_PROPERTY")); |
if (stubCallName != null) { |
JS('', '#[#] = #', prototype, stubCallName, |
isStatic ? stub : forwardCallTo(receiver, stub, isIntercepted)); |
} |
} |
- JS('', '#["call*"] = #', prototype, trampoline); |
+ JS('', '#[#] = #', prototype, JS_GET_NAME('CALL_CATCH_ALL'), 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; |
} |