Chromium Code Reviews| 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; |
| } |