Playbit apps
Playbit programs are wasm modules with an optional extra pbapp section describing the app and its embedded resources.
pbapp.toml
pbapp.toml describes your app and may list resources to be included in the app.
Example of myapp/pbapp.toml & myapp/myapp.c:
# myapp/pbapp.toml
app_name = "My App"
app_id = "my-identifier.my-app"
[resources]
app_icon = "icon.png"
names_db = "family_names.txt"
// myapp/myapp.c
void main(void) {
print("app name: \"%.*s\"", PBStr_FMT_ARG(PBAppName()));
print("app ID: \"%.*s\"", PBStr_FMT_ARG(PBAppId()));
PBAppResource db = PBAppResourceWithName(PBStrLit("named_db"));
print("names db: %p (%zu bytes)", db.data.v, db.data.len);
}
Create dummy resources:
$ printf '\211PNG\r\n\032\n' > icon.png
$ truncate -s 123 family_names.txt
Build & run it via the Playbit.app GUI or pb run myapp:
Each "resource" listed in the [resources] section will be embedded as read-only data into the program's memory and becomes available at runtime via PBAppResource in the C library.
Binary format
typedef struct PBBundleResource {
u32 flags;
u32 nameLen;
u64 size;
u64 addr;
// u8 name[nameLen]
} PBBundleResource;
typedef struct PBBundleManifest {
u32 version;
u32 flags;
u32 appNameLen;
u32 appIdLen;
u32 resourceCount;
// u8 appName[appNameLen]
// u8 appId[appIdLen]
// u8 padding[...] // align each PBBundleResource to 8 bytes
// PBBundleResource resource[resourceCount]
} PBBundleManifest;
extern const uint8_t __pbbundle_manifest[]; // 8-byte aligned
extern const uint32_t __pbbundle_manifest_size;
__pbbundle_manifestpoints at the start of a single exported data blob (PBBundleManifest):- the normalized manifest bytes
- the raw resource file bytes, concatenated in manifest order
__pbbundle_manifest_sizeis the size of the normalized manifest prefix only, not the full blob.version: currently1flags: bitset; currently onlyPBBundleManifestFlag_DISABLE_GUI(1 << 0)appNameLen: byte length of the trailing UTF-8 app nameappIdLen: byte length of the trailing ASCII app idresourceCount: number of variable-lengthPBBundleResourceentriesPBBundleResource.flags: reserved for future use, currently0PBBundleResource.nameLen: byte length of the trailing UTF-8 resource namePBBundleResource.size: resource byte lengthPBBundleResource.addr: runtime linear-memory address of the resource bytes
Each PBBundleResource entry starts at the next 8-byte boundary after the app id. This means there may be zero padding bytes after the app id and after each resource name. The normalized manifest size is padded to a 16-byte boundary.
Each PBBundleResource.addr points into the resource payload bytes stored after the manifest within the same exported wasm data blob. Each resource payload starts at a 16-byte boundary, so there may be zero padding bytes before each payload.