@mikrojs/native 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +198 -0
- package/LICENSE +21 -0
- package/README.md +49 -0
- package/cmake/mikrojs_bytecode.cmake +146 -0
- package/cmake.js +22 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +132 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +43 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/include/byteorder_apple.h +11 -0
- package/include/byteorder_windows.h +12 -0
- package/include/mikrojs/cbor_helpers.h +24 -0
- package/include/mikrojs/cutils_wrap.h +59 -0
- package/include/mikrojs/errors.h +144 -0
- package/include/mikrojs/mem.h +11 -0
- package/include/mikrojs/mik_color.h +32 -0
- package/include/mikrojs/mikrojs.h +331 -0
- package/include/mikrojs/platform.h +82 -0
- package/include/mikrojs/private.h +281 -0
- package/include/mikrojs/utils.h +125 -0
- package/package.json +100 -0
- package/prebuilds/darwin-arm64/mikrojs.napi.node +0 -0
- package/prebuilds/linux-arm64/mikrojs.napi.node +0 -0
- package/prebuilds/linux-x64/mikrojs.napi.node +0 -0
- package/runtime/ble/ble.ts +231 -0
- package/runtime/ble/types.ts +194 -0
- package/runtime/ble/uuid.ts +89 -0
- package/runtime/ble/validators.ts +61 -0
- package/runtime/cbor/cbor.ts +1 -0
- package/runtime/cbor/types.ts +8 -0
- package/runtime/console/types.ts +50 -0
- package/runtime/env/env.ts +17 -0
- package/runtime/env/types.ts +12 -0
- package/runtime/format/types.ts +4 -0
- package/runtime/fs/fs.ts +93 -0
- package/runtime/fs/types.ts +92 -0
- package/runtime/globals.d.ts +87 -0
- package/runtime/http/helpers.ts +222 -0
- package/runtime/http/native.ts +151 -0
- package/runtime/http/request.ts +25 -0
- package/runtime/i2c/i2c.ts +35 -0
- package/runtime/i2c/types.ts +55 -0
- package/runtime/inspect/types.ts +10 -0
- package/runtime/internal.d.ts +456 -0
- package/runtime/kv/nvs.ts +17 -0
- package/runtime/kv/rtc.ts +17 -0
- package/runtime/kv/shared.ts +107 -0
- package/runtime/kv/types.ts +150 -0
- package/runtime/neopixel/neopixel.ts +38 -0
- package/runtime/neopixel/types.ts +27 -0
- package/runtime/pin/pin.ts +51 -0
- package/runtime/pin/types.ts +49 -0
- package/runtime/pwm/pwm.ts +32 -0
- package/runtime/pwm/types.ts +29 -0
- package/runtime/reader/reader.ts +167 -0
- package/runtime/reader/types.ts +34 -0
- package/runtime/result/native-result.node-shim.ts +44 -0
- package/runtime/result/result.ts +26 -0
- package/runtime/result/types.ts +60 -0
- package/runtime/schema/schema.ts +321 -0
- package/runtime/schema/types.ts +152 -0
- package/runtime/sleep/sleep.ts +14 -0
- package/runtime/sleep/types.ts +44 -0
- package/runtime/sntp/sntp.ts +54 -0
- package/runtime/sntp/types.ts +38 -0
- package/runtime/spi/spi.ts +31 -0
- package/runtime/spi/types.ts +42 -0
- package/runtime/stdio/stdio.ts +44 -0
- package/runtime/stdio/types.ts +22 -0
- package/runtime/stream/stream.ts +150 -0
- package/runtime/stream/types.ts +47 -0
- package/runtime/sys/sys.ts +90 -0
- package/runtime/sys/types.ts +131 -0
- package/runtime/test/test.ts +595 -0
- package/runtime/test/types.ts +97 -0
- package/runtime/uart/types.ts +75 -0
- package/runtime/uart/uart.ts +51 -0
- package/runtime/wifi/types.ts +156 -0
- package/runtime/wifi/wifi.ts +208 -0
- package/scripts/bundle-runtime.js +149 -0
- package/scripts/compare-minifiers.js +189 -0
- package/scripts/compile-bytecode.sh +38 -0
- package/scripts/copy-prebuild.js +20 -0
- package/scripts/generate-symbol-map.js +146 -0
- package/src/builtins.cpp +82 -0
- package/src/cutils_compat.c +38 -0
- package/src/eval_bytecode.cpp +42 -0
- package/src/fs.cpp +878 -0
- package/src/mem.cpp +63 -0
- package/src/mik_abort.cpp +160 -0
- package/src/mik_app_config.cpp +358 -0
- package/src/mik_cbor.cpp +334 -0
- package/src/mik_color.cpp +46 -0
- package/src/mik_console.cpp +422 -0
- package/src/mik_inspect.cpp +850 -0
- package/src/mik_repl.cpp +1122 -0
- package/src/mik_result.cpp +344 -0
- package/src/mik_stdio.cpp +147 -0
- package/src/mik_sys.cpp +239 -0
- package/src/mik_text_encoding.cpp +443 -0
- package/src/mikrojs.cpp +942 -0
- package/src/modules.cpp +944 -0
- package/src/platform_posix.cpp +134 -0
- package/src/timers.cpp +208 -0
- package/src/utils.cpp +173 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <string>
|
|
4
|
+
#include <unordered_map>
|
|
5
|
+
#include <unordered_set>
|
|
6
|
+
#include <vector>
|
|
7
|
+
|
|
8
|
+
#include "mikrojs/cutils_wrap.h"
|
|
9
|
+
#include "mikrojs/mikrojs.h"
|
|
10
|
+
#include "quickjs.h"
|
|
11
|
+
|
|
12
|
+
#define MIK_TIMER_MAX_ARGS 4
|
|
13
|
+
#define MIK_MAX_DUE_TIMERS 16
|
|
14
|
+
#define MIK_STDIN_BUF_SIZE 256
|
|
15
|
+
|
|
16
|
+
#ifndef PATH_MAX
|
|
17
|
+
#define PATH_MAX 255
|
|
18
|
+
#endif
|
|
19
|
+
|
|
20
|
+
typedef struct MIKTimerEntry {
|
|
21
|
+
uint32_t id;
|
|
22
|
+
// is it an interval or a one-shot timer?
|
|
23
|
+
bool is_interval;
|
|
24
|
+
// original timeout (delay) value in microseconds
|
|
25
|
+
int64_t timeout;
|
|
26
|
+
// next deadline in microseconds
|
|
27
|
+
int64_t next_deadline;
|
|
28
|
+
JSValue func;
|
|
29
|
+
int argc;
|
|
30
|
+
JSValue argv[MIK_TIMER_MAX_ARGS];
|
|
31
|
+
} MIKTimerEntry;
|
|
32
|
+
|
|
33
|
+
typedef struct MIKTimers {
|
|
34
|
+
std::vector<MIKTimerEntry> entries;
|
|
35
|
+
// note: start at 1 to avoid if (timerId) {...} bugs
|
|
36
|
+
uint32_t next_timer_id = 1;
|
|
37
|
+
} MIKTimerRegistry;
|
|
38
|
+
|
|
39
|
+
/* Registered native module init function */
|
|
40
|
+
struct MIKNativeModuleEntry {
|
|
41
|
+
std::string name;
|
|
42
|
+
MIKNativeModuleInitFn init_fn;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/* Registered loop consumer */
|
|
46
|
+
struct MIKLoopConsumerEntry {
|
|
47
|
+
MIKLoopConsumeFn consume_fn;
|
|
48
|
+
MIKLoopDestroyFn destroy_fn;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
struct MIKRuntime {
|
|
52
|
+
MIKRunOptions options;
|
|
53
|
+
MIKConfig config;
|
|
54
|
+
JSRuntime* rt;
|
|
55
|
+
JSContext* ctx;
|
|
56
|
+
bool is_worker;
|
|
57
|
+
bool freeing;
|
|
58
|
+
bool stop_requested; /* Set by promise rejection tracker to stop the loop */
|
|
59
|
+
const char* fs_base_path;
|
|
60
|
+
const char* fs_root; /* Sandbox root for mikrojs/fs operations (separate from module resolution) */
|
|
61
|
+
size_t fs_limit; /* Max bytes for fs_root (0 = unlimited) */
|
|
62
|
+
/* Cached bytes used under fs_root. Populated lazily on the first quota
|
|
63
|
+
* check; adjusted in-place on write/unlink so the O(tree) walk only
|
|
64
|
+
* happens once per run, not per write. Callers invalidate by setting
|
|
65
|
+
* fs_used_known=false when they can't cheaply compute the delta. */
|
|
66
|
+
size_t fs_used;
|
|
67
|
+
bool fs_used_known;
|
|
68
|
+
/* Max bytes a single readFile() call will return. Files larger than
|
|
69
|
+
* this throw FSError(EFBIG); callers use open() for streaming. */
|
|
70
|
+
size_t fs_read_max;
|
|
71
|
+
MIKTimerRegistry* timers;
|
|
72
|
+
std::vector<MIKNativeModuleEntry> native_modules;
|
|
73
|
+
std::vector<MIKLoopConsumerEntry> loop_consumers;
|
|
74
|
+
struct {
|
|
75
|
+
JSValue promise_event_ctor;
|
|
76
|
+
JSValue dispatch_event_func;
|
|
77
|
+
} builtins;
|
|
78
|
+
/* Shared prototype for Result objects ({ok, value} / {ok, error}) created
|
|
79
|
+
* by mik__result_ok/mik__result_err and the native:result ok()/err()
|
|
80
|
+
* functions. Holds .map/.mapErr/.andThen/.match/.orDefault/.orPanic +
|
|
81
|
+
* Symbol.for('mikrojs.inspect'). Initialized eagerly by mik__result_init
|
|
82
|
+
* and freed in MIK_FreeRuntime. */
|
|
83
|
+
JSValue result_proto;
|
|
84
|
+
/* Frozen {ok: true} singleton returned (via JS_DupValue) from
|
|
85
|
+
* mik__result_ok_void. Safe to share because Result is immutable by
|
|
86
|
+
* convention, and the singleton is frozen + non-extensible. */
|
|
87
|
+
JSValue result_ok_void_singleton;
|
|
88
|
+
JSValue env_obj; /* Frozen object with env vars, set on import.meta.env */
|
|
89
|
+
struct {
|
|
90
|
+
JSValue on_data; /* JS callback for stdin data, JS_UNDEFINED when not listening */
|
|
91
|
+
} stdin_state;
|
|
92
|
+
/* Env vars stored before runtime init (for building env_obj) */
|
|
93
|
+
std::vector<std::pair<std::string, std::string>> env_vars;
|
|
94
|
+
/* Opaque per-module data slots for platform-specific modules.
|
|
95
|
+
* Used by registered native modules to store their state on the runtime.
|
|
96
|
+
* Slots are allocated dynamically via MIK_AllocModuleSlot(). */
|
|
97
|
+
void* module_data[MIK_MODULE_DATA_SLOTS] = {};
|
|
98
|
+
int next_module_slot = 0;
|
|
99
|
+
/* Virtual modules: name → JS source. Checked by the module loader before
|
|
100
|
+
* the builtin bytecode table, allowing host-side JS to override any
|
|
101
|
+
* native:* C module (e.g. mocking device modules for desktop dev). */
|
|
102
|
+
std::unordered_map<std::string, std::string> virtual_modules;
|
|
103
|
+
/* Module dependency graph, populated by mik_module_normalizer on every
|
|
104
|
+
* successful normalization call. module_imports[A] = set of modules A
|
|
105
|
+
* statically imports; module_importers[B] = set of modules that import B.
|
|
106
|
+
* Both are keyed by normalized module names (the same strings that
|
|
107
|
+
* appear as JSAtom values on JSModuleDef). Used by mik__unload_module to
|
|
108
|
+
* locate orphaned transitive dependencies. Edges for non-module bases
|
|
109
|
+
* (REPL input, "<input>", task wrappers) are skipped. */
|
|
110
|
+
std::unordered_map<std::string, std::unordered_set<std::string>> module_imports;
|
|
111
|
+
std::unordered_map<std::string, std::unordered_set<std::string>> module_importers;
|
|
112
|
+
/* Optional preprocessor called on module source before compilation.
|
|
113
|
+
* Returns a malloc'd string (caller frees), or NULL to use original source.
|
|
114
|
+
* Used by the Node.js addon to strip TypeScript types. */
|
|
115
|
+
char* (*preprocess_fn)(const char* filename, const char* source, size_t source_len,
|
|
116
|
+
size_t* out_len, void* opaque) = nullptr;
|
|
117
|
+
void* preprocess_opaque = nullptr;
|
|
118
|
+
/* Optional error handler called with the exception value before mik_dump_error
|
|
119
|
+
* consumes it. The handler receives the exception as a borrowed JSValue
|
|
120
|
+
* (do NOT free it). Used by the Node.js addon to forward errors to the host. */
|
|
121
|
+
void (*error_handler_fn)(JSContext* ctx, JSValue error, void* opaque) = nullptr;
|
|
122
|
+
void* error_handler_opaque = nullptr;
|
|
123
|
+
/* Memory profiling: per-module load deltas. Vector capacity is reserved
|
|
124
|
+
* up-front when profiling is enabled so loads don't trigger reallocations
|
|
125
|
+
* that would themselves be visible to JS_ComputeMemoryUsage. The vector
|
|
126
|
+
* itself lives in the regular C++ heap, not the js_malloc pool, so it's
|
|
127
|
+
* invisible to the numbers we're measuring. */
|
|
128
|
+
bool profile_enabled = false;
|
|
129
|
+
std::vector<MIKProfileEntry> profile_entries;
|
|
130
|
+
size_t profile_baseline = 0; /* malloc_size at profiling start */
|
|
131
|
+
/* OOM signalling: flag set by MIK_ReportOOM() when the detection code
|
|
132
|
+
* thinks the runtime is at or past its QuickJS memory ceiling. Cleared
|
|
133
|
+
* by MIK_ConsumeOOMFlag(). Cold path — not read during bytecode
|
|
134
|
+
* execution or allocation, so it adds zero runtime tax. */
|
|
135
|
+
bool oom_flagged = false;
|
|
136
|
+
MIKOOMHandlerFn oom_handler_fn = nullptr;
|
|
137
|
+
void* oom_handler_opaque = nullptr;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
void mik__pub_fs_register(JSContext* ctx);
|
|
141
|
+
void mik__stdio_init(JSContext* ctx, JSValue ns);
|
|
142
|
+
void mik__sys_api_init(JSContext* ctx, JSValue ns);
|
|
143
|
+
void mik__text_encoding_init(JSContext* ctx, JSValue global);
|
|
144
|
+
void mik__abort_init(JSContext* ctx, JSValue global_obj);
|
|
145
|
+
|
|
146
|
+
JSValue mik_new_error(JSContext* ctx, int err);
|
|
147
|
+
JSValue mik_throw_errno(JSContext* ctx, int err);
|
|
148
|
+
|
|
149
|
+
void mik__execute_jobs(JSContext* ctx);
|
|
150
|
+
JSModuleDef* mik__load_builtin(JSContext* ctx, const char* name);
|
|
151
|
+
int mik__load_file(JSContext* ctx, DynBuf* dbuf, const char* filename);
|
|
152
|
+
void mik__resolve_fs_path(JSContext* ctx, const char* module_name, char* out, size_t out_size);
|
|
153
|
+
int mik__resolve_fs_root(JSContext* ctx, const char* path, char* out, size_t out_size);
|
|
154
|
+
size_t mik__fs_dir_usage(const char* dir_path);
|
|
155
|
+
JSModuleDef* mik_module_loader(JSContext* ctx, const char* module_name, void* opaque);
|
|
156
|
+
char* mik_module_normalizer(JSContext* ctx, const char* base_name, const char* name, void* opaque);
|
|
157
|
+
|
|
158
|
+
/* Unload a module by its normalized name. Walks the mikrojs-side import
|
|
159
|
+
* dependency graph, recursively unloading any transitive dependency
|
|
160
|
+
* whose importer set becomes empty (builtin prefixes native:, mikrojs/,
|
|
161
|
+
* @mikrojs/ are anchored and skipped). Safe to call only on
|
|
162
|
+
* modules in JS_MODULE_STATUS_EVALUATED state; returns the number of
|
|
163
|
+
* modules actually freed, or -1 with a JS exception on invalid,
|
|
164
|
+
* mid-evaluation, or unknown modules. */
|
|
165
|
+
int mik__unload_module(JSContext* ctx, const char* normalized_name);
|
|
166
|
+
|
|
167
|
+
int js_module_set_import_meta(JSContext* ctx, JSValue func_val, bool use_realpath, bool is_main);
|
|
168
|
+
|
|
169
|
+
JSValue mik__get_args(JSContext* ctx);
|
|
170
|
+
|
|
171
|
+
int mik__eval_bytecode(JSContext* ctx, const uint8_t* buf, size_t buf_len, bool check_promise);
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
void mik__sab_free(void* opaque, void* ptr);
|
|
175
|
+
void mik__sab_dup(void* opaque, void* ptr);
|
|
176
|
+
|
|
177
|
+
MIKTimerRegistry* MIK_NewTimerRegistry(void);
|
|
178
|
+
MIKRuntime* MIK_NewRuntimeWorker(void);
|
|
179
|
+
MIKRuntime* MIK_NewRuntimeInternal(MIKRunOptions* options);
|
|
180
|
+
JSValue MIK_EvalScript(JSContext* ctx, const char* filename);
|
|
181
|
+
JSValue MIK_EvalModule(JSContext* ctx, const char* filename, bool is_main);
|
|
182
|
+
JSValue MIK_EvalModuleContent(JSContext* ctx, const char* filename, const char* content,
|
|
183
|
+
size_t len);
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
void mik__timers_init(JSContext* ctx, JSValue ns);
|
|
187
|
+
void mik__timers_consume(JSContext* ctx);
|
|
188
|
+
void mik__timers_destroy(JSContext* ctx);
|
|
189
|
+
|
|
190
|
+
void mik__stdin_consume(JSContext* ctx);
|
|
191
|
+
|
|
192
|
+
/* Console global (mik_console.cpp) */
|
|
193
|
+
void mik__console_init(JSContext* ctx, JSValue global_obj);
|
|
194
|
+
void mik__report_uncaught(JSContext* ctx, JSValue exc, bool in_promise = false);
|
|
195
|
+
|
|
196
|
+
/* Inspect (mik_inspect.cpp) */
|
|
197
|
+
std::string mik_inspect(JSContext* ctx, JSValue value, int depth = 2, bool colors = false,
|
|
198
|
+
bool show_hidden = false);
|
|
199
|
+
void mik__inspect_register(JSContext* ctx);
|
|
200
|
+
|
|
201
|
+
/* CBOR module (mik_cbor.cpp) */
|
|
202
|
+
JSModuleDef* mik__cbor_init(JSContext* ctx);
|
|
203
|
+
|
|
204
|
+
/* Result module (mik_result.cpp) */
|
|
205
|
+
JSModuleDef* mik__result_init(JSContext* ctx);
|
|
206
|
+
|
|
207
|
+
bool mik__repl_is_evaluating(void);
|
|
208
|
+
|
|
209
|
+
/* REPL protocol mode (mik_repl.cpp) — used by mik_console.cpp, mik_stdio.cpp */
|
|
210
|
+
bool mik__repl_is_protocol_mode(void);
|
|
211
|
+
void mik__repl_proto_send_output(uint8_t msg_type, const void* data, size_t len);
|
|
212
|
+
|
|
213
|
+
/* Suspend/resume MIK_Loop pumping (timers + loop consumers). Microtasks
|
|
214
|
+
* still drain so in-flight promises can settle. Used by mik_deploy.cpp to
|
|
215
|
+
* freeze user code while a deploy is streaming in. */
|
|
216
|
+
bool mik__repl_is_paused(void);
|
|
217
|
+
void mik__repl_set_paused(bool paused);
|
|
218
|
+
|
|
219
|
+
/* ── Unified MIK Protocol ───────────────────────────────────────── */
|
|
220
|
+
/* Frame format: [type: u8][length: u32le][payload: bytes] */
|
|
221
|
+
|
|
222
|
+
/* Escape hatch: raw byte that triggers hard restart */
|
|
223
|
+
#define MIK_CTRL_R 0x12
|
|
224
|
+
|
|
225
|
+
/* Header size: 1 (type) + 4 (u32le length) */
|
|
226
|
+
#define MIK_PROTO_HEADER_SIZE 5
|
|
227
|
+
|
|
228
|
+
/* Device → CLI message types */
|
|
229
|
+
#define MIK_MSG_READY 0x01
|
|
230
|
+
#define MIK_MSG_LOG 0x02
|
|
231
|
+
#define MIK_MSG_WARN 0x03
|
|
232
|
+
#define MIK_MSG_ERROR 0x04
|
|
233
|
+
#define MIK_MSG_RESULT 0x05
|
|
234
|
+
#define MIK_MSG_INFO 0x06
|
|
235
|
+
#define MIK_MSG_COMPLETIONS 0x07
|
|
236
|
+
#define MIK_MSG_EVAL_ERROR 0x08
|
|
237
|
+
#define MIK_MSG_PROMPT 0x09
|
|
238
|
+
#define MIK_MSG_TEST 0x0B
|
|
239
|
+
#define MIK_MSG_DEBUG 0x0C
|
|
240
|
+
/* Emitted once after the last test file's run_done when the device drove
|
|
241
|
+
* a supervisor-mode manifest. Signals "no more tests coming" to the CLI. */
|
|
242
|
+
#define MIK_MSG_MANIFEST_DONE 0x0D
|
|
243
|
+
|
|
244
|
+
#define MIK_MSG_OK 0x80
|
|
245
|
+
#define MIK_MSG_ERR 0x81
|
|
246
|
+
#define MIK_MSG_CHECKSUM_RESULT 0x82
|
|
247
|
+
#define MIK_MSG_CONFIG_ENTRIES 0x83
|
|
248
|
+
|
|
249
|
+
/* CLI → Device command types */
|
|
250
|
+
#define MIK_CMD_EVAL 0x10
|
|
251
|
+
#define MIK_CMD_COMPLETE 0x11
|
|
252
|
+
/* 0x12 reserved for CTRL_R hard-restart escape hatch */
|
|
253
|
+
#define MIK_CMD_DIRECTIVE 0x13
|
|
254
|
+
#define MIK_CMD_EXIT 0x14
|
|
255
|
+
#define MIK_CMD_HELLO 0x15
|
|
256
|
+
|
|
257
|
+
/* PUT opens the staged file and records the total size; the body arrives in
|
|
258
|
+
* one or more PUT_CHUNK frames so a single TLV frame never exceeds the USJ
|
|
259
|
+
* RX ring. PUT payload: u16le name_len | name | u32le total_size. */
|
|
260
|
+
#define MIK_CMD_DEPLOY_PUT 0x20
|
|
261
|
+
#define MIK_CMD_DEPLOY_DONE 0x21
|
|
262
|
+
#define MIK_CMD_DEPLOY_ABORT 0x22
|
|
263
|
+
#define MIK_CMD_DEPLOY_ERASE 0x23
|
|
264
|
+
/* PUT_CHUNK payload: file bytes (1..N). Appended to the file opened by the
|
|
265
|
+
* preceding PUT; closed automatically when total_remaining reaches zero. */
|
|
266
|
+
#define MIK_CMD_DEPLOY_PUT_CHUNK 0x24
|
|
267
|
+
/* 0x25 formerly MIK_CMD_DEPLOY_ENV_CLEAR — no longer needed; deploy diffs env via CONFIG_DELETE */
|
|
268
|
+
#define MIK_CMD_DEPLOY_KEEP 0x26
|
|
269
|
+
#define MIK_CMD_DEPLOY_CHECKSUM 0x27
|
|
270
|
+
#define MIK_CMD_RESTART 0x28
|
|
271
|
+
#define MIK_CMD_RUNTIME_PAUSE 0x29
|
|
272
|
+
#define MIK_CMD_RUNTIME_RESUME 0x2A
|
|
273
|
+
|
|
274
|
+
#define MIK_CMD_CONFIG_LIST 0x40
|
|
275
|
+
#define MIK_CMD_CONFIG_SET 0x41
|
|
276
|
+
#define MIK_CMD_CONFIG_DELETE 0x42
|
|
277
|
+
|
|
278
|
+
/* Env entry flags */
|
|
279
|
+
#define MIK_ENV_FLAG_SECRET 0x01
|
|
280
|
+
|
|
281
|
+
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
|
|
2
|
+
#pragma once
|
|
3
|
+
|
|
4
|
+
#include <mikrojs/cutils_wrap.h>
|
|
5
|
+
#include <quickjs.h>
|
|
6
|
+
|
|
7
|
+
#ifndef countof
|
|
8
|
+
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
|
9
|
+
#endif
|
|
10
|
+
|
|
11
|
+
struct AssertionInfo {
|
|
12
|
+
const char* file_line; // filename:line
|
|
13
|
+
const char* message;
|
|
14
|
+
const char* function;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
#define ERROR_AND_ABORT(expr) \
|
|
18
|
+
do { \
|
|
19
|
+
static const struct AssertionInfo args = {__FILE__ ":" STRINGIFY(__LINE__), #expr, \
|
|
20
|
+
PRETTY_FUNCTION_NAME}; \
|
|
21
|
+
mik_assert(args); \
|
|
22
|
+
} while (0)
|
|
23
|
+
|
|
24
|
+
#define MIK__LIKELY(expr) __builtin_expect(!!(expr), 1)
|
|
25
|
+
#define MIK__UNLIKELY(expr) __builtin_expect(!!(expr), 0)
|
|
26
|
+
#define PRETTY_FUNCTION_NAME __PRETTY_FUNCTION__
|
|
27
|
+
|
|
28
|
+
#define STRINGIFY_(x) #x
|
|
29
|
+
#define STRINGIFY(x) STRINGIFY_(x)
|
|
30
|
+
|
|
31
|
+
#define CHECK(expr) \
|
|
32
|
+
do { \
|
|
33
|
+
if (MIK__UNLIKELY(!(expr))) { \
|
|
34
|
+
ERROR_AND_ABORT(expr); \
|
|
35
|
+
} \
|
|
36
|
+
} while (0)
|
|
37
|
+
|
|
38
|
+
#define CHECK_EQ(a, b) CHECK((a) == (b))
|
|
39
|
+
#define CHECK_GE(a, b) CHECK((a) >= (b))
|
|
40
|
+
#define CHECK_GT(a, b) CHECK((a) > (b))
|
|
41
|
+
#define CHECK_LE(a, b) CHECK((a) <= (b))
|
|
42
|
+
#define CHECK_LT(a, b) CHECK((a) < (b))
|
|
43
|
+
#define CHECK_NE(a, b) CHECK((a) != (b))
|
|
44
|
+
#define CHECK_NULL(val) CHECK((val) == NULL)
|
|
45
|
+
#define CHECK_NOT_NULL(val) CHECK((val) != NULL)
|
|
46
|
+
|
|
47
|
+
void mik_assert(const struct AssertionInfo info);
|
|
48
|
+
|
|
49
|
+
#define MIK_CONST(x) JS_PROP_INT32_DEF(#x, x, JS_PROP_ENUMERABLE)
|
|
50
|
+
#define MIK_CONST2(name, val) JS_PROP_INT32_DEF(name, val, JS_PROP_ENUMERABLE)
|
|
51
|
+
#define MIK_CFUNC_DEF(name, length, func1) \
|
|
52
|
+
{ \
|
|
53
|
+
name, JS_PROP_C_W_E, JS_DEF_CFUNC, 0, { \
|
|
54
|
+
.func = { length, JS_CFUNC_generic, {.generic = func1} } \
|
|
55
|
+
} \
|
|
56
|
+
}
|
|
57
|
+
#define MIK_CFUNC_MAGIC_DEF(name, length, func1, magic) \
|
|
58
|
+
{ \
|
|
59
|
+
name, JS_PROP_C_W_E, JS_DEF_CFUNC, magic, { \
|
|
60
|
+
.func = { length, JS_CFUNC_generic_magic, {.generic_magic = func1} } \
|
|
61
|
+
} \
|
|
62
|
+
}
|
|
63
|
+
#define MIK_CGETSET_DEF(name, fgetter, fsetter) \
|
|
64
|
+
{ \
|
|
65
|
+
name, JS_PROP_C_W_E, JS_DEF_CGETSET, 0, { \
|
|
66
|
+
.getset = {.get = {.getter = fgetter}, .set = {.setter = fsetter} } \
|
|
67
|
+
} \
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
void mik_call_handler(JSContext* ctx, JSValue func, int argc, JSValue* argv);
|
|
71
|
+
void mik_dump_error(JSContext* ctx);
|
|
72
|
+
void mik_dump_error1(JSContext* ctx, JSValue exception_val);
|
|
73
|
+
|
|
74
|
+
typedef struct {
|
|
75
|
+
JSValue p;
|
|
76
|
+
JSValue rfuncs[2];
|
|
77
|
+
} MIKPromise;
|
|
78
|
+
|
|
79
|
+
JSValue MIK_InitPromise(JSContext* ctx, MIKPromise* p);
|
|
80
|
+
bool MIK_IsPromisePending(JSContext* ctx, MIKPromise* p);
|
|
81
|
+
void MIK_FreePromise(JSContext* ctx, MIKPromise* p);
|
|
82
|
+
void MIK_FreePromiseRT(JSRuntime* rt, MIKPromise* p);
|
|
83
|
+
void MIK_ClearPromise(JSContext* ctx, MIKPromise* p);
|
|
84
|
+
void MIK_MarkPromise(JSRuntime* rt, MIKPromise* p, JS_MarkFunc* mark_func);
|
|
85
|
+
void MIK_SettlePromise(JSContext* ctx, MIKPromise* p, bool is_reject, int argc, JSValue* argv);
|
|
86
|
+
void MIK_ResolvePromise(JSContext* ctx, MIKPromise* p, int argc, JSValue* argv);
|
|
87
|
+
void MIK_RejectPromise(JSContext* ctx, MIKPromise* p, int argc, JSValue* argv);
|
|
88
|
+
JSValue MIK_NewResolvedPromise(JSContext* ctx, int argc, JSValue* argv);
|
|
89
|
+
JSValue MIK_NewRejectedPromise(JSContext* ctx, int argc, JSValue* argv);
|
|
90
|
+
|
|
91
|
+
JSValue MIK_NewUint8Array(JSContext* ctx, uint8_t* data, size_t size);
|
|
92
|
+
|
|
93
|
+
#define MIK_THROW_ARG_ERR(ctx, argno, expected) \
|
|
94
|
+
JS_ThrowTypeError(ctx, "expected argument %d to be %s", argno + 1, expected)
|
|
95
|
+
#define MIK_CHECK_ARG_RET(ctx, check, argno, expected) \
|
|
96
|
+
if (!(check)) { \
|
|
97
|
+
return MIK_THROW_ARG_ERR(ctx, argno, expected); \
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
void mik_dbuf_init(JSContext* ctx, DynBuf* s);
|
|
101
|
+
|
|
102
|
+
/* ── Native result helpers ───────────────────────────────────────── */
|
|
103
|
+
/* Return {ok: true, value: <val>} or {ok: true} (void)
|
|
104
|
+
* or {ok: false, error: {code: 0x8xxx, message: "...", errno?: 0x...}}
|
|
105
|
+
* or {ok: false, error: {name: "VariantName", message: "..."}} (named variant)
|
|
106
|
+
* or {ok: false, error: {name: "VariantName"}} (tag-only variant)
|
|
107
|
+
*
|
|
108
|
+
* Implemented in mik_result.cpp. The returned objects have the shared
|
|
109
|
+
* Result prototype installed, so user code can chain .map/.match/etc.
|
|
110
|
+
*
|
|
111
|
+
* The `_named` / `_tag` forms produce error objects the JS layer can use
|
|
112
|
+
* directly without a code-to-variant remap — keeps mikrojs/X wrappers as
|
|
113
|
+
* pure re-exports of native:X. */
|
|
114
|
+
|
|
115
|
+
JSValue mik__result_ok(JSContext* ctx, JSValue value);
|
|
116
|
+
JSValue mik__result_ok_void(JSContext* ctx);
|
|
117
|
+
JSValue mik__result_err(JSContext* ctx, int code, int platform_errno, const char* fmt, ...)
|
|
118
|
+
__attribute__((format(printf, 4, 5)));
|
|
119
|
+
JSValue mik__result_err_named(JSContext* ctx, const char* name, const char* fmt, ...)
|
|
120
|
+
__attribute__((format(printf, 3, 4)));
|
|
121
|
+
JSValue mik__result_err_tag(JSContext* ctx, const char* name);
|
|
122
|
+
/* Wrap an already-built error object (any shape) in a Result. Caller passes
|
|
123
|
+
* ownership of `error_obj`. For variants with extra fields beyond
|
|
124
|
+
* {name, message} — path, code, limit, etc. */
|
|
125
|
+
JSValue mik__result_err_obj(JSContext* ctx, JSValue error_obj);
|
package/package.json
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mikrojs/native",
|
|
3
|
+
"version": "0.0.7",
|
|
4
|
+
"description": "Mikro.js C++ runtime library and Node.js native addon",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"esp32",
|
|
7
|
+
"mikrojs",
|
|
8
|
+
"native",
|
|
9
|
+
"quickjs",
|
|
10
|
+
"runtime"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/mikrojs/mikrojs#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/mikrojs/mikrojs/issues"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": "Bjørge Næss <bjoerge@gmail.com>",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/mikrojs/mikrojs.git"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"prebuilds",
|
|
25
|
+
"cmake",
|
|
26
|
+
"cmake.js",
|
|
27
|
+
"CMakeLists.txt",
|
|
28
|
+
"include",
|
|
29
|
+
"runtime",
|
|
30
|
+
"scripts",
|
|
31
|
+
"src",
|
|
32
|
+
"!**/__test__",
|
|
33
|
+
"!**/*.test.ts",
|
|
34
|
+
"!**/*.test.tsx",
|
|
35
|
+
"!**/*.test-d.ts"
|
|
36
|
+
],
|
|
37
|
+
"os": [
|
|
38
|
+
"darwin",
|
|
39
|
+
"linux"
|
|
40
|
+
],
|
|
41
|
+
"type": "module",
|
|
42
|
+
"sideEffects": false,
|
|
43
|
+
"exports": {
|
|
44
|
+
".": "./dist/index.js",
|
|
45
|
+
"./cmake": "./cmake.js",
|
|
46
|
+
"./package.json": "./package.json",
|
|
47
|
+
"./runtime/ble/types": "./runtime/ble/types.ts",
|
|
48
|
+
"./runtime/cbor/types": "./runtime/cbor/types.ts",
|
|
49
|
+
"./runtime/console/types": "./runtime/console/types.ts",
|
|
50
|
+
"./runtime/env/types": "./runtime/env/types.ts",
|
|
51
|
+
"./runtime/format/types": "./runtime/format/types.ts",
|
|
52
|
+
"./runtime/http/helpers": "./runtime/http/helpers.ts",
|
|
53
|
+
"./runtime/fs/types": "./runtime/fs/types.ts",
|
|
54
|
+
"./runtime/i2c/types": "./runtime/i2c/types.ts",
|
|
55
|
+
"./runtime/inspect/types": "./runtime/inspect/types.ts",
|
|
56
|
+
"./runtime/kv/shared": "./runtime/kv/shared.ts",
|
|
57
|
+
"./runtime/kv/types": "./runtime/kv/types.ts",
|
|
58
|
+
"./runtime/neopixel/types": "./runtime/neopixel/types.ts",
|
|
59
|
+
"./runtime/pin/types": "./runtime/pin/types.ts",
|
|
60
|
+
"./runtime/pwm/types": "./runtime/pwm/types.ts",
|
|
61
|
+
"./runtime/reader/types": "./runtime/reader/types.ts",
|
|
62
|
+
"./runtime/result/types": "./runtime/result/types.ts",
|
|
63
|
+
"./runtime/schema/types": "./runtime/schema/types.ts",
|
|
64
|
+
"./runtime/sleep/types": "./runtime/sleep/types.ts",
|
|
65
|
+
"./runtime/sntp/types": "./runtime/sntp/types.ts",
|
|
66
|
+
"./runtime/spi/types": "./runtime/spi/types.ts",
|
|
67
|
+
"./runtime/stdio/types": "./runtime/stdio/types.ts",
|
|
68
|
+
"./runtime/stream/types": "./runtime/stream/types.ts",
|
|
69
|
+
"./runtime/sys/types": "./runtime/sys/types.ts",
|
|
70
|
+
"./runtime/test/types": "./runtime/test/types.ts",
|
|
71
|
+
"./runtime/uart/types": "./runtime/uart/types.ts",
|
|
72
|
+
"./runtime/wifi/types": "./runtime/wifi/types.ts"
|
|
73
|
+
},
|
|
74
|
+
"dependencies": {
|
|
75
|
+
"cmake-js": "^8.0.0",
|
|
76
|
+
"node-addon-api": "^8.7.0",
|
|
77
|
+
"node-gyp-build": "^4.8.4",
|
|
78
|
+
"@mikrojs/quickjs": "0.0.7"
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@swc/core": "^1.15.30",
|
|
82
|
+
"@types/node": "^25.6.0",
|
|
83
|
+
"esbuild": "^0.28.0",
|
|
84
|
+
"terser": "^5.46.2"
|
|
85
|
+
},
|
|
86
|
+
"engines": {
|
|
87
|
+
"node": ">=24.0.0"
|
|
88
|
+
},
|
|
89
|
+
"scripts": {
|
|
90
|
+
"bench": "cmake -B build -DBUILD_TESTING=ON && cmake --build build --target memory_bench &&./build/memory_bench",
|
|
91
|
+
"build:native": "cmake-js compile --directory addon && node scripts/copy-prebuild.js",
|
|
92
|
+
"build:native:debug": "cmake-js compile --debug --directory addon && node scripts/copy-prebuild.js",
|
|
93
|
+
"build:ts": "tsc -p tsconfig.build.json",
|
|
94
|
+
"clean": "cmake-js clean --directory addon && rm -rf prebuilds",
|
|
95
|
+
"compare-minifiers": "node scripts/compare-minifiers.js --open",
|
|
96
|
+
"publint": "publint",
|
|
97
|
+
"typecheck": "tsc --noEmit -p tsconfig.addon.json && tsc --noEmit -p tsconfig.runtime.json",
|
|
98
|
+
"watch": "node --experimental-strip-types watch.ts"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|