==> src/ctx.c <==1/* The instance's Ctx, built on first use (a wasm instance has one thread). Also memcpy, memset and
2 * memmove: freestanding wasm32 code may call them (struct and array copies). */
3#include "mesh/rt_wasm.h"
4
5static mesh_ctx ctx;
6static bool ready;
7
8const mesh_ctx *mesh_ctx_get(void) {
9 if (!ready) {
10 ctx.slot = mesh_sys_info(MESH_WASM_I_SLOT);
11 ctx.node = mesh_sys_info(MESH_WASM_I_NODE);
12 ctx.nodes = mesh_sys_info(MESH_WASM_I_NODES);
13 ctx.view.h = MESH_WASM_W_VIEW;
14 ctx.view.base = 0;
15 ctx.view.len = mesh_sys_info(MESH_WASM_I_VIEW_BYTES);
16 ctx.req_off = mesh_sys_info(MESH_WASM_I_REQ_OFF);
17 ctx.resp_off = mesh_sys_info(MESH_WASM_I_RESP_OFF);
18 ctx.resp_max = mesh_sys_info(MESH_WASM_I_RESP_MAX);
19 ctx.lockstep = mesh_sys_info(MESH_WASM_I_LOCKSTEP) != 0;
20 ready = true;
21 }
22 return &ctx;
23}
24
25void *memcpy(void *restrict dst, const void *restrict src, size_t n);
26void *memmove(void *dst, const void *src, size_t n);
27void *memset(void *dst, int c, size_t n);
28
29void *memcpy(void *restrict dst, const void *restrict src, size_t n) {
30 unsigned char *d = dst;
31 const unsigned char *s = src;
32 while (n--) *d++ = *s++;
33 return dst;
34}
35
36void *memmove(void *dst, const void *src, size_t n) {
37 unsigned char *d = dst;
38 const unsigned char *s = src;
39 if (d < s) {
40 while (n--) *d++ = *s++;
41 } else {
42 while (n--) d[n] = s[n];
43 }
44 return dst;
45}
46
47void *memset(void *dst, int c, size_t n) {
48 unsigned char *d = dst;
49 while (n--) *d++ = (unsigned char)c;
50 return dst;
51}
52
53/* compiler-rt's 128-bit multiply: clang calls it for u64 x u64 -> u128 products on wasm32 (nothing
54 * else here links compiler-rt). */
55__extension__ typedef __int128 mesh_ti;
56mesh_ti __multi3(mesh_ti a, mesh_ti b);
57mesh_ti __multi3(mesh_ti a, mesh_ti b) {
58 __extension__ typedef unsigned __int128 mesh_tu;
59 mesh_tu x = (mesh_tu)a, y = (mesh_tu)b;
60 uint64_t a0 = (uint64_t)x, a1 = (uint64_t)(x >> 64), b0 = (uint64_t)y, b1 = (uint64_t)(y >> 64);
61 /* a0 * b0 in full from 32-bit halves, then the cross terms into the high word. */
62 uint64_t l0 = a0 & 0xffffffffu, h0 = a0 >> 32, l1 = b0 & 0xffffffffu, h1 = b0 >> 32;
63 uint64_t ll = l0 * l1, lh = l0 * h1, hl = h0 * l1, hh = h0 * h1;
64 uint64_t mid = (ll >> 32) + (lh & 0xffffffffu) + (hl & 0xffffffffu);
65 uint64_t lo = (ll & 0xffffffffu) | mid << 32;
66 uint64_t hi = hh + (lh >> 32) + (hl >> 32) + (mid >> 32) + a0 * b1 + a1 * b0;
67 return (mesh_ti)((mesh_tu)hi << 64 | lo);
68}