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

Side by Side Diff: lib/compiler/implementation/native_emitter.dart

Issue 10108012: Fix for issue 2468: also convert Dart closures to Js closures in stubs for native methods. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/tests/native/src/NativeWrappingFunction3FrogTest.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 class NativeEmitter { 5 class NativeEmitter {
6 6
7 Compiler compiler; 7 Compiler compiler;
8 StringBuffer buffer; 8 StringBuffer buffer;
9 9
10 // Classes that participate in dynamic dispatch. These are the 10 // Classes that participate in dynamic dispatch. These are the
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 132
133 if (hasUsedSelectors) classesWithDynamicDispatch.add(classElement); 133 if (hasUsedSelectors) classesWithDynamicDispatch.add(classElement);
134 } 134 }
135 135
136 List<ClassElement> getDirectSubclasses(ClassElement cls) { 136 List<ClassElement> getDirectSubclasses(ClassElement cls) {
137 List<ClassElement> result = subtypes[cls]; 137 List<ClassElement> result = subtypes[cls];
138 if (result === null) result = const<ClassElement>[]; 138 if (result === null) result = const<ClassElement>[];
139 return result; 139 return result;
140 } 140 }
141 141
142 void potentiallyConvertDartClosuresToJs(StringBuffer code,
143 FunctionElement member) {
144 FunctionParameters parameters = member.computeParameters(compiler);
145 Element converter =
146 compiler.findHelper(const SourceString('convertDartClosureToJS'));
147 String closureConverter = compiler.namer.isolateAccess(converter);
148 parameters.forEachParameter((Element parameter) {
149 Type type = parameter.computeType(compiler);
150 if (type is FunctionType) {
151 String name = parameter.name.slowToString();
152 code.add(' $name = $closureConverter($name);\n');
153 }
154 });
155 }
156
142 void emitParameterStub(Element member, 157 void emitParameterStub(Element member,
143 String invocationName, 158 String invocationName,
144 String stubParameters, 159 String stubParameters,
145 List<String> argumentsBuffer, 160 List<String> argumentsBuffer,
146 int indexOfLastOptionalArgumentInParameters) { 161 int indexOfLastOptionalArgumentInParameters) {
147 // The target JS function may check arguments.length so we need to 162 // The target JS function may check arguments.length so we need to
148 // make sure not to pass any unspecified optional arguments to it. 163 // make sure not to pass any unspecified optional arguments to it.
149 // For example, for the following Dart method: 164 // For example, for the following Dart method:
150 // foo([x, y, z]); 165 // foo([x, y, z]);
151 // The call: 166 // The call:
152 // foo(y: 1) 167 // foo(y: 1)
153 // must be turned into a JS call to: 168 // must be turned into a JS call to:
154 // foo(null, y). 169 // foo(null, y).
155 170
156 List<String> nativeArgumentsBuffer = argumentsBuffer.getRange( 171 List<String> nativeArgumentsBuffer = argumentsBuffer.getRange(
157 0, indexOfLastOptionalArgumentInParameters + 1); 172 0, indexOfLastOptionalArgumentInParameters + 1);
158 173
159 ClassElement classElement = member.enclosingElement; 174 ClassElement classElement = member.enclosingElement;
160 String nativeName = classElement.nativeName.slowToString(); 175 String nativeName = classElement.nativeName.slowToString();
161 String nativeArguments = Strings.join(nativeArgumentsBuffer, ","); 176 String nativeArguments = Strings.join(nativeArgumentsBuffer, ",");
162 177
178 StringBuffer code = new StringBuffer();
179 potentiallyConvertDartClosuresToJs(code, member);
180
163 String name = member.name.slowToString(); 181 String name = member.name.slowToString();
164 String code = ' return this.$name($nativeArguments);\n'; 182 code.add(' return this.$name($nativeArguments);');
183
165 if (isNativeLiteral(nativeName) || !overriddenMethods.contains(member)) { 184 if (isNativeLiteral(nativeName) || !overriddenMethods.contains(member)) {
166 // Call the method directly. 185 // Call the method directly.
167 buffer.add(code); 186 buffer.add(code.toString());
168 } else { 187 } else {
169 native.generateMethodWithPrototypeCheck( 188 native.generateMethodWithPrototypeCheck(
170 compiler, buffer, invocationName, code, stubParameters); 189 compiler, buffer, invocationName, code.toString(), stubParameters);
171 } 190 }
172 } 191 }
173 192
174 void emitDynamicDispatchMetadata() { 193 void emitDynamicDispatchMetadata() {
175 if (classesWithDynamicDispatch.isEmpty()) return; 194 if (classesWithDynamicDispatch.isEmpty()) return;
176 buffer.add('// ${classesWithDynamicDispatch.length} dynamic classes.\n'); 195 buffer.add('// ${classesWithDynamicDispatch.length} dynamic classes.\n');
177 196
178 // Build a pre-order traversal over all the classes and their subclasses. 197 // Build a pre-order traversal over all the classes and their subclasses.
179 Set<ClassElement> seen = new Set<ClassElement>(); 198 Set<ClassElement> seen = new Set<ClassElement>();
180 List<ClassElement> classes = <ClassElement>[]; 199 List<ClassElement> classes = <ClassElement>[];
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 String toStringName = compiler.namer.instanceMethodName( 353 String toStringName = compiler.namer.instanceMethodName(
335 null, const SourceString('toString'), 0); 354 null, const SourceString('toString'), 0);
336 objectProperties.add("$defPropName(Object.prototype, '$toStringName', "); 355 objectProperties.add("$defPropName(Object.prototype, '$toStringName', ");
337 objectProperties.add( 356 objectProperties.add(
338 'function() { return $toStringHelperName(this); });\n'); 357 'function() { return $toStringHelperName(this); });\n');
339 358
340 // Finally, emit the code in the main buffer. 359 // Finally, emit the code in the main buffer.
341 targetBuffer.add('(function() {\n$objectProperties$buffer\n})();\n'); 360 targetBuffer.add('(function() {\n$objectProperties$buffer\n})();\n');
342 } 361 }
343 } 362 }
OLDNEW
« no previous file with comments | « frog/tests/native/src/NativeWrappingFunction3FrogTest.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698