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

Side by Side Diff: pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart

Issue 2404123002: Build CFG for various JS() foreign methods (Closed)
Patch Set: format Created 4 years, 1 month 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 | « pkg/compiler/lib/src/ssa/builder_kernel.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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import 'package:js_runtime/shared/embedded_names.dart';
5 import 'package:kernel/ast.dart' as ir; 6 import 'package:kernel/ast.dart' as ir;
6 7
7 import '../constants/expressions.dart'; 8 import '../constants/expressions.dart';
8 import '../common.dart'; 9 import '../common.dart';
9 import '../common/names.dart'; 10 import '../common/names.dart';
10 import '../compiler.dart'; 11 import '../compiler.dart';
11 import '../constants/values.dart'; 12 import '../constants/values.dart';
12 import '../dart_types.dart'; 13 import '../dart_types.dart';
13 import '../elements/elements.dart'; 14 import '../elements/elements.dart';
15 import '../js/js.dart' as js;
14 import '../js_backend/backend_helpers.dart'; 16 import '../js_backend/backend_helpers.dart';
15 import '../js_backend/js_backend.dart'; 17 import '../js_backend/js_backend.dart';
16 import '../kernel/kernel.dart'; 18 import '../kernel/kernel.dart';
17 import '../kernel/kernel_debug.dart'; 19 import '../kernel/kernel_debug.dart';
18 import '../native/native.dart' show NativeBehavior, TypeLookup; 20 import '../native/native.dart' as native;
19 import '../resolution/tree_elements.dart'; 21 import '../resolution/tree_elements.dart';
20 import '../tree/tree.dart' as ast; 22 import '../tree/tree.dart' as ast;
21 import '../types/masks.dart'; 23 import '../types/masks.dart';
22 import '../types/types.dart'; 24 import '../types/types.dart';
23 import '../universe/call_structure.dart'; 25 import '../universe/call_structure.dart';
24 import '../universe/selector.dart'; 26 import '../universe/selector.dart';
25 import '../universe/side_effects.dart'; 27 import '../universe/side_effects.dart';
26 import '../world.dart'; 28 import '../world.dart';
27 import 'locals_handler.dart'; 29 import 'locals_handler.dart';
28 import 'types.dart'; 30 import 'types.dart';
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 } 236 }
235 237
236 TypeMask inferredTypeOf(ir.Member node) { 238 TypeMask inferredTypeOf(ir.Member node) {
237 return TypeMaskFactory.inferredTypeForElement(getElement(node), _compiler); 239 return TypeMaskFactory.inferredTypeForElement(getElement(node), _compiler);
238 } 240 }
239 241
240 TypeMask selectorTypeOf(Selector selector, TypeMask mask) { 242 TypeMask selectorTypeOf(Selector selector, TypeMask mask) {
241 return TypeMaskFactory.inferredTypeForSelector(selector, mask, _compiler); 243 return TypeMaskFactory.inferredTypeForSelector(selector, mask, _compiler);
242 } 244 }
243 245
246 TypeMask typeFromNativeBehavior(native.NativeBehavior nativeBehavior) {
247 return TypeMaskFactory.fromNativeBehavior(nativeBehavior, _compiler);
248 }
249
244 ConstantValue getConstantFor(ir.Node node) { 250 ConstantValue getConstantFor(ir.Node node) {
245 ConstantValue constantValue = 251 ConstantValue constantValue =
246 _backend.constants.getConstantValueForNode(getNode(node), elements); 252 _backend.constants.getConstantValueForNode(getNode(node), elements);
247 assert(invariant(getNode(node), constantValue != null, 253 assert(invariant(getNode(node), constantValue != null,
248 message: 'No constant computed for $node')); 254 message: 'No constant computed for $node'));
249 return constantValue; 255 return constantValue;
250 } 256 }
251 257
252 bool isIntercepted(ir.Node node) { 258 bool isIntercepted(ir.Node node) {
253 Selector selector = getSelector(node); 259 Selector selector = getSelector(node);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 kernel.functions[_backend.helpers.assertThrow]; 308 kernel.functions[_backend.helpers.assertThrow];
303 309
304 ir.Procedure get setRuntimeTypeInfo => 310 ir.Procedure get setRuntimeTypeInfo =>
305 kernel.functions[_backend.helpers.setRuntimeTypeInfo]; 311 kernel.functions[_backend.helpers.setRuntimeTypeInfo];
306 312
307 TypeMask get assertThrowReturnType => TypeMaskFactory 313 TypeMask get assertThrowReturnType => TypeMaskFactory
308 .inferredReturnTypeForElement(_backend.helpers.assertThrow, _compiler); 314 .inferredReturnTypeForElement(_backend.helpers.assertThrow, _compiler);
309 315
310 ir.Class get objectClass => kernel.classes[_compiler.coreClasses.objectClass]; 316 ir.Class get objectClass => kernel.classes[_compiler.coreClasses.objectClass];
311 317
318 ir.Procedure get currentIsolate =>
319 kernel.functions[_backend.helpers.currentIsolate];
320
321 bool isInForeignLibrary(ir.Member member) =>
322 _backend.isForeign(getElement(member));
323
324 native.NativeBehavior getNativeBehavior(ir.Node node) {
325 return elements.getNativeData(getNode(node));
326 }
327
328 js.Name getNameForJsGetName(ir.Node argument, ConstantValue constant) {
329 int index = _extractEnumIndexFromConstantValue(
330 constant, _backend.helpers.jsGetNameEnum);
331 if (index == null) return null;
332 return _backend.namer
333 .getNameForJsGetName(getNode(argument), JsGetName.values[index]);
334 }
335
336 js.Template getJsBuiltinTemplate(ConstantValue constant) {
337 int index = _extractEnumIndexFromConstantValue(
338 constant, _backend.helpers.jsBuiltinEnum);
339 if (index == null) return null;
340 return _backend.emitter.builtinTemplateFor(JsBuiltin.values[index]);
341 }
342
343 int _extractEnumIndexFromConstantValue(
344 ConstantValue constant, Element classElement) {
345 if (constant is ConstructedConstantValue) {
346 if (constant.type.element == classElement) {
347 assert(constant.fields.length == 1);
348 ConstantValue indexConstant = constant.fields.values.single;
349 if (indexConstant is IntConstantValue) {
350 return indexConstant.primitiveValue;
351 }
352 }
353 }
354 return null;
355 }
356
312 DartType getDartType(ir.DartType type) { 357 DartType getDartType(ir.DartType type) {
313 return type.accept(_typeConverter); 358 return type.accept(_typeConverter);
314 } 359 }
315 360
316 List<DartType> getDartTypes(List<ir.DartType> types) { 361 List<DartType> getDartTypes(List<ir.DartType> types) {
317 return types.map(getDartType).toList(); 362 return types.map(getDartType).toList();
318 } 363 }
319 364
320 DartType getFunctionReturnType(ir.FunctionNode node) { 365 DartType getFunctionReturnType(ir.FunctionNode node) {
321 return getDartType(node.returnType); 366 return getDartType(node.returnType);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 } 420 }
376 return ForeignKind.NONE; 421 return ForeignKind.NONE;
377 } 422 }
378 423
379 /// Return `true` if [node] is the `dart:_foreign_helper` library. 424 /// Return `true` if [node] is the `dart:_foreign_helper` library.
380 bool isForeignLibrary(ir.Library node) { 425 bool isForeignLibrary(ir.Library node) {
381 return node.importUri == BackendHelpers.DART_FOREIGN_HELPER; 426 return node.importUri == BackendHelpers.DART_FOREIGN_HELPER;
382 } 427 }
383 428
384 /// Looks up [typeName] for use in the spec-string of a `JS` called. 429 /// Looks up [typeName] for use in the spec-string of a `JS` called.
385 // TODO(johnniwinther): Use this in [NativeBehavior] instead of calling the 430 // TODO(johnniwinther): Use this in [native.NativeBehavior] instead of calling the
386 // `ForeignResolver`. 431 // `ForeignResolver`.
387 // TODO(johnniwinther): Cache the result to avoid redundant lookups? 432 // TODO(johnniwinther): Cache the result to avoid redundant lookups?
388 TypeLookup _typeLookup({bool resolveAsRaw: true}) { 433 native.TypeLookup _typeLookup({bool resolveAsRaw: true}) {
389 return (String typeName) { 434 return (String typeName) {
390 DartType findIn(Uri uri) { 435 DartType findIn(Uri uri) {
391 LibraryElement library = _compiler.libraryLoader.lookupLibrary(uri); 436 LibraryElement library = _compiler.libraryLoader.lookupLibrary(uri);
392 if (library != null) { 437 if (library != null) {
393 Element element = library.find(typeName); 438 Element element = library.find(typeName);
394 if (element != null && element.isClass) { 439 if (element != null && element.isClass) {
395 ClassElement cls = element; 440 ClassElement cls = element;
396 // TODO(johnniwinther): Align semantics. 441 // TODO(johnniwinther): Align semantics.
397 return resolveAsRaw ? cls.rawType : cls.thisType; 442 return resolveAsRaw ? cls.rawType : cls.thisType;
398 } 443 }
(...skipping 11 matching lines...) Expand all
410 type ??= findIn(Uris.dart_web_audio); 455 type ??= findIn(Uris.dart_web_audio);
411 type ??= findIn(Uris.dart_web_gl); 456 type ??= findIn(Uris.dart_web_gl);
412 return type; 457 return type;
413 }; 458 };
414 } 459 }
415 460
416 String _getStringArgument(ir.StaticInvocation node, int index) { 461 String _getStringArgument(ir.StaticInvocation node, int index) {
417 return node.arguments.positional[index].accept(new Stringifier()); 462 return node.arguments.positional[index].accept(new Stringifier());
418 } 463 }
419 464
420 /// Computes the [NativeBehavior] for a call to the [JS] function. 465 /// Computes the [native.NativeBehavior] for a call to the [JS] function.
421 // TODO(johnniwinther): Cache this for later use. 466 // TODO(johnniwinther): Cache this for later use.
422 NativeBehavior getNativeBehaviorForJsCall(ir.StaticInvocation node) { 467 native.NativeBehavior getNativeBehaviorForJsCall(ir.StaticInvocation node) {
423 if (node.arguments.positional.length < 2 || 468 if (node.arguments.positional.length < 2 ||
424 node.arguments.named.isNotEmpty) { 469 node.arguments.named.isNotEmpty) {
425 reporter.reportErrorMessage( 470 reporter.reportErrorMessage(
426 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS); 471 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS);
427 return new NativeBehavior(); 472 return new native.NativeBehavior();
428 } 473 }
429 String specString = _getStringArgument(node, 0); 474 String specString = _getStringArgument(node, 0);
430 if (specString == null) { 475 if (specString == null) {
431 reporter.reportErrorMessage( 476 reporter.reportErrorMessage(
432 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_FIRST); 477 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_FIRST);
433 return new NativeBehavior(); 478 return new native.NativeBehavior();
434 } 479 }
435 480
436 String codeString = _getStringArgument(node, 1); 481 String codeString = _getStringArgument(node, 1);
437 if (codeString == null) { 482 if (codeString == null) {
438 reporter.reportErrorMessage( 483 reporter.reportErrorMessage(
439 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND); 484 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND);
440 return new NativeBehavior(); 485 return new native.NativeBehavior();
441 } 486 }
442 487
443 return NativeBehavior.ofJsCall( 488 return native.NativeBehavior.ofJsCall(
444 specString, 489 specString,
445 codeString, 490 codeString,
446 _typeLookup(resolveAsRaw: true), 491 _typeLookup(resolveAsRaw: true),
447 CURRENT_ELEMENT_SPANNABLE, 492 CURRENT_ELEMENT_SPANNABLE,
448 reporter, 493 reporter,
449 _compiler.coreTypes); 494 _compiler.coreTypes);
450 } 495 }
451 496
452 /// Computes the [NativeBehavior] for a call to the [JS_BUILTIN] function. 497 /// Computes the [native.NativeBehavior] for a call to the [JS_BUILTIN] functi on.
453 // TODO(johnniwinther): Cache this for later use. 498 // TODO(johnniwinther): Cache this for later use.
454 NativeBehavior getNativeBehaviorForJsBuiltinCall(ir.StaticInvocation node) { 499 native.NativeBehavior getNativeBehaviorForJsBuiltinCall(
500 ir.StaticInvocation node) {
455 if (node.arguments.positional.length < 1) { 501 if (node.arguments.positional.length < 1) {
456 reporter.internalError( 502 reporter.internalError(
457 CURRENT_ELEMENT_SPANNABLE, "JS builtin expression has no type."); 503 CURRENT_ELEMENT_SPANNABLE, "JS builtin expression has no type.");
458 return new NativeBehavior(); 504 return new native.NativeBehavior();
459 } 505 }
460 if (node.arguments.positional.length < 2) { 506 if (node.arguments.positional.length < 2) {
461 reporter.internalError( 507 reporter.internalError(
462 CURRENT_ELEMENT_SPANNABLE, "JS builtin is missing name."); 508 CURRENT_ELEMENT_SPANNABLE, "JS builtin is missing name.");
463 return new NativeBehavior(); 509 return new native.NativeBehavior();
464 } 510 }
465 String specString = _getStringArgument(node, 0); 511 String specString = _getStringArgument(node, 0);
466 if (specString == null) { 512 if (specString == null) {
467 reporter.internalError( 513 reporter.internalError(
468 CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument."); 514 CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument.");
469 return new NativeBehavior(); 515 return new native.NativeBehavior();
470 } 516 }
471 return NativeBehavior.ofJsBuiltinCall( 517 return native.NativeBehavior.ofJsBuiltinCall(
472 specString, 518 specString,
473 _typeLookup(resolveAsRaw: true), 519 _typeLookup(resolveAsRaw: true),
474 CURRENT_ELEMENT_SPANNABLE, 520 CURRENT_ELEMENT_SPANNABLE,
475 reporter, 521 reporter,
476 _compiler.coreTypes); 522 _compiler.coreTypes);
477 } 523 }
478 524
479 /// Computes the [NativeBehavior] for a call to the [JS_EMBEDDED_GLOBAL] 525 /// Computes the [native.NativeBehavior] for a call to the [JS_EMBEDDED_GLOBAL ]
480 /// function. 526 /// function.
481 // TODO(johnniwinther): Cache this for later use. 527 // TODO(johnniwinther): Cache this for later use.
482 NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall( 528 native.NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall(
483 ir.StaticInvocation node) { 529 ir.StaticInvocation node) {
484 if (node.arguments.positional.length < 1) { 530 if (node.arguments.positional.length < 1) {
485 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, 531 reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
486 "JS embedded global expression has no type."); 532 "JS embedded global expression has no type.");
487 return new NativeBehavior(); 533 return new native.NativeBehavior();
488 } 534 }
489 if (node.arguments.positional.length < 2) { 535 if (node.arguments.positional.length < 2) {
490 reporter.internalError( 536 reporter.internalError(
491 CURRENT_ELEMENT_SPANNABLE, "JS embedded global is missing name."); 537 CURRENT_ELEMENT_SPANNABLE, "JS embedded global is missing name.");
492 return new NativeBehavior(); 538 return new native.NativeBehavior();
493 } 539 }
494 if (node.arguments.positional.length > 2 || 540 if (node.arguments.positional.length > 2 ||
495 node.arguments.named.isNotEmpty) { 541 node.arguments.named.isNotEmpty) {
496 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, 542 reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
497 "JS embedded global has more than 2 arguments."); 543 "JS embedded global has more than 2 arguments.");
498 return new NativeBehavior(); 544 return new native.NativeBehavior();
499 } 545 }
500 String specString = _getStringArgument(node, 0); 546 String specString = _getStringArgument(node, 0);
501 if (specString == null) { 547 if (specString == null) {
502 reporter.internalError( 548 reporter.internalError(
503 CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument."); 549 CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument.");
504 return new NativeBehavior(); 550 return new native.NativeBehavior();
505 } 551 }
506 return NativeBehavior.ofJsEmbeddedGlobalCall( 552 return native.NativeBehavior.ofJsEmbeddedGlobalCall(
507 specString, 553 specString,
508 _typeLookup(resolveAsRaw: true), 554 _typeLookup(resolveAsRaw: true),
509 CURRENT_ELEMENT_SPANNABLE, 555 CURRENT_ELEMENT_SPANNABLE,
510 reporter, 556 reporter,
511 _compiler.coreTypes); 557 _compiler.coreTypes);
512 } 558 }
513 559
514 /// Returns `true` is [node] has a `@Native(...)` annotation. 560 /// Returns `true` is [node] has a `@Native(...)` annotation.
515 // TODO(johnniwinther): Cache this for later use. 561 // TODO(johnniwinther): Cache this for later use.
516 bool isNative(ir.Class node) { 562 bool isNative(ir.Class node) {
517 for (ir.Expression annotation in node.annotations) { 563 for (ir.Expression annotation in node.annotations) {
518 if (annotation is ir.ConstructorInvocation) { 564 if (annotation is ir.ConstructorInvocation) {
519 ConstructorElement target = getElement(annotation.target).declaration; 565 ConstructorElement target = getElement(annotation.target).declaration;
520 if (target.enclosingClass == 566 if (target.enclosingClass ==
521 _compiler.commonElements.nativeAnnotationClass) { 567 _compiler.commonElements.nativeAnnotationClass) {
522 return true; 568 return true;
523 } 569 }
524 } 570 }
525 } 571 }
526 return false; 572 return false;
527 } 573 }
528 574
529 /// Computes the native behavior for reading the native [field]. 575 /// Computes the native behavior for reading the native [field].
530 // TODO(johnniwinther): Cache this for later use. 576 // TODO(johnniwinther): Cache this for later use.
531 NativeBehavior getNativeBehaviorForFieldLoad(ir.Field field) { 577 native.NativeBehavior getNativeBehaviorForFieldLoad(ir.Field field) {
532 DartType type = getDartType(field.type); 578 DartType type = getDartType(field.type);
533 List<ConstantExpression> metadata = getMetadata(field.annotations); 579 List<ConstantExpression> metadata = getMetadata(field.annotations);
534 return NativeBehavior.ofFieldLoad(CURRENT_ELEMENT_SPANNABLE, type, metadata, 580 return native.NativeBehavior.ofFieldLoad(CURRENT_ELEMENT_SPANNABLE, type,
535 _typeLookup(resolveAsRaw: false), _compiler, 581 metadata, _typeLookup(resolveAsRaw: false), _compiler,
536 isJsInterop: false); 582 isJsInterop: false);
537 } 583 }
538 584
539 /// Computes the native behavior for writing to the native [field]. 585 /// Computes the native behavior for writing to the native [field].
540 // TODO(johnniwinther): Cache this for later use. 586 // TODO(johnniwinther): Cache this for later use.
541 NativeBehavior getNativeBehaviorForFieldStore(ir.Field field) { 587 native.NativeBehavior getNativeBehaviorForFieldStore(ir.Field field) {
542 DartType type = getDartType(field.type); 588 DartType type = getDartType(field.type);
543 return NativeBehavior.ofFieldStore(type, _compiler.resolution); 589 return native.NativeBehavior.ofFieldStore(type, _compiler.resolution);
544 } 590 }
545 591
546 /// Computes the native behavior for calling [procedure]. 592 /// Computes the native behavior for calling [procedure].
547 // TODO(johnniwinther): Cache this for later use. 593 // TODO(johnniwinther): Cache this for later use.
548 NativeBehavior getNativeBehaviorForMethod(ir.Procedure procedure) { 594 native.NativeBehavior getNativeBehaviorForMethod(ir.Procedure procedure) {
549 DartType type = getFunctionType(procedure.function); 595 DartType type = getFunctionType(procedure.function);
550 List<ConstantExpression> metadata = getMetadata(procedure.annotations); 596 List<ConstantExpression> metadata = getMetadata(procedure.annotations);
551 return NativeBehavior.ofMethod(CURRENT_ELEMENT_SPANNABLE, type, metadata, 597 return native.NativeBehavior.ofMethod(CURRENT_ELEMENT_SPANNABLE, type,
552 _typeLookup(resolveAsRaw: false), _compiler, 598 metadata, _typeLookup(resolveAsRaw: false), _compiler,
553 isJsInterop: false); 599 isJsInterop: false);
554 } 600 }
555 } 601 }
556 602
557 /// Kinds of foreign functions. 603 /// Kinds of foreign functions.
558 enum ForeignKind { 604 enum ForeignKind {
559 JS, 605 JS,
560 JS_BUILTIN, 606 JS_BUILTIN,
561 JS_EMBEDDED_GLOBAL, 607 JS_EMBEDDED_GLOBAL,
562 JS_INTERCEPTOR_CONSTANT, 608 JS_INTERCEPTOR_CONSTANT,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 astAdapter.reporter.internalError( 739 astAdapter.reporter.internalError(
694 CURRENT_ELEMENT_SPANNABLE, "Unexpected constant target: $element."); 740 CURRENT_ELEMENT_SPANNABLE, "Unexpected constant target: $element.");
695 return null; 741 return null;
696 } 742 }
697 743
698 @override 744 @override
699 ConstantExpression visitStringLiteral(ir.StringLiteral node) { 745 ConstantExpression visitStringLiteral(ir.StringLiteral node) {
700 return new StringConstantExpression(node.value); 746 return new StringConstantExpression(node.value);
701 } 747 }
702 } 748 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/builder_kernel.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698