Skip to content

Commit f5aec72

Browse files
Fan LinFan Lin
authored andcommitted
adding linemb support and documents
1 parent 2b384fe commit f5aec72

8 files changed

Lines changed: 382 additions & 100 deletions

File tree

build/devices/linemb/manifest.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
{
22
"modules": {
33
"*": [
4-
"$(MODULES)/base/timer/*",
5-
"$(MODULES)/base/timer/mc/*"
4+
"$(MODULES)/base/timer/*"
5+
, "$(MODULES)/base/timer/lin/*"
6+
, "$(MODULES)/base/time/*"
7+
, "$(MODULES)/base/time/lin/*"
68
]
79
},
810
"preload": [
911
"timer"
1012
],
1113
"platforms": {
12-
"linarm/*": {
14+
"linemb/*": {
1315
}
1416
}
1517
}
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
#include "xsAll.h"
2+
#include "mc.xs.h"
3+
#include "xs.h"
4+
#include "xsAll.h"
5+
#include "xsHost.h"
6+
#include <fcntl.h>
7+
#include <unistd.h>
8+
#include <execinfo.h> // Add header file for retrieving call stack
9+
#include <signal.h> // Add header file for signal handling
10+
#include <pthread.h> // Add pthread header file
11+
12+
#define ITERATION_TIMEOUT_US 5000000 // Set 5 second timeout threshold
13+
#define FATAL_ERROR_TOKEN "\n\n!!!FATAL ERROR!!!\n\n"
14+
extern txPreparation *xsPreparation;
15+
16+
// Use thread-local storage to save txMachine pointer
17+
static __thread txMachine *gxMachine = NULL;
18+
19+
#if mxInstrument
20+
gboolean on_instrumentation_timeout(gpointer data)
21+
{
22+
// Execute your code here
23+
// Return TRUE if you want to continue calling, or FALSE if you want to stop after executing once
24+
txMachine *the = (void *)data;
25+
fxSampleInstrumentation(the, 0, NULL);
26+
// Reset
27+
the->garbageCollectionCount = 0;
28+
the->stackPeak = the->stack;
29+
the->peakParserSize = 0;
30+
the->floatingPointOps = 0;
31+
the->promisesSettledCount = 0;
32+
33+
return TRUE; // Continue calling
34+
}
35+
#endif
36+
37+
// Modify dump_js_stack function, add thread check
38+
void dump_js_stack(txMachine* the) {
39+
fprintf(stderr, "JavaScript stack trace:\n");
40+
txSlot *aFrame = the->frame;
41+
while (aFrame) {
42+
char name[128] = "";
43+
fxBufferFrameName(the, name, sizeof(name), aFrame, "");
44+
45+
txSlot* environment = mxFrameToEnvironment(aFrame);
46+
if (environment->ID != XS_NO_ID)
47+
printf("%s: %s:%d\n", name, fxGetKeyName(the, environment->ID), environment->value.environment.line);
48+
else
49+
printf("%s\n", name);
50+
51+
aFrame = aFrame->next;
52+
}
53+
}
54+
55+
static void fatal_error_exit() {
56+
void *buffer[50];
57+
int nptrs = backtrace(buffer, 50);
58+
char **strings = backtrace_symbols(buffer, nptrs);
59+
printf("==== Native stack trace: =====\n");
60+
for (int i = 0; i < nptrs; i++)
61+
{
62+
printf("%s\n", strings[i]);
63+
}
64+
free(strings);
65+
printf("==============================\n");
66+
printf(FATAL_ERROR_TOKEN);
67+
68+
signal(SIGQUIT, SIG_DFL);
69+
exit(1);
70+
}
71+
72+
static void fatal_error_handler(int signum) {
73+
const char* signame = "UNKNOWN";
74+
switch(signum) {
75+
case SIGABRT: signame = "SIGABRT"; break;
76+
case SIGFPE: signame = "SIGFPE"; break;
77+
case SIGILL: signame = "SIGILL"; break;
78+
case SIGINT: signame = "SIGINT"; break;
79+
case SIGQUIT: signame = "SIGQUIT"; break;
80+
case SIGSEGV: signame = "SIGSEGV"; break;
81+
case SIGTERM: signame = "SIGTERM"; break;
82+
case SIGBUS: signame = "SIGBUS"; break;
83+
case SIGPIPE: signame = "SIGPIPE"; break;
84+
}
85+
86+
printf("!!!! Signal %s (%d) caught. Stack trace:\n", signame, signum);
87+
// Reset signal handler to allow default behavior to terminate program
88+
signal(signum, SIG_DFL);
89+
fatal_error_exit();
90+
}
91+
92+
// Modified: Unified signal handling function
93+
static void signal_handler(int signum) {
94+
fatal_error_handler(signum);
95+
}
96+
97+
static void timeout_handler(int signum) {
98+
if (gxMachine) {
99+
printf("!!!! Execution timeout !!!!\n");
100+
dump_js_stack(gxMachine);
101+
fatal_error_exit();
102+
}
103+
}
104+
105+
int main(int argc, char *argv[]) {
106+
// Use setvbuf to disable buffering
107+
setvbuf(stdout, NULL, _IONBF, 0);
108+
setvbuf(stderr, NULL, _IONBF, 0);
109+
110+
// Register all signals to be captured
111+
signal(SIGABRT, signal_handler);
112+
signal(SIGFPE, signal_handler);
113+
signal(SIGILL, signal_handler);
114+
signal(SIGQUIT, signal_handler);
115+
signal(SIGSEGV, signal_handler);
116+
signal(SIGTERM, signal_handler);
117+
signal(SIGBUS, signal_handler);
118+
signal(SIGPIPE, signal_handler);
119+
signal(SIGALRM, timeout_handler); // Used for timeout
120+
121+
int error = 0;
122+
static txMachine _root;
123+
txMachine *the = &_root;
124+
txPreparation *preparation = xsPreparation();
125+
126+
c_memset(the, 0, sizeof(txMachine));
127+
the->preparation = preparation;
128+
the->keyArray = preparation->keys;
129+
the->keyCount = (txID)preparation->keyCount + (txID)preparation->creation.initialKeyCount;
130+
the->keyIndex = (txID)preparation->keyCount;
131+
the->nameModulo = preparation->nameModulo;
132+
the->nameTable = preparation->names;
133+
the->symbolModulo = preparation->symbolModulo;
134+
the->symbolTable = preparation->symbols;
135+
136+
the->stack = &preparation->stack[0];
137+
the->stackBottom = &preparation->stack[0];
138+
the->stackTop = &preparation->stack[preparation->stackCount];
139+
140+
the->firstHeap = &preparation->heap[0];
141+
the->freeHeap = &preparation->heap[preparation->heapCount - 1];
142+
the->aliasCount = (txID)preparation->aliasCount;
143+
144+
setvbuf(stdout, NULL, _IONBF, 0);
145+
the = fxCloneMachine(&preparation->creation, the, "linemb", NULL);
146+
gxMachine = the; // Save to thread-local storage
147+
#if mxInstrument
148+
fxDescribeInstrumentation(the, 0, NULL, NULL);
149+
#endif
150+
xsBeginHost(the);
151+
{
152+
xsVars(2);
153+
{
154+
// XS: set global string array argv, and put input string into it
155+
xsTry
156+
{
157+
xsResult = xsNewArray(0);
158+
xsSet(xsGlobal, xsID("argv"), xsResult);
159+
for (int i = 0; i < argc; i++)
160+
{
161+
xsVar(0) = xsString(argv[i]);
162+
xsCall1(xsResult, xsID("push"), xsVar(0));
163+
}
164+
}
165+
xsCatch
166+
{
167+
xsStringValue message = xsToString(xsException);
168+
fprintf(stderr, "### %s\n", message);
169+
error = 1;
170+
}
171+
}
172+
{
173+
xsResult = xsAwaitImport("main", XS_IMPORT_NAMESPACE);
174+
}
175+
}
176+
xsEndHost(the);
177+
178+
// Start event loop
179+
GMainContext *main_context = g_main_context_default();
180+
GMainLoop *main_loop = g_main_loop_new(main_context, FALSE);
181+
182+
#if mxInstrument
183+
g_timeout_add_seconds(1, on_instrumentation_timeout, (void *)the);
184+
#endif
185+
186+
// g_main_loop_run(main_loop);
187+
int testTime = 0;
188+
while (TRUE)
189+
{
190+
// Set timer: trigger SIGALRM on timeout
191+
struct itimerval timer;
192+
timer.it_value.tv_sec = ITERATION_TIMEOUT_US / 1000000;
193+
timer.it_value.tv_usec = ITERATION_TIMEOUT_US % 1000000;
194+
timer.it_interval.tv_sec = 0;
195+
timer.it_interval.tv_usec = 0;
196+
setitimer(ITIMER_REAL, &timer, NULL);
197+
198+
// Record time before event handling
199+
guint64 start = g_get_monotonic_time();
200+
// Process one event non-blocking
201+
gboolean processed = g_main_context_iteration(NULL, FALSE);
202+
// Record time after event handling
203+
guint64 end = g_get_monotonic_time();
204+
205+
// Disable timer
206+
timer.it_value.tv_sec = 0;
207+
timer.it_value.tv_usec = 0;
208+
setitimer(ITIMER_REAL, &timer, NULL);
209+
210+
if (processed)
211+
{
212+
// printf("process time: %" G_GUINT64_FORMAT " us\n", end - start);
213+
}
214+
}
215+
216+
xsDeleteMachine(the);
217+
218+
return error;
219+
}
220+
221+
const char *gXSAbortStrings[] ICACHE_FLASH_ATTR = {
222+
"debugger",
223+
"memory full",
224+
"stack overflow",
225+
"fatal",
226+
"dead strip",
227+
"unhandled exception",
228+
"not enough keys",
229+
"too much computation",
230+
"unhandled rejection"
231+
};
232+
233+
void fxAbort(xsMachine *the, int status)
234+
{
235+
const char *msg = (status <= XS_UNHANDLED_REJECTION_EXIT) ? gXSAbortStrings[status] : "unknown";
236+
#if 0 // MODDEF_XS_ABORTHOOK
237+
238+
if ((XS_STACK_OVERFLOW_EXIT != status) && (XS_DEBUGGER_EXIT != status)) {
239+
xsBooleanValue ignore = false;
240+
241+
fxBeginHost(the);
242+
{
243+
mxPush(mxException);
244+
txSlot *exception = the->stack;
245+
mxException = xsUndefined;
246+
mxTry(the) {
247+
txID abortID = fxFindName(the, "abort");
248+
mxOverflow(-8);
249+
mxPush(mxGlobal);
250+
if (fxHasID(the, abortID)) {
251+
mxPush(mxGlobal);
252+
fxCallID(the, abortID);
253+
mxPushStringC((char *)msg);
254+
mxPushSlot(exception);
255+
fxRunCount(the, 2);
256+
ignore = (XS_BOOLEAN_KIND == the->stack->kind) && !the->stack->value.boolean;
257+
mxPop();
258+
}
259+
}
260+
mxCatch(the) {
261+
}
262+
}
263+
fxEndHost(the);
264+
if (ignore)
265+
return;
266+
}
267+
#endif
268+
printf("Aborting with status %d, %s\n", status, msg);
269+
270+
fatal_error_exit();
271+
}

build/devices/linemb/xsProj/main.c

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)