Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(615)

Unified Diff: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart

Issue 928203003: Implement Function.apply in the new emitter. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor fix Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/model.dart ('k') | pkg/compiler/lib/src/js_emitter/program_builder.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
index ad7057b5154513348953c6f6d30b6f2a4cd1bfc7..d6272700206cab5d3a90d3da3aff06ba682a3717 100644
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
@@ -4,6 +4,7 @@
library dart2js.new_js_emitter.model_emitter;
+import '../../constants/values.dart' show ConstantValue;
import '../../dart2jslib.dart' show Compiler;
import '../../dart_types.dart' show DartType;
import '../../elements/elements.dart' show ClassElement;
@@ -113,7 +114,11 @@ class ModelEmitter {
'holders': emitHolders(program.holders),
'tearOff': buildTearOffCode(backend),
'parseFunctionDescriptor':
- js.js.statement(parseFunctionDescriptorBoilerplate),
+ js.js.statement(parseFunctionDescriptorBoilerplate,
+ {'argCnt': js.string(namer.requiredParameterField),
+ 'defArgValues': js.string(namer.defaultValuesField),
+ 'callName': js.string(namer.callNameField)}),
+
'cyclicThrow':
backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()),
'outputContainsConstantList': program.outputContainsConstantList,
@@ -122,6 +127,7 @@ class ModelEmitter {
'staticNonFinals':
emitStaticNonFinalFields(fragment.staticNonFinalFields),
'operatorIsPrefix': js.string(namer.operatorIsPrefix),
+ 'callName': js.string(namer.callNameField),
'eagerClasses': emitEagerClassInitializations(fragment.libraries),
'invokeMain': fragment.invokeMain,
'code': code};
@@ -552,19 +558,27 @@ class ModelEmitter {
/// facilitate the generation of tearOffs at runtime. The format is an array
/// with the following fields:
///
- /// [InstanceMethod.aliasName] (optional).
- /// [Method.code]
- /// [DartMethod.callName]
- /// isInterceptedMethod (optional, present if [DartMethod.needsTearOff]).
- /// [DartMethod.tearOffName] (optional, present if [DartMethod.needsTearOff]).
- /// functionType (optional, present if [DartMethod.needsTearOff]).
+ /// * [InstanceMethod.aliasName] (optional).
+ /// * [Method.code]
+ /// * [DartMethod.callName]
+ /// * isInterceptedMethod (optional, present if [DartMethod.needsTearOff]).
+ /// * [DartMethod.tearOffName] (optional, present if
+ /// [DartMethod.needsTearOff]).
+ /// * functionType (optional, present if [DartMethod.needsTearOff]).
///
/// followed by
///
- /// [ParameterStubMethod.name]
- /// [ParameterStubMethod.code]
+ /// * [ParameterStubMethod.name]
+ /// * [ParameterStubMethod.callName]
+ /// * [ParameterStubMethod.code]
///
/// for each stub in [DartMethod.parameterStubs].
+ ///
+ /// If the closure could be used in `Function.apply` (i.e.
+ /// [DartMethod.canBeApplied] is true) then the following fields are appended:
+ ///
+ /// * [DartMethod.requiredParameterCount]
+ /// * [DartMethod.optionalParameterDefaultValues]
static final String parseFunctionDescriptorBoilerplate = r"""
function parseFunctionDescriptor(proto, name, descriptor) {
@@ -581,7 +595,7 @@ function parseFunctionDescriptor(proto, name, descriptor) {
proto[name] = f;
var funs = [f];
- f.$callName = descriptor[++pos];
+ f[#callName] = descriptor[++pos];
var isInterceptedOrParameterStubName = descriptor[pos + 1];
var isIntercepted, tearOffName, reflectionInfo;
@@ -591,9 +605,12 @@ function parseFunctionDescriptor(proto, name, descriptor) {
reflectionInfo = descriptor[++pos];
}
- for (++pos; pos < descriptor.length; pos += 3) {
+ // We iterate in blocks of 3 but have to stop before we reach the (optional)
+ // two trailing items. To accomplish this, we only iterate until we reach
+ // length - 2.
+ for (++pos; pos < descriptor.length - 2; pos += 3) {
var stub = descriptor[pos + 2];
- stub.$callName = descriptor[pos + 1];
+ stub[#callName] = descriptor[pos + 1];
proto[descriptor[pos]] = stub;
funs.push(stub);
}
@@ -602,7 +619,10 @@ function parseFunctionDescriptor(proto, name, descriptor) {
proto[tearOffName] =
tearOff(funs, reflectionInfo, false, name, isIntercepted);
}
-
+ if (descriptor[pos] != null) {
+ f[#argCnt] = descriptor[pos];
+ f[#defArgValues] = descriptor[pos + 1];
+ }
} else {
proto[name] = descriptor;
}
@@ -618,6 +638,24 @@ function parseFunctionDescriptor(proto, name, descriptor) {
}
}
+ js.Expression _encodeOptionalParameterDefaultValues(DartMethod method) {
+ js.Expression result;
+ // TODO(herhut): Replace [js.LiteralNull] with [js.ArrayHole].
+ if (method.optionalParameterDefaultValues is List) {
+ List<ConstantValue> defs = method.optionalParameterDefaultValues;
+ Iterable<js.Expression> elements = defs.map(constantEmitter.reference);
+ return new js.ArrayInitializer(elements.toList());
+ } else {
+ Map<String, ConstantValue> defs = method.optionalParameterDefaultValues;
+ List<js.Property> properties = <js.Property>[];
+ defs.forEach((String name, ConstantValue value) {
+ properties.add(new js.Property(js.string(name),
+ constantEmitter.reference(value)));
+ });
+ return new js.ObjectInitializer(properties);
+ }
+ }
+
Iterable<js.Expression> emitInstanceMethod(Method method) {
List<js.Expression> makeNameCodePair(Method method) {
@@ -652,6 +690,10 @@ function parseFunctionDescriptor(proto, name, descriptor) {
}
data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet));
+ if (method.canBeApplied) {
+ data.add(js.number(method.requiredParameterCount));
+ data.add(_encodeOptionalParameterDefaultValues(method));
+ }
return [js.string(method.name), new js.ArrayInitializer(data)];
} else {
// TODO(floitsch): not the most efficient way...
@@ -695,6 +737,10 @@ function parseFunctionDescriptor(proto, name, descriptor) {
data.add(js.string(method.tearOffName));
data.add(_generateFunctionType(method.type));
data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet));
+ if (method.canBeApplied) {
+ data.add(js.number(method.requiredParameterCount));
+ data.add(_encodeOptionalParameterDefaultValues(method));
+ }
return [js.string(method.name), holderIndex,
new js.ArrayInitializer(data)];
} else {
@@ -782,13 +828,13 @@ function parseFunctionDescriptor(proto, name, descriptor) {
function compileAllStubs() {
var funs;
var fun = compile(name, descriptor[0]);
- fun.\$callName = descriptor[1];
+ fun[#callName] = descriptor[1];
holder[name] = fun;
funs = [fun];
for (var pos = 4; pos < descriptor.length; pos += 3) {
var stubName = descriptor[pos];
fun = compile(stubName, descriptor[pos + 2]);
- fun.\$callName = descriptor[pos + 1];
+ fun[#callName] = descriptor[pos + 1];
holder[stubName] = fun;
funs.push(fun);
}
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/model.dart ('k') | pkg/compiler/lib/src/js_emitter/program_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698