Handle more BinaryExpression cases

Summary:
Release notes: none

Follow up to https://github.com/facebook/prepack/pull/1464. This adds serializer tests and fixes `+` binary expressions in pure mode.
Closes https://github.com/facebook/prepack/pull/1473

Differential Revision: D7040965

Pulled By: trueadm

fbshipit-source-id: ba2b377b6f7c6fc8260b0afcb5098c6e50c050ed
This commit is contained in:
Dominic Gannaway 2018-02-21 03:50:59 -08:00 committed by Facebook Github Bot
parent 113099043e
commit bfc005a15b
3 changed files with 58 additions and 9 deletions

View File

@ -79,19 +79,30 @@ export function getPureBinaryOperationResultType(
if (op === "+") {
let ltype = To.GetToPrimitivePureResultType(realm, lval);
let rtype = To.GetToPrimitivePureResultType(realm, rval);
function recoverWithValue() {
// Assume that the unknown value is actually a primitive or otherwise a well behaved object.
ltype = lval.getType();
rtype = rval.getType();
if (ltype === StringValue || rtype === StringValue) return StringValue;
if (ltype === IntegralValue && rtype === IntegralValue) return IntegralValue;
if ((ltype === NumberValue || ltype === IntegralValue) && (rtype === NumberValue || rtype === IntegralValue))
return NumberValue;
return Value;
}
if (realm.isInPureScope()) {
if (!ltype) Leak.leakValue(realm, lval);
if (!rtype) Leak.leakValue(realm, rval);
return recoverWithValue();
}
if (ltype === undefined || rtype === undefined) {
let loc = ltype === undefined ? lloc : rloc;
let error = new CompilerDiagnostic(unknownValueOfOrToString, loc, "PP0002", "RecoverableError");
if (realm.handleError(error) === "Recover") {
// Assume that the unknown value is actually a primitive or otherwise a well behaved object.
ltype = lval.getType();
rtype = rval.getType();
if (ltype === StringValue || rtype === StringValue) return StringValue;
if (ltype === IntegralValue && rtype === IntegralValue) return IntegralValue;
if ((ltype === NumberValue || ltype === IntegralValue) && (rtype === NumberValue || rtype === IntegralValue))
return NumberValue;
return Value;
return recoverWithValue();
}
throw new FatalError();
}

View File

@ -0,0 +1,19 @@
// additional functions
// abstract effects
let obj1 = global.__abstract ? __abstract('object', '({foo: {valueOf() { return 42; }}})') : {foo: {valueOf() { return 42; }}};
let obj2 = global.__abstract ? __abstract('object', '({foo: {bar: {valueOf() { return 42; }}}})') : {foo: {bar: {valueOf() { return 42; }}}};
function additional1() {
return '' + obj1.foo;
}
function additional2() {
return obj2.foo.bar + 10;
}
inspect = function() {
let ret1 = additional1();
let ret2 = additional2();
return JSON.stringify({ ret1, ret2 });
}

View File

@ -0,0 +1,19 @@
// additional functions
// abstract effects
let obj1 = global.__abstract ? __abstract('object', '({foo: {valueOf() { return 42; }}})') : {foo: {valueOf() { return 42; }}};
let obj2 = global.__abstract ? __abstract('object', '({foo: {bar: {valueOf() { return 42; }}}})') : {foo: {bar: {valueOf() { return 42; }}}};
function additional1() {
return 42 < obj1.foo;
}
function additional2() {
return obj2.foo.bar > 42;
}
inspect = function() {
let ret1 = additional1();
let ret2 = additional2();
return JSON.stringify({ ret1, ret2 });
}