Properly handle unsigned literals, fix typing issue with unary +.
Properly convert unsigned literals. Forbid using unary + on a kAsmInt. Forbid multiplies other than * 1.0 as being equivalent to unary +. BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203 TEST=test-asm-validator,asm-wasm R=titzer@chromium.org,aseemgarg@chromium.org LOG=N Review URL: https://codereview.chromium.org/1832603002 Cr-Commit-Position: refs/heads/master@{#35046}
This commit is contained in:
parent
3e0b6daf54
commit
942ed11488
@ -1281,12 +1281,27 @@ void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
return;
|
||||
}
|
||||
} else if (expr->op() == Token::MUL && expr->right()->IsLiteral() &&
|
||||
right_type->Is(cache_.kAsmDouble)) {
|
||||
right_type->Is(cache_.kAsmDouble) &&
|
||||
expr->right()->AsLiteral()->raw_value()->ContainsDot() &&
|
||||
expr->right()->AsLiteral()->raw_value()->AsNumber() == 1.0) {
|
||||
// For unary +, expressed as x * 1.0
|
||||
if (expr->left()->IsCall() && expr->op() == Token::MUL &&
|
||||
if (expr->left()->IsCall() &&
|
||||
Type::Number()->Is(expr->left()->bounds().upper)) {
|
||||
// Force the return types of foreign functions.
|
||||
expr->left()->set_bounds(Bounds(cache_.kAsmDouble));
|
||||
left_type = expr->left()->bounds().upper;
|
||||
}
|
||||
if (!(expr->left()->IsProperty() &&
|
||||
Type::Number()->Is(expr->left()->bounds().upper))) {
|
||||
if (!left_type->Is(cache_.kAsmSigned) &&
|
||||
!left_type->Is(cache_.kAsmUnsigned) &&
|
||||
!left_type->Is(cache_.kAsmFixnum) &&
|
||||
!left_type->Is(cache_.kAsmFloatQ) &&
|
||||
!left_type->Is(cache_.kAsmDoubleQ)) {
|
||||
FAIL(
|
||||
expr->left(),
|
||||
"unary + only allowed on signed, unsigned, float?, or double?");
|
||||
}
|
||||
}
|
||||
IntersectResult(expr, cache_.kAsmDouble);
|
||||
return;
|
||||
|
@ -461,33 +461,32 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
||||
}
|
||||
|
||||
void VisitLiteral(Literal* expr) {
|
||||
if (in_function_) {
|
||||
if (expr->raw_value()->IsNumber()) {
|
||||
LocalType type = TypeOf(expr);
|
||||
switch (type) {
|
||||
case kAstI32: {
|
||||
int val = static_cast<int>(expr->raw_value()->AsNumber());
|
||||
// TODO(bradnelson): variable size
|
||||
byte code[] = {WASM_I32V(val)};
|
||||
current_function_builder_->EmitCode(code, sizeof(code));
|
||||
break;
|
||||
Handle<Object> value = expr->value();
|
||||
if (!in_function_ || !value->IsNumber()) {
|
||||
return;
|
||||
}
|
||||
case kAstF32: {
|
||||
float val = static_cast<float>(expr->raw_value()->AsNumber());
|
||||
byte code[] = {WASM_F32(val)};
|
||||
current_function_builder_->EmitCode(code, sizeof(code));
|
||||
break;
|
||||
}
|
||||
case kAstF64: {
|
||||
double val = static_cast<double>(expr->raw_value()->AsNumber());
|
||||
byte code[] = {WASM_F64(val)};
|
||||
current_function_builder_->EmitCode(code, sizeof(code));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Type* type = expr->bounds().upper;
|
||||
if (type->Is(cache_.kAsmSigned)) {
|
||||
int32_t i;
|
||||
if (!value->ToInt32(&i)) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
byte code[] = {WASM_I32V(i)};
|
||||
current_function_builder_->EmitCode(code, sizeof(code));
|
||||
} else if (type->Is(cache_.kAsmUnsigned) || type->Is(cache_.kAsmFixnum)) {
|
||||
uint32_t u;
|
||||
if (!value->ToUint32(&u)) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
int32_t i = static_cast<int32_t>(u);
|
||||
byte code[] = {WASM_I32V(i)};
|
||||
current_function_builder_->EmitCode(code, sizeof(code));
|
||||
} else if (type->Is(cache_.kAsmDouble)) {
|
||||
double val = expr->raw_value()->AsNumber();
|
||||
byte code[] = {WASM_F64(val)};
|
||||
current_function_builder_->EmitCode(code, sizeof(code));
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1985,6 +1985,20 @@ TEST(BadFunctionCallOutside) {
|
||||
"asm: line 2: illegal variable reference in module body\n");
|
||||
}
|
||||
|
||||
TEST(UnaryPlusOnIntForbidden) {
|
||||
CHECK_FUNC_ERROR(
|
||||
"function bar() { var x = 1; return +x; }\n"
|
||||
"function foo() { bar(); }",
|
||||
"asm: line 1: "
|
||||
"unary + only allowed on signed, unsigned, float?, or double?\n");
|
||||
}
|
||||
|
||||
TEST(MultiplyNon1ConvertForbidden) {
|
||||
CHECK_FUNC_ERROR(
|
||||
"function bar() { var x = 0.0; return x * 2.0; }\n"
|
||||
"function foo() { bar(); }",
|
||||
"asm: line 1: invalid type annotation on binary op\n");
|
||||
}
|
||||
|
||||
TEST(NestedVariableAssignment) {
|
||||
CHECK_FUNC_TYPES_BEGIN(
|
||||
|
@ -508,7 +508,7 @@ function TestConvertF64FromInt() {
|
||||
|
||||
function caller() {
|
||||
var a = 1;
|
||||
if ((+(a + a)) > 1.5) {
|
||||
if ((+((a + a)|0)) > 1.5) {
|
||||
return 25;
|
||||
}
|
||||
return 0;
|
||||
@ -526,7 +526,7 @@ function TestConvertF64FromUnsigned() {
|
||||
function caller() {
|
||||
var a = 0xffffffff;
|
||||
if ((+(a>>>0)) > 0.0) {
|
||||
if((+a) < 0.0) {
|
||||
if((+(a|0)) < 0.0) {
|
||||
return 26;
|
||||
}
|
||||
}
|
||||
@ -1376,6 +1376,21 @@ assertWasm(1, TestXor);
|
||||
})();
|
||||
|
||||
|
||||
(function TestBadCastFromInt() {
|
||||
function Module(stdlib, foreign, heap) {
|
||||
"use asm";
|
||||
function func() {
|
||||
var a = 1;
|
||||
return +a;
|
||||
}
|
||||
return {func: func};
|
||||
}
|
||||
assertThrows(function() {
|
||||
Wasm.instantiateModuleFromAsm(Module.toString());
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
(function TestAndNegative() {
|
||||
function Module() {
|
||||
"use asm";
|
||||
@ -1457,3 +1472,30 @@ assertWasm(1, TestXor);
|
||||
var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
|
||||
assertEquals(1321347704, wasm.main());
|
||||
})();
|
||||
|
||||
(function TestUnsignedLiterals() {
|
||||
function asmModule() {
|
||||
"use asm";
|
||||
function u0xffffffff() {
|
||||
var f = 0xffffffff;
|
||||
return +(f >>> 0);
|
||||
}
|
||||
function u0x80000000() {
|
||||
var f = 0x80000000;
|
||||
return +(f >>> 0);
|
||||
}
|
||||
function u0x87654321() {
|
||||
var f = 0x87654321;
|
||||
return +(f >>> 0);
|
||||
}
|
||||
return {
|
||||
u0xffffffff: u0xffffffff,
|
||||
u0x80000000: u0x80000000,
|
||||
u0x87654321: u0x87654321,
|
||||
};
|
||||
}
|
||||
var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
|
||||
assertEquals(0xffffffff, wasm.u0xffffffff());
|
||||
assertEquals(0x80000000, wasm.u0x80000000());
|
||||
assertEquals(0x87654321, wasm.u0x87654321());
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user