@mikrojs/native 0.18.2 → 0.18.3-next.20260829153835
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 +1 -0
- package/dist/runtime/schema/core.d.ts +68 -20
- package/dist/runtime/schema/core.d.ts.map +1 -1
- package/dist/runtime/schema/core.js +51 -4
- package/dist/runtime/schema/core.js.map +1 -1
- package/dist/runtime/schema/shared.d.ts +26 -1
- package/dist/runtime/schema/shared.d.ts.map +1 -1
- package/dist/runtime/schema/shared.js +533 -17
- package/dist/runtime/schema/shared.js.map +1 -1
- package/include/mikrojs/mem.h +4 -0
- package/include/mikrojs/ota_client.h +3 -3
- package/include/mikrojs/platform.h +8 -0
- package/package.json +3 -3
- 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/internal.d.ts +13 -2
- package/runtime/ota/client.ts +4 -0
- package/runtime/ota/ota.ts +4 -0
- package/runtime/ota/types.ts +75 -0
- package/runtime/schema/core.ts +325 -22
- package/runtime/schema/schema.ts +9 -0
- package/runtime/schema/shared.ts +568 -22
- package/runtime/schema/types.ts +192 -14
- package/runtime/sys/types.ts +11 -1
- package/src/mem.cpp +83 -37
- package/src/mik_ota_client.cpp +3 -3
- package/src/mik_sys.cpp +9 -1
package/runtime/schema/types.ts
CHANGED
|
@@ -2,17 +2,153 @@ import type {Result} from '../result/types.js'
|
|
|
2
2
|
|
|
3
3
|
type Primitive = string | number | boolean
|
|
4
4
|
|
|
5
|
-
export
|
|
5
|
+
export type Format = 'url' | 'hostname' | 'ipv4' | 'mac' | 'email'
|
|
6
|
+
|
|
7
|
+
export type Unit =
|
|
8
|
+
| 'm'
|
|
9
|
+
| 'kg'
|
|
10
|
+
| 's'
|
|
11
|
+
| 'A'
|
|
12
|
+
| 'K'
|
|
13
|
+
| 'cd'
|
|
14
|
+
| 'mol'
|
|
15
|
+
| 'Hz'
|
|
16
|
+
| 'rad'
|
|
17
|
+
| 'sr'
|
|
18
|
+
| 'N'
|
|
19
|
+
| 'Pa'
|
|
20
|
+
| 'J'
|
|
21
|
+
| 'W'
|
|
22
|
+
| 'C'
|
|
23
|
+
| 'V'
|
|
24
|
+
| 'F'
|
|
25
|
+
| 'Ohm'
|
|
26
|
+
| 'S'
|
|
27
|
+
| 'Wb'
|
|
28
|
+
| 'T'
|
|
29
|
+
| 'H'
|
|
30
|
+
| 'Cel'
|
|
31
|
+
| 'lm'
|
|
32
|
+
| 'lx'
|
|
33
|
+
| 'Bq'
|
|
34
|
+
| 'Gy'
|
|
35
|
+
| 'Sv'
|
|
36
|
+
| 'kat'
|
|
37
|
+
| 'm2'
|
|
38
|
+
| 'm3'
|
|
39
|
+
| 'm/s'
|
|
40
|
+
| 'm/s2'
|
|
41
|
+
| 'm3/s'
|
|
42
|
+
| 'W/m2'
|
|
43
|
+
| 'cd/m2'
|
|
44
|
+
| 'bit'
|
|
45
|
+
| 'bit/s'
|
|
46
|
+
| 'lat'
|
|
47
|
+
| 'lon'
|
|
48
|
+
| 'pH'
|
|
49
|
+
| 'dB'
|
|
50
|
+
| 'dBW'
|
|
51
|
+
| 'count'
|
|
52
|
+
| '/'
|
|
53
|
+
| '%RH'
|
|
54
|
+
| '%EL'
|
|
55
|
+
| 'EL'
|
|
56
|
+
| '1/s'
|
|
57
|
+
| 'S/m'
|
|
58
|
+
| 'B'
|
|
59
|
+
| 'VA'
|
|
60
|
+
| 'VAs'
|
|
61
|
+
| 'var'
|
|
62
|
+
| 'vars'
|
|
63
|
+
| 'J/m'
|
|
64
|
+
| 'kg/m3'
|
|
65
|
+
| 'deg'
|
|
66
|
+
| 'NTU'
|
|
67
|
+
| 'ms'
|
|
68
|
+
| 'min'
|
|
69
|
+
| 'h'
|
|
70
|
+
| 'MHz'
|
|
71
|
+
| 'kW'
|
|
72
|
+
| 'kVA'
|
|
73
|
+
| 'kvar'
|
|
74
|
+
| 'Ah'
|
|
75
|
+
| 'Wh'
|
|
76
|
+
| 'kWh'
|
|
77
|
+
| 'varh'
|
|
78
|
+
| 'kvarh'
|
|
79
|
+
| 'kVAh'
|
|
80
|
+
| 'Wh/km'
|
|
81
|
+
| 'KiB'
|
|
82
|
+
| 'GB'
|
|
83
|
+
| 'Mbit/s'
|
|
84
|
+
| 'B/s'
|
|
85
|
+
| 'MB/s'
|
|
86
|
+
| 'mV'
|
|
87
|
+
| 'mA'
|
|
88
|
+
| 'dBm'
|
|
89
|
+
| 'ug/m3'
|
|
90
|
+
| 'mm/h'
|
|
91
|
+
| 'm/h'
|
|
92
|
+
| 'ppm'
|
|
93
|
+
| '/100'
|
|
94
|
+
| '/1000'
|
|
95
|
+
| 'hPa'
|
|
96
|
+
| 'mm'
|
|
97
|
+
| 'cm'
|
|
98
|
+
| 'km'
|
|
99
|
+
| 'km/h'
|
|
100
|
+
| 'ppb'
|
|
101
|
+
| 'ppt'
|
|
102
|
+
| 'VAh'
|
|
103
|
+
| 'mg/l'
|
|
104
|
+
| 'ug/l'
|
|
105
|
+
| 'g/l'
|
|
106
|
+
| 'us'
|
|
107
|
+
| 'kHz'
|
|
108
|
+
| 'GHz'
|
|
109
|
+
| 'mW'
|
|
110
|
+
| 'uA'
|
|
111
|
+
| 'uV'
|
|
112
|
+
| 'mAh'
|
|
113
|
+
| 'MiB'
|
|
114
|
+
| 'kB'
|
|
115
|
+
| 'MB'
|
|
116
|
+
| 'kbit/s'
|
|
117
|
+
| 'KiB/s'
|
|
118
|
+
| 'kohm'
|
|
119
|
+
| 'Mohm'
|
|
120
|
+
| 'kPa'
|
|
121
|
+
| 'bar'
|
|
122
|
+
| 'Bd'
|
|
123
|
+
|
|
124
|
+
/* Display annotations, carried by every node a form can render. They never
|
|
125
|
+
* change what validates. Not on optional(): the wrapper expresses absence, the
|
|
126
|
+
* node it wraps expresses identity, so annotations go on the inner. */
|
|
127
|
+
interface Annotated {
|
|
128
|
+
readonly title?: string
|
|
129
|
+
readonly description?: string
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface StringSchema extends Annotated {
|
|
6
133
|
readonly kind: 'string'
|
|
7
134
|
readonly default?: string
|
|
135
|
+
readonly mask?: boolean
|
|
136
|
+
readonly minLength?: number
|
|
137
|
+
readonly maxLength?: number
|
|
138
|
+
readonly format?: Format
|
|
8
139
|
}
|
|
9
140
|
|
|
10
|
-
export interface NumberSchema {
|
|
141
|
+
export interface NumberSchema extends Annotated {
|
|
11
142
|
readonly kind: 'number'
|
|
12
143
|
readonly default?: number
|
|
144
|
+
readonly mask?: boolean
|
|
145
|
+
readonly min?: number
|
|
146
|
+
readonly max?: number
|
|
147
|
+
readonly integer?: boolean
|
|
148
|
+
readonly unit?: Unit
|
|
13
149
|
}
|
|
14
150
|
|
|
15
|
-
export interface BooleanSchema {
|
|
151
|
+
export interface BooleanSchema extends Annotated {
|
|
16
152
|
readonly kind: 'boolean'
|
|
17
153
|
readonly default?: boolean
|
|
18
154
|
}
|
|
@@ -21,19 +157,23 @@ export interface UnknownSchema {
|
|
|
21
157
|
readonly kind: 'unknown'
|
|
22
158
|
}
|
|
23
159
|
|
|
24
|
-
export interface LiteralSchema<T extends Primitive = Primitive> {
|
|
160
|
+
export interface LiteralSchema<T extends Primitive = Primitive> extends Annotated {
|
|
25
161
|
readonly kind: 'literal'
|
|
26
162
|
readonly value: T
|
|
27
163
|
readonly default?: T
|
|
28
164
|
}
|
|
29
165
|
|
|
30
|
-
export interface ArraySchema<S extends Schema = Schema> {
|
|
166
|
+
export interface ArraySchema<S extends Schema = Schema> extends Annotated {
|
|
31
167
|
readonly kind: 'array'
|
|
32
168
|
readonly element: S
|
|
33
169
|
readonly default?: unknown
|
|
170
|
+
readonly minItems?: number
|
|
171
|
+
readonly maxItems?: number
|
|
34
172
|
}
|
|
35
173
|
|
|
36
|
-
export interface ObjectSchema<
|
|
174
|
+
export interface ObjectSchema<
|
|
175
|
+
Shape extends Record<string, Schema> = Record<string, Schema>,
|
|
176
|
+
> extends Annotated {
|
|
37
177
|
readonly kind: 'object'
|
|
38
178
|
readonly shape: Shape
|
|
39
179
|
}
|
|
@@ -43,13 +183,17 @@ export interface OptionalSchema<S extends Schema = Schema> {
|
|
|
43
183
|
readonly inner: S
|
|
44
184
|
}
|
|
45
185
|
|
|
46
|
-
export interface TupleSchema<
|
|
186
|
+
export interface TupleSchema<
|
|
187
|
+
Elements extends readonly Schema[] = readonly Schema[],
|
|
188
|
+
> extends Annotated {
|
|
47
189
|
readonly kind: 'tuple'
|
|
48
190
|
readonly elements: Elements
|
|
49
191
|
readonly default?: unknown
|
|
50
192
|
}
|
|
51
193
|
|
|
52
|
-
export interface UnionSchema<
|
|
194
|
+
export interface UnionSchema<
|
|
195
|
+
Members extends readonly Schema[] = readonly Schema[],
|
|
196
|
+
> extends Annotated {
|
|
53
197
|
readonly kind: 'union'
|
|
54
198
|
readonly members: Members
|
|
55
199
|
readonly default?: unknown
|
|
@@ -58,7 +202,7 @@ export interface UnionSchema<Members extends readonly Schema[] = readonly Schema
|
|
|
58
202
|
export interface TaggedUnionSchema<
|
|
59
203
|
Key extends string = string,
|
|
60
204
|
Branches extends Record<string, ObjectSchema> = Record<string, ObjectSchema>,
|
|
61
|
-
> {
|
|
205
|
+
> extends Annotated {
|
|
62
206
|
readonly kind: 'taggedUnion'
|
|
63
207
|
readonly key: Key
|
|
64
208
|
readonly branches: Branches
|
|
@@ -162,22 +306,52 @@ type InferReadObject<Shape> = {
|
|
|
162
306
|
|
|
163
307
|
export type SchemaError = {name: 'ValidationFailed'; message: string; path: string}
|
|
164
308
|
|
|
165
|
-
export interface
|
|
309
|
+
export interface DisplayOptions {
|
|
310
|
+
readonly title?: string
|
|
311
|
+
readonly description?: string
|
|
312
|
+
}
|
|
313
|
+
export interface ScalarOptions<T> extends DisplayOptions {
|
|
166
314
|
readonly default?: T
|
|
167
315
|
}
|
|
168
|
-
export interface DefaultOption<T> {
|
|
316
|
+
export interface DefaultOption<T> extends DisplayOptions {
|
|
169
317
|
readonly default?: T
|
|
170
318
|
}
|
|
319
|
+
export interface MaskableOptions<T> extends ScalarOptions<T> {
|
|
320
|
+
readonly mask?: boolean
|
|
321
|
+
}
|
|
322
|
+
export interface StringOptions<T> extends MaskableOptions<T> {
|
|
323
|
+
readonly minLength?: number
|
|
324
|
+
readonly maxLength?: number
|
|
325
|
+
readonly format?: Format
|
|
326
|
+
}
|
|
327
|
+
export interface NumberOptions<T> extends MaskableOptions<T> {
|
|
328
|
+
readonly min?: number
|
|
329
|
+
readonly max?: number
|
|
330
|
+
readonly integer?: boolean
|
|
331
|
+
readonly unit?: Unit
|
|
332
|
+
}
|
|
333
|
+
export interface ArrayOptions<T> extends DefaultOption<T> {
|
|
334
|
+
readonly minItems?: number
|
|
335
|
+
readonly maxItems?: number
|
|
336
|
+
}
|
|
337
|
+
export interface EnumEntry<T extends Primitive> {
|
|
338
|
+
readonly value: T
|
|
339
|
+
readonly title?: string
|
|
340
|
+
readonly description?: string
|
|
341
|
+
}
|
|
342
|
+
type EnumMembers<Entries extends readonly EnumEntry<Primitive>[]> = {
|
|
343
|
+
[K in keyof Entries]: LiteralSchema<Entries[K]['value']>
|
|
344
|
+
}
|
|
171
345
|
|
|
172
346
|
/* Mirrors core.ts: the constructors record a `default` annotation in their
|
|
173
347
|
* return type, which is what lets InferRead see it. */
|
|
174
348
|
type Defaulted<S, D> = [D] extends [undefined] ? S : S & {readonly default: unknown}
|
|
175
349
|
|
|
176
350
|
export declare function string<D extends string | undefined = undefined>(
|
|
177
|
-
options?:
|
|
351
|
+
options?: StringOptions<D>,
|
|
178
352
|
): Defaulted<StringSchema, D>
|
|
179
353
|
export declare function number<D extends number | undefined = undefined>(
|
|
180
|
-
options?:
|
|
354
|
+
options?: NumberOptions<D>,
|
|
181
355
|
): Defaulted<NumberSchema, D>
|
|
182
356
|
export declare function boolean<D extends boolean | undefined = undefined>(
|
|
183
357
|
options?: ScalarOptions<D>,
|
|
@@ -190,7 +364,7 @@ export declare function literal<T extends Primitive, D extends T | undefined = u
|
|
|
190
364
|
export declare function array<
|
|
191
365
|
S extends Schema,
|
|
192
366
|
D extends NoInfer<Infer<S>>[] | undefined = undefined,
|
|
193
|
-
>(element: S, options?:
|
|
367
|
+
>(element: S, options?: ArrayOptions<D>): Defaulted<ArraySchema<S>, D>
|
|
194
368
|
export declare function object<Shape extends Record<string, Schema>>(
|
|
195
369
|
shape: Shape,
|
|
196
370
|
options?: DefaultOption<never>,
|
|
@@ -204,6 +378,10 @@ export declare function union<
|
|
|
204
378
|
Members extends readonly Schema[],
|
|
205
379
|
D extends NoInfer<Infer<UnionSchema<Members>>> | undefined = undefined,
|
|
206
380
|
>(members: [...Members], options?: DefaultOption<D>): Defaulted<UnionSchema<Members>, D>
|
|
381
|
+
export declare function enumOf<
|
|
382
|
+
const Entries extends readonly EnumEntry<Primitive>[],
|
|
383
|
+
D extends Entries[number]['value'] | undefined = undefined,
|
|
384
|
+
>(entries: Entries, options?: DefaultOption<D>): Defaulted<UnionSchema<EnumMembers<Entries>>, D>
|
|
207
385
|
export declare function taggedUnion<
|
|
208
386
|
Key extends string,
|
|
209
387
|
Branches extends Record<string, ObjectSchema>,
|
package/runtime/sys/types.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import type {Result} from '../result/types.js'
|
|
2
2
|
|
|
3
3
|
export interface MemoryUsage {
|
|
4
|
+
/** Bytes allocated from the JS heap. On device this counts real
|
|
5
|
+
* allocator block sizes (requested bytes rounded up to the heap's
|
|
6
|
+
* granularity), so it reflects what the heap actually spends; small
|
|
7
|
+
* run-to-run variation is normal. */
|
|
4
8
|
heapUsed: number
|
|
9
|
+
/** The JS heap's configured memory limit in bytes. */
|
|
5
10
|
heapTotal: number
|
|
6
11
|
/** Free system heap in bytes (0 on host) */
|
|
7
12
|
systemFree: number
|
|
@@ -87,6 +92,11 @@ export declare function gc(): void
|
|
|
87
92
|
/** Firmware version string (e.g. "0.1.0") */
|
|
88
93
|
export declare const version: string
|
|
89
94
|
|
|
95
|
+
/** Values {@link BoardInfo.features} can contain. `wifi`, `ble` and `bt` need
|
|
96
|
+
* both the silicon and the matching stack compiled into the firmware;
|
|
97
|
+
* `ieee802154` reports silicon alone. */
|
|
98
|
+
export type BoardFeature = 'wifi' | 'ble' | 'bt' | 'ieee802154'
|
|
99
|
+
|
|
90
100
|
export interface BoardInfo {
|
|
91
101
|
/** Board name from the firmware build (e.g. "xiao-esp32c6") or "generic" */
|
|
92
102
|
name: string
|
|
@@ -97,7 +107,7 @@ export interface BoardInfo {
|
|
|
97
107
|
/** Silicon revision (major * 100 + minor on ESP32, 0 on host) */
|
|
98
108
|
revision: number
|
|
99
109
|
/** Supported features (e.g. ["wifi", "ble"]) */
|
|
100
|
-
features:
|
|
110
|
+
features: BoardFeature[]
|
|
101
111
|
/** Flash size in bytes (0 on host) */
|
|
102
112
|
flash: number
|
|
103
113
|
/** PSRAM size in bytes (0 if unavailable) */
|
package/src/mem.cpp
CHANGED
|
@@ -9,15 +9,56 @@
|
|
|
9
9
|
|
|
10
10
|
/*
|
|
11
11
|
* QuickJS uses malloc_usable_size to track memory consumption against its
|
|
12
|
-
* memory limit.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* memory limit. When the platform reports live-allocation sizes
|
|
13
|
+
* (malloc_usable_size hook: libc malloc_usable_size / malloc_size,
|
|
14
|
+
* heap_caps_get_allocated_size on ESP-IDF), allocations are returned as-is
|
|
15
|
+
* and QuickJS accounts blocks by their real (rounded-up) size.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
+
* Without the hook, each allocation is prepended with a size_t header
|
|
18
|
+
* storing the requested size. That costs one word of RAM per live block —
|
|
19
|
+
* ~13 KB across a loaded app's ~3400 blocks on a 32-bit device — which is
|
|
20
|
+
* why the hook path is preferred.
|
|
21
|
+
*
|
|
22
|
+
* The mode is latched at the first allocation and never changes, so every
|
|
23
|
+
* pointer is freed the same way it was allocated. Platforms install before
|
|
24
|
+
* the first runtime exists (ESP32 and node have theirs as the compile-time
|
|
25
|
+
* default), so the latch sees the final platform. The latch is a single
|
|
26
|
+
* word-sized store (null = unlatched, mik__hdr_usable_size = header mode),
|
|
27
|
+
* so concurrent first allocations on a dual-core target can at worst both
|
|
28
|
+
* compute and store the same value — there is no two-variable ordering to
|
|
29
|
+
* observe half-done.
|
|
17
30
|
*/
|
|
18
31
|
|
|
19
32
|
#define HDR_SIZE sizeof(size_t)
|
|
20
33
|
|
|
34
|
+
static inline size_t hdr_read(void* user) {
|
|
35
|
+
size_t sz;
|
|
36
|
+
memcpy(&sz, static_cast<char*>(user) - HDR_SIZE, sizeof(sz));
|
|
37
|
+
return sz;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Header-mode usable_size; doubles as the latch marker for that mode. */
|
|
41
|
+
static size_t mik__hdr_usable_size(const void* ptr) {
|
|
42
|
+
return hdr_read(const_cast<void*>(ptr));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
typedef size_t (*MIKUsableSizeFn)(const void*);
|
|
46
|
+
static MIKUsableSizeFn g_usable_size_fn = nullptr; /* null = not latched yet */
|
|
47
|
+
|
|
48
|
+
static inline MIKUsableSizeFn usable_size_fn(void) {
|
|
49
|
+
MIKUsableSizeFn fn = g_usable_size_fn;
|
|
50
|
+
if (!fn) {
|
|
51
|
+
const MIKPlatform* p = MIK_GetPlatform();
|
|
52
|
+
fn = (p && p->malloc_usable_size) ? p->malloc_usable_size : mik__hdr_usable_size;
|
|
53
|
+
g_usable_size_fn = fn;
|
|
54
|
+
}
|
|
55
|
+
return fn;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static inline size_t hdr_size(void) {
|
|
59
|
+
return usable_size_fn() == mik__hdr_usable_size ? HDR_SIZE : 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
21
62
|
/* Fault injection for the host OOM tests: fail the JS-heap allocators after
|
|
22
63
|
* a countdown, and keep a net live-allocation counter across every allocator
|
|
23
64
|
* here (all of them free through mik__free, so one counter balances). */
|
|
@@ -39,6 +80,11 @@ static bool oom_inject_should_fail(void) {
|
|
|
39
80
|
g_oom_countdown--;
|
|
40
81
|
return false;
|
|
41
82
|
}
|
|
83
|
+
|
|
84
|
+
void mik__usable_size_latch_override(size_t (*fn)(const void*)) {
|
|
85
|
+
g_usable_size_fn = fn ? fn : mik__hdr_usable_size;
|
|
86
|
+
}
|
|
87
|
+
|
|
42
88
|
#define OOM_INJECT_FAIL() oom_inject_should_fail()
|
|
43
89
|
#define LIVE_ALLOCS_ADD(d) (g_live_allocs += (d))
|
|
44
90
|
#else
|
|
@@ -46,27 +92,22 @@ static bool oom_inject_should_fail(void) {
|
|
|
46
92
|
#define LIVE_ALLOCS_ADD(d) ((void)0)
|
|
47
93
|
#endif
|
|
48
94
|
|
|
49
|
-
static inline
|
|
50
|
-
|
|
51
|
-
memcpy(&sz, static_cast<char*>(user) - HDR_SIZE, sizeof(sz));
|
|
52
|
-
return sz;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
static inline void hdr_write(void* raw, size_t sz) {
|
|
56
|
-
memcpy(raw, &sz, sizeof(sz));
|
|
95
|
+
static inline void hdr_write(void* raw, size_t size, size_t hdr) {
|
|
96
|
+
if (hdr) memcpy(raw, &size, sizeof(size));
|
|
57
97
|
}
|
|
58
98
|
|
|
59
99
|
size_t mik__malloc_usable_size(const void* ptr) {
|
|
60
100
|
if (!ptr) return 0;
|
|
61
|
-
return
|
|
101
|
+
return usable_size_fn()(ptr);
|
|
62
102
|
}
|
|
63
103
|
|
|
64
104
|
void* mik__malloc(size_t size) {
|
|
65
|
-
|
|
105
|
+
size_t hdr = hdr_size();
|
|
106
|
+
void* raw = malloc(size + hdr);
|
|
66
107
|
if (!raw) return nullptr;
|
|
67
|
-
hdr_write(raw, size);
|
|
108
|
+
hdr_write(raw, size, hdr);
|
|
68
109
|
LIVE_ALLOCS_ADD(1);
|
|
69
|
-
return static_cast<char*>(raw) +
|
|
110
|
+
return static_cast<char*>(raw) + hdr;
|
|
70
111
|
}
|
|
71
112
|
|
|
72
113
|
void* mik__mallocz(size_t size) { return mik__calloc(1, size); }
|
|
@@ -74,26 +115,28 @@ void* mik__mallocz(size_t size) { return mik__calloc(1, size); }
|
|
|
74
115
|
void* mik__calloc(size_t count, size_t size) {
|
|
75
116
|
if (size && count > SIZE_MAX / size) return nullptr;
|
|
76
117
|
size_t total = count * size;
|
|
77
|
-
|
|
118
|
+
size_t hdr = hdr_size();
|
|
119
|
+
void* raw = calloc(1, total + hdr);
|
|
78
120
|
if (!raw) return nullptr;
|
|
79
|
-
hdr_write(raw, total);
|
|
121
|
+
hdr_write(raw, total, hdr);
|
|
80
122
|
LIVE_ALLOCS_ADD(1);
|
|
81
|
-
return static_cast<char*>(raw) +
|
|
123
|
+
return static_cast<char*>(raw) + hdr;
|
|
82
124
|
}
|
|
83
125
|
|
|
84
126
|
void mik__free(void* ptr) {
|
|
85
127
|
if (!ptr) return;
|
|
86
128
|
LIVE_ALLOCS_ADD(-1);
|
|
87
|
-
free(static_cast<char*>(ptr) -
|
|
129
|
+
free(static_cast<char*>(ptr) - hdr_size());
|
|
88
130
|
}
|
|
89
131
|
|
|
90
132
|
void* mik__realloc(void* ptr, size_t size) {
|
|
91
|
-
|
|
92
|
-
raw =
|
|
133
|
+
size_t hdr = hdr_size();
|
|
134
|
+
void* raw = ptr ? static_cast<char*>(ptr) - hdr : nullptr;
|
|
135
|
+
raw = realloc(raw, size + hdr);
|
|
93
136
|
if (!raw) return nullptr;
|
|
94
|
-
hdr_write(raw, size);
|
|
137
|
+
hdr_write(raw, size, hdr);
|
|
95
138
|
if (!ptr) LIVE_ALLOCS_ADD(1);
|
|
96
|
-
return static_cast<char*>(raw) +
|
|
139
|
+
return static_cast<char*>(raw) + hdr;
|
|
97
140
|
}
|
|
98
141
|
|
|
99
142
|
/* QuickJS-heap allocator. When the PSRAM flag is set, route through the
|
|
@@ -115,51 +158,54 @@ bool mik__is_quickjs_heap_psram(void) {
|
|
|
115
158
|
|
|
116
159
|
void* mik__js_malloc(size_t size) {
|
|
117
160
|
if (OOM_INJECT_FAIL()) return nullptr;
|
|
161
|
+
size_t hdr = hdr_size();
|
|
118
162
|
void* raw = nullptr;
|
|
119
163
|
if (g_quickjs_heap_psram) {
|
|
120
164
|
const MIKPlatform* p = MIK_GetPlatform();
|
|
121
165
|
if (p && p->malloc_psram) {
|
|
122
|
-
raw = p->malloc_psram(size +
|
|
166
|
+
raw = p->malloc_psram(size + hdr);
|
|
123
167
|
}
|
|
124
168
|
}
|
|
125
|
-
if (!raw) raw = malloc(size +
|
|
169
|
+
if (!raw) raw = malloc(size + hdr);
|
|
126
170
|
if (!raw) return nullptr;
|
|
127
|
-
hdr_write(raw, size);
|
|
171
|
+
hdr_write(raw, size, hdr);
|
|
128
172
|
LIVE_ALLOCS_ADD(1);
|
|
129
|
-
return static_cast<char*>(raw) +
|
|
173
|
+
return static_cast<char*>(raw) + hdr;
|
|
130
174
|
}
|
|
131
175
|
|
|
132
176
|
void* mik__js_calloc(size_t count, size_t size) {
|
|
133
177
|
if (OOM_INJECT_FAIL()) return nullptr;
|
|
134
178
|
if (size && count > SIZE_MAX / size) return nullptr;
|
|
135
179
|
size_t total = count * size;
|
|
180
|
+
size_t hdr = hdr_size();
|
|
136
181
|
void* raw = nullptr;
|
|
137
182
|
if (g_quickjs_heap_psram) {
|
|
138
183
|
const MIKPlatform* p = MIK_GetPlatform();
|
|
139
184
|
if (p && p->calloc_psram) {
|
|
140
|
-
raw = p->calloc_psram(1, total +
|
|
185
|
+
raw = p->calloc_psram(1, total + hdr);
|
|
141
186
|
}
|
|
142
187
|
}
|
|
143
|
-
if (!raw) raw = calloc(1, total +
|
|
188
|
+
if (!raw) raw = calloc(1, total + hdr);
|
|
144
189
|
if (!raw) return nullptr;
|
|
145
|
-
hdr_write(raw, total);
|
|
190
|
+
hdr_write(raw, total, hdr);
|
|
146
191
|
LIVE_ALLOCS_ADD(1);
|
|
147
|
-
return static_cast<char*>(raw) +
|
|
192
|
+
return static_cast<char*>(raw) + hdr;
|
|
148
193
|
}
|
|
149
194
|
|
|
150
195
|
void* mik__js_realloc(void* ptr, size_t size) {
|
|
151
196
|
if (OOM_INJECT_FAIL()) return nullptr;
|
|
152
|
-
|
|
197
|
+
size_t hdr = hdr_size();
|
|
198
|
+
void* raw = ptr ? static_cast<char*>(ptr) - hdr : nullptr;
|
|
153
199
|
void* new_raw = nullptr;
|
|
154
200
|
if (g_quickjs_heap_psram) {
|
|
155
201
|
const MIKPlatform* p = MIK_GetPlatform();
|
|
156
202
|
if (p && p->realloc_psram) {
|
|
157
|
-
new_raw = p->realloc_psram(raw, size +
|
|
203
|
+
new_raw = p->realloc_psram(raw, size + hdr);
|
|
158
204
|
}
|
|
159
205
|
}
|
|
160
|
-
if (!new_raw) new_raw = realloc(raw, size +
|
|
206
|
+
if (!new_raw) new_raw = realloc(raw, size + hdr);
|
|
161
207
|
if (!new_raw) return nullptr;
|
|
162
|
-
hdr_write(new_raw, size);
|
|
208
|
+
hdr_write(new_raw, size, hdr);
|
|
163
209
|
if (!ptr) LIVE_ALLOCS_ADD(1);
|
|
164
|
-
return static_cast<char*>(new_raw) +
|
|
210
|
+
return static_cast<char*>(new_raw) + hdr;
|
|
165
211
|
}
|
package/src/mik_ota_client.cpp
CHANGED
|
@@ -384,10 +384,9 @@ void MIKOtaClient::Check(const MIKOtaCheckOptions& options, MIKOtaCheckSink sink
|
|
|
384
384
|
* config — the floor is what bounds the damage a mistyped document can do. */
|
|
385
385
|
constexpr uint32_t kMinCheckinIntervalMs = 30000;
|
|
386
386
|
|
|
387
|
-
|
|
387
|
+
bool MIKOtaClient::Watch(const MIKOtaWatchOptions& options) {
|
|
388
388
|
if (!Enrollment(&watch_registry_url_, &watch_bearer_)) {
|
|
389
|
-
|
|
390
|
-
return;
|
|
389
|
+
return false;
|
|
391
390
|
}
|
|
392
391
|
watch_options_ = options;
|
|
393
392
|
if (watch_options_.checkin_interval_ms < kMinCheckinIntervalMs) {
|
|
@@ -402,6 +401,7 @@ void MIKOtaClient::Watch(const MIKOtaWatchOptions& options) {
|
|
|
402
401
|
wait_started_ms_ = Now();
|
|
403
402
|
deadline_ms_ = wait_started_ms_ + scheduled_delay_ms_;
|
|
404
403
|
pending_wait_ = PendingWait::kInitial;
|
|
404
|
+
return true;
|
|
405
405
|
}
|
|
406
406
|
|
|
407
407
|
void MIKOtaClient::SetCheckinInterval(uint32_t interval_ms) {
|
package/src/mik_sys.cpp
CHANGED
|
@@ -187,15 +187,23 @@ static JSValue mik__sys_board(JSContext* ctx) {
|
|
|
187
187
|
JS_SetPropertyStr(ctx, obj, "cores", JS_NewInt32(ctx, chip_info.cores));
|
|
188
188
|
JS_SetPropertyStr(ctx, obj, "revision", JS_NewInt32(ctx, chip_info.revision));
|
|
189
189
|
|
|
190
|
-
/* Features as string array
|
|
190
|
+
/* Features as string array. Callers use this to decide whether an
|
|
191
|
+
* optional module will work, so a radio only counts when the silicon
|
|
192
|
+
* has it AND the stack behind it was compiled in. */
|
|
191
193
|
JSValue features = JS_NewArray(ctx);
|
|
192
194
|
uint32_t fi = 0;
|
|
195
|
+
#ifdef CONFIG_ESP_WIFI_ENABLED
|
|
193
196
|
if (chip_info.features & CHIP_FEATURE_WIFI_BGN)
|
|
194
197
|
JS_SetPropertyUint32(ctx, features, fi++, JS_NewString(ctx, "wifi"));
|
|
198
|
+
#endif
|
|
199
|
+
#ifdef CONFIG_BT_ENABLED
|
|
195
200
|
if (chip_info.features & CHIP_FEATURE_BLE)
|
|
196
201
|
JS_SetPropertyUint32(ctx, features, fi++, JS_NewString(ctx, "ble"));
|
|
197
202
|
if (chip_info.features & CHIP_FEATURE_BT)
|
|
198
203
|
JS_SetPropertyUint32(ctx, features, fi++, JS_NewString(ctx, "bt"));
|
|
204
|
+
#endif
|
|
205
|
+
/* No stack to gate on: mikrojs has no 802.15.4 API, so this stays a
|
|
206
|
+
* plain silicon report. */
|
|
199
207
|
if (chip_info.features & CHIP_FEATURE_IEEE802154)
|
|
200
208
|
JS_SetPropertyUint32(ctx, features, fi++, JS_NewString(ctx, "ieee802154"));
|
|
201
209
|
JS_SetPropertyStr(ctx, obj, "features", features);
|