| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** A dynamic member stub. */ | 5 /** A dynamic member stub. */ |
| 6 class VarMember { | 6 class VarMember { |
| 7 final String name; | 7 final String name; |
| 8 | 8 |
| 9 VarMember(this.name); | 9 VarMember(this.name); |
| 10 | 10 |
| 11 abstract void generate(CodeWriter code); | 11 abstract void generate(CodeWriter code); |
| 12 | 12 |
| 13 Type get returnType() => world.varType; | 13 Type get returnType() => world.varType; |
| 14 | 14 |
| 15 Value invoke(MethodGenerator context, Node node, Value target, Arguments args)
{ | 15 Value invoke(MethodGenerator context, Node node, Value target, Arguments args)
{ |
| 16 return new Value(returnType, | 16 return new Value(returnType, |
| 17 '${target.code}.$name(${args.getCode()})'); | 17 '${target.code}.$name(${args.getCode()})', node.span); |
| 18 } | 18 } |
| 19 } | 19 } |
| 20 | 20 |
| 21 /** | 21 /** |
| 22 * This function generates a dynamic call stub for functions. It's part of a | 22 * This function generates a dynamic call stub for functions. It's part of a |
| 23 * series of steps described below. Most of the code is generated by | 23 * series of steps described below. Most of the code is generated by |
| 24 * gen.dart, with some helpers in core.js | 24 * gen.dart, with some helpers in core.js |
| 25 * | 25 * |
| 26 * Given a call site in Dart like: | 26 * Given a call site in Dart like: |
| 27 * f(1, 2, capture:true); | 27 * f(1, 2, capture:true); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 } | 189 } |
| 190 | 190 |
| 191 /** Invokes members to ensure they're generated. */ | 191 /** Invokes members to ensure they're generated. */ |
| 192 _invokeMembers(MethodGenerator context, Node node) { | 192 _invokeMembers(MethodGenerator context, Node node) { |
| 193 if (_fallbackStubs != null) return; | 193 if (_fallbackStubs != null) return; |
| 194 | 194 |
| 195 _fallbackStubs = []; | 195 _fallbackStubs = []; |
| 196 for (var member in members) { | 196 for (var member in members) { |
| 197 // Invoke the member with the stub args (this gives us the method body), | 197 // Invoke the member with the stub args (this gives us the method body), |
| 198 // then create the stub method. | 198 // then create the stub method. |
| 199 final target = new Value(member.declaringType, 'this'); | 199 final target = new Value(member.declaringType, 'this', node.span); |
| 200 var result = member.invoke(context, node, target, args); | 200 var result = member.invoke(context, node, target, args); |
| 201 var stub = new VarMethodStub(name, member, args, result); | 201 var stub = new VarMethodStub(name, member, args, result); |
| 202 | 202 |
| 203 // Put the stub on the type directly if possible. Otherwise | 203 // Put the stub on the type directly if possible. Otherwise |
| 204 // put the stub on Object.prototype. | 204 // put the stub on Object.prototype. |
| 205 var type = member.declaringType; | 205 var type = member.declaringType; |
| 206 if (type.library != world.dom && !type.isObject) { | 206 if (type.library != world.dom && !type.isObject) { |
| 207 _addVarStub(type, stub); | 207 _addVarStub(type, stub); |
| 208 } else { | 208 } else { |
| 209 _fallbackStubs.add(stub); | 209 _fallbackStubs.add(stub); |
| 210 } | 210 } |
| 211 } | 211 } |
| 212 | 212 |
| 213 // Finally, invoke noSuchMethod | 213 // Finally, invoke noSuchMethod |
| 214 final target = new Value(world.objectType, 'this'); | 214 final target = new Value(world.objectType, 'this', node.span); |
| 215 var result = target.invokeNoSuchMethod(context, baseName, node, args); | 215 var result = target.invokeNoSuchMethod(context, baseName, node, args); |
| 216 var stub = new VarMethodStub(name, null, args, result); | 216 var stub = new VarMethodStub(name, null, args, result); |
| 217 if (_fallbackStubs.length == 0) { | 217 if (_fallbackStubs.length == 0) { |
| 218 _addVarStub(world.objectType, stub); | 218 _addVarStub(world.objectType, stub); |
| 219 } else { | 219 } else { |
| 220 _fallbackStubs.add(stub); | 220 _fallbackStubs.add(stub); |
| 221 world.gen.corejs.useVarMethod = true; | 221 world.gen.corejs.useVarMethod = true; |
| 222 } | 222 } |
| 223 } | 223 } |
| 224 | 224 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 } | 256 } |
| 257 } | 257 } |
| 258 | 258 |
| 259 String _getCallStubName(String name, Arguments args) { | 259 String _getCallStubName(String name, Arguments args) { |
| 260 final nameBuilder = new StringBuffer('${name}\$${args.bareCount}'); | 260 final nameBuilder = new StringBuffer('${name}\$${args.bareCount}'); |
| 261 for (int i = args.bareCount; i < args.length; i++) { | 261 for (int i = args.bareCount; i < args.length; i++) { |
| 262 nameBuilder.add('\$').add(args.getName(i)); | 262 nameBuilder.add('\$').add(args.getName(i)); |
| 263 } | 263 } |
| 264 return nameBuilder.toString(); | 264 return nameBuilder.toString(); |
| 265 } | 265 } |
| OLD | NEW |