@mikrojs/native 0.6.0-pr-70.g7bdc6dd → 0.6.0-pr-70.gd2fdc0d
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/include/mikrojs/mem.h +17 -0
- package/include/mikrojs/mikrojs.h +11 -0
- package/include/mikrojs/platform.h +27 -1
- package/package.json +2 -2
- 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 +29 -12
- package/runtime/sys/types.ts +14 -1
- package/runtime/wifi/wifi.ts +35 -21
- package/src/mem.cpp +64 -0
- package/src/mik_sys.cpp +4 -0
- package/src/mikrojs.cpp +17 -5
- package/src/platform_posix.cpp +30 -0
package/include/mikrojs/mem.h
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include <stdbool.h>
|
|
3
4
|
#include <stddef.h>
|
|
4
5
|
#include <stdlib.h>
|
|
5
6
|
|
|
@@ -9,3 +10,19 @@ void* mik__mallocz(size_t size);
|
|
|
9
10
|
void* mik__calloc(size_t count, size_t size);
|
|
10
11
|
void mik__free(void* ptr);
|
|
11
12
|
void* mik__realloc(void* ptr, size_t size);
|
|
13
|
+
|
|
14
|
+
/* QuickJS-heap allocators. Backed by libc malloc by default; routed to
|
|
15
|
+
* PSRAM via the platform's malloc_psram/calloc_psram/realloc_psram hooks
|
|
16
|
+
* when mik__set_quickjs_heap_psram(true) has been called and the platform
|
|
17
|
+
* supports PSRAM. Free is unchanged: PSRAM pointers from heap_caps_malloc
|
|
18
|
+
* free cleanly via standard free() on ESP-IDF. */
|
|
19
|
+
void* mik__js_malloc(size_t size);
|
|
20
|
+
void* mik__js_calloc(size_t count, size_t size);
|
|
21
|
+
void* mik__js_realloc(void* ptr, size_t size);
|
|
22
|
+
|
|
23
|
+
/* Toggle QuickJS heap allocations to PSRAM (no-op on platforms without
|
|
24
|
+
* PSRAM). Set once before JS_NewRuntime2; do not change mid-run since
|
|
25
|
+
* mik__js_realloc relies on the flag staying consistent with the heap
|
|
26
|
+
* the original pointer came from. */
|
|
27
|
+
void mik__set_quickjs_heap_psram(bool enable);
|
|
28
|
+
bool mik__is_quickjs_heap_psram(void);
|
|
@@ -10,6 +10,17 @@ typedef struct MIKRuntime MIKRuntime;
|
|
|
10
10
|
typedef struct MIKRunOptions {
|
|
11
11
|
int mem_limit;
|
|
12
12
|
size_t stack_size;
|
|
13
|
+
/* Allocate the QuickJS heap from PSRAM instead of internal SRAM on
|
|
14
|
+
* chips with both. Frees ~150-250 KB of contiguous internal SRAM for
|
|
15
|
+
* mbedTLS, WiFi/BLE, and DMA buffers, the dominant root cause of
|
|
16
|
+
* HTTPS handshake failures (error 0x7002) on apps with significant
|
|
17
|
+
* retained JS state. JS execution is somewhat slower (PSRAM has
|
|
18
|
+
* higher access latency than internal SRAM); for typical embedded
|
|
19
|
+
* IO-bound workloads this is invisible against networking and IO
|
|
20
|
+
* costs. No effect on hosts and chips without PSRAM. Defaults false
|
|
21
|
+
* for backward compatibility; the firmware bootstrap flips it on
|
|
22
|
+
* when CONFIG_MIKROJS_QUICKJS_HEAP_PSRAM is set. */
|
|
23
|
+
bool use_psram_heap;
|
|
13
24
|
} MIKRunOptions;
|
|
14
25
|
|
|
15
26
|
typedef struct MIKConfig {
|
|
@@ -18,11 +18,37 @@ typedef struct MIKPlatform {
|
|
|
18
18
|
size_t (*get_free_system_mem)(void);
|
|
19
19
|
size_t (*get_min_free_system_mem)(void); /* All-time low watermark */
|
|
20
20
|
size_t (*get_total_system_mem)(void);
|
|
21
|
-
/** Largest contiguous free block (for diagnosing heap fragmentation
|
|
21
|
+
/** Largest contiguous free block (for diagnosing heap fragmentation:
|
|
22
22
|
* an allocation larger than this fails even if total free is bigger).
|
|
23
23
|
* On platforms without a native largest-block API, implementations
|
|
24
24
|
* may return the same value as get_free_system_mem. */
|
|
25
25
|
size_t (*get_largest_free_system_mem)(void);
|
|
26
|
+
/** Free internal-SRAM bytes. On chips with PSRAM this is the subset of
|
|
27
|
+
* free heap that lives in fast on-chip RAM, which is also what mbedTLS
|
|
28
|
+
* handshake buffers, WiFi/BLE drivers, and DMA-capable buffers compete
|
|
29
|
+
* for. Distinct from get_free_system_mem on PSRAM-equipped chips, where
|
|
30
|
+
* combined heap is dominated by PSRAM and hides internal-SRAM pressure.
|
|
31
|
+
* On hosts and chips without PSRAM, may return the same value as
|
|
32
|
+
* get_free_system_mem (or 0 if unavailable). */
|
|
33
|
+
size_t (*get_free_internal_mem)(void);
|
|
34
|
+
/** Largest contiguous free block in internal SRAM. Allocations that
|
|
35
|
+
* must land in internal RAM (such as mbedTLS record buffers) fail when
|
|
36
|
+
* this drops below their size, even when get_largest_free_system_mem
|
|
37
|
+
* reports plenty of contiguous PSRAM. Same fallback rules as
|
|
38
|
+
* get_free_internal_mem. */
|
|
39
|
+
size_t (*get_largest_free_internal_mem)(void);
|
|
40
|
+
/** Allocate `size` bytes from PSRAM/external RAM. Returns NULL if
|
|
41
|
+
* PSRAM is unavailable (host platforms, chips without PSRAM, or
|
|
42
|
+
* PSRAM exhaustion); the caller falls back to the regular allocator.
|
|
43
|
+
* On ESP32 with CONFIG_SPIRAM=y, implemented via heap_caps_malloc
|
|
44
|
+
* with MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT. The returned pointer is
|
|
45
|
+
* freed via standard free(). */
|
|
46
|
+
void* (*malloc_psram)(size_t size);
|
|
47
|
+
/** PSRAM-targeted calloc. Same fallback rules as malloc_psram. */
|
|
48
|
+
void* (*calloc_psram)(size_t count, size_t size);
|
|
49
|
+
/** PSRAM-targeted realloc. Grows or moves the allocation while keeping
|
|
50
|
+
* it in PSRAM. Same fallback rules as malloc_psram. */
|
|
51
|
+
void* (*realloc_psram)(void* ptr, size_t size);
|
|
26
52
|
bool (*get_fs_info)(const char* label, size_t* total, size_t* used);
|
|
27
53
|
void (*log)(int level, const char* tag, const char* fmt, ...);
|
|
28
54
|
int (*stdout_write)(const void* buf, size_t len);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikrojs/native",
|
|
3
|
-
"version": "0.6.0-pr-70.
|
|
3
|
+
"version": "0.6.0-pr-70.gd2fdc0d",
|
|
4
4
|
"description": "Mikro.js C++ runtime library and Node.js native addon",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"esp32",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"cmake-js": "^8.0.0",
|
|
79
79
|
"node-addon-api": "^8.7.0",
|
|
80
80
|
"node-gyp-build": "^4.8.4",
|
|
81
|
-
"@mikrojs/quickjs": "0.6.0-pr-70.
|
|
81
|
+
"@mikrojs/quickjs": "0.6.0-pr-70.gd2fdc0d"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
84
|
"@swc/core": "^1.15.30",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/runtime/ble/ble.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {Observable} from 'mikrojs/observable'
|
|
|
2
2
|
import {err, ok} from 'mikrojs/result'
|
|
3
3
|
import {Ble as NativeBle} from 'native:ble'
|
|
4
4
|
|
|
5
|
+
import type {Subscriber} from '../observable/types.js'
|
|
5
6
|
import type {Result} from '../result/types.js'
|
|
6
7
|
import type {
|
|
7
8
|
AdvertiseHandle,
|
|
@@ -142,15 +143,31 @@ function normalizeServices(services: Service[]) {
|
|
|
142
143
|
|
|
143
144
|
const native = new NativeBle()
|
|
144
145
|
|
|
145
|
-
/*
|
|
146
|
-
*
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
146
|
+
/* Lazy-attach: native.on runs only after the first JS subscriber and is
|
|
147
|
+
* removed when the last one leaves. Same pattern as wifi.ts; see the note
|
|
148
|
+
* there for the mbedTLS internal-RAM rationale. */
|
|
149
|
+
function lazyEvent<T>(eventName: string): Observable<T> {
|
|
150
|
+
const subscribers: Subscriber<T>[] = []
|
|
151
|
+
function handler(value: unknown): void {
|
|
152
|
+
const snapshot = subscribers.slice()
|
|
153
|
+
for (const s of snapshot) {
|
|
154
|
+
if (!s.closed) s.next(value as T)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return new Observable<T>((sub) => {
|
|
158
|
+
subscribers.push(sub)
|
|
159
|
+
if (subscribers.length === 1) {
|
|
160
|
+
native.on(eventName, handler)
|
|
161
|
+
}
|
|
162
|
+
sub.addTeardown(() => {
|
|
163
|
+
const i = subscribers.indexOf(sub)
|
|
164
|
+
if (i >= 0) subscribers.splice(i, 1)
|
|
165
|
+
if (subscribers.length === 0) {
|
|
166
|
+
native.off(eventName, handler)
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
}
|
|
154
171
|
|
|
155
172
|
const ble: Ble = {
|
|
156
173
|
get name(): string {
|
|
@@ -231,9 +248,9 @@ const peripheral: Peripheral = {
|
|
|
231
248
|
return ok(handle)
|
|
232
249
|
},
|
|
233
250
|
|
|
234
|
-
onConnect:
|
|
235
|
-
onDisconnect:
|
|
236
|
-
onMtu:
|
|
251
|
+
onConnect: lazyEvent<ConnectionInfo>('connect'),
|
|
252
|
+
onDisconnect: lazyEvent<ConnectionInfo>('disconnect'),
|
|
253
|
+
onMtu: lazyEvent<MtuInfo>('mtu'),
|
|
237
254
|
}
|
|
238
255
|
|
|
239
256
|
export {ble, peripheral}
|
package/runtime/sys/types.ts
CHANGED
|
@@ -10,10 +10,23 @@ export interface MemoryUsage {
|
|
|
10
10
|
/** Total system heap in bytes (0 on host) */
|
|
11
11
|
systemTotal: number
|
|
12
12
|
/** Largest contiguous free block in bytes (0 on host). Allocations
|
|
13
|
-
* larger than this fail even when `systemFree` is bigger
|
|
13
|
+
* larger than this fail even when `systemFree` is bigger; the gap
|
|
14
14
|
* between `systemLargestFree` and `systemFree` measures heap
|
|
15
15
|
* fragmentation. */
|
|
16
16
|
systemLargestFree: number
|
|
17
|
+
/** Free internal-SRAM bytes (0 on host). On chips with PSRAM this is
|
|
18
|
+
* the subset of free heap that lives in fast on-chip RAM, which
|
|
19
|
+
* also holds mbedTLS handshake buffers, WiFi/BLE driver state, and
|
|
20
|
+
* DMA-capable buffers. On PSRAM-equipped chips `systemFree` is
|
|
21
|
+
* dominated by PSRAM and can hide internal-SRAM pressure: watch
|
|
22
|
+
* `internalFree` instead when diagnosing TLS handshake or driver
|
|
23
|
+
* allocation failures. On chips without PSRAM, equals `systemFree`. */
|
|
24
|
+
internalFree: number
|
|
25
|
+
/** Largest contiguous free block in internal SRAM (0 on host).
|
|
26
|
+
* Allocations that must land in internal RAM (such as mbedTLS record
|
|
27
|
+
* buffers, ~16 KB each) fail when this drops below their size, even
|
|
28
|
+
* when `systemLargestFree` reports plenty of contiguous PSRAM. */
|
|
29
|
+
internalLargestFree: number
|
|
17
30
|
}
|
|
18
31
|
|
|
19
32
|
export interface Uptime {
|
package/runtime/wifi/wifi.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {Observable} from 'mikrojs/observable'
|
|
|
2
2
|
import {err, ok} from 'mikrojs/result'
|
|
3
3
|
import {Wifi as NativeWifi} from 'native:wifi'
|
|
4
4
|
|
|
5
|
+
import type {Subscriber} from '../observable/types.js'
|
|
5
6
|
import type {Result} from '../result/types.js'
|
|
6
7
|
import type {
|
|
7
8
|
ApStartOptions,
|
|
@@ -37,22 +38,35 @@ const StatusFromCode = new Map<number, WifiStatus>(
|
|
|
37
38
|
|
|
38
39
|
const native = new NativeWifi()
|
|
39
40
|
|
|
40
|
-
/*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
/* Lazy-attach Observable: native.on is only called once a JS subscriber
|
|
42
|
+
* appears, and native.off runs when the last one unsubscribes. Code paths
|
|
43
|
+
* that import wifi but don't subscribe (e.g. a fetch-only flow) take the
|
|
44
|
+
* exact same internal-RAM path as before observables existed — important
|
|
45
|
+
* because mbedTLS handshake needs ~16 KB contiguous internal SRAM and
|
|
46
|
+
* each eager closure pinned at module load chips into that headroom. */
|
|
47
|
+
function lazyEvent<T>(eventName: string): Observable<T> {
|
|
48
|
+
const subscribers: Subscriber<T>[] = []
|
|
49
|
+
function handler(value: unknown): void {
|
|
50
|
+
/* Snapshot so unsubscribes during dispatch don't shift indices. */
|
|
51
|
+
const snapshot = subscribers.slice()
|
|
52
|
+
for (const s of snapshot) {
|
|
53
|
+
if (!s.closed) s.next(value as T)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return new Observable<T>((sub) => {
|
|
57
|
+
subscribers.push(sub)
|
|
58
|
+
if (subscribers.length === 1) {
|
|
59
|
+
native.on(eventName, handler)
|
|
60
|
+
}
|
|
61
|
+
sub.addTeardown(() => {
|
|
62
|
+
const i = subscribers.indexOf(sub)
|
|
63
|
+
if (i >= 0) subscribers.splice(i, 1)
|
|
64
|
+
if (subscribers.length === 0) {
|
|
65
|
+
native.off(eventName, handler)
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
}
|
|
56
70
|
|
|
57
71
|
const ap: WifiAp = {
|
|
58
72
|
start(options: ApStartOptions): Result<void, WifiError> {
|
|
@@ -88,8 +102,8 @@ const ap: WifiAp = {
|
|
|
88
102
|
native.apSetInactiveTimeout(seconds)
|
|
89
103
|
},
|
|
90
104
|
|
|
91
|
-
onStationConnect:
|
|
92
|
-
onStationDisconnect:
|
|
105
|
+
onStationConnect: lazyEvent<ApStationInfo>('station-connect'),
|
|
106
|
+
onStationDisconnect: lazyEvent<ApStationInfo>('station-disconnect'),
|
|
93
107
|
}
|
|
94
108
|
|
|
95
109
|
const MAX_CONNECT_RETRIES = 5
|
|
@@ -147,9 +161,9 @@ const wifi: Wifi = {
|
|
|
147
161
|
return ok(asyncResult.value as ScanResult[])
|
|
148
162
|
},
|
|
149
163
|
|
|
150
|
-
onConnect:
|
|
151
|
-
onDisconnect:
|
|
152
|
-
onRssiLow:
|
|
164
|
+
onConnect: lazyEvent<WifiConnectionInfo>('connect'),
|
|
165
|
+
onDisconnect: lazyEvent<WifiDisconnectReason>('disconnect'),
|
|
166
|
+
onRssiLow: lazyEvent<number>('rssi-low'),
|
|
153
167
|
|
|
154
168
|
get mac(): string {
|
|
155
169
|
const result = native.mac()
|
package/src/mem.cpp
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
#include <stdlib.h>
|
|
6
6
|
#include <string.h>
|
|
7
7
|
|
|
8
|
+
#include "mikrojs/platform.h"
|
|
9
|
+
|
|
8
10
|
/*
|
|
9
11
|
* QuickJS uses malloc_usable_size to track memory consumption against its
|
|
10
12
|
* memory limit. ESP-IDF lacks a standard malloc_usable_size, and the
|
|
@@ -61,3 +63,65 @@ void* mik__realloc(void* ptr, size_t size) {
|
|
|
61
63
|
hdr_write(raw, size);
|
|
62
64
|
return static_cast<char*>(raw) + HDR_SIZE;
|
|
63
65
|
}
|
|
66
|
+
|
|
67
|
+
/* QuickJS-heap allocator. When the PSRAM flag is set, route through the
|
|
68
|
+
* platform's malloc_psram first; if the platform can't satisfy the request
|
|
69
|
+
* (no PSRAM, or PSRAM exhausted), fall back to libc malloc so the runtime
|
|
70
|
+
* keeps working. The fallback only matters on host builds and in PSRAM-OOM
|
|
71
|
+
* edge cases. Under normal ESP32 operation with CONFIG_SPIRAM=y, every
|
|
72
|
+
* allocation lands in PSRAM. */
|
|
73
|
+
|
|
74
|
+
static bool g_quickjs_heap_psram = false;
|
|
75
|
+
|
|
76
|
+
void mik__set_quickjs_heap_psram(bool enable) {
|
|
77
|
+
g_quickjs_heap_psram = enable;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
bool mik__is_quickjs_heap_psram(void) {
|
|
81
|
+
return g_quickjs_heap_psram;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
void* mik__js_malloc(size_t size) {
|
|
85
|
+
void* raw = nullptr;
|
|
86
|
+
if (g_quickjs_heap_psram) {
|
|
87
|
+
const MIKPlatform* p = MIK_GetPlatform();
|
|
88
|
+
if (p && p->malloc_psram) {
|
|
89
|
+
raw = p->malloc_psram(size + HDR_SIZE);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!raw) raw = malloc(size + HDR_SIZE);
|
|
93
|
+
if (!raw) return nullptr;
|
|
94
|
+
hdr_write(raw, size);
|
|
95
|
+
return static_cast<char*>(raw) + HDR_SIZE;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
void* mik__js_calloc(size_t count, size_t size) {
|
|
99
|
+
if (size && count > SIZE_MAX / size) return nullptr;
|
|
100
|
+
size_t total = count * size;
|
|
101
|
+
void* raw = nullptr;
|
|
102
|
+
if (g_quickjs_heap_psram) {
|
|
103
|
+
const MIKPlatform* p = MIK_GetPlatform();
|
|
104
|
+
if (p && p->calloc_psram) {
|
|
105
|
+
raw = p->calloc_psram(1, total + HDR_SIZE);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (!raw) raw = calloc(1, total + HDR_SIZE);
|
|
109
|
+
if (!raw) return nullptr;
|
|
110
|
+
hdr_write(raw, total);
|
|
111
|
+
return static_cast<char*>(raw) + HDR_SIZE;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
void* mik__js_realloc(void* ptr, size_t size) {
|
|
115
|
+
void* raw = ptr ? static_cast<char*>(ptr) - HDR_SIZE : nullptr;
|
|
116
|
+
void* new_raw = nullptr;
|
|
117
|
+
if (g_quickjs_heap_psram) {
|
|
118
|
+
const MIKPlatform* p = MIK_GetPlatform();
|
|
119
|
+
if (p && p->realloc_psram) {
|
|
120
|
+
new_raw = p->realloc_psram(raw, size + HDR_SIZE);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (!new_raw) new_raw = realloc(raw, size + HDR_SIZE);
|
|
124
|
+
if (!new_raw) return nullptr;
|
|
125
|
+
hdr_write(new_raw, size);
|
|
126
|
+
return static_cast<char*>(new_raw) + HDR_SIZE;
|
|
127
|
+
}
|
package/src/mik_sys.cpp
CHANGED
|
@@ -47,6 +47,10 @@ static JSValue mik__sys_memory_usage(JSContext* ctx, JSValue this_val, int argc,
|
|
|
47
47
|
JS_NewInt64(ctx, (int64_t)platform->get_total_system_mem()));
|
|
48
48
|
JS_SetPropertyStr(ctx, obj, "systemLargestFree",
|
|
49
49
|
JS_NewInt64(ctx, (int64_t)platform->get_largest_free_system_mem()));
|
|
50
|
+
JS_SetPropertyStr(ctx, obj, "internalFree",
|
|
51
|
+
JS_NewInt64(ctx, (int64_t)platform->get_free_internal_mem()));
|
|
52
|
+
JS_SetPropertyStr(ctx, obj, "internalLargestFree",
|
|
53
|
+
JS_NewInt64(ctx, (int64_t)platform->get_largest_free_internal_mem()));
|
|
50
54
|
return obj;
|
|
51
55
|
}
|
|
52
56
|
|
package/src/mikrojs.cpp
CHANGED
|
@@ -17,16 +17,18 @@
|
|
|
17
17
|
|
|
18
18
|
#define MIK__DEFAULT_STACK_SIZE 1024 * 1024 // 1 MB
|
|
19
19
|
|
|
20
|
-
/* JS malloc functions
|
|
20
|
+
/* JS malloc functions. Routed through the mik__js_* family so the QuickJS
|
|
21
|
+
* heap can be relocated to PSRAM on chips with both internal SRAM and PSRAM,
|
|
22
|
+
* leaving internal SRAM free for mbedTLS, WiFi/BLE, and DMA buffers. */
|
|
21
23
|
|
|
22
24
|
static void* mik__mf_calloc(void* opaque, size_t count, size_t size) {
|
|
23
25
|
(void)opaque;
|
|
24
|
-
return
|
|
26
|
+
return mik__js_calloc(count, size);
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
static void* mik__mf_malloc(void* opaque, size_t size) {
|
|
28
30
|
(void)opaque;
|
|
29
|
-
return
|
|
31
|
+
return mik__js_malloc(size);
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
static void mik__mf_free(void* opaque, void* ptr) {
|
|
@@ -36,7 +38,7 @@ static void mik__mf_free(void* opaque, void* ptr) {
|
|
|
36
38
|
|
|
37
39
|
static void* mik__mf_realloc(void* opaque, void* ptr, size_t size) {
|
|
38
40
|
(void)opaque;
|
|
39
|
-
return
|
|
41
|
+
return mik__js_realloc(ptr, size);
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
static const JSMallocFunctions mik_mf = {
|
|
@@ -199,7 +201,11 @@ static void mik__promise_rejection_tracker(JSContext* ctx, JSValue promise, JSVa
|
|
|
199
201
|
}
|
|
200
202
|
|
|
201
203
|
void MIK_DefaultOptions(MIKRunOptions* options) {
|
|
202
|
-
static MIKRunOptions default_options = {
|
|
204
|
+
static MIKRunOptions default_options = {
|
|
205
|
+
.mem_limit = 0,
|
|
206
|
+
.stack_size = MIK__DEFAULT_STACK_SIZE,
|
|
207
|
+
.use_psram_heap = false,
|
|
208
|
+
};
|
|
203
209
|
|
|
204
210
|
memcpy(options, &default_options, sizeof(*options));
|
|
205
211
|
}
|
|
@@ -228,6 +234,12 @@ MIKRuntime* MIK_NewRuntimeInternal(MIKRunOptions* options) {
|
|
|
228
234
|
memcpy(&mik_rt->options, options, sizeof(*options));
|
|
229
235
|
MIK_DefaultConfig(&mik_rt->config);
|
|
230
236
|
|
|
237
|
+
/* Switch the QuickJS heap to PSRAM before constructing the runtime,
|
|
238
|
+
* so JS_NewRuntime2 and every subsequent QuickJS allocation lands
|
|
239
|
+
* in PSRAM. The MIKRuntime struct itself stays in internal SRAM:
|
|
240
|
+
* it was allocated before this point. */
|
|
241
|
+
mik__set_quickjs_heap_psram(options->use_psram_heap);
|
|
242
|
+
|
|
231
243
|
rt = JS_NewRuntime2(&mik_mf, NULL);
|
|
232
244
|
CHECK_NOT_NULL(rt);
|
|
233
245
|
mik_rt->rt = rt;
|
package/src/platform_posix.cpp
CHANGED
|
@@ -45,6 +45,31 @@ static size_t posix_get_largest_free_system_mem(void) {
|
|
|
45
45
|
return 0; /* Not available on desktop */
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
static size_t posix_get_free_internal_mem(void) {
|
|
49
|
+
return 0; /* No internal/PSRAM distinction on desktop */
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static size_t posix_get_largest_free_internal_mem(void) {
|
|
53
|
+
return 0; /* No internal/PSRAM distinction on desktop */
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static void* posix_malloc_psram(size_t size) {
|
|
57
|
+
(void)size;
|
|
58
|
+
return NULL; /* No PSRAM on desktop; caller falls back to libc */
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static void* posix_calloc_psram(size_t count, size_t size) {
|
|
62
|
+
(void)count;
|
|
63
|
+
(void)size;
|
|
64
|
+
return NULL;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static void* posix_realloc_psram(void* ptr, size_t size) {
|
|
68
|
+
(void)ptr;
|
|
69
|
+
(void)size;
|
|
70
|
+
return NULL;
|
|
71
|
+
}
|
|
72
|
+
|
|
48
73
|
static bool posix_get_fs_info(const char* label, size_t* total, size_t* used) {
|
|
49
74
|
(void)label;
|
|
50
75
|
(void)total;
|
|
@@ -111,6 +136,11 @@ static const MIKPlatform posix_platform = {
|
|
|
111
136
|
.get_min_free_system_mem = posix_get_min_free_system_mem,
|
|
112
137
|
.get_total_system_mem = posix_get_total_system_mem,
|
|
113
138
|
.get_largest_free_system_mem = posix_get_largest_free_system_mem,
|
|
139
|
+
.get_free_internal_mem = posix_get_free_internal_mem,
|
|
140
|
+
.get_largest_free_internal_mem = posix_get_largest_free_internal_mem,
|
|
141
|
+
.malloc_psram = posix_malloc_psram,
|
|
142
|
+
.calloc_psram = posix_calloc_psram,
|
|
143
|
+
.realloc_psram = posix_realloc_psram,
|
|
114
144
|
.get_fs_info = posix_get_fs_info,
|
|
115
145
|
.log = posix_log,
|
|
116
146
|
.stdout_write = posix_stdout_write,
|