Imported and defined globals share an index space, but previously the decoder clobbered the imported global indices with the defined globals.

BUG=none

Review-Url: https://codereview.chromium.org/2410953003
Cr-Commit-Position: refs/heads/master@{#40230}
This commit is contained in:
dschuff 2016-10-12 08:19:22 -07:00 committed by Commit bot
parent 760328f229
commit 9b55c07698
3 changed files with 37 additions and 3 deletions

View File

@ -406,7 +406,13 @@ class ModuleDecoder : public Decoder {
// ===== Global section ==================================================
if (section_iter.section_code() == kGlobalSectionCode) {
uint32_t globals_count = consume_u32v("globals count");
module->globals.reserve(SafeReserve(globals_count));
uint32_t imported_globals = static_cast<uint32_t>(module->globals.size());
if (!IsWithinLimit(std::numeric_limits<int32_t>::max(), globals_count,
imported_globals)) {
error(pos, pos, "too many imported+defined globals: %u + %u",
imported_globals, globals_count);
}
module->globals.reserve(SafeReserve(imported_globals + globals_count));
for (uint32_t i = 0; ok() && i < globals_count; ++i) {
TRACE("DecodeGlobal[%d] module+%d\n", i,
static_cast<int>(pc_ - start_));
@ -414,7 +420,7 @@ class ModuleDecoder : public Decoder {
module->globals.push_back(
{kAstStmt, false, WasmInitExpr(), 0, false, false});
WasmGlobal* global = &module->globals.back();
DecodeGlobalInModule(module, i, global);
DecodeGlobalInModule(module, i + imported_globals, global);
}
section_iter.advance();
}
@ -675,7 +681,10 @@ class ModuleDecoder : public Decoder {
case WasmInitExpr::kGlobalIndex: {
uint32_t other_index = global->init.val.global_index;
if (other_index >= index) {
error("invalid global index in init expression");
error(pos, pos,
"invalid global index in init expression, "
"index %u, other_index %u",
index, other_index);
} else if (module->globals[other_index].type != global->type) {
error(pos, pos,
"type mismatch in global initialization "

View File

@ -1544,6 +1544,9 @@ class WasmInstanceBuilder {
uint32_t source_size =
static_cast<uint32_t>(segment->get_int(kSourceSize));
// TODO(titzer): These should be runtime errors and not CHECKs if
// dest_addr is global (and therefore initialized at linktime to an
// possibly-invalid value).
CHECK_LT(dest_addr, mem_size);
CHECK_LE(source_size, mem_size);
CHECK_LE(dest_addr, mem_size - source_size);

View File

@ -64,3 +64,25 @@ function TestImportedExported(type, val, expected) {
TestImportedExported(kAstI32, 415.5, 415);
TestImportedExported(kAstF32, -979.34343, Math.fround(-979.34343));
TestImportedExported(kAstF64, 81347.66666, 81347.66666);
function TestGlobalIndexSpace(type, val) {
print("TestGlobalIndexSpace(" + val + ") = " + val);
var builder = new WasmModuleBuilder();
var im = builder.addImportedGlobal("foo", undefined, type);
assertEquals(0, im);
var def = builder.addGlobal(type, false);
assertEquals(1, def.index);
def.init_index = im;
var sig = makeSig([], [type]);
builder.addFunction("main", sig)
.addBody([kExprGetGlobal, def.index])
.exportAs("main");
var instance = builder.instantiate({foo: val});
assertEquals(val, instance.exports.main());
}
TestGlobalIndexSpace(kAstI32, 123);
TestGlobalIndexSpace(kAstF32, 54321.125);
TestGlobalIndexSpace(kAstF64, 12345.678);