Skip to content

Commit

Permalink
simplify emitting dart.bind for native types
Browse files Browse the repository at this point in the history
R=het@google.com

Review URL: https://codereview.chromium.org/1921503007 .
  • Loading branch information
John Messerly committed Apr 27, 2016
1 parent 45f57aa commit aa0b75f
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 18 deletions.
5 changes: 2 additions & 3 deletions pkg/dev_compiler/lib/runtime/dart_sdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,8 @@ dart_library.library('dart_sdk', null, /* Imports */[
dart._methodSig = Symbol("sig");
dart._staticSig = Symbol("sigStatic");
dart.getMethodType = function(obj, name) {
if (obj === void 0) return void 0;
if (obj == null) return void 0;
return dart.getMethodTypeFromType(obj.__proto__.constructor, name);
let type = obj == null ? core.Object : obj.__proto__.constructor;
return dart.getMethodTypeFromType(type, name);
};
dart.getMethodTypeFromType = function(type, name) {
let sigObj = type[dart._methodSig];
Expand Down
26 changes: 15 additions & 11 deletions pkg/dev_compiler/lib/src/compiler/code_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2284,7 +2284,7 @@ class CodeGenerator extends GeneralizingAstVisitor
// class Foo { Function bar; }
// new Foo().bar(); // dynamic call
code = 'dart.dcall(#.#, #)';
} else if (_requiresStaticDispatch(target, name)) {
} else if (_isObjectMemberCall(target, name)) {
// Object methods require a helper for null checks.
return js.call('dart.#(#, #)',
[memberName, _visit(target), _visit(node.argumentList)]);
Expand Down Expand Up @@ -3129,15 +3129,21 @@ class CodeGenerator extends GeneralizingAstVisitor
}
}

bool _requiresStaticDispatch(Expression target, String memberName) {
var type = getStaticType(target);
/// Everything in Dart is an Object and supports the 4 members on Object,
/// so we have to use a runtime helper to handle values such as `null` and
/// native types.
///
/// For example `null.toString()` is legal in Dart, so we need to generate
/// that as `dart.toString(obj)`.
bool _isObjectMemberCall(Expression target, String memberName) {
// Is this a member on `Object`?
if (!isObjectProperty(memberName)) {
return false;
}

// If the target could be `null`, we need static dispatch.
// If the target may be an extension type, we also use static dispatch
// as we don't symbolize object properties like hashCode.
// Check if the target could be `null`, is dynamic, or may be an extension
// native type. In all of those cases we need defensive code generation.
var type = getStaticType(target);
return isNullable(target) ||
type.isDynamic ||
(_extensionTypes.contains(type.element) && target is! SuperExpression);
Expand Down Expand Up @@ -3169,13 +3175,11 @@ class CodeGenerator extends GeneralizingAstVisitor
// Tear-off methods: explicitly bind it.
if (target is SuperExpression) {
return js.call('dart.bind(this, #, #.#)', [name, _visit(target), name]);
} else if (_requiresStaticDispatch(target, memberId.name)) {
var type = member.type;
var clos = js.call('dart.#.bind(#)', [name, _visit(target)]);
return js.call('dart.fn(#, #)', [clos, _emitFunctionTypeParts(type)]);
} else if (_isObjectMemberCall(target, memberId.name)) {
return js.call('dart.bind(#, #, dart.#)', [_visit(target), name, name]);
}
code = 'dart.bind(#, #)';
} else if (_requiresStaticDispatch(target, memberId.name)) {
} else if (_isObjectMemberCall(target, memberId.name)) {
return js.call('dart.#(#)', [name, _visit(target)]);
} else {
code = '#.#';
Expand Down
2 changes: 1 addition & 1 deletion pkg/dev_compiler/test/codegen/expect/language-all.js
Original file line number Diff line number Diff line change
Expand Up @@ -117604,7 +117604,7 @@ dart_library.library('null_to_string2_test', null, /* Imports */[
let nullObj = null_to_string2_test.foo();
let x = dart.toString(nullObj);
expect$.Expect.isTrue(typeof x == 'string');
let y = dart.fn(dart.toString.bind(nullObj), core.String, []);
let y = dart.bind(nullObj, 'toString', dart.toString);
expect$.Expect.isNotNull(y);
};
dart.fn(null_to_string2_test.main);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,8 @@ final _staticSig = JS('', 'Symbol("sigStatic")');

/// Get the type of a method from an object using the stored signature
getMethodType(obj, name) => JS('', '''(() => {
if ($obj === void 0) return void 0;
if ($obj == null) return void 0;
return $getMethodTypeFromType($obj.__proto__.constructor, $name);
let type = $obj == null ? $Object : $obj.__proto__.constructor;
return $getMethodTypeFromType(type, $name);
})()''');

/// Get the type of a method from a type using the stored signature
Expand Down

0 comments on commit aa0b75f

Please sign in to comment.