Bug 1311994 - Baldr: update type codes to match 0xd (r=sunfish)

MozReview-Commit-ID: 7pCkgkiouDY

--HG--
extra : rebase_source : 8032194e65c7c91693795098ae3d865b563b8036
This commit is contained in:
Luke Wagner 2016-10-24 13:10:32 -05:00
Родитель af0242407d
Коммит 37c2676a61
15 изменённых файлов: 147 добавлений и 151 удалений

Просмотреть файл

@ -7578,8 +7578,6 @@ ValidateGlobalVariable(JSContext* cx, const AsmJSGlobal& global, HandleValue imp
*val = Val(simdConstant.asInt32x4());
return true;
}
case ValType::Limit:
MOZ_CRASH("Limit");
}
}
}

Просмотреть файл

@ -600,7 +600,7 @@ class AstGlobal : public AstNode
Maybe<AstExpr*> init_;
public:
AstGlobal() : isMutable_(false), type_(ValType::Limit)
AstGlobal() : isMutable_(false), type_(ValType(TypeCode::Limit))
{}
explicit AstGlobal(AstName name, ValType type, bool isMutable,

Просмотреть файл

@ -87,36 +87,58 @@ enum class SectionId {
static const char NameSectionName[] = "name";
enum class ValType
enum class TypeCode
{
I32 = 0x01,
I64 = 0x02,
F32 = 0x03,
F64 = 0x04,
I32 = 0x7f, // SLEB128(-0x01)
I64 = 0x7e, // SLEB128(-0x02)
F32 = 0x7d, // SLEB128(-0x03)
F64 = 0x7c, // SLEB128(-0x04)
// Only emitted internally for asm.js, likely to get collapsed into I128
I8x16 = 0x7b,
I16x8 = 0x7a,
I32x4 = 0x79,
F32x4 = 0x78,
B8x16 = 0x77,
B16x8 = 0x76,
B32x4 = 0x75,
// A function pointer with any signature
AnyFunc = 0x70, // SLEB128(-0x10)
// Type constructor for function types
Func = 0x60, // SLEB128(-0x20)
// Special code representing the block signature ()->()
BlockVoid = 0x40, // SLEB128(-0x40)
// Type codes currently always fit in a single byte
Max = 0x7f,
Limit = 0x80
};
enum class ValType : uint32_t // fix type so we can cast from any u8 in decoder
{
I32 = uint8_t(TypeCode::I32),
I64 = uint8_t(TypeCode::I64),
F32 = uint8_t(TypeCode::F32),
F64 = uint8_t(TypeCode::F64),
// ------------------------------------------------------------------------
// The rest of these types are currently only emitted internally when
// compiling asm.js and are rejected by wasm validation.
I8x16,
I16x8,
I32x4,
F32x4,
B8x16,
B16x8,
B32x4,
Limit
I8x16 = uint8_t(TypeCode::I8x16),
I16x8 = uint8_t(TypeCode::I16x8),
I32x4 = uint8_t(TypeCode::I32x4),
F32x4 = uint8_t(TypeCode::F32x4),
B8x16 = uint8_t(TypeCode::B8x16),
B16x8 = uint8_t(TypeCode::B16x8),
B32x4 = uint8_t(TypeCode::B32x4)
};
typedef Vector<ValType, 8, SystemAllocPolicy> ValTypeVector;
enum class TypeConstructor
{
AnyFunc = 0x20,
Function = 0x40
};
enum class DefinitionKind
{
Function = 0x00,
@ -131,7 +153,7 @@ enum class GlobalFlags
AllowedMask = 0x1
};
enum class Expr
enum class Expr : uint32_t // fix type so we can cast from any u16 in decoder
{
// Control flow operators
Unreachable = 0x00,
@ -456,22 +478,24 @@ enum class Expr
// generalized to a list of ValType and this enum will go away, replaced,
// wherever it is used, by a varU32 + list of ValType.
enum class ExprType
enum class ExprType : uint32_t // fix type so we can cast from any u8 in decoder
{
Void = 0x00,
I32 = uint8_t(ValType::I32),
I64 = uint8_t(ValType::I64),
F32 = uint8_t(ValType::F32),
F64 = uint8_t(ValType::F64),
I8x16 = uint8_t(ValType::I8x16),
I16x8 = uint8_t(ValType::I16x8),
I32x4 = uint8_t(ValType::I32x4),
F32x4 = uint8_t(ValType::F32x4),
B8x16 = uint8_t(ValType::B8x16),
B16x8 = uint8_t(ValType::B16x8),
B32x4 = uint8_t(ValType::B32x4),
Void = uint8_t(TypeCode::BlockVoid),
Limit
I32 = uint8_t(TypeCode::I32),
I64 = uint8_t(TypeCode::I64),
F32 = uint8_t(TypeCode::F32),
F64 = uint8_t(TypeCode::F64),
I8x16 = uint8_t(TypeCode::I8x16),
I16x8 = uint8_t(TypeCode::I16x8),
I32x4 = uint8_t(TypeCode::I32x4),
F32x4 = uint8_t(TypeCode::F32x4),
B8x16 = uint8_t(TypeCode::B8x16),
B16x8 = uint8_t(TypeCode::B16x8),
B32x4 = uint8_t(TypeCode::B32x4),
Limit = uint8_t(TypeCode::Limit)
};
typedef int8_t I8x16[16];
@ -613,12 +637,14 @@ class Encoder
return writeVarS<int64_t>(i);
}
MOZ_MUST_USE bool writeValType(ValType type) {
static_assert(size_t(ValType::Limit) <= INT8_MAX, "fits");
return writeFixedU8(size_t(type));
static_assert(size_t(TypeCode::Max) <= INT8_MAX, "fits");
MOZ_ASSERT(size_t(type) <= size_t(TypeCode::Max));
return writeFixedU8(uint8_t(type));
}
MOZ_MUST_USE bool writeExprType(ExprType type) {
static_assert(size_t(ExprType::Limit) <= INT8_MAX, "fits");
return writeFixedU8(size_t(type));
MOZ_MUST_USE bool writeBlockType(ExprType type) {
static_assert(size_t(TypeCode::Max) <= INT8_MAX, "fits");
MOZ_ASSERT(size_t(type) <= size_t(TypeCode::Max));
return writeFixedU8(uint8_t(type));
}
MOZ_MUST_USE bool writeExpr(Expr expr) {
static_assert(size_t(Expr::Limit) <= ExprLimit, "fits");
@ -857,13 +883,21 @@ class Decoder
return readVarS<int64_t>(out);
}
MOZ_MUST_USE bool readValType(ValType* type) {
static_assert(uint8_t(ValType::Limit) <= INT8_MAX, "fits");
static_assert(uint8_t(TypeCode::Max) <= INT8_MAX, "fits");
uint8_t u8;
if (!readFixedU8(&u8))
return false;
*type = (ValType)u8;
return true;
}
MOZ_MUST_USE bool readBlockType(ExprType* type) {
static_assert(size_t(TypeCode::Max) <= INT8_MAX, "fits");
uint8_t u8;
if (!readFixedU8(&u8))
return false;
*type = (ExprType)u8;
return true;
}
MOZ_MUST_USE bool readExpr(Expr* expr) {
static_assert(size_t(Expr::Limit) <= ExprLimit, "fits");
uint8_t u8;
@ -877,7 +911,7 @@ class Decoder
return false;
if (u8 == UINT8_MAX)
return false;
*expr = Expr(u8 + UINT8_MAX);
*expr = Expr(uint16_t(u8) + UINT8_MAX);
return true;
}

Просмотреть файл

@ -41,7 +41,7 @@ bool
wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals)
{
uint32_t numLocalEntries = 0;
ValType prev = ValType::Limit;
ValType prev = ValType(TypeCode::Limit);
for (ValType t : locals) {
if (t != prev) {
numLocalEntries++;

Просмотреть файл

@ -192,7 +192,7 @@ class TypeAndValue
Value value_;
public:
TypeAndValue() : type_(ValType::Limit), value_() {}
TypeAndValue() : type_(ValType(TypeCode::Limit)), value_() {}
explicit TypeAndValue(ValType type)
: type_(type), value_()
{}
@ -217,7 +217,7 @@ class TypeAndValue<Nothing>
ValType type_;
public:
TypeAndValue() : type_(ValType::Limit) {}
TypeAndValue() : type_(ValType(TypeCode::Limit)) {}
explicit TypeAndValue(ValType type) : type_(type) {}
TypeAndValue(ValType type, Nothing value)
@ -375,7 +375,7 @@ class MOZ_STACK_CLASS ExprIter : private Policy
}
MOZ_MUST_USE bool readLinearMemoryAddress(uint32_t byteSize, LinearMemoryAddress<Value>* addr);
MOZ_MUST_USE bool readExprType(ExprType* expr);
MOZ_MUST_USE bool readBlockType(ExprType* expr);
MOZ_MUST_USE bool typeMismatch(ExprType actual, ExprType expected) MOZ_COLD;
MOZ_MUST_USE bool checkType(ValType actual, ValType expected);
@ -809,16 +809,30 @@ ExprIter<Policy>::popControl(LabelKind* kind, ExprType* type, Value* value)
template <typename Policy>
inline bool
ExprIter<Policy>::readExprType(ExprType* type)
ExprIter<Policy>::readBlockType(ExprType* type)
{
uint8_t byte;
if (!readFixedU8(&byte))
if (!d_.readBlockType(type))
return fail("unable to read block signature");
if (Validate && byte >= uint8_t(ExprType::Limit))
return fail("invalid inline type");
*type = ExprType(byte);
if (Validate) {
switch (*type) {
case ExprType::Void:
case ExprType::I32:
case ExprType::I64:
case ExprType::F32:
case ExprType::F64:
case ExprType::I8x16:
case ExprType::I16x8:
case ExprType::I32x4:
case ExprType::F32x4:
case ExprType::B8x16:
case ExprType::B16x8:
case ExprType::B32x4:
break;
default:
return fail("invalid inline block type");
}
}
return true;
}
@ -898,7 +912,7 @@ ExprIter<Policy>::readBlock()
MOZ_ASSERT(Classify(expr_) == ExprKind::Block);
ExprType type = ExprType::Limit;
if (!readExprType(&type))
if (!readBlockType(&type))
return false;
return pushControl(LabelKind::Block, type, false);
@ -911,7 +925,7 @@ ExprIter<Policy>::readLoop()
MOZ_ASSERT(Classify(expr_) == ExprKind::Loop);
ExprType type = ExprType::Limit;
if (!readExprType(&type))
if (!readBlockType(&type))
return false;
return pushControl(LabelKind::Loop, type, reachable_);
@ -924,7 +938,7 @@ ExprIter<Policy>::readIf(Value* condition)
MOZ_ASSERT(Classify(expr_) == ExprKind::If);
ExprType type = ExprType::Limit;
if (!readExprType(&type))
if (!readBlockType(&type))
return false;
if (MOZ_LIKELY(reachable_)) {

Просмотреть файл

@ -1472,7 +1472,7 @@ AstDecodeTypeSection(AstDecodeContext& c)
for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) {
uint32_t form;
if (!c.d.readVarU32(&form) || form != uint32_t(TypeConstructor::Function))
if (!c.d.readVarU32(&form) || form != uint32_t(TypeCode::Func))
return c.d.fail("expected function form");
uint32_t numArgs;
@ -1586,7 +1586,7 @@ AstDecodeTableSection(AstDecodeContext& c)
if (!c.d.readVarU32(&typeConstructorValue))
return c.d.fail("expected type constructor kind");
if (typeConstructorValue != uint32_t(TypeConstructor::AnyFunc))
if (typeConstructorValue != uint32_t(TypeCode::AnyFunc))
return c.d.fail("unknown type constructor kind");
Limits table;
@ -1631,7 +1631,7 @@ AstDecodeLimitsTable(AstDecodeContext& c, Limits* limits)
if (!c.d.readVarU32(&kind))
return false;
if (kind != uint32_t(TypeConstructor::AnyFunc))
if (kind != uint32_t(TypeCode::AnyFunc))
return c.d.fail("unknown type constructor kind");
if (!DecodeLimits(c.d, limits))

Просмотреть файл

@ -147,42 +147,6 @@ DecodeCallIndirect(FunctionDecoder& f)
return DecodeCallReturn(f, sig);
}
static bool
DecodeBlock(FunctionDecoder& f)
{
if (!f.iter().readBlock())
return false;
if (f.iter().controlType() > ExprType::F64)
return f.iter().fail("unknown block signature type");
return true;
}
static bool
DecodeLoop(FunctionDecoder& f)
{
if (!f.iter().readLoop())
return false;
if (f.iter().controlType() > ExprType::F64)
return f.iter().fail("unknown loop signature type");
return true;
}
static bool
DecodeIf(FunctionDecoder& f)
{
if (!f.iter().readIf(nullptr))
return false;
if (f.iter().controlType() > ExprType::F64)
return f.iter().fail("unknown if signature type");
return true;
}
static bool
DecodeBrTable(FunctionDecoder& f)
{
@ -247,11 +211,11 @@ DecodeFunctionBodyExprs(FunctionDecoder& f)
case Expr::Select:
CHECK(f.iter().readSelect(nullptr, nullptr, nullptr, nullptr));
case Expr::Block:
CHECK(DecodeBlock(f));
CHECK(f.iter().readBlock());
case Expr::Loop:
CHECK(DecodeLoop(f));
CHECK(f.iter().readLoop());
case Expr::If:
CHECK(DecodeIf(f));
CHECK(f.iter().readIf(nullptr));
case Expr::Else:
CHECK(f.iter().readElse(nullptr, nullptr));
case Expr::I32Clz:
@ -488,7 +452,7 @@ DecodeTypeSection(Decoder& d, ModuleGeneratorData* init)
for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) {
uint32_t form;
if (!d.readVarU32(&form) || form != uint32_t(TypeConstructor::Function))
if (!d.readVarU32(&form) || form != uint32_t(TypeCode::Func))
return d.fail("expected function form");
uint32_t numArgs;
@ -642,7 +606,7 @@ DecodeResizableTable(Decoder& d, ModuleGeneratorData* init)
if (!d.readVarU32(&elementType))
return d.fail("expected table element type");
if (elementType != uint32_t(TypeConstructor::AnyFunc))
if (elementType != uint32_t(TypeCode::AnyFunc))
return d.fail("expected 'anyfunc' element type");
Limits limits;

Просмотреть файл

@ -670,9 +670,6 @@ ModuleGenerator::allocateGlobal(GlobalDesc* global)
case ValType::B32x4:
width = 16;
break;
case ValType::Limit:
MOZ_CRASH("Limit");
break;
}
uint32_t offset;

Просмотреть файл

@ -166,7 +166,6 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
case ValType::B8x16:
case ValType::B16x8:
case ValType::B32x4:
case ValType::Limit:
MOZ_CRASH("unhandled type in callImport");
}
}
@ -239,7 +238,6 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
case ValType::B8x16: MOZ_CRASH("NYI");
case ValType::B16x8: MOZ_CRASH("NYI");
case ValType::B32x4: MOZ_CRASH("NYI");
case ValType::Limit: MOZ_CRASH("Limit");
}
if (!TypeScript::ArgTypes(script, i)->hasType(type))
return true;
@ -640,8 +638,6 @@ Instance::callExport(JSContext* cx, uint32_t funcDefIndex, CallArgs args)
memcpy(&exportArgs[i], simd.asInt32x4(), Simd128DataSize);
break;
}
case ValType::Limit:
MOZ_CRASH("Limit");
}
}

Просмотреть файл

@ -264,8 +264,6 @@ class FunctionCompiler
// Bool32x4 uses the same data layout as Int32x4.
ins = MSimdConstant::New(alloc(), SimdConstant::SplatX4(0), MIRType::Bool32x4);
break;
case ValType::Limit:
MOZ_CRASH("Limit");
}
curBlock_->add(ins);
@ -2685,7 +2683,7 @@ SimdToLaneType(ValType type)
case ValType::I64:
case ValType::F32:
case ValType::F64:
case ValType::Limit:;
break;
}
MOZ_CRASH("bad simd type");
}
@ -2971,7 +2969,6 @@ EmitSimdCtor(FunctionCompiler& f, ValType type)
case ValType::I64:
case ValType::F32:
case ValType::F64:
case ValType::Limit:
break;
}
MOZ_CRASH("unexpected SIMD type");

Просмотреть файл

@ -3859,7 +3859,7 @@ EncodeBlock(Encoder& e, AstBlock& b)
if (!e.writeExpr(b.expr()))
return false;
if (!e.writeExprType(b.type()))
if (!e.writeBlockType(b.type()))
return false;
if (!EncodeExprList(e, b.exprs()))
@ -4063,7 +4063,7 @@ EncodeIf(Encoder& e, AstIf& i)
if (!EncodeExpr(e, i.cond()) || !e.writeExpr(Expr::If))
return false;
if (!e.writeExprType(i.type()))
if (!e.writeBlockType(i.type()))
return false;
if (!EncodeExprList(e, i.thenExprs()))
@ -4228,7 +4228,7 @@ EncodeTypeSection(Encoder& e, AstModule& module)
return false;
for (AstSig* sig : module.sigs()) {
if (!e.writeVarU32(uint32_t(TypeConstructor::Function)))
if (!e.writeVarU32(uint32_t(TypeCode::Func)))
return false;
if (!e.writeVarU32(sig->args().length()))
@ -4303,7 +4303,7 @@ EncodeLimits(Encoder& e, const Limits& limits)
static bool
EncodeTableLimits(Encoder& e, const Limits& limits)
{
if (!e.writeVarU32(uint32_t(TypeConstructor::AnyFunc)))
if (!e.writeVarU32(uint32_t(TypeCode::AnyFunc)))
return false;
return EncodeLimits(e, limits);

Просмотреть файл

@ -62,8 +62,6 @@ Val::writePayload(uint8_t* dst) const
case ValType::B32x4:
memcpy(dst, &u, jit::Simd128DataSize);
return;
case ValType::Limit:
MOZ_CRASH("Bad value type");
}
}

Просмотреть файл

@ -269,7 +269,6 @@ ToMIRType(ValType vt)
case ValType::B8x16: return jit::MIRType::Bool8x16;
case ValType::B16x8: return jit::MIRType::Bool16x8;
case ValType::B32x4: return jit::MIRType::Bool32x4;
case ValType::Limit: break;
}
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad type");
}

Просмотреть файл

@ -11,32 +11,30 @@ const ver2 = (Wasm.experimentalVersion >>> 16) & 0xff;
const ver3 = (Wasm.experimentalVersion >>> 24) & 0xff;
// Section opcodes
const userDefinedId = 0;
const typeId = 1;
const importId = 2;
const functionId = 3;
const tableId = 4;
const memoryId = 5;
const globalId = 6;
const exportId = 7;
const startId = 8;
const elemId = 9;
const codeId = 10;
const dataId = 11;
const userDefinedId = 0;
const typeId = 1;
const importId = 2;
const functionId = 3;
const tableId = 4;
const memoryId = 5;
const globalId = 6;
const exportId = 7;
const startId = 8;
const elemId = 9;
const codeId = 10;
const dataId = 11;
// User-defined section names
const nameName = "name";
const nameName = "name";
// Type codes
const VoidCode = 0;
const I32Code = 1;
const I64Code = 2;
const F32Code = 3;
const F64Code = 4;
// Type constructors
const AnyFuncCode = 0x20;
const FunctionConstructorCode = 0x40;
const I32Code = 0x7f;
const I64Code = 0x7e;
const F32Code = 0x7d;
const F64Code = 0x7c;
const AnyFuncCode = 0x70;
const FuncCode = 0x60;
const VoidCode = 0x40;
// Opcodes
const UnreachableCode = 0x00;
@ -86,11 +84,11 @@ const I64TruncUF64Code = 0xa5;
const GrowMemoryCode = 0x39;
// DefinitionKind
const FunctionCode = 0x00;
const TableCode = 0x01;
const MemoryCode = 0x02;
const GlobalCode = 0x03;
const FunctionCode = 0x00;
const TableCode = 0x01;
const MemoryCode = 0x02;
const GlobalCode = 0x03;
// ResizableFlags
const HasMaximumFlag = 0x1;
const HasMaximumFlag = 0x1;

Просмотреть файл

@ -129,7 +129,7 @@ function sigSection(sigs) {
var body = [];
body.push(...varU32(sigs.length));
for (let sig of sigs) {
body.push(...varU32(FunctionConstructorCode));
body.push(...varU32(FuncCode));
body.push(...varU32(sig.args.length));
for (let arg of sig.args)
body.push(...varU32(arg));
@ -245,7 +245,7 @@ const v2vBody = funcBody({locals:[], body:[]});
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: U32MAX_LEB } ])), CompileError, /too many signatures/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, 0], } ])), CompileError, /expected function form/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, FunctionConstructorCode, ...U32MAX_LEB], } ])), CompileError, /too many arguments in signature/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, FuncCode, ...U32MAX_LEB], } ])), CompileError, /too many arguments in signature/);
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1]}])), CompileError);
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1, 1, 0]}])), CompileError);
@ -346,7 +346,8 @@ wasmEval(moduleWithSections([userDefSec, userDefSec, sigSec, declSec, bodySec]))
wasmEval(moduleWithSections([userDefSec, userDefSec, sigSec, userDefSec, declSec, userDefSec, bodySec]));
// Diagnose nonstandard block signature types.
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:[BlockCode, F64Code + 1, EndCode]})])])), CompileError, /unknown block signature type/);
for (var bad of [0xff, 0, 1, 0x3f])
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:[BlockCode, bad, EndCode]})])])), CompileError, /invalid inline block type/);
// Checking stack trace.
function runStackTraceTest(namesContent, expectedName) {