Repository navigation
Conversation
Provide the half duplex direction control a UART driver offers for RS485 transceivers whose driver enable is wired to the RTS pin, via the Linux TIOCGRS485 and TIOCSRS485 ioctls; compiled only on Linux. getrs485() returns the serial_rs485 configuration as an object with the flags as booleans (enabled, rts_on_send, rts_after_send, rx_during_tx, terminate_bus) and the two RTS delays in milliseconds (delay_before, delay_after). setrs485() applies a read-modify-write of the supplied fields, or of just the enabled flag when given a boolean, and returns the configuration read back from the driver afterwards rather than the one requested: drivers silently drop flags and delays they cannot honour, and the caller otherwise has no way to find out. A driver without RS485 support fails the initial read, so the error surfaces before anything is changed. The newer SER_RS485_RX_DURING_TX and SER_RS485_TERMINATE_BUS flags are defined locally when the toolchain headers predate them. Signed-off-by: John Crispin <john@phrozen.org>
Every object got a json-c table of 16 entries, 40 bytes each on 64-bit, however few keys it held. The compiler already emits the number of plain keys of a literal as the operand of I_NOBJ, but the VM ignored it. Size a literal's table from that count, so a schema or config table of small objects no longer costs about 700 bytes per object. Spreads are not counted; an object filled by spreading grows as before, and an empty literal keeps the 16 entries of ucv_object_new(). Signed-off-by: John Crispin <john@phrozen.org>
jow-
reviewed
Oct 15, 2026
| * fs.dup2(errlog.fileno(), 2); | ||
| * errlog.close(); | ||
| * }); | ||
| */ |
Collaborator
There was a problem hiding this comment.
This feels unergonomic. What about this:
- when the first argument is a function, it is invoked, receiving all subsequent arguments as params, and returning the final argv handed to exec. It can then do whatever preparatory work it needs to do:
const myProcess = uloop.process((args, env) => {
const fs = require('fs');
const errlog = fs.open('/tmp/error.log', 'w');
fs.dup2(errlog.fileno(), 2);
errlog.close();
return ["/bin/ls", ...args];
}, ["-l", "/tmp"], null, (code) => {
printf(`Process exited with code ${code}\n`);
});uc_vm_call() took a reference to the function value on the stack, ran the call and then inspected the type of the value to decide whether to run the interpreter loop. For a C function the callee has returned at that point: uc_vm_call_native() popped its frame, which released the reference that uc_vm_call() held and the stack slot the function was called from. When that slot held the only other reference, as for a function expression that is called at once, the type check read freed memory. Decide before the call whether the callee is native. Only a closure needs the interpreter loop, and the answer does not change while the call runs. Signed-off-by: John Crispin <john@phrozen.org>
A dynamically loaded module whose body raised comes back with the exports it reached before the exception, and the modules table caches it in that state. The import went on to resolve its names against that scope, so the importer saw "Module does not export ..." in place of the exception the module raised. Return as soon as the load left an exception pending; the caller sees the original error with its stack trace. Signed-off-by: John Crispin <john@phrozen.org>
The dynamic load an import turns into was emitted at source position 0, so a stack trace through a module that raised during a dynamic load pointed at the start of the import statement in the importer, not at the module name. A static import records the position of the import statement. Record the same position for the dynamic load; the import() call form already did. Signed-off-by: John Crispin <john@phrozen.org>
uc_vm_insn_dynload() took a pointer to the current callframe before uc_require_library() and used it afterwards, to read the import names and to store the imported values. Loading a ucode module runs its body, and a body that imports further modules pushes more callframes. When the callframe vector grows, realloc() moves it, and the saved pointer then points into freed memory. A program compiled with a forced dynamic link (ucode -c dynlink=name) to a module with a chain of imports reads freed memory this way. Read the frame after the load. Signed-off-by: John Crispin <john@phrozen.org>
uc_require_path() stored every loaded module in the modules table, also when the load raised. A library that dlopen() refused, a library without uc_module_entry() and a .uc file that failed to compile were cached as null, and the next require() or import of the name returned null without an error. Cache a module only when its load raised no exception, so that a later import tries again and reports the error again. Signed-off-by: John Crispin <john@phrozen.org>
Collaborator
|
All commits except "vm: size object literals from the compiler's key count" have been cherry picked into master. For the remainder follow up in #496 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
53c3f2e lib: do not cache a module whose load raised
3ec9a96 vm: read the importing frame after the module load
a8e1ad1 compiler: give dynamic loads the position of the import
d2aa3fe vm: keep the exception of a module that failed to load
d89e319 vm: read the callee type before uc_vm_call() runs it
9077139 uloop: add optional setup callback to process()
44bb9d4 vm: size object literals from the compiler's key count
5eab42c serial: add RS485 mode access (Linux)