bool Module::instantiateTable(JSContext* cx, MutableHandleWasmTableObject tableObj, SharedTableVector* tables) const { if (tableObj) { MOZ_ASSERT(!metadata_->isAsmJS()); MOZ_ASSERT(metadata_->tables.length() == 1); const TableDesc& td = metadata_->tables[0]; MOZ_ASSERT(td.external); Table& table = tableObj->table(); if (!CheckLimits(cx, td.limits.initial, td.limits.maximum, table.length(), table.maximum(), metadata_->isAsmJS(), "Table")) { return false; } if (!tables->append(&table)) { ReportOutOfMemory(cx); return false; } } else { for (const TableDesc& td : metadata_->tables) { SharedTable table; if (td.external) { MOZ_ASSERT(!tableObj); MOZ_ASSERT(td.kind == TableKind::AnyFunction); tableObj.set(WasmTableObject::create(cx, td.limits)); if (!tableObj) return false; table = &tableObj->table(); } else { table = Table::create(cx, td, /* HandleWasmTableObject = */ nullptr); if (!table) return false; } if (!tables->emplaceBack(table)) { ReportOutOfMemory(cx); return false; } } } return true; }
static bool CreateExportObject(JSContext* cx, HandleWasmInstanceObject instanceObj, MutableHandleWasmTableObject tableObj, HandleWasmMemoryObject memoryObj, const ValVector& globalImports, const ExportVector& exports, MutableHandleObject exportObj) { const Instance& instance = instanceObj->instance(); const Metadata& metadata = instance.metadata(); if (metadata.isAsmJS() && exports.length() == 1 && strlen(exports[0].fieldName()) == 0) { RootedFunction fun(cx); if (!instanceObj->getExportedFunction(cx, instanceObj, exports[0].funcIndex(), &fun)) return false; exportObj.set(fun); return true; } exportObj.set(JS_NewPlainObject(cx)); if (!exportObj) return false; for (const Export& exp : exports) { JSAtom* atom = AtomizeUTF8Chars(cx, exp.fieldName(), strlen(exp.fieldName())); if (!atom) return false; RootedId id(cx, AtomToId(atom)); RootedValue val(cx); switch (exp.kind()) { case DefinitionKind::Function: { RootedFunction fun(cx); if (!instanceObj->getExportedFunction(cx, instanceObj, exp.funcIndex(), &fun)) return false; val = ObjectValue(*fun); break; } case DefinitionKind::Table: { if (!tableObj) { MOZ_ASSERT(instance.tables().length() == 1); tableObj.set(WasmTableObject::create(cx, *instance.tables()[0])); if (!tableObj) return false; } val = ObjectValue(*tableObj); break; } case DefinitionKind::Memory: { if (metadata.assumptions.newFormat) val = ObjectValue(*memoryObj); else val = ObjectValue(memoryObj->buffer()); break; } case DefinitionKind::Global: { if (!ExportGlobalValue(cx, metadata.globals, exp.globalIndex(), globalImports, &val)) return false; break; } } if (!JS_DefinePropertyById(cx, exportObj, id, val, JSPROP_ENUMERATE)) return false; } return true; }