Difference between revisions of "WebAssembly/Globals"
Line 35: | Line 35: | ||
const | const | ||
ccc: LongInt = 10; wasmglobal; // immutable global | ccc: LongInt = 10; wasmglobal; // immutable global | ||
+ | |||
+ | Supported types: | ||
+ | * LongInt (32-bit signed int) - mapped to i32 | ||
+ | * LongWord (32-bit unsigned int) - mapped to i32 | ||
+ | * Int64 (64-bit signed int) - mapped to i64 | ||
+ | * QWord (64-bit unsigned int) - mapped to i64 | ||
+ | * Single - mapped to f32 | ||
+ | * Double - mapped to f64 | ||
+ | * Pointer (typed or untyped) - mapped to i32 | ||
[[Category:WebAssembly]] | [[Category:WebAssembly]] |
Revision as of 14:58, 22 July 2022
WebAssembly supports a feature, called "global variables" or just "globals". They differ from global variables in Pascal. This page discusses the possibility of extending FPC, in order to be able to declare WebAssembly globals from Pascal code.
Differences between Pascal global variables and WebAssembly globals
WebAssembly globals have the following restrictions:
- they can be only one of 4 types - 32-bit int, 64-bit int, single (float32) or double (float64)
- their address cannot be taken
- in a multithreaded environment, they are usually not shared between threads, i.e. they behave like threadvars
Special WebAssembly globals
Free Pascal already creates and uses some WebAssembly globals, which are considered special and are part of the Basic C ABI, which Free Pascal supports.
__stack_pointer
WebAssembly has an evaluation stack, which holds local variables, stack frames and temporary values. However, this stack is not visible in linear memory. This means that you cannot take the address of a value on this stack. Another restriction is that it can only hold the 4 basic WebAssembly types (int32, int64, float32, float64). To avoid these restrictions, Free Pascal maintains a second stack in linear memory. The WebAssembly global __stack_pointer points to the top of this stack. It is always 16-byte aligned.
When multithreading is enabled, the linker creates the following globals:
- __tls_size - the total size of the thread local block of the program. This is the sum of the sizes of all threadvars, plus padding.
- __tls_align - the alignment requirement for the thread local block.
- __tls_base - initialized to 0, but can be set by the function __wasm_init_tls, which is created by the linker. All threadvar accesses, created by the compiler take the address of this variable and add an offset.
Pascal syntax proposal
var a: LongInt; wasmglobal; // FPC's name mangling applies aa: LongInt = 5; wasmglobal; // initialized global b: LongInt; wasmglobal name 'x'; // FPC's name mangling is not applied c: LongInt; wasmglobal; external name 'q'; // external, declared in a different unit, or .o module d: LongInt; wasmglobal; import name 'ddd'; // an import for the final .wasm module const ccc: LongInt = 10; wasmglobal; // immutable global
Supported types:
* LongInt (32-bit signed int) - mapped to i32 * LongWord (32-bit unsigned int) - mapped to i32 * Int64 (64-bit signed int) - mapped to i64 * QWord (64-bit unsigned int) - mapped to i64 * Single - mapped to f32 * Double - mapped to f64 * Pointer (typed or untyped) - mapped to i32