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

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

Issue 11238035: Make isEmpty a getter. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update status file with co19 issue number. Created 8 years, 2 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 CodeEmitterTask emitter; 7 CodeEmitterTask emitter;
8 CodeBuffer nativeBuffer; 8 CodeBuffer nativeBuffer;
9 9
10 // Classes that participate in dynamic dispatch. These are the 10 // Classes that participate in dynamic dispatch. These are the
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 // Global object, just be like the other types for now. 146 // Global object, just be like the other types for now.
147 return quotedName.substring(3, quotedName.length - 1); 147 return quotedName.substring(3, quotedName.length - 1);
148 } else { 148 } else {
149 return quotedName.substring(2, quotedName.length - 1); 149 return quotedName.substring(2, quotedName.length - 1);
150 } 150 }
151 } 151 }
152 152
153 void generateNativeClass(ClassElement classElement) { 153 void generateNativeClass(ClassElement classElement) {
154 nativeClasses.add(classElement); 154 nativeClasses.add(classElement);
155 155
156 assert(classElement.backendMembers.isEmpty()); 156 assert(classElement.backendMembers.isEmpty);
157 String quotedName = classElement.nativeName.slowToString(); 157 String quotedName = classElement.nativeName.slowToString();
158 if (isNativeLiteral(quotedName)) { 158 if (isNativeLiteral(quotedName)) {
159 generateNativeLiteral(classElement); 159 generateNativeLiteral(classElement);
160 // The native literal kind needs to be dealt with specially when 160 // The native literal kind needs to be dealt with specially when
161 // generating code for it. 161 // generating code for it.
162 return; 162 return;
163 } 163 }
164 164
165 CodeBuffer fieldBuffer = new CodeBuffer(); 165 CodeBuffer fieldBuffer = new CodeBuffer();
166 CodeBuffer getterSetterBuffer = new CodeBuffer(); 166 CodeBuffer getterSetterBuffer = new CodeBuffer();
167 167
168 emitter.emitClassFields(classElement, fieldBuffer); 168 emitter.emitClassFields(classElement, fieldBuffer);
169 emitter.emitClassGettersSetters(classElement, getterSetterBuffer, 169 emitter.emitClassGettersSetters(classElement, getterSetterBuffer,
170 omitLeadingComma: true); 170 omitLeadingComma: true);
171 171
172 CodeBuffer methodBuffer = new CodeBuffer(); 172 CodeBuffer methodBuffer = new CodeBuffer();
173 emitter.emitInstanceMembers(classElement, methodBuffer, false); 173 emitter.emitInstanceMembers(classElement, methodBuffer, false);
174 174
175 if (methodBuffer.isEmpty() 175 if (methodBuffer.isEmpty
176 && fieldBuffer.isEmpty() 176 && fieldBuffer.isEmpty
177 && getterSetterBuffer.isEmpty()) { 177 && getterSetterBuffer.isEmpty) {
178 return; 178 return;
179 } 179 }
180 180
181 String nativeName = toNativeName(classElement); 181 String nativeName = toNativeName(classElement);
182 nativeBuffer.add("$defineNativeClassName('$nativeName', "); 182 nativeBuffer.add("$defineNativeClassName('$nativeName', ");
183 nativeBuffer.add('{'); 183 nativeBuffer.add('{');
184 bool firstInMap = true; 184 bool firstInMap = true;
185 if (!fieldBuffer.isEmpty()) { 185 if (!fieldBuffer.isEmpty) {
186 firstInMap = false; 186 firstInMap = false;
187 nativeBuffer.add(fieldBuffer); 187 nativeBuffer.add(fieldBuffer);
188 } 188 }
189 if (!getterSetterBuffer.isEmpty()) { 189 if (!getterSetterBuffer.isEmpty) {
190 if (!firstInMap) nativeBuffer.add(","); 190 if (!firstInMap) nativeBuffer.add(",");
191 firstInMap = false; 191 firstInMap = false;
192 nativeBuffer.add("\n "); 192 nativeBuffer.add("\n ");
193 nativeBuffer.add(getterSetterBuffer); 193 nativeBuffer.add(getterSetterBuffer);
194 } 194 }
195 if (!methodBuffer.isEmpty()) { 195 if (!methodBuffer.isEmpty) {
196 if (!firstInMap) nativeBuffer.add(","); 196 if (!firstInMap) nativeBuffer.add(",");
197 nativeBuffer.add(methodBuffer); 197 nativeBuffer.add(methodBuffer);
198 } 198 }
199 nativeBuffer.add('\n});\n\n'); 199 nativeBuffer.add('\n});\n\n');
200 200
201 classesWithDynamicDispatch.add(classElement); 201 classesWithDynamicDispatch.add(classElement);
202 } 202 }
203 203
204 List<ClassElement> getDirectSubclasses(ClassElement cls) { 204 List<ClassElement> getDirectSubclasses(ClassElement cls) {
205 List<ClassElement> result = directSubtypes[cls]; 205 List<ClassElement> result = directSubtypes[cls];
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 if (isNativeLiteral(nativeName) || !overriddenMethods.contains(member)) { 268 if (isNativeLiteral(nativeName) || !overriddenMethods.contains(member)) {
269 // Call the method directly. 269 // Call the method directly.
270 buffer.add(code.toString()); 270 buffer.add(code.toString());
271 } else { 271 } else {
272 native.generateMethodWithPrototypeCheck( 272 native.generateMethodWithPrototypeCheck(
273 compiler, buffer, invocationName, code.toString(), stubParameters); 273 compiler, buffer, invocationName, code.toString(), stubParameters);
274 } 274 }
275 } 275 }
276 276
277 void emitDynamicDispatchMetadata() { 277 void emitDynamicDispatchMetadata() {
278 if (classesWithDynamicDispatch.isEmpty()) return; 278 if (classesWithDynamicDispatch.isEmpty) return;
279 int length = classesWithDynamicDispatch.length; 279 int length = classesWithDynamicDispatch.length;
280 nativeBuffer.add('// $length dynamic classes.\n'); 280 nativeBuffer.add('// $length dynamic classes.\n');
281 281
282 // Build a pre-order traversal over all the classes and their subclasses. 282 // Build a pre-order traversal over all the classes and their subclasses.
283 Set<ClassElement> seen = new Set<ClassElement>(); 283 Set<ClassElement> seen = new Set<ClassElement>();
284 List<ClassElement> classes = <ClassElement>[]; 284 List<ClassElement> classes = <ClassElement>[];
285 void visit(ClassElement cls) { 285 void visit(ClassElement cls) {
286 if (seen.contains(cls)) return; 286 if (seen.contains(cls)) return;
287 seen.add(cls); 287 seen.add(cls);
288 for (final ClassElement subclass in getDirectSubclasses(cls)) { 288 for (final ClassElement subclass in getDirectSubclasses(cls)) {
289 visit(subclass); 289 visit(subclass);
290 } 290 }
291 classes.add(cls); 291 classes.add(cls);
292 } 292 }
293 for (final ClassElement classElement in classesWithDynamicDispatch) { 293 for (final ClassElement classElement in classesWithDynamicDispatch) {
294 visit(classElement); 294 visit(classElement);
295 } 295 }
296 296
297 Collection<ClassElement> dispatchClasses = classes.filter( 297 Collection<ClassElement> dispatchClasses = classes.filter(
298 (cls) => !getDirectSubclasses(cls).isEmpty() && 298 (cls) => !getDirectSubclasses(cls).isEmpty &&
299 classesWithDynamicDispatch.contains(cls)); 299 classesWithDynamicDispatch.contains(cls));
300 300
301 nativeBuffer.add('// ${classes.length} classes\n'); 301 nativeBuffer.add('// ${classes.length} classes\n');
302 Collection<ClassElement> classesThatHaveSubclasses = classes.filter( 302 Collection<ClassElement> classesThatHaveSubclasses = classes.filter(
303 (ClassElement t) => !getDirectSubclasses(t).isEmpty()); 303 (ClassElement t) => !getDirectSubclasses(t).isEmpty);
304 nativeBuffer.add('// ${classesThatHaveSubclasses.length} !leaf\n'); 304 nativeBuffer.add('// ${classesThatHaveSubclasses.length} !leaf\n');
305 305
306 // Generate code that builds the map from cls tags used in dynamic dispatch 306 // Generate code that builds the map from cls tags used in dynamic dispatch
307 // to the set of cls tags of classes that extend (TODO: or implement) those 307 // to the set of cls tags of classes that extend (TODO: or implement) those
308 // classes. The set is represented as a string of tags joined with '|'. 308 // classes. The set is represented as a string of tags joined with '|'.
309 // This is easily split into an array of tags, or converted into a regexp. 309 // This is easily split into an array of tags, or converted into a regexp.
310 // 310 //
311 // To reduce the size of the sets, subsets are CSE-ed out into variables. 311 // To reduce the size of the sets, subsets are CSE-ed out into variables.
312 // The sets could be much smaller if we could make assumptions about the 312 // The sets could be much smaller if we could make assumptions about the
313 // cls tags of other classes (which are constructor names or part of the 313 // cls tags of other classes (which are constructor names or part of the
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 expression = "[${Strings.join(expressions, ',')}].join('|')"; 358 expression = "[${Strings.join(expressions, ',')}].join('|')";
359 } 359 }
360 return expression; 360 return expression;
361 } 361 }
362 362
363 for (final ClassElement classElement in dispatchClasses) { 363 for (final ClassElement classElement in dispatchClasses) {
364 tagDefns[classElement] = makeExpression(classElement); 364 tagDefns[classElement] = makeExpression(classElement);
365 } 365 }
366 366
367 // Write out a thunk that builds the metadata. 367 // Write out a thunk that builds the metadata.
368 if (!tagDefns.isEmpty()) { 368 if (!tagDefns.isEmpty) {
369 nativeBuffer.add('(function(){\n'); 369 nativeBuffer.add('(function(){\n');
370 370
371 for (final String varName in varNames) { 371 for (final String varName in varNames) {
372 nativeBuffer.add(' var ${varName} = ${varDefns[varName]};\n'); 372 nativeBuffer.add(' var ${varName} = ${varDefns[varName]};\n');
373 } 373 }
374 374
375 nativeBuffer.add(' var table = [\n'); 375 nativeBuffer.add(' var table = [\n');
376 nativeBuffer.add( 376 nativeBuffer.add(
377 ' // [dynamic-dispatch-tag, ' 377 ' // [dynamic-dispatch-tag, '
378 'tags of classes implementing dynamic-dispatch-tag]'); 378 'tags of classes implementing dynamic-dispatch-tag]');
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 void emitIsChecks(Map<String, String> objectProperties) { 419 void emitIsChecks(Map<String, String> objectProperties) {
420 for (Element element in emitter.checkedClasses) { 420 for (Element element in emitter.checkedClasses) {
421 if (!requiresNativeIsCheck(element)) continue; 421 if (!requiresNativeIsCheck(element)) continue;
422 if (element.isObject(compiler)) continue; 422 if (element.isObject(compiler)) continue;
423 String name = backend.namer.operatorIs(element); 423 String name = backend.namer.operatorIs(element);
424 objectProperties[name] = 'function() { return false; }'; 424 objectProperties[name] = 'function() { return false; }';
425 } 425 }
426 } 426 }
427 427
428 void assembleCode(CodeBuffer targetBuffer) { 428 void assembleCode(CodeBuffer targetBuffer) {
429 if (nativeClasses.isEmpty()) return; 429 if (nativeClasses.isEmpty) return;
430 emitDynamicDispatchMetadata(); 430 emitDynamicDispatchMetadata();
431 targetBuffer.add('$defineNativeClassName = ' 431 targetBuffer.add('$defineNativeClassName = '
432 '$defineNativeClassFunction;\n\n'); 432 '$defineNativeClassFunction;\n\n');
433 433
434 // Because of native classes, we have to generate some is checks 434 // Because of native classes, we have to generate some is checks
435 // by calling a method, instead of accessing a property. So we 435 // by calling a method, instead of accessing a property. So we
436 // attach to the JS Object prototype these methods that return 436 // attach to the JS Object prototype these methods that return
437 // false, and will be overridden by subclasses when they have to 437 // false, and will be overridden by subclasses when they have to
438 // return true. 438 // return true.
439 Map<String, String> objectProperties = new Map<String, String>(); 439 Map<String, String> objectProperties = new Map<String, String>();
(...skipping 15 matching lines...) Expand all
455 // If the native emitter has been asked to take care of the 455 // If the native emitter has been asked to take care of the
456 // noSuchMethod handlers, we do that now. 456 // noSuchMethod handlers, we do that now.
457 if (handleNoSuchMethod) { 457 if (handleNoSuchMethod) {
458 emitter.emitNoSuchMethodHandlers((String name, CodeBuffer buffer) { 458 emitter.emitNoSuchMethodHandlers((String name, CodeBuffer buffer) {
459 objectProperties[name] = buffer.toString(); 459 objectProperties[name] = buffer.toString();
460 }); 460 });
461 } 461 }
462 462
463 // If we have any properties to add to Object.prototype, we run 463 // If we have any properties to add to Object.prototype, we run
464 // through them and add them using defineProperty. 464 // through them and add them using defineProperty.
465 if (!objectProperties.isEmpty()) { 465 if (!objectProperties.isEmpty) {
466 targetBuffer.add("(function(table) {\n" 466 targetBuffer.add("(function(table) {\n"
467 " for (var key in table) {\n" 467 " for (var key in table) {\n"
468 " $defPropName(Object.prototype, key, table[key]);\n" 468 " $defPropName(Object.prototype, key, table[key]);\n"
469 " }\n" 469 " }\n"
470 "})({\n"); 470 "})({\n");
471 bool first = true; 471 bool first = true;
472 objectProperties.forEach((String name, String function) { 472 objectProperties.forEach((String name, String function) {
473 if (!first) targetBuffer.add(",\n"); 473 if (!first) targetBuffer.add(",\n");
474 targetBuffer.add(" $name: $function"); 474 targetBuffer.add(" $name: $function");
475 first = false; 475 first = false;
476 }); 476 });
477 targetBuffer.add("\n});\n\n"); 477 targetBuffer.add("\n});\n\n");
478 } 478 }
479 targetBuffer.add(nativeBuffer); 479 targetBuffer.add(nativeBuffer);
480 targetBuffer.add('\n'); 480 targetBuffer.add('\n');
481 } 481 }
482 } 482 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/js_backend/namer.dart ('k') | lib/compiler/implementation/lib/constant_map.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698