Manifest
A compiled manifest is shaped by two independent choices:
| Choice | What it controls | Values | Set in coco.nut | Compile override |
|---|---|---|---|---|
| Manifest format | How the whole manifest file is encoded | YAML, JSON, POLO | [target.moi] format | -f, --fileform |
| Executable format | How the code of each endpoint and function is written inside the manifest | ASM, HEX, BIN | [target.pisa] format | -c, --codeform |
coco compile produces the manifest in the formats set in coco.nut. The coco manifest command
works on a manifest that's already compiled: it converts it to other formats and encodes it for
deployment, without the source code.
Manifest Formats
| Format | File extension | Description |
|---|---|---|
YAML | .yaml | Human-readable. The default of coco nut init |
JSON | .json | The same structure as YAML, for tools and scripts |
POLO | .polo | The manifest encoded as POLO binary and written as hex. Compact and deterministic, but not meant to be read |
Executable Formats
The executable format only changes how the instructions under executes are written. Here is the
Init endpoint of the Flipper manifest in each format:
executes:
asm:
- LLOAD $0 &0
- PMAKE $1 &1
- NOT $1 $1
- ORIGIN $2
- SETKEY $0 $2 $1
- STORE $0
executes:
hex: '0x9000002a01016201018402590002019f00'
executes:
bin:
- 144
- 0
- 0
- 42
# ... 17 bytes in total
HEX and BIN hold the same bytes (0x90 is 144, 0x2a is 42), and ASM is their
disassembly. Converting between the three is lossless in every direction: a manifest converted
from ASM to BIN and back is identical to the original.
What Changes With the Format
Formats change how the manifest is written down, not what the logic does:
- Behavior is identical. Endpoints, state layout, return values and execution fuel are the same whichever formats you choose.
- The artifact is identical. When a manifest is deployed, it's turned into an
artifact, the form the network stores and PISA executes. All nine
combinations of manifest and executable format produce the same artifact, which you can check with
coco manifest <file> artifact. - Size and compile cost differ with the executable format. Before building the artifact, the
engine has to decode
HEXand assembleASM, whileBINis used as is. For the Flipper logic:
| Executable format | POLO-encoded manifest | Cocolab compile fuel |
|---|---|---|
ASM | 796 bytes | 525 |
HEX | 629 bytes | 447 |
BIN | 550 bytes | 395 |
Cocolab charges compile fuel per instruction: 5 for BIN, 7 for HEX and 10 for ASM in v0.9.1.
The manifest format doesn't affect it: the YAML and POLO manifests with ASM code both cost 525.
Keep the YAML and ASM defaults while developing: the manifest is readable and easy to review and
diff. Convert to BIN when you want the smallest manifest to deploy. The logic behaves the same.
Changing the Formats
There are three ways to change formats, depending on when you decide:
| When | How |
|---|---|
| For every compilation of a module | Set [target.moi] format and [target.pisa] format in coco.nut |
| For a single compilation | coco compile -f <format> -c <codeform> |
| After compilation, without the source | coco manifest convert |
coco manifest keeps the manifest's PISA version (engine.version). The PISA version decides which
language features compile and which instructions are generated, so to target a different version,
change [target.pisa] version in coco.nut and compile again.
coco manifest Command
coco manifest <manifest_file>
coco manifest convert <manifest_file> [-f <format>] [-c <codeform>] [-o <output_file>]
coco manifest <manifest_file> artifact
The input format is taken from the file extension: .yaml or .yml, .json, or .polo.
Encoding a Manifest
coco manifest flipper.yaml
Prints the manifest POLO-encoded, as hex with a 0x prefix:
0x0e6f031ef601ce02013f064e56504953410f302e382e306c6f676963df010e9e04de0a...
This is the whole manifest as a single value. Cocolab accepts it in place of a file path, e.g.
compile Flipper from manifest(0x0e6f031e...).
Converting Manifests
coco manifest convert <manifest_file> [-f <format>] [-c <codeform>] [-o <output_file>]
| flag | description | supported values |
|---|---|---|
-f, --fileform <FORMAT> | output manifest format [default: the input's format] | yaml, json, polo |
-c, --codeform <CODE_FORMAT> | output executable format [default: unchanged] | asm, hex, bin |
-o, --output <OUTPUT> | write to this file instead of printing to standard output | a path whose extension matches the output format |
At least one of -f and -c is required.
# YAML to JSON, printed to standard output
coco manifest convert flipper.yaml -f json
# Switch the code to BIN and keep the YAML format
coco manifest convert flipper.yaml -c bin -o flipper-bin.yaml
# Change both at once: a POLO manifest with HEX code
coco manifest convert flipper.yaml -f polo -c hex -o flipper.polo
# Turn a manifest you received back into readable YAML and assembly
coco manifest convert flipper.polo -f yaml -c asm -o flipper-asm.yaml
The extension of -o must be exactly .yaml, .json or .polo. .yml is accepted as input but
rejected as output. A .polo file written by convert holds the hex without the 0x prefix that
coco manifest <file> prints. Both forms are accepted as input.
Producing the Artifact
coco manifest flipper.yaml artifact
Prints the artifact built from the manifest, POLO-encoded as hex (without a
0x prefix). The manifest file comes before artifact: coco manifest artifact flipper.yaml
is rejected.
Since the artifact doesn't depend on the manifest or executable format, comparing artifacts tells you whether two manifests deploy the same logic:
[ "$(coco manifest flipper.yaml artifact)" = "$(coco manifest flipper.polo artifact)" ] \
&& echo "same logic"
Errors
| Error | Cause |
|---|---|
format flag or codeformat flag must be used with `manifest convert` | convert without -f or -c |
Output file extension does not match selected format | The -o extension differs from the output format, including .yml |
Unsupported file format | The input extension isn't .yaml, .yml, .json or .polo |
Input file has no extension | The input file name has no extension |
Invalid combination of manifest command and input | No input file, or an input file given both before and after convert |
unexpected argument '<file>' found | The input file was placed after artifact |