static bool CreateExportObject(JSContext* cx, Handle<WasmModuleObject*> moduleObj, const ExportMap& exportMap, const ExportVector& exports, MutableHandleObject exportObj) { MOZ_ASSERT(exportMap.exportNames.length() == exports.length()); MOZ_ASSERT(exportMap.fieldNames.length() == exportMap.fieldsToExports.length()); for (size_t fieldIndex = 0; fieldIndex < exportMap.fieldNames.length(); fieldIndex++) { const char* fieldName = exportMap.fieldNames[fieldIndex].get(); if (!*fieldName) { MOZ_ASSERT(!exportObj); uint32_t exportIndex = exportMap.fieldsToExports[fieldIndex]; exportObj.set(NewExportedFunction(cx, moduleObj, exportMap, exportIndex)); if (!exportObj) return false; break; } } Rooted<ValueVector> vals(cx, ValueVector(cx)); for (size_t exportIndex = 0; exportIndex < exports.length(); exportIndex++) { JSFunction* fun = NewExportedFunction(cx, moduleObj, exportMap, exportIndex); if (!fun || !vals.append(ObjectValue(*fun))) return false; } if (!exportObj) { exportObj.set(JS_NewPlainObject(cx)); if (!exportObj) return false; } for (size_t fieldIndex = 0; fieldIndex < exportMap.fieldNames.length(); fieldIndex++) { const char* fieldName = exportMap.fieldNames[fieldIndex].get(); if (!*fieldName) continue; JSAtom* atom = AtomizeUTF8Chars(cx, fieldName, strlen(fieldName)); if (!atom) return false; RootedId id(cx, AtomToId(atom)); HandleValue val = vals[exportMap.fieldsToExports[fieldIndex]]; if (!JS_DefinePropertyById(cx, exportObj, id, val, JSPROP_ENUMERATE)) 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; }
static bool CreateExportObject(JSContext* cx, HandleWasmInstanceObject instanceObj, HandleWasmMemoryObject memoryObj, const ExportVector& exports, MutableHandleObject exportObj) { const Instance& instance = instanceObj->instance(); const Metadata& metadata = instance.metadata(); const SharedTableVector& tables = instance.tables(); if (metadata.isAsmJS() && exports.length() == 1 && strlen(exports[0].fieldName()) == 0) { exportObj.set(NewExportedFunction(cx, instanceObj, 0)); return !!exportObj; } exportObj.set(JS_NewPlainObject(cx)); if (!exportObj) return false; Rooted<ValueVector> vals(cx, ValueVector(cx)); for (size_t i = 0; i < metadata.funcExports.length(); i++) { JSFunction* fun = NewExportedFunction(cx, instanceObj, i); if (!fun || !vals.append(ObjectValue(*fun))) return false; } RootedWasmTableObject tableObj(cx); 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: val = vals[exp.funcExportIndex()]; break; case DefinitionKind::Table: MOZ_ASSERT(tables.length() == 1); if (!tableObj) { tableObj = WasmTableObject::create(cx, *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; } if (!JS_DefinePropertyById(cx, exportObj, id, val, JSPROP_ENUMERATE)) return false; } return true; }
static bool CreateExportObject(JSContext* cx, HandleWasmInstanceObject instanceObj, Handle<FunctionVector> funcImports, HandleWasmTableObject 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) { RootedValue val(cx); if (!GetFunctionExport(cx, instanceObj, funcImports, exports[0], &val)) return false; exportObj.set(&val.toObject()); return true; } if (metadata.isAsmJS()) exportObj.set(NewBuiltinClassInstance<PlainObject>(cx)); else exportObj.set(NewObjectWithGivenProto<PlainObject>(cx, nullptr)); 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: if (!GetFunctionExport(cx, instanceObj, funcImports, exp, &val)) return false; break; case DefinitionKind::Table: val = ObjectValue(*tableObj); break; case DefinitionKind::Memory: val = ObjectValue(*memoryObj); break; case DefinitionKind::Global: if (!GetGlobalExport(cx, metadata.globals, exp.globalIndex(), globalImports, &val)) return false; break; } if (!JS_DefinePropertyById(cx, exportObj, id, val, JSPROP_ENUMERATE)) return false; } if (!metadata.isAsmJS()) { if (!JS_FreezeObject(cx, exportObj)) return false; } return true; }