Bug 1253137 - Baldr: pass around Bytes instead of Bytecode/UniqueBytecode (r=sunfish)

MozReview-Commit-ID: 5RzN8IwDc7C
This commit is contained in:
Luke Wagner 2016-03-06 17:46:23 -06:00
Родитель a1da5ec894
Коммит c4ff9aece7
12 изменённых файлов: 146 добавлений и 170 удалений

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

@ -2650,7 +2650,7 @@ class MOZ_STACK_CLASS FunctionValidator
if (!m_.mg().startFuncDef(line, &fg_))
return false;
encoder_.emplace(fg_.bytecode());
encoder_.emplace(fg_.bytes());
return true;
}

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

@ -1265,10 +1265,10 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func
if (d.currentPosition() != bodyEnd)
return Fail(cx, d, "function body length mismatch");
if (!fg.bytecode().resize(bodySize))
if (!fg.bytes().resize(bodySize))
return false;
memcpy(fg.bytecode().begin(), bodyBegin, bodySize);
memcpy(fg.bytes().begin(), bodyBegin, bodySize);
int64_t after = PRMJ_Now();
unsigned generateTime = (after - before) / PRMJ_USEC_PER_MSEC;

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

@ -19,15 +19,11 @@
#ifndef wasm_binary_h
#define wasm_binary_h
#include "mozilla/DebugOnly.h"
#include "builtin/SIMD.h"
namespace js {
namespace wasm {
using mozilla::DebugOnly;
static const uint32_t MagicNumber = 0x6d736100; // "\0asm"
static const uint32_t EncodingVersion = 0xa;
@ -328,20 +324,19 @@ enum class ExprType
typedef int32_t I32x4[4];
typedef float F32x4[4];
typedef Vector<uint8_t, 0, SystemAllocPolicy> Bytecode;
typedef UniquePtr<Bytecode> UniqueBytecode;
typedef Vector<uint8_t, 0, SystemAllocPolicy> Bytes;
// The Encoder class appends bytes to the Bytecode object it is given during
// construction. The client is responsible for the Bytecode's lifetime and must
// keep the Bytecode alive as long as the Encoder is used.
// The Encoder class appends bytes to the Bytes object it is given during
// construction. The client is responsible for the Bytes's lifetime and must
// keep the Bytes alive as long as the Encoder is used.
class Encoder
{
Bytecode& bytecode_;
Bytes& bytes_;
template <class T>
MOZ_WARN_UNUSED_RESULT bool write(const T& v) {
return bytecode_.append(reinterpret_cast<const uint8_t*>(&v), sizeof(T));
return bytes_.append(reinterpret_cast<const uint8_t*>(&v), sizeof(T));
}
template <typename UInt>
@ -351,7 +346,7 @@ class Encoder
i >>= 7;
if (i != 0)
byte |= 0x80;
if (!bytecode_.append(byte))
if (!bytes_.append(byte))
return false;
} while(i != 0);
return true;
@ -374,15 +369,15 @@ class Encoder
assertByte |= 0x80;
patchByte |= 0x80;
}
MOZ_ASSERT(assertByte == bytecode_[offset]);
bytecode_[offset] = patchByte;
MOZ_ASSERT(assertByte == bytes_[offset]);
bytes_[offset] = patchByte;
offset++;
} while(assertBits != 0);
}
uint32_t varU32ByteLength(size_t offset) const {
size_t start = offset;
while (bytecode_[offset] & 0x80)
while (bytes_[offset] & 0x80)
offset++;
return offset - start + 1;
}
@ -391,7 +386,7 @@ class Encoder
template <class T>
MOZ_WARN_UNUSED_RESULT bool writePatchableEnum(size_t* offset) {
static_assert(uint32_t(T::Limit) <= EnumSentinel, "reserve enough bits");
*offset = bytecode_.length();
*offset = bytes_.length();
return writeVarU32(EnumSentinel);
}
@ -403,13 +398,13 @@ class Encoder
}
public:
explicit Encoder(Bytecode& bytecode)
: bytecode_(bytecode)
explicit Encoder(Bytes& bytes)
: bytes_(bytes)
{
MOZ_ASSERT(empty());
}
size_t currentOffset() const { return bytecode_.length(); }
size_t currentOffset() const { return bytes_.length(); }
bool empty() const { return currentOffset() == 0; }
// Fixed-size encoding operations simply copy the literal bytes (without
@ -452,7 +447,7 @@ class Encoder
// Variable-length encodings that allow back-patching.
MOZ_WARN_UNUSED_RESULT bool writePatchableVarU32(size_t* offset) {
*offset = bytecode_.length();
*offset = bytes_.length();
return writeVarU32(UINT32_MAX);
}
void patchVarU32(size_t offset, uint32_t patchBits) {
@ -460,7 +455,7 @@ class Encoder
}
MOZ_WARN_UNUSED_RESULT bool writePatchableVarU8(size_t* offset) {
*offset = bytecode_.length();
*offset = bytes_.length();
return writeU8(UINT8_MAX);
}
void patchVarU8(size_t offset, uint8_t patchBits) {
@ -479,10 +474,10 @@ class Encoder
// contain nulls and instead has an explicit byte length.
MOZ_WARN_UNUSED_RESULT bool writeCString(const char* cstr) {
return bytecode_.append(reinterpret_cast<const uint8_t*>(cstr), strlen(cstr) + 1);
return bytes_.append(reinterpret_cast<const uint8_t*>(cstr), strlen(cstr) + 1);
}
MOZ_WARN_UNUSED_RESULT bool writeRawData(const uint8_t* bytes, uint32_t numBytes) {
return bytecode_.append(bytes, numBytes);
return bytes_.append(bytes, numBytes);
}
// A "section" is a contiguous range of bytes that stores its own size so
@ -500,7 +495,7 @@ class Encoder
writeRawData(reinterpret_cast<const uint8_t*>(id), IdSize);
}
void finishSection(size_t offset) {
return patchVarU32(offset, bytecode_.length() - offset - varU32ByteLength(offset));
return patchVarU32(offset, bytes_.length() - offset - varU32ByteLength(offset));
}
// Temporary encoding forms which should be removed as part of the
@ -510,12 +505,12 @@ class Encoder
return write<uint8_t>(i);
}
MOZ_WARN_UNUSED_RESULT bool writePatchableU8(size_t* offset) {
*offset = bytecode_.length();
return bytecode_.append(0xff);
*offset = bytes_.length();
return bytes_.append(0xff);
}
void patchU8(size_t offset, uint8_t i) {
MOZ_ASSERT(bytecode_[offset] == 0xff);
bytecode_[offset] = i;
MOZ_ASSERT(bytes_[offset] == 0xff);
bytes_[offset] = i;
}
};
@ -599,10 +594,10 @@ class Decoder
{
MOZ_ASSERT(begin <= end);
}
explicit Decoder(const Bytecode& bytecode)
: beg_(bytecode.begin()),
end_(bytecode.end()),
cur_(bytecode.begin())
explicit Decoder(const Bytes& bytes)
: beg_(bytes.begin()),
end_(bytes.end()),
cur_(bytes.begin())
{}
bool done() const {
@ -620,9 +615,6 @@ class Decoder
size_t currentOffset() const {
return cur_ - beg_;
}
void assertCurrentIs(const DebugOnly<size_t> offset) const {
MOZ_ASSERT(currentOffset() == offset);
}
// Fixed-size encoding operations simply copy the literal bytes (without
// attempting to align).
@ -706,7 +698,7 @@ class Decoder
goto backup;
cur_ += IdSize;
*startOffset = before - beg_;
return true;
return true;
backup:
cur_ = before;
*startOffset = NotStarted;
@ -735,7 +727,7 @@ class Decoder
}
// The infallible "unchecked" decoding functions can be used when we are
// sure that the bytecode is well-formed (by construction or due to previous
// sure that the bytes are well-formed (by construction or due to previous
// validation).
uint32_t uncheckedReadFixedU32() {
@ -790,9 +782,6 @@ class Decoder
MOZ_WARN_UNUSED_RESULT bool readFixedU8(uint8_t* i = nullptr) {
return read<uint8_t>(i);
}
MOZ_WARN_UNUSED_RESULT bool readFixedI32(int32_t* i = nullptr) {
return read<int32_t>(i);
}
uint8_t uncheckedReadFixedU8() {
return uncheckedRead<uint8_t>();
}

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

@ -301,7 +301,7 @@ ModuleGenerator::convertOutOfRangeBranchesToThunks()
bool
ModuleGenerator::finishTask(IonCompileTask* task)
{
const FuncBytecode& func = task->func();
const FuncBytes& func = task->func();
FuncCompileResults& results = task->results();
// Before merging in the new function's code, if jumps/calls in a previous
@ -782,15 +782,8 @@ ModuleGenerator::startFuncDef(uint32_t lineOrBytecode, FunctionGenerator* fg)
IonCompileTask* task = freeTasks_.popCopy();
task->reset(&fg->bytecode_);
if (fg->bytecode_) {
fg->bytecode_->clear();
} else {
fg->bytecode_ = MakeUnique<Bytecode>();
if (!fg->bytecode_)
return false;
}
task->reset(&fg->bytes_);
fg->bytes_.clear();
fg->lineOrBytecode_ = lineOrBytecode;
fg->m_ = this;
fg->task_ = task;
@ -803,13 +796,12 @@ ModuleGenerator::finishFuncDef(uint32_t funcIndex, unsigned generateTime, Functi
{
MOZ_ASSERT(activeFunc_ == fg);
UniqueFuncBytecode func =
js::MakeUnique<FuncBytecode>(funcIndex,
funcSig(funcIndex),
Move(fg->bytecode_),
fg->lineOrBytecode_,
Move(fg->callSiteLineNums_),
generateTime);
auto func = js::MakeUnique<FuncBytes>(Move(fg->bytes_),
funcIndex,
funcSig(funcIndex),
fg->lineOrBytecode_,
Move(fg->callSiteLineNums_),
generateTime);
if (!func)
return false;

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

@ -51,7 +51,7 @@ typedef Vector<SlowFunction> SlowFunctionVector;
// is encapsulated by ModuleGenerator/ModuleGeneratorThreadView classes which
// present a race-free interface to the code in each thread assuming any given
// element is initialized by the ModuleGenerator thread before an index to that
// element is written to Bytecode sent to a ModuleGeneratorThreadView thread.
// element is written to Bytes sent to a ModuleGeneratorThreadView thread.
// Once created, the Vectors are never resized.
struct TableModuleGeneratorData
@ -202,8 +202,8 @@ class MOZ_STACK_CLASS ModuleGenerator
Vector<IonCompileTask*> freeTasks_;
// Assertions
DebugOnly<FunctionGenerator*> activeFunc_;
DebugOnly<bool> finishedFuncs_;
FunctionGenerator* activeFunc_;
bool finishedFuncs_;
bool finishOutstandingTask();
bool funcIsDefined(uint32_t funcIndex) const;
@ -288,13 +288,13 @@ class MOZ_STACK_CLASS FunctionGenerator
{
friend class ModuleGenerator;
ModuleGenerator* m_;
IonCompileTask* task_;
ModuleGenerator* m_;
IonCompileTask* task_;
// Data created during function generation, then handed over to the
// FuncBytecode in ModuleGenerator::finishFunc().
UniqueBytecode bytecode_;
Uint32Vector callSiteLineNums_;
// FuncBytes in ModuleGenerator::finishFunc().
Bytes bytes_;
Uint32Vector callSiteLineNums_;
uint32_t lineOrBytecode_;
@ -303,8 +303,8 @@ class MOZ_STACK_CLASS FunctionGenerator
: m_(nullptr), task_(nullptr), lineOrBytecode_(0)
{}
Bytecode& bytecode() const {
return *bytecode_;
Bytes& bytes() {
return bytes_;
}
bool addCallSiteLineNum(uint32_t lineno) {
return callSiteLineNums_.append(lineno);

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

@ -40,7 +40,7 @@ class FunctionCompiler
ModuleGeneratorThreadView& mg_;
Decoder& decoder_;
const FuncBytecode& func_;
const FuncBytes& func_;
const ValTypeVector& locals_;
size_t lastReadCallSite_;
@ -60,7 +60,7 @@ class FunctionCompiler
public:
FunctionCompiler(ModuleGeneratorThreadView& mg,
Decoder& decoder,
const FuncBytecode& func,
const FuncBytes& func,
const ValTypeVector& locals,
MIRGenerator& mirGen,
FuncCompileResults& compileResults)
@ -153,7 +153,7 @@ class FunctionCompiler
}
#endif
MOZ_ASSERT(inDeadCode());
MOZ_ASSERT(decoder_.done(), "all bytecode must be consumed");
MOZ_ASSERT(decoder_.done(), "all bytes must be consumed");
MOZ_ASSERT(func_.callSiteLineNums().length() == lastReadCallSite_);
}
@ -3048,10 +3048,10 @@ wasm::IonCompileFunction(IonCompileTask* task)
{
int64_t before = PRMJ_Now();
const FuncBytecode& func = task->func();
const FuncBytes& func = task->func();
FuncCompileResults& results = task->results();
Decoder d(func.bytecode());
Decoder d(func.bytes());
// Build the local types vector.

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

@ -31,52 +31,48 @@ typedef Vector<jit::MIRType, 8, SystemAllocPolicy> MIRTypeVector;
typedef jit::ABIArgIter<MIRTypeVector> ABIArgMIRTypeIter;
typedef jit::ABIArgIter<ValTypeVector> ABIArgValTypeIter;
// The FuncBytecode class contains the intermediate representation of a
// parsed/decoded and validated asm.js/WebAssembly function. The FuncBytecode
// lives only until it is fully compiled.
// The FuncBytes class represents a single, concurrently-compilable function.
// A FuncBytes object is composed of the wasm function body bytes along with the
// ambient metadata describing the function necessary to compile it.
class FuncBytecode
class FuncBytes
{
// Function metadata
Bytes bytes_;
uint32_t index_;
const DeclaredSig& sig_;
uint32_t lineOrBytecode_;
Uint32Vector callSiteLineNums_;
// Compilation bookkeeping
uint32_t index_;
unsigned generateTime_;
UniqueBytecode bytecode_;
uint32_t lineOrBytecode_;
Uint32Vector callSiteLineNums_;
unsigned generateTime_;
public:
FuncBytecode(uint32_t index,
const DeclaredSig& sig,
UniqueBytecode bytecode,
uint32_t lineOrBytecode,
Uint32Vector&& callSiteLineNums,
unsigned generateTime)
: sig_(sig),
FuncBytes(Bytes&& bytes,
uint32_t index,
const DeclaredSig& sig,
uint32_t lineOrBytecode,
Uint32Vector&& callSiteLineNums,
unsigned generateTime)
: bytes_(Move(bytes)),
index_(index),
sig_(sig),
lineOrBytecode_(lineOrBytecode),
callSiteLineNums_(Move(callSiteLineNums)),
index_(index),
generateTime_(generateTime),
bytecode_(Move(bytecode))
generateTime_(generateTime)
{}
UniqueBytecode recycleBytecode() { return Move(bytecode_); }
uint32_t lineOrBytecode() const { return lineOrBytecode_; }
const Uint32Vector& callSiteLineNums() const { return callSiteLineNums_; }
Bytes& bytes() { return bytes_; }
const Bytes& bytes() const { return bytes_; }
uint32_t index() const { return index_; }
const DeclaredSig& sig() const { return sig_; }
const Bytecode& bytecode() const { return *bytecode_; }
uint32_t lineOrBytecode() const { return lineOrBytecode_; }
const Uint32Vector& callSiteLineNums() const { return callSiteLineNums_; }
unsigned generateTime() const { return generateTime_; }
};
typedef UniquePtr<FuncBytecode> UniqueFuncBytecode;
typedef UniquePtr<FuncBytes> UniqueFuncBytes;
// The FuncCompileResults class contains the results of compiling a single
// function body, ready to be merged into the whole-module MacroAssembler.
// The FuncCompileResults contains the results of compiling a single function
// body, ready to be merged into the whole-module MacroAssembler.
class FuncCompileResults
{
jit::TempAllocator alloc_;
@ -108,13 +104,14 @@ class FuncCompileResults
// the FuncCompileResults, and finally sent back to the validation thread. To
// save time allocating and freeing memory, IonCompileTasks are reset() and
// reused.
class IonCompileTask
{
JSRuntime* const runtime_;
JSRuntime* const runtime_;
ModuleGeneratorThreadView& mg_;
LifoAlloc lifo_;
UniqueFuncBytecode func_;
mozilla::Maybe<FuncCompileResults> results_;
LifoAlloc lifo_;
UniqueFuncBytes func_;
Maybe<FuncCompileResults> results_;
IonCompileTask(const IonCompileTask&) = delete;
IonCompileTask& operator=(const IonCompileTask&) = delete;
@ -132,21 +129,21 @@ class IonCompileTask
ModuleGeneratorThreadView& mg() const {
return mg_;
}
void init(UniqueFuncBytecode func) {
void init(UniqueFuncBytes func) {
MOZ_ASSERT(!func_);
func_ = mozilla::Move(func);
func_ = Move(func);
results_.emplace(lifo_);
}
const FuncBytecode& func() const {
const FuncBytes& func() const {
MOZ_ASSERT(func_);
return *func_;
}
FuncCompileResults& results() {
return *results_;
}
void reset(UniqueBytecode* recycled) {
void reset(Bytes* recycled) {
if (func_)
*recycled = func_->recycleBytecode();
*recycled = Move(func_->bytes());
func_.reset(nullptr);
results_.reset();
lifo_.releaseAll();

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

@ -4024,60 +4024,56 @@ EncodeDataSegments(Encoder& e, WasmAstModule& module)
return true;
}
static UniqueBytecode
EncodeModule(WasmAstModule& module)
static bool
EncodeModule(WasmAstModule& module, Bytes* bytes)
{
UniqueBytecode bytecode = MakeUnique<Bytecode>();
if (!bytecode)
return nullptr;
Encoder e(*bytecode);
Encoder e(*bytes);
if (!e.writeFixedU32(MagicNumber))
return nullptr;
return false;
if (!e.writeFixedU32(EncodingVersion))
return nullptr;
return false;
if (!EncodeSignatures(e, module))
return nullptr;
return false;
if (!EncodeImportTable(e, module))
return nullptr;
return false;
if (!EncodeFunctionSignatures(e, module))
return nullptr;
return false;
if (!EncodeFunctionTable(e, module))
return nullptr;
return false;
if (!EncodeMemory(e, module))
return nullptr;
return false;
if (!EncodeExportTable(e, module))
return nullptr;
return false;
if (!EncodeFunctionBodies(e, module))
return nullptr;
return false;
if (!EncodeDataSegments(e, module))
return nullptr;
return false;
return Move(bytecode);
return true;
}
/*****************************************************************************/
UniqueBytecode
wasm::TextToBinary(const char16_t* text, UniqueChars* error)
bool
wasm::TextToBinary(const char16_t* text, Bytes* bytes, UniqueChars* error)
{
LifoAlloc lifo(AST_LIFO_DEFAULT_CHUNK_SIZE);
WasmAstModule* module = ParseModule(text, lifo, error);
if (!module)
return nullptr;
return false;
if (!ResolveModule(lifo, module, error))
return nullptr;
return false;
return EncodeModule(*module);
return EncodeModule(*module, bytes);
}

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

@ -26,11 +26,11 @@ namespace js {
namespace wasm {
// Translate the textual representation of a wasm module (given by a
// null-terminated char16_t array) into a Bytecode object. If there is an error
// null-terminated char16_t array) into serialized bytes. If there is an error
// other than out-of-memory an error message string will be stored in 'error'.
extern UniqueBytecode
TextToBinary(const char16_t* text, UniqueChars* error);
extern bool
TextToBinary(const char16_t* text, Bytes* bytes, UniqueChars* error);
} // namespace wasm
} // namespace js

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

@ -21,6 +21,7 @@
#include "mozilla/EnumeratedArray.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/Maybe.h"
#include "mozilla/Move.h"
#include "NamespaceImports.h"
@ -39,6 +40,7 @@ class PropertyName;
namespace wasm {
using mozilla::EnumeratedArray;
using mozilla::Maybe;
using mozilla::Move;
using mozilla::MallocSizeOf;

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

@ -525,19 +525,19 @@ WasmTextToBinary(JSContext* cx, unsigned argc, Value* vp)
if (!twoByteChars.initTwoByte(cx, args[0].toString()))
return false;
wasm::Bytes bytes;
UniqueChars error;
wasm::UniqueBytecode bytes = wasm::TextToBinary(twoByteChars.twoByteChars(), &error);
if (!bytes) {
if (!wasm::TextToBinary(twoByteChars.twoByteChars(), &bytes, &error)) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_TEXT_FAIL,
error.get() ? error.get() : "out of memory");
return false;
}
RootedObject obj(cx, JS_NewUint8Array(cx, bytes->length()));
RootedObject obj(cx, JS_NewUint8Array(cx, bytes.length()));
if (!obj)
return false;
memcpy(obj->as<TypedArrayObject>().viewDataUnshared(), bytes->begin(), bytes->length());
memcpy(obj->as<TypedArrayObject>().viewDataUnshared(), bytes.begin(), bytes.length());
args.rval().setObject(*obj);
return true;

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

@ -43,8 +43,8 @@ BEGIN_TEST(testWasmLEB128_encoding)
using namespace js;
using namespace wasm;
Bytecode bc;
Encoder encoder(bc);
Bytes bytes;
Encoder encoder(bytes);
bool passed;
if (!WriteValidBytes(encoder, &passed))
@ -52,18 +52,18 @@ BEGIN_TEST(testWasmLEB128_encoding)
CHECK(passed);
size_t i = 0;
CHECK(bc[i++] == 0x0);
CHECK(bc[i++] == 0x1);
CHECK(bc[i++] == 0x42);
CHECK(bytes[i++] == 0x0);
CHECK(bytes[i++] == 0x1);
CHECK(bytes[i++] == 0x42);
CHECK(bc[i++] == 0x80);
CHECK(bc[i++] == 0x01);
CHECK(bytes[i++] == 0x80);
CHECK(bytes[i++] == 0x01);
CHECK(bc[i++] == 0x80);
CHECK(bc[i++] == 0x03);
CHECK(bytes[i++] == 0x80);
CHECK(bytes[i++] == 0x03);
if (i + 1 < bc.length())
CHECK(bc[i++] == 0x00);
if (i + 1 < bytes.length())
CHECK(bytes[i++] == 0x00);
return true;
}
END_TEST(testWasmLEB128_encoding)
@ -73,19 +73,19 @@ BEGIN_TEST(testWasmLEB128_valid_decoding)
using namespace js;
using namespace wasm;
Bytecode bc;
if (!bc.append(0x0) || !bc.append(0x1) || !bc.append(0x42))
Bytes bytes;
if (!bytes.append(0x0) || !bytes.append(0x1) || !bytes.append(0x42))
return false;
if (!bc.append(0x80) || !bc.append(0x01))
if (!bytes.append(0x80) || !bytes.append(0x01))
return false;
if (!bc.append(0x80) || !bc.append(0x03))
if (!bytes.append(0x80) || !bytes.append(0x03))
return false;
{
// Fallible decoding
Decoder decoder(bc);
Decoder decoder(bytes);
uint32_t value;
CHECK(decoder.readVarU32(&value) && value == 0x0);
@ -99,7 +99,7 @@ BEGIN_TEST(testWasmLEB128_valid_decoding)
{
// Infallible decoding
Decoder decoder(bc);
Decoder decoder(bytes);
uint32_t value;
value = decoder.uncheckedReadVarU32();
@ -124,20 +124,20 @@ BEGIN_TEST(testWasmLEB128_invalid_decoding)
using namespace js;
using namespace wasm;
Bytecode bc;
Bytes bytes;
// Fill bits as per 28 encoded bits
if (!bc.append(0x80) || !bc.append(0x80) || !bc.append(0x80) || !bc.append(0x80))
if (!bytes.append(0x80) || !bytes.append(0x80) || !bytes.append(0x80) || !bytes.append(0x80))
return false;
// Test last valid values
if (!bc.append(0x00))
if (!bytes.append(0x00))
return false;
for (uint8_t i = 0; i < 0x0F; i++) {
bc[4] = i;
bytes[4] = i;
{
Decoder decoder(bc);
Decoder decoder(bytes);
uint32_t value;
CHECK(decoder.readVarU32(&value));
CHECK(value == uint32_t(i << 28));
@ -145,7 +145,7 @@ BEGIN_TEST(testWasmLEB128_invalid_decoding)
}
{
Decoder decoder(bc);
Decoder decoder(bytes);
uint32_t value = decoder.uncheckedReadVarU32();
CHECK(value == uint32_t(i << 28));
CHECK(decoder.done());
@ -154,9 +154,9 @@ BEGIN_TEST(testWasmLEB128_invalid_decoding)
// Test all invalid values of the same size
for (uint8_t i = 0x10; i < 0xF0; i++) {
bc[4] = i;
bytes[4] = i;
Decoder decoder(bc);
Decoder decoder(bytes);
uint32_t value;
CHECK(!decoder.readVarU32(&value));
}