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

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

Issue 10092012: Fix issue 2358: dart methods on native classes must also check if the current prototype has the met… (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
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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // must be turned into a JS call to: 153 // must be turned into a JS call to:
154 // foo(null, y). 154 // foo(null, y).
155 155
156 List<String> nativeArgumentsBuffer = argumentsBuffer.getRange( 156 List<String> nativeArgumentsBuffer = argumentsBuffer.getRange(
157 0, indexOfLastOptionalArgumentInParameters + 1); 157 0, indexOfLastOptionalArgumentInParameters + 1);
158 158
159 ClassElement classElement = member.enclosingElement; 159 ClassElement classElement = member.enclosingElement;
160 String nativeName = classElement.nativeName.slowToString(); 160 String nativeName = classElement.nativeName.slowToString();
161 String nativeArguments = Strings.join(nativeArgumentsBuffer, ","); 161 String nativeArguments = Strings.join(nativeArgumentsBuffer, ",");
162 162
163 String name = member.name.slowToString();
164 String code = ' return this.$name($nativeArguments);\n';
163 if (isNativeLiteral(nativeName) || !overriddenMethods.contains(member)) { 165 if (isNativeLiteral(nativeName) || !overriddenMethods.contains(member)) {
164 // Call the method directly. 166 // Call the method directly.
165 buffer.add(' return this.${member.name.slowToString()}'); 167 buffer.add(code);
166 buffer.add('($nativeArguments)'); 168 } else {
167 return; 169 native.generateMethodWithPrototypeCheck(
170 compiler, buffer, invocationName, code, stubParameters);
168 } 171 }
169
170 // If the method is overridden, we must check if the prototype of
171 // 'this' has the method available. Otherwise, we may end up
172 // calling the method from the super class. If the method is not
173 // available, we make a direct call to
174 // Object.prototype.$invocationName. This method will patch the
175 // prototype of 'this' to the real method.
176
177 buffer.add(' if (Object.getPrototypeOf(this).hasOwnProperty(');
178 buffer.add("'$invocationName')) {\n");
179 buffer.add(' return this.${member.name.slowToString()}');
180 buffer.add('($nativeArguments)');
181 buffer.add('\n }\n');
182 buffer.add(' return Object.prototype.$invocationName.call(this');
183 buffer.add(stubParameters == '' ? '' : ', $stubParameters');
184 buffer.add(');');
185 } 172 }
186 173
187 void emitDynamicDispatchMetadata() { 174 void emitDynamicDispatchMetadata() {
188 if (classesWithDynamicDispatch.isEmpty()) return; 175 if (classesWithDynamicDispatch.isEmpty()) return;
189 buffer.add('// ${classesWithDynamicDispatch.length} dynamic classes.\n'); 176 buffer.add('// ${classesWithDynamicDispatch.length} dynamic classes.\n');
190 177
191 // Build a pre-order traversal over all the classes and their subclasses. 178 // Build a pre-order traversal over all the classes and their subclasses.
192 Set<ClassElement> seen = new Set<ClassElement>(); 179 Set<ClassElement> seen = new Set<ClassElement>();
193 List<ClassElement> classes = <ClassElement>[]; 180 List<ClassElement> classes = <ClassElement>[];
194 void visit(ClassElement cls) { 181 void visit(ClassElement cls) {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 String toStringName = compiler.namer.instanceMethodName( 334 String toStringName = compiler.namer.instanceMethodName(
348 null, const SourceString('toString'), 0); 335 null, const SourceString('toString'), 0);
349 objectProperties.add("$defPropName(Object.prototype, '$toStringName', "); 336 objectProperties.add("$defPropName(Object.prototype, '$toStringName', ");
350 objectProperties.add( 337 objectProperties.add(
351 'function() { return $toStringHelperName(this); });\n'); 338 'function() { return $toStringHelperName(this); });\n');
352 339
353 // Finally, emit the code in the main buffer. 340 // Finally, emit the code in the main buffer.
354 targetBuffer.add('(function() {\n$objectProperties$buffer\n})();\n'); 341 targetBuffer.add('(function() {\n$objectProperties$buffer\n})();\n');
355 } 342 }
356 } 343 }
OLDNEW
« no previous file with comments | « frog/tests/native/src/NativeClassInheritance4FrogTest.dart ('k') | lib/compiler/implementation/native_handler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698