[strong] Disallow implicit conversions for bitwise ops, shifts
See https://codereview.chromium.org/1092353002/ Due to parser rewrites, also implements restrictions for unary ~. Still to come, implementing restrictions for binary + and comparison. BUG=v8:3956 LOG=N Review URL: https://codereview.chromium.org/1102923002 Cr-Commit-Position: refs/heads/master@{#28104}
This commit is contained in:
parent
b3000dda14
commit
6988aec61f
@ -179,11 +179,17 @@ enum BuiltinExtraArguments {
|
|||||||
V(MOD, 1) \
|
V(MOD, 1) \
|
||||||
V(MOD_STRONG, 1) \
|
V(MOD_STRONG, 1) \
|
||||||
V(BIT_OR, 1) \
|
V(BIT_OR, 1) \
|
||||||
|
V(BIT_OR_STRONG, 1) \
|
||||||
V(BIT_AND, 1) \
|
V(BIT_AND, 1) \
|
||||||
|
V(BIT_AND_STRONG, 1) \
|
||||||
V(BIT_XOR, 1) \
|
V(BIT_XOR, 1) \
|
||||||
|
V(BIT_XOR_STRONG, 1) \
|
||||||
V(SHL, 1) \
|
V(SHL, 1) \
|
||||||
|
V(SHL_STRONG, 1) \
|
||||||
V(SAR, 1) \
|
V(SAR, 1) \
|
||||||
|
V(SAR_STRONG, 1) \
|
||||||
V(SHR, 1) \
|
V(SHR, 1) \
|
||||||
|
V(SHR_STRONG, 1) \
|
||||||
V(DELETE, 2) \
|
V(DELETE, 2) \
|
||||||
V(IN, 1) \
|
V(IN, 1) \
|
||||||
V(INSTANCE_OF, 1) \
|
V(INSTANCE_OF, 1) \
|
||||||
|
@ -347,8 +347,7 @@ Reduction JSTypedLowering::ReduceNumberBinop(Node* node,
|
|||||||
const Operator* numberOp) {
|
const Operator* numberOp) {
|
||||||
JSBinopReduction r(this, node);
|
JSBinopReduction r(this, node);
|
||||||
if (is_strong(OpParameter<LanguageMode>(node))) {
|
if (is_strong(OpParameter<LanguageMode>(node))) {
|
||||||
if (r.left_type()->Is(Type::Number()) &&
|
if (r.BothInputsAre(Type::Number())) {
|
||||||
(r.right_type()->Is(Type::Number()))) {
|
|
||||||
return r.ChangeToPureOperator(numberOp, Type::Number());
|
return r.ChangeToPureOperator(numberOp, Type::Number());
|
||||||
}
|
}
|
||||||
return NoChange();
|
return NoChange();
|
||||||
@ -361,6 +360,13 @@ Reduction JSTypedLowering::ReduceNumberBinop(Node* node,
|
|||||||
|
|
||||||
Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) {
|
Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) {
|
||||||
JSBinopReduction r(this, node);
|
JSBinopReduction r(this, node);
|
||||||
|
if (is_strong(OpParameter<LanguageMode>(node))) {
|
||||||
|
if (r.BothInputsAre(Type::Number())) {
|
||||||
|
r.ConvertInputsToUI32(kSigned, kSigned);
|
||||||
|
return r.ChangeToPureOperator(intOp, Type::Integral32());
|
||||||
|
}
|
||||||
|
return NoChange();
|
||||||
|
}
|
||||||
Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
|
Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
|
||||||
r.ConvertInputsToNumber(frame_state);
|
r.ConvertInputsToNumber(frame_state);
|
||||||
r.ConvertInputsToUI32(kSigned, kSigned);
|
r.ConvertInputsToUI32(kSigned, kSigned);
|
||||||
@ -372,7 +378,10 @@ Reduction JSTypedLowering::ReduceUI32Shift(Node* node,
|
|||||||
Signedness left_signedness,
|
Signedness left_signedness,
|
||||||
const Operator* shift_op) {
|
const Operator* shift_op) {
|
||||||
JSBinopReduction r(this, node);
|
JSBinopReduction r(this, node);
|
||||||
if (r.BothInputsAre(Type::Primitive())) {
|
Type* reduce_type = is_strong(
|
||||||
|
OpParameter<LanguageMode>(node)) ? Type::Number() :
|
||||||
|
Type::Primitive();
|
||||||
|
if (r.BothInputsAre(reduce_type)) {
|
||||||
r.ConvertInputsForShift(left_signedness);
|
r.ConvertInputsForShift(left_signedness);
|
||||||
return r.ChangeToPureOperator(shift_op, Type::Integral32());
|
return r.ChangeToPureOperator(shift_op, Type::Integral32());
|
||||||
}
|
}
|
||||||
|
12
src/ic/ic.cc
12
src/ic/ic.cc
@ -2826,12 +2826,12 @@ Builtins::JavaScript BinaryOpIC::TokenToJSBuiltin(Token::Value op,
|
|||||||
case Token::MUL: return Builtins::MUL_STRONG;
|
case Token::MUL: return Builtins::MUL_STRONG;
|
||||||
case Token::DIV: return Builtins::DIV_STRONG;
|
case Token::DIV: return Builtins::DIV_STRONG;
|
||||||
case Token::MOD: return Builtins::MOD_STRONG;
|
case Token::MOD: return Builtins::MOD_STRONG;
|
||||||
case Token::BIT_OR: return Builtins::BIT_OR;
|
case Token::BIT_OR: return Builtins::BIT_OR_STRONG;
|
||||||
case Token::BIT_AND: return Builtins::BIT_AND;
|
case Token::BIT_AND: return Builtins::BIT_AND_STRONG;
|
||||||
case Token::BIT_XOR: return Builtins::BIT_XOR;
|
case Token::BIT_XOR: return Builtins::BIT_XOR_STRONG;
|
||||||
case Token::SAR: return Builtins::SAR;
|
case Token::SAR: return Builtins::SAR_STRONG;
|
||||||
case Token::SHR: return Builtins::SHR;
|
case Token::SHR: return Builtins::SHR_STRONG;
|
||||||
case Token::SHL: return Builtins::SHL;
|
case Token::SHL: return Builtins::SHL_STRONG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -272,6 +272,15 @@ function BIT_OR(y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//ECMA-262, section 11.10, page 57.
|
||||||
|
function BIT_OR_STRONG(y) {
|
||||||
|
if (IS_NUMBER(this) && IS_NUMBER(y)) {
|
||||||
|
return %NumberOr(this, y);
|
||||||
|
}
|
||||||
|
throw %MakeTypeError('strong_implicit_cast');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ECMA-262, section 11.10, page 57.
|
// ECMA-262, section 11.10, page 57.
|
||||||
function BIT_AND(y) {
|
function BIT_AND(y) {
|
||||||
var x;
|
var x;
|
||||||
@ -294,6 +303,15 @@ function BIT_AND(y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//ECMA-262, section 11.10, page 57.
|
||||||
|
function BIT_AND_STRONG(y) {
|
||||||
|
if (IS_NUMBER(this) && IS_NUMBER(y)) {
|
||||||
|
return %NumberAnd(this, y);
|
||||||
|
}
|
||||||
|
throw %MakeTypeError('strong_implicit_cast');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ECMA-262, section 11.10, page 57.
|
// ECMA-262, section 11.10, page 57.
|
||||||
function BIT_XOR(y) {
|
function BIT_XOR(y) {
|
||||||
var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
|
var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
|
||||||
@ -302,6 +320,15 @@ function BIT_XOR(y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//ECMA-262, section 11.10, page 57.
|
||||||
|
function BIT_XOR_STRONG(y) {
|
||||||
|
if (IS_NUMBER(this) && IS_NUMBER(y)) {
|
||||||
|
return %NumberXor(this, y);
|
||||||
|
}
|
||||||
|
throw %MakeTypeError('strong_implicit_cast');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ECMA-262, section 11.7.1, page 51.
|
// ECMA-262, section 11.7.1, page 51.
|
||||||
function SHL(y) {
|
function SHL(y) {
|
||||||
var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
|
var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
|
||||||
@ -310,6 +337,15 @@ function SHL(y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//ECMA-262, section 11.7.1, page 51.
|
||||||
|
function SHL_STRONG(y) {
|
||||||
|
if (IS_NUMBER(this) && IS_NUMBER(y)) {
|
||||||
|
return %NumberShl(this, y);
|
||||||
|
}
|
||||||
|
throw %MakeTypeError('strong_implicit_cast');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ECMA-262, section 11.7.2, page 51.
|
// ECMA-262, section 11.7.2, page 51.
|
||||||
function SAR(y) {
|
function SAR(y) {
|
||||||
var x;
|
var x;
|
||||||
@ -332,6 +368,15 @@ function SAR(y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//ECMA-262, section 11.7.2, page 51.
|
||||||
|
function SAR_STRONG(y) {
|
||||||
|
if (IS_NUMBER(this) && IS_NUMBER(y)) {
|
||||||
|
return %NumberSar(this, y);
|
||||||
|
}
|
||||||
|
throw %MakeTypeError('strong_implicit_cast');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ECMA-262, section 11.7.3, page 52.
|
// ECMA-262, section 11.7.3, page 52.
|
||||||
function SHR(y) {
|
function SHR(y) {
|
||||||
var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
|
var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
|
||||||
@ -340,6 +385,14 @@ function SHR(y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//ECMA-262, section 11.7.3, page 52.
|
||||||
|
function SHR_STRONG(y) {
|
||||||
|
if (IS_NUMBER(this) && IS_NUMBER(y)) {
|
||||||
|
return %NumberShr(this, y);
|
||||||
|
}
|
||||||
|
throw %MakeTypeError('strong_implicit_cast');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------
|
/* -----------------------------
|
||||||
- - - H e l p e r s - - -
|
- - - H e l p e r s - - -
|
||||||
|
@ -4,72 +4,165 @@
|
|||||||
|
|
||||||
// Flags: --strong-mode --allow-natives-syntax
|
// Flags: --strong-mode --allow-natives-syntax
|
||||||
|
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
// TODO(conradw): Implement other strong operators
|
// TODO(conradw): Implement other strong operators
|
||||||
let strong_arith = [
|
let strongBinops = [
|
||||||
"-",
|
"-",
|
||||||
"*",
|
"*",
|
||||||
"/",
|
"/",
|
||||||
"%"
|
"%",
|
||||||
]
|
"|",
|
||||||
|
"&",
|
||||||
|
"^",
|
||||||
|
"<<",
|
||||||
|
">>",
|
||||||
|
">>>",
|
||||||
|
];
|
||||||
|
|
||||||
let nonnumber_values = [
|
let strongUnops = [
|
||||||
"{}",
|
"~",
|
||||||
"'foo'",
|
"+",
|
||||||
"(function(){})",
|
"-"
|
||||||
"[]",
|
];
|
||||||
"'0'",
|
|
||||||
"'NaN'",
|
|
||||||
"(class Foo {})"
|
|
||||||
]
|
|
||||||
|
|
||||||
let number_values = [
|
let nonNumberValues = [
|
||||||
"0",
|
"{}",
|
||||||
"(-0)",
|
"'foo'",
|
||||||
"1",
|
"(function(){})",
|
||||||
"0.79",
|
"[]",
|
||||||
"(-0.79)",
|
"'0'",
|
||||||
"4294967295",
|
"'NaN'",
|
||||||
"4294967296",
|
"(class Foo {})"
|
||||||
"(-4294967295)",
|
];
|
||||||
"(-4294967296)",
|
|
||||||
"9999999999999",
|
let numberValues = [
|
||||||
"(-9999999999999)",
|
"0",
|
||||||
"1.5e10",
|
"(-0)",
|
||||||
"(-1.5e10)",
|
"1",
|
||||||
"0xFFF",
|
"0.79",
|
||||||
"(-0xFFF)",
|
"(-0.79)",
|
||||||
"NaN",
|
"4294967295",
|
||||||
"Infinity",
|
"4294967296",
|
||||||
"(-Infinity)"
|
"(-4294967295)",
|
||||||
]
|
"(-4294967296)",
|
||||||
|
"9999999999999",
|
||||||
|
"(-9999999999999)",
|
||||||
|
"1.5e10",
|
||||||
|
"(-1.5e10)",
|
||||||
|
"0xFFF",
|
||||||
|
"(-0xFFF)",
|
||||||
|
"NaN",
|
||||||
|
"Infinity",
|
||||||
|
"(-Infinity)"
|
||||||
|
];
|
||||||
|
|
||||||
function sub_strong(x, y) {
|
function sub_strong(x, y) {
|
||||||
"use strong";
|
"use strong";
|
||||||
let v = x - y;
|
return x - y;
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mul_strong(x, y) {
|
function mul_strong(x, y) {
|
||||||
"use strong";
|
"use strong";
|
||||||
let v = x * y;
|
return x * y;
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function div_strong(x, y) {
|
function div_strong(x, y) {
|
||||||
"use strong";
|
"use strong";
|
||||||
let v = x / y;
|
return x / y;
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mod_strong(x, y) {
|
function mod_strong(x, y) {
|
||||||
"use strong";
|
"use strong";
|
||||||
let v = x % y;
|
return x % y;
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let strong_funcs = [sub_strong, mul_strong, div_strong, mod_strong];
|
function or_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return x | y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function and_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return x & y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function xor_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return x ^ y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function shl_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return x << y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function shr_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return x >> y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sar_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return x >>> y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function typed_sub_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return (+x) - (+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function typed_mul_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return (+x) * (+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function typed_div_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return (+x) / (+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function typed_mod_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return (+x) % (+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function typed_or_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return (+x) | (+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function typed_and_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return (+x) & (+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function typed_xor_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return (+x) ^ (+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function typed_shl_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return (+x) << (+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function typed_shr_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return (+x) >> (+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function typed_sar_strong(x, y) {
|
||||||
|
"use strong";
|
||||||
|
return (+x) >>> (+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
let strongFuncs = [sub_strong, mul_strong, div_strong, mod_strong, or_strong,
|
||||||
|
and_strong, xor_strong, shl_strong, shr_strong, sar_strong,
|
||||||
|
typed_sub_strong, typed_mul_strong, typed_div_strong,
|
||||||
|
typed_mod_strong, typed_or_strong, typed_and_strong,
|
||||||
|
typed_xor_strong, typed_shl_strong, typed_shr_strong,
|
||||||
|
typed_sar_strong];
|
||||||
|
|
||||||
function inline_sub_strong(x, y) {
|
function inline_sub_strong(x, y) {
|
||||||
"use strong";
|
"use strong";
|
||||||
@ -91,36 +184,52 @@ function inline_outer_strong(x, y) {
|
|||||||
return inline_sub(x, y);
|
return inline_sub(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let op of strong_arith) {
|
function assertStrongNonThrowBehaviour(expr) {
|
||||||
for (let left of number_values) {
|
assertEquals(eval(expr), eval("'use strong';" + expr));
|
||||||
for (let right of number_values) {
|
assertDoesNotThrow("'use strong'; " + expr + ";");
|
||||||
let expr = "(" + left + op + right + ")";
|
assertDoesNotThrow("'use strong'; let v = " + expr + ";");
|
||||||
assertEquals(eval(expr), eval("'use strong';" + expr));
|
}
|
||||||
assertDoesNotThrow("'use strong'; " + expr + ";");
|
|
||||||
assertDoesNotThrow("'use strong'; let v = " + expr + ";");
|
function assertStrongThrowBehaviour(expr) {
|
||||||
|
assertDoesNotThrow("'use strict'; " + expr + ";");
|
||||||
|
assertDoesNotThrow("'use strict'; let v = " + expr + ";");
|
||||||
|
assertThrows("'use strong'; " + expr + ";", TypeError);
|
||||||
|
assertThrows("'use strong'; let v = " + expr + ";", TypeError);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let op of strongBinops) {
|
||||||
|
for (let v1 of numberValues) {
|
||||||
|
let assignExpr = "foo " + op + "= " + v1 + ";";
|
||||||
|
for (let v2 of numberValues) {
|
||||||
|
assertDoesNotThrow("'use strong'; let foo = " + v2 + "; " + assignExpr);
|
||||||
|
assertStrongNonThrowBehaviour("(" + v1 + op + v2 + ")");
|
||||||
|
}
|
||||||
|
for (let v2 of nonNumberValues) {
|
||||||
|
assertThrows("'use strong'; let foo = " + v2 + "; " + assignExpr,
|
||||||
|
TypeError);
|
||||||
|
assertStrongThrowBehaviour("(" + v1 + op + v2 + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let left of number_values) {
|
for (let v1 of nonNumberValues) {
|
||||||
for (let right of nonnumber_values) {
|
let assignExpr = "foo " + op + "= " + v1 + ";";
|
||||||
let expr = "(" + left + op + right + ")";
|
for (let v2 of numberValues.concat(nonNumberValues)) {
|
||||||
assertDoesNotThrow("'use strict'; " + expr + ";");
|
assertThrows("'use strong'; let foo = " + v2 + "; " + assignExpr,
|
||||||
assertDoesNotThrow("'use strict'; let v = " + expr + ";");
|
TypeError);
|
||||||
assertThrows("'use strong'; " + expr + ";", TypeError);
|
assertStrongThrowBehaviour("(" + v1 + op + v2 + ")");
|
||||||
assertThrows("'use strong'; let v = " + expr + ";", TypeError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let left of nonnumber_values) {
|
|
||||||
for (let right of number_values.concat(nonnumber_values)) {
|
|
||||||
let expr = "(" + left + op + right + ")";
|
|
||||||
assertDoesNotThrow("'use strict'; " + expr + ";");
|
|
||||||
assertDoesNotThrow("'use strict'; let v = " + expr + ";");
|
|
||||||
assertThrows("'use strong'; " + expr + ";", TypeError);
|
|
||||||
assertThrows("'use strong'; let v = " + expr + ";", TypeError);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let func of strong_funcs) {
|
for (let op of strongUnops) {
|
||||||
|
for (let value of numberValues) {
|
||||||
|
assertStrongNonThrowBehaviour("(" + op + value + ")");
|
||||||
|
}
|
||||||
|
for (let value of nonNumberValues) {
|
||||||
|
assertStrongThrowBehaviour("(" + op + value + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let func of strongFuncs) {
|
||||||
let a = func(4, 5);
|
let a = func(4, 5);
|
||||||
let b = func(4, 5);
|
let b = func(4, 5);
|
||||||
assertTrue(a === b);
|
assertTrue(a === b);
|
||||||
@ -135,7 +244,7 @@ for (let func of strong_funcs) {
|
|||||||
%ClearFunctionTypeFeedback(func);
|
%ClearFunctionTypeFeedback(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let func of strong_funcs) {
|
for (let func of strongFuncs) {
|
||||||
try {
|
try {
|
||||||
let a = func(2, 3);
|
let a = func(2, 3);
|
||||||
let b = func(2, 3);
|
let b = func(2, 3);
|
||||||
@ -143,8 +252,8 @@ for (let func of strong_funcs) {
|
|||||||
%OptimizeFunctionOnNextCall(func);
|
%OptimizeFunctionOnNextCall(func);
|
||||||
let c = func(2, "foo");
|
let c = func(2, "foo");
|
||||||
assertUnreachable();
|
assertUnreachable();
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
assertTrue(e instanceof TypeError);
|
assertInstanceof(e, TypeError);
|
||||||
assertUnoptimized(func);
|
assertUnoptimized(func);
|
||||||
assertThrows(function(){func(2, "foo");}, TypeError);
|
assertThrows(function(){func(2, "foo");}, TypeError);
|
||||||
assertDoesNotThrow(function(){func(2, 3);});
|
assertDoesNotThrow(function(){func(2, 3);});
|
||||||
|
@ -456,13 +456,15 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) {
|
|||||||
Node* const effect = graph()->start();
|
Node* const effect = graph()->start();
|
||||||
Node* const control = graph()->start();
|
Node* const control = graph()->start();
|
||||||
TRACED_FORRANGE(double, rhs, 0, 31) {
|
TRACED_FORRANGE(double, rhs, 0, 31) {
|
||||||
Reduction r =
|
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
|
||||||
Reduce(graph()->NewNode(javascript()->ShiftLeft(LanguageMode::SLOPPY),
|
Reduction r =
|
||||||
lhs, NumberConstant(rhs), context, effect,
|
Reduce(graph()->NewNode(javascript()->ShiftLeft(language_mode), lhs,
|
||||||
control));
|
NumberConstant(rhs), context, effect,
|
||||||
ASSERT_TRUE(r.Changed());
|
control));
|
||||||
EXPECT_THAT(r.replacement(),
|
ASSERT_TRUE(r.Changed());
|
||||||
IsWord32Shl(lhs, IsNumberConstant(BitEq(rhs))));
|
EXPECT_THAT(r.replacement(),
|
||||||
|
IsWord32Shl(lhs, IsNumberConstant(BitEq(rhs))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,12 +475,14 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) {
|
|||||||
Node* const context = UndefinedConstant();
|
Node* const context = UndefinedConstant();
|
||||||
Node* const effect = graph()->start();
|
Node* const effect = graph()->start();
|
||||||
Node* const control = graph()->start();
|
Node* const control = graph()->start();
|
||||||
Reduction r =
|
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
|
||||||
Reduce(graph()->NewNode(javascript()->ShiftLeft(LanguageMode::SLOPPY),
|
Reduction r =
|
||||||
lhs, rhs, context, effect, control));
|
Reduce(graph()->NewNode(javascript()->ShiftLeft(language_mode), lhs,
|
||||||
ASSERT_TRUE(r.Changed());
|
rhs, context, effect, control));
|
||||||
EXPECT_THAT(r.replacement(),
|
ASSERT_TRUE(r.Changed());
|
||||||
IsWord32Shl(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
|
EXPECT_THAT(r.replacement(),
|
||||||
|
IsWord32Shl(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -492,13 +496,15 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) {
|
|||||||
Node* const effect = graph()->start();
|
Node* const effect = graph()->start();
|
||||||
Node* const control = graph()->start();
|
Node* const control = graph()->start();
|
||||||
TRACED_FORRANGE(double, rhs, 0, 31) {
|
TRACED_FORRANGE(double, rhs, 0, 31) {
|
||||||
Reduction r =
|
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
|
||||||
Reduce(graph()->NewNode(javascript()->
|
Reduction r =
|
||||||
ShiftRight(LanguageMode::SLOPPY), lhs,
|
Reduce(graph()->NewNode(javascript()-> ShiftRight(language_mode), lhs,
|
||||||
NumberConstant(rhs), context, effect, control));
|
NumberConstant(rhs), context, effect,
|
||||||
ASSERT_TRUE(r.Changed());
|
control));
|
||||||
EXPECT_THAT(r.replacement(),
|
ASSERT_TRUE(r.Changed());
|
||||||
IsWord32Sar(lhs, IsNumberConstant(BitEq(rhs))));
|
EXPECT_THAT(r.replacement(),
|
||||||
|
IsWord32Sar(lhs, IsNumberConstant(BitEq(rhs))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,12 +515,14 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) {
|
|||||||
Node* const context = UndefinedConstant();
|
Node* const context = UndefinedConstant();
|
||||||
Node* const effect = graph()->start();
|
Node* const effect = graph()->start();
|
||||||
Node* const control = graph()->start();
|
Node* const control = graph()->start();
|
||||||
Reduction r = Reduce(graph()->NewNode(javascript()->
|
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
|
||||||
ShiftRight(LanguageMode::SLOPPY),
|
Reduction r = Reduce(graph()->NewNode(javascript()->
|
||||||
lhs, rhs, context, effect, control));
|
ShiftRight(language_mode), lhs, rhs,
|
||||||
ASSERT_TRUE(r.Changed());
|
context, effect, control));
|
||||||
EXPECT_THAT(r.replacement(),
|
ASSERT_TRUE(r.Changed());
|
||||||
IsWord32Sar(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
|
EXPECT_THAT(r.replacement(),
|
||||||
|
IsWord32Sar(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -529,14 +537,16 @@ TEST_F(JSTypedLoweringTest,
|
|||||||
Node* const effect = graph()->start();
|
Node* const effect = graph()->start();
|
||||||
Node* const control = graph()->start();
|
Node* const control = graph()->start();
|
||||||
TRACED_FORRANGE(double, rhs, 0, 31) {
|
TRACED_FORRANGE(double, rhs, 0, 31) {
|
||||||
Reduction r =
|
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
|
||||||
Reduce(graph()->NewNode(javascript()->
|
Reduction r =
|
||||||
ShiftRightLogical(LanguageMode::SLOPPY),
|
Reduce(graph()->NewNode(javascript()->
|
||||||
lhs, NumberConstant(rhs), context, effect,
|
ShiftRightLogical(language_mode), lhs,
|
||||||
control));
|
NumberConstant(rhs), context, effect,
|
||||||
ASSERT_TRUE(r.Changed());
|
control));
|
||||||
EXPECT_THAT(r.replacement(),
|
ASSERT_TRUE(r.Changed());
|
||||||
IsWord32Shr(lhs, IsNumberConstant(BitEq(rhs))));
|
EXPECT_THAT(r.replacement(),
|
||||||
|
IsWord32Shr(lhs, IsNumberConstant(BitEq(rhs))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,12 +558,14 @@ TEST_F(JSTypedLoweringTest,
|
|||||||
Node* const context = UndefinedConstant();
|
Node* const context = UndefinedConstant();
|
||||||
Node* const effect = graph()->start();
|
Node* const effect = graph()->start();
|
||||||
Node* const control = graph()->start();
|
Node* const control = graph()->start();
|
||||||
Reduction r = Reduce(graph()->NewNode(javascript()->
|
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
|
||||||
ShiftRightLogical(LanguageMode::SLOPPY),
|
Reduction r = Reduce(graph()->NewNode(javascript()->
|
||||||
lhs, rhs, context, effect, control));
|
ShiftRightLogical(language_mode), lhs,
|
||||||
ASSERT_TRUE(r.Changed());
|
rhs, context, effect, control));
|
||||||
EXPECT_THAT(r.replacement(),
|
ASSERT_TRUE(r.Changed());
|
||||||
IsWord32Shr(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
|
EXPECT_THAT(r.replacement(),
|
||||||
|
IsWord32Shr(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user