Chromium Code Reviews| 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 ba0f2974d4253f6394045b2f69a6986860fafd53..9f4538222f9b6e80497279692cf87b06f8bb5495 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 |
| @@ -22,7 +22,7 @@ import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show |
| METADATA, |
| TYPE_TO_INTERCEPTOR_MAP; |
| -import '../js_emitter.dart' show NativeGenerator; |
| +import '../js_emitter.dart' show NativeGenerator, buildTearOffCode; |
| import '../model.dart'; |
| class ModelEmitter { |
| @@ -108,6 +108,9 @@ class ModelEmitter { |
| boilerplate, |
| {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap), |
| 'holders': emitHolders(fragment.holders), |
| + 'tearOff': buildTearOffCode(backend), |
| + 'parseFunctionDescriptor': |
| + js.js.statement(parseFunctionDescriptorBoilerplate), |
| 'cyclicThrow': |
| backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()), |
| 'outputContainsConstantList': program.outputContainsConstantList, |
| @@ -409,20 +412,24 @@ class ModelEmitter { |
| return unparse(compiler, field.code); |
| } |
| - static final String tearOffBoilerplate = """ |
| -function(prototype, tearOffDescriptor) { |
| - prototype[tearOffDescriptor[0]] = tearOffDescriptor[1]; |
| - for (var i = 3; i < tearOffDescriptor.length; i += 3) { |
| - // Copy over the adapter stubs. |
| - prototype[tearOffDescriptor[i]] = tearOffDescriptor[i + 2]; |
| - } |
| - // Build the functions map. |
| - var funcs = Object.create(null); |
| - for (var i = 3; i < tearOffDescriptor.length; i += 3) { |
| - // Copy over the adapter stubs. |
| - prototype[tearOffDescriptor[i]] = tearOffDescriptor[i + 2]; |
| + static final String parseFunctionDescriptorBoilerplate = r""" |
| +function parseFunctionDescriptor(proto, name, desc) { |
| + if (desc instanceof Array) { |
| + proto[name] = desc[0]; |
| + var funs = [desc[0]]; |
| + funs[0].$callName = desc[1]; |
| + for (var pos = 4; pos < desc.length; pos += 3) { |
| + var stub = desc[pos+2]; |
| + stub.$callName = desc[pos+1]; |
| + proto[desc[pos]] = stub; |
| + funs.push(stub); |
| + } |
| + if (desc[2] != null) { |
| + proto[desc[2]] = tearOff(funs, desc[3], false, name, false); |
| + } |
| + } else { |
| + proto[name] = desc; |
| } |
| - |
| } |
| """; |
| @@ -441,10 +448,14 @@ function(prototype, tearOffDescriptor) { |
| if (method is DartMethod) { |
| if (method.needsTearOff) { |
| - var data = makeNameCodePair(method); |
| + // [name, [function, callName, tearOffName, functionType, |
| + // stub1_name, stub1_callName, stub1_code, ...] |
| + var data = [method.code]; |
| + data.add(js.string(method.callName)); |
| data.add(js.string(method.tearOffName)); |
| + data.add(new js.LiteralNull()); |
| data.addAll(method.adapterStubs.expand(makeNameCallNameCodeTriplet)); |
| - return [new js.ArrayInitializer(data)]; |
| + return [js.string(method.name), new js.ArrayInitializer(data)]; |
| } else { |
| // TODO(floitsch): not the most efficient way... |
| return ([method]..addAll(method.adapterStubs)).expand(makeNameCodePair); |
| @@ -479,7 +490,7 @@ function(prototype, tearOffDescriptor) { |
| #deferredInitializer; |
| !function(start, program) { |
| - |
| + var functionCounter = 0; |
| // Initialize holder objects. |
| #holders; |
| @@ -568,6 +579,10 @@ function(prototype, tearOffDescriptor) { |
| holder[name] = patch; |
| } |
| + #tearOff; |
| + |
| + #parseFunctionDescriptor; |
| + |
| function compileConstructor(name, descriptor) { |
| descriptor = compile(name, descriptor); |
| var prototype = determinePrototype(descriptor); |
| @@ -576,12 +591,12 @@ function(prototype, tearOffDescriptor) { |
| if (typeof descriptor[2] !== 'function') { |
| constructor = compileMixinConstructor(name, prototype, descriptor); |
| for (var i = 4; i < descriptor.length; i += 2) { |
| - prototype[descriptor[i]] = descriptor[i + 1]; |
| + parseFunctionDescriptor(prototype, descriptor); |
| } |
| } else { |
| constructor = descriptor[2]; |
| for (var i = 3; i < descriptor.length; i += 2) { |
| - prototype[descriptor[i]] = descriptor[i + 1]; |
| + parseFunctionDescriptor(prototype, descriptor[i], descriptor[i+1]); |
|
floitsch
2015/01/30 22:08:39
Don't remove the spaces of "i + 1".
|
| } |
| } |
| constructor.builtin\$cls = name; // Needed for RTI. |