Skip to content

Marshalling

How JavaScript values cross the WASM boundary to the Gmsh C API and back. This is handled entirely by src/runtime.mjs, driven by the generated descriptor — you do not write any of this, but understanding it explains the API shapes.

Inputs

Gmsh argument You pass Sent to C as
bool boolean int (0/1)
int, size_t number int / size_t
double number double
string string const char* (UTF-8, heap-allocated)
vector<int> number[] const int*, size_t n
vector<double> number[] const double*, size_t n
vector<string> string[] const char* const*, size_t n
vector<pair> number[] flat const int*, size_t n (n = flattened length)
vector<vector<int>> number[][] const int* const*, const size_t*, size_t nn
mesh size callback (setSizeCallback only) (dim, tag, x, y, z, lc) => number native function pointer, via Module.addFunction

All temporary heap allocations for inputs are freed after the call — except the mesh size callback's function-pointer table slot, which Gmsh stores and invokes later during mesh.generate(); it is released only when replaced by a later setSizeCallback call, or dropped by removeSizeCallback/finalize.

Outputs

Output parameters are allocated by the wrapper, filled by Gmsh (which mallocs the arrays), copied into JS values, and then released with gmshFree.

Gmsh output You receive
int* / size_t* / double* number
char** string
int**+size_t* (vector) number[]
char***+size_t* (vector of strings) string[]
int***+size_t**+size_t* (vector of vectors) number[][]

Return shape rules

For a function f:

  1. No outputs, no scalar return → returns undefined.
  2. Scalar return only (e.g. addPoint → a tag) → returns that number.
  3. One or more output parameters → returns an object keyed by each output's name. If the function also has a scalar return, it is included as value.
// rule 2
const tag = gmsh.model.geo.addPoint(0, 0, 0);          // number

// rule 3
const { nodeTags, coord } = gmsh.model.mesh.getNodes(); // object

Memory & numeric notes

  • The boundary is wasm32: pointers and size_t are 4 bytes; double is 8.
  • size_t outputs are read unsigned (HEAPU32), so large tags/counts up to 2³² are represented correctly.
  • Heap views are re-fetched on every access, so memory growth during a call cannot leave a stale typed-array view.
  • Errors are surfaced by reading gmshLoggerGetLastError and throwing.