Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/wasm-binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -1678,6 +1678,20 @@ class WasmBinaryReader {
uint8_t& pageSizeLog2,
Address defaultIfNoMax);
void readImports();
void readImport(Name module, Name base, uint32_t kind);

void addImport(std::unique_ptr<Function> func);
void addImport(std::unique_ptr<Table> table);
void addImport(std::unique_ptr<Memory> memory);
void addImport(std::unique_ptr<Global> global);
void addImport(std::unique_ptr<Tag> tag);

std::unique_ptr<Function>
readFunctionImport(Name module, Name base, uint32_t kind);
std::unique_ptr<Table> readTableImport(Name module, Name base);
std::unique_ptr<Memory> readMemoryImport(Name module, Name base);
std::unique_ptr<Global> readGlobalImport(Name module, Name base);
std::unique_ptr<Tag> readTagImport(Name module, Name base);

// The signatures of each function, including imported functions, given in the
// import and function sections. Store HeapTypes instead of Signatures because
Expand Down
280 changes: 162 additions & 118 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3017,130 +3017,174 @@ void WasmBinaryReader::getResizableLimits(Address& initial,
}
}

void WasmBinaryReader::addImport(std::unique_ptr<Function> func) {
auto [name, isExplicit] =
getOrMakeName(functionNames,
wasm.functions.size(),
makeName("fimport$", wasm.functions.size()),
usedFunctionNames);
func->name = name;
func->hasExplicitName = isExplicit;
functionTypes.push_back(func->type.getHeapType());
setLocalNames(*func, wasm.functions.size());
wasm.addFunction(std::move(func));
}

void WasmBinaryReader::addImport(std::unique_ptr<Table> table) {
auto [name, isExplicit] =
getOrMakeName(tableNames,
wasm.tables.size(),
makeName("timport$", wasm.tables.size()),
usedTableNames);
table->name = name;
table->hasExplicitName = isExplicit;
wasm.addTable(std::move(table));
}

void WasmBinaryReader::addImport(std::unique_ptr<Memory> memory) {
auto [name, isExplicit] =
getOrMakeName(memoryNames,
wasm.memories.size(),
makeName("mimport$", wasm.memories.size()),
usedMemoryNames);
memory->name = name;
memory->hasExplicitName = isExplicit;
wasm.addMemory(std::move(memory));
}

void WasmBinaryReader::addImport(std::unique_ptr<Global> global) {
auto [name, isExplicit] =
getOrMakeName(globalNames,
wasm.globals.size(),
makeName("gimport$", wasm.globals.size()),
usedGlobalNames);
global->name = name;
global->hasExplicitName = isExplicit;
wasm.addGlobal(std::move(global));
}

void WasmBinaryReader::addImport(std::unique_ptr<Tag> tag) {
auto [name, isExplicit] =
getOrMakeName(tagNames,
wasm.tags.size(),
makeName("eimport$", wasm.tags.size()),
usedTagNames);
tag->name = name;
tag->hasExplicitName = isExplicit;
wasm.addTag(std::move(tag));
}

std::unique_ptr<Function>
WasmBinaryReader::readFunctionImport(Name module, Name base, uint32_t kind) {
Builder builder(wasm);
auto index = getU32LEB();
auto type = getTypeByIndex(index);
if (!type.isSignature()) {
throwError(std::string("Imported function ") + module.toString() + '.' +
base.toString() +
"'s type must be a signature. Given: " + type.toString());
}
auto exact = (kind & BinaryConsts::ExactImport) ? Exact : Inexact;
auto curr = builder.makeFunction("", Type(type, NonNullable, exact), {});
curr->module = module;
curr->base = base;
return curr;
}

std::unique_ptr<Table> WasmBinaryReader::readTableImport(Name module,
Name base) {
Builder builder(wasm);
auto table = builder.makeTable("");
table->module = module;
table->base = base;
table->type = getType();

bool is_shared;
uint8_t page_size = 0xff;
getResizableLimits(table->initial,
table->max,
is_shared,
table->addressType,
page_size,
Table::kUnlimitedSize);
if (is_shared) {
throwError("Tables may not be shared");
}
if (page_size != 0xff) {
throwError("Tables may not have a custom page size");
}
return table;
}

std::unique_ptr<Memory> WasmBinaryReader::readMemoryImport(Name module,
Name base) {
Builder builder(wasm);
auto memory = builder.makeMemory("");
memory->module = module;
memory->base = base;
getResizableLimits(memory->initial,
memory->max,
memory->shared,
memory->addressType,
memory->pageSizeLog2,
Memory::kUnlimitedSize);
return memory;
}

std::unique_ptr<Global> WasmBinaryReader::readGlobalImport(Name module,
Name base) {
Builder builder(wasm);
auto type = getConcreteType();
auto mutable_ = getU32LEB();
if (mutable_ & ~1) {
throwError("Global mutability must be 0 or 1");
}
auto curr = builder.makeGlobal(
"", type, nullptr, mutable_ ? Builder::Mutable : Builder::Immutable);
curr->module = module;
curr->base = base;
return curr;
}

std::unique_ptr<Tag> WasmBinaryReader::readTagImport(Name module, Name base) {
Builder builder(wasm);
getInt8(); // Reserved 'attribute' field
auto index = getU32LEB();
auto curr = builder.makeTag("", getSignatureByTypeIndex(index));
curr->module = module;
curr->base = base;
return curr;
}

void WasmBinaryReader::readImport(Name module, Name base, uint32_t kind) {
switch (kind & ~BinaryConsts::ExactImport) {
case ExternalKind::Function:
addImport(readFunctionImport(module, base, kind));
break;
case ExternalKind::Table:
addImport(readTableImport(module, base));
break;
case ExternalKind::Memory:
addImport(readMemoryImport(module, base));
break;
case ExternalKind::Global:
addImport(readGlobalImport(module, base));
break;
case ExternalKind::Tag:
addImport(readTagImport(module, base));
break;
default:
throwError("bad import kind");
}
}

void WasmBinaryReader::readImports() {
size_t num = getU32LEB();
Builder builder(wasm);
for (size_t i = 0; i < num; i++) {
auto module = getInlineString();
auto base = getInlineString();
auto kind = getU32LEB();
// We set a unique prefix for the name based on the kind. This ensures no
// collisions between them, which can't occur here (due to the index i) but
// could occur later due to the names section.
switch (kind) {
case ExternalKind::Function:
case ExternalKind::Function | BinaryConsts::ExactImport: {
auto [name, isExplicit] =
getOrMakeName(functionNames,
wasm.functions.size(),
makeName("fimport$", wasm.functions.size()),
usedFunctionNames);
auto index = getU32LEB();
functionTypes.push_back(getTypeByIndex(index));
auto type = getTypeByIndex(index);
if (!type.isSignature()) {
throwError(std::string("Imported function ") + module.toString() +
'.' + base.toString() +
"'s type must be a signature. Given: " + type.toString());
}
auto exact = (kind & BinaryConsts::ExactImport) ? Exact : Inexact;
auto curr =
builder.makeFunction(name, Type(type, NonNullable, exact), {});
curr->hasExplicitName = isExplicit;
curr->module = module;
curr->base = base;
setLocalNames(*curr, wasm.functions.size());
wasm.addFunction(std::move(curr));
break;
}
case ExternalKind::Table: {
auto [name, isExplicit] =
getOrMakeName(tableNames,
wasm.tables.size(),
makeName("timport$", wasm.tables.size()),
usedTableNames);
auto table = builder.makeTable(name);
table->hasExplicitName = isExplicit;
table->module = module;
table->base = base;
table->type = getType();
bool is_shared;
uint8_t page_size = 0xff;
getResizableLimits(table->initial,
table->max,
is_shared,
table->addressType,
page_size,
Table::kUnlimitedSize);
if (is_shared) {
throwError("Tables may not be shared");
}
if (page_size != 0xff) {
throwError("Tables may not have a custom page size");
}
wasm.addTable(std::move(table));
break;
}
case ExternalKind::Memory: {
auto [name, isExplicit] =
getOrMakeName(memoryNames,
wasm.memories.size(),
makeName("mimport$", wasm.memories.size()),
usedMemoryNames);
auto memory = builder.makeMemory(name);
memory->hasExplicitName = isExplicit;
memory->module = module;
memory->base = base;
getResizableLimits(memory->initial,
memory->max,
memory->shared,
memory->addressType,
memory->pageSizeLog2,
Memory::kUnlimitedSize);
wasm.addMemory(std::move(memory));
break;
}
case ExternalKind::Global: {
auto [name, isExplicit] =
getOrMakeName(globalNames,
wasm.globals.size(),
makeName("gimport$", wasm.globals.size()),
usedGlobalNames);
auto type = getConcreteType();
auto mutable_ = getU32LEB();
if (mutable_ & ~1) {
throwError("Global mutability must be 0 or 1");
}
auto curr =
builder.makeGlobal(name,
type,
nullptr,
mutable_ ? Builder::Mutable : Builder::Immutable);
curr->hasExplicitName = isExplicit;
curr->module = module;
curr->base = base;
wasm.addGlobal(std::move(curr));
break;
}
case ExternalKind::Tag: {
auto [name, isExplicit] =
getOrMakeName(tagNames,
wasm.tags.size(),
makeName("eimport$", wasm.tags.size()),
usedTagNames);
getInt8(); // Reserved 'attribute' field
auto index = getU32LEB();
auto curr = builder.makeTag(name, getSignatureByTypeIndex(index));
curr->hasExplicitName = isExplicit;
curr->module = module;
curr->base = base;
wasm.addTag(std::move(curr));
break;
}
default: {
throwError("bad import kind");
}
}
readImport(module, base, kind);
}
numFuncImports = wasm.functions.size();
}
Expand Down
Loading