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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart

Issue 1982413002: Fix "break" vs "continue" bug in js interop codegen that was the real source of missing js interop … (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « no previous file | 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library dart2js.js_emitter.program_builder; 5 library dart2js.js_emitter.program_builder;
6 6
7 import '../../closure.dart' show ClosureFieldElement; 7 import '../../closure.dart' show ClosureFieldElement;
8 import '../../common.dart'; 8 import '../../common.dart';
9 import '../../common/names.dart' show Names, Selectors; 9 import '../../common/names.dart' show Names, Selectors;
10 import '../../compiler.dart' show Compiler; 10 import '../../compiler.dart' show Compiler;
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 List<Library> _buildLibraries(LibrariesMap librariesMap) { 316 List<Library> _buildLibraries(LibrariesMap librariesMap) {
317 List<Library> libraries = new List<Library>(librariesMap.length); 317 List<Library> libraries = new List<Library>(librariesMap.length);
318 int count = 0; 318 int count = 0;
319 librariesMap.forEach((LibraryElement library, List<Element> elements) { 319 librariesMap.forEach((LibraryElement library, List<Element> elements) {
320 libraries[count++] = _buildLibrary(library, elements); 320 libraries[count++] = _buildLibrary(library, elements);
321 }); 321 });
322 return libraries; 322 return libraries;
323 } 323 }
324 324
325 void _addJsInteropStubs(LibrariesMap librariesMap) { 325 void _addJsInteropStubs(LibrariesMap librariesMap) {
326 // TODO(26456): we should be using codegenWorld instead of resolverWorld
327 // to determine what invocations could be live but codegenWorld has a bug
328 // resulting in it missing some invocations.
329 if (_classes.containsKey(_compiler.coreClasses.objectClass)) { 326 if (_classes.containsKey(_compiler.coreClasses.objectClass)) {
330 var toStringInvocation = namer.invocationName(Selectors.toString_); 327 var toStringInvocation = namer.invocationName(Selectors.toString_);
331 // TODO(jacobr): register toString as used so that it is always accessible 328 // TODO(jacobr): register toString as used so that it is always accessible
332 // from JavaScript. 329 // from JavaScript.
333 _classes[_compiler.coreClasses.objectClass].callStubs.add( 330 _classes[_compiler.coreClasses.objectClass].callStubs.add(
334 _buildStubMethod(new StringBackedName("toString"), 331 _buildStubMethod(new StringBackedName("toString"),
335 js.js('function() { return this.#(this) }', toStringInvocation))); 332 js.js('function() { return this.#(this) }', toStringInvocation)));
336 } 333 }
337 334
338 // We add all members from classes marked with isJsInterop to the base 335 // We add all members from classes marked with isJsInterop to the base
339 // Interceptor class with implementations that directly call the 336 // Interceptor class with implementations that directly call the
340 // corresponding JavaScript member. We do not attempt to bind this when 337 // corresponding JavaScript member. We do not attempt to bind this when
341 // tearing off JavaScript methods as we cannot distinguish between calling 338 // tearing off JavaScript methods as we cannot distinguish between calling
342 // a regular getter that returns a JavaScript function and tearing off 339 // a regular getter that returns a JavaScript function and tearing off
343 // a method in the case where there exist multiple JavaScript classes 340 // a method in the case where there exist multiple JavaScript classes
344 // that conflict on whether the member is a getter or a method. 341 // that conflict on whether the member is a getter or a method.
345 var interceptorClass = _classes[helpers.jsJavaScriptObjectClass]; 342 var interceptorClass = _classes[helpers.jsJavaScriptObjectClass];
346 var stubNames = new Set<String>(); 343 var stubNames = new Set<String>();
347 librariesMap.forEach((LibraryElement library, List<Element> elements) { 344 librariesMap.forEach((LibraryElement library, List<Element> elements) {
348 for (Element e in elements) { 345 for (Element e in elements) {
349 if (e is ClassElement && backend.isJsInterop(e)) { 346 if (e is ClassElement && backend.isJsInterop(e)) {
350 e.declaration.forEachMember((_, Element member) { 347 e.declaration.forEachMember((_, Element member) {
351 if (!member.isInstanceMember) return; 348 if (!member.isInstanceMember) return;
352 if (member.isGetter || member.isField || member.isFunction) { 349 if (member.isGetter || member.isField || member.isFunction) {
353 var selectors = 350 var selectors =
354 _compiler.resolverWorld.getterInvocationsByName(member.name); 351 _compiler.codegenWorld.getterInvocationsByName(member.name);
355 if (selectors != null && !selectors.isEmpty) { 352 if (selectors != null && !selectors.isEmpty) {
356 for (var selector in selectors.keys) { 353 for (var selector in selectors.keys) {
357 var stubName = namer.invocationName(selector); 354 var stubName = namer.invocationName(selector);
358 if (stubNames.add(stubName.key)) { 355 if (stubNames.add(stubName.key)) {
359 interceptorClass.callStubs.add(_buildStubMethod(stubName, 356 interceptorClass.callStubs.add(_buildStubMethod(stubName,
360 js.js('function(obj) { return obj.# }', [member.name]), 357 js.js('function(obj) { return obj.# }', [member.name]),
361 element: member)); 358 element: member));
362 } 359 }
363 } 360 }
364 } 361 }
365 } 362 }
366 363
367 if (member.isSetter || (member.isField && !member.isConst)) { 364 if (member.isSetter || (member.isField && !member.isConst)) {
368 var selectors = 365 var selectors =
369 _compiler.resolverWorld.setterInvocationsByName(member.name); 366 _compiler.codegenWorld.setterInvocationsByName(member.name);
370 if (selectors != null && !selectors.isEmpty) { 367 if (selectors != null && !selectors.isEmpty) {
371 var stubName = namer.setterForElement(member); 368 var stubName = namer.setterForElement(member);
372 if (stubNames.add(stubName.key)) { 369 if (stubNames.add(stubName.key)) {
373 interceptorClass.callStubs.add(_buildStubMethod( 370 interceptorClass.callStubs.add(_buildStubMethod(
374 stubName, 371 stubName,
375 js.js('function(obj, v) { return obj.# = v }', 372 js.js('function(obj, v) { return obj.# = v }',
376 [member.name]), 373 [member.name]),
377 element: member)); 374 element: member));
378 } 375 }
379 } 376 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 int minArgs; 412 int minArgs;
416 int maxArgs; 413 int maxArgs;
417 if (functionType != null) { 414 if (functionType != null) {
418 minArgs = functionType.parameterTypes.length; 415 minArgs = functionType.parameterTypes.length;
419 maxArgs = minArgs + functionType.optionalParameterTypes.length; 416 maxArgs = minArgs + functionType.optionalParameterTypes.length;
420 } else { 417 } else {
421 minArgs = 0; 418 minArgs = 0;
422 maxArgs = 32767; 419 maxArgs = 32767;
423 } 420 }
424 var selectors = 421 var selectors =
425 _compiler.resolverWorld.invocationsByName(member.name); 422 _compiler.codegenWorld.invocationsByName(member.name);
423
426 // Named arguments are not yet supported. In the future we 424 // Named arguments are not yet supported. In the future we
427 // may want to map named arguments to an object literal containing 425 // may want to map named arguments to an object literal containing
428 // all named arguments. 426 // all named arguments.
429 if (selectors != null && !selectors.isEmpty) { 427 if (selectors != null && !selectors.isEmpty) {
430 for (var selector in selectors.keys) { 428 for (var selector in selectors.keys) {
431 // Check whether the arity matches this member. 429 // Check whether the arity matches this member.
432 var argumentCount = selector.argumentCount; 430 var argumentCount = selector.argumentCount;
433 // JS interop does not support named arguments. 431 // JS interop does not support named arguments.
434 if (selector.namedArgumentCount > 0) break; 432 if (selector.namedArgumentCount > 0) continue;
435 if (argumentCount < minArgs) break; 433 if (argumentCount < minArgs) continue;
436 if (argumentCount > maxArgs) break; 434 if (argumentCount > maxArgs) continue;
437 var stubName = namer.invocationName(selector); 435 var stubName = namer.invocationName(selector);
438 if (!stubNames.add(stubName.key)) break; 436 if (!stubNames.add(stubName.key)) continue;
439 var parameters = 437 var parameters =
440 new List<String>.generate(argumentCount, (i) => 'p$i'); 438 new List<String>.generate(argumentCount, (i) => 'p$i');
441 439
442 // We intentionally generate the same stub method for direct 440 // We intentionally generate the same stub method for direct
443 // calls and call-throughs of getters so that calling a 441 // calls and call-throughs of getters so that calling a
444 // getter that returns a function behaves the same as calling 442 // getter that returns a function behaves the same as calling
445 // a method. This is helpful as many typed JavaScript APIs 443 // a method. This is helpful as many typed JavaScript APIs
446 // specify member functions with getters that return 444 // specify member functions with getters that return
447 // functions. The behavior of this solution matches JavaScript 445 // functions. The behavior of this solution matches JavaScript
448 // behavior implicitly binding this only when JavaScript 446 // behavior implicitly binding this only when JavaScript
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 Constant constant = new Constant(name, holder, constantValue); 976 Constant constant = new Constant(name, holder, constantValue);
979 _constants[constantValue] = constant; 977 _constants[constantValue] = constant;
980 } 978 }
981 } 979 }
982 980
983 Holder _registerStaticStateHolder() { 981 Holder _registerStaticStateHolder() {
984 return _registry.registerHolder(namer.staticStateHolder, 982 return _registry.registerHolder(namer.staticStateHolder,
985 isStaticStateHolder: true); 983 isStaticStateHolder: true);
986 } 984 }
987 } 985 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698