Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions devices/wasm/wasm/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ static void print_flush(bool is_error) {
fprintf(is_error ? stderr : stdout, "\n");
}

/** Browser only: EV3/desktop use runner.c’s get_time_ms + clock_gettime. */
static uint64_t wasm_get_time_ms(void) {
return (uint64_t)emscripten_get_now();
}

EMSCRIPTEN_KEEPALIVE
void siwasm_alloc_heap(size_t size) {
if (heap) {
Expand Down Expand Up @@ -93,6 +98,7 @@ void siwasm_run(unsigned char *code, size_t code_size) {
sinter_printer_integer = print_integer;
sinter_printer_string = print_string;
sinter_printer_flush = print_flush;
sinter_get_time_ms = wasm_get_time_ms;

sinter_value_t result;
sinter_fault_t fault = (uint8_t) sinter_run(code, code_size, &result);
Expand Down
17 changes: 17 additions & 0 deletions runner/src/runner.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#define _POSIX_C_SOURCE 200809L

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
Expand All @@ -8,10 +10,17 @@
#include <unistd.h>
#include <errno.h>

#include <time.h>
#include <sinter.h>

#define eprintf(...) fprintf(stderr, __VA_ARGS__)

static uint64_t get_time_ms(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t) ts.tv_sec * 1000u + (uint64_t) ts.tv_nsec / 1000000u;
}

static const char *fault_names[] = {
"no fault",
"out of memory",
Expand Down Expand Up @@ -94,9 +103,17 @@ int main(int argc, char *argv[]) {
sinter_printer_string = print_string;
sinter_printer_integer = print_integer;
sinter_printer_flush = print_flush;
sinter_get_time_ms = get_time_ms;

setup_internals();

void *heap = malloc(0x100000); // 1MB
if (!heap) {
eprintf("Failed to allocate heap\n");
return 1;
}
sinter_setup_heap(heap, 0x100000);
Comment thread
LucasChen1108 marked this conversation as resolved.

sinter_value_t result = { 0 };
sinter_fault_t fault = sinter_run(program, size, &result);

Expand Down
2 changes: 2 additions & 0 deletions vm/include/sinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ extern sinter_printfn_integer sinter_printer_integer;
extern sinter_printfn_float sinter_printer_float;
extern sinter_printfn_flush sinter_printer_flush;

extern uint64_t (*sinter_get_time_ms)(void);

#ifdef __cplusplus
}
#endif
Expand Down
69 changes: 67 additions & 2 deletions vm/src/primitives.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <string.h>
#include <limits.h>
#include <math.h>
#include <errno.h>

#include <sinter/nanbox.h>
#include <sinter/fault.h>
Expand Down Expand Up @@ -1596,6 +1597,70 @@ static sinanbox_t sivmfn_prim_noop(uint8_t argc, sinanbox_t *argv) {
return NANBOX_OFUNDEF();
}

uint64_t (*sinter_get_time_ms)(void) = NULL;

static sinanbox_t sivmfn_prim_parse_int(uint8_t argc, sinanbox_t *argv) {
CHECK_ARGC(2);

if (!NANBOX_ISPTR(argv[0]) || !siheap_is_string(SIHEAP_NANBOXTOPTR(argv[0]))) {
sifault(sinter_fault_type);
return NANBOX_OFEMPTY();
}

int32_t radix = 0;
if (NANBOX_ISINT(argv[1])) {
radix = NANBOX_INT(argv[1]);
} else if (NANBOX_ISFLOAT(argv[1])) {
float fv = NANBOX_FLOAT(argv[1]);
if (!isfinite(fv) || truncf(fv) != fv) {
sifault(sinter_fault_type);
return NANBOX_OFEMPTY();
}
radix = (int32_t) fv;
} else {
sifault(sinter_fault_type);
return NANBOX_OFEMPTY();
}

if (radix < 2 || radix > 36) {
sifault(sinter_fault_type);
return NANBOX_OFEMPTY();
}

const char *str = sistrobj_tocharptr(SIHEAP_NANBOXTOPTR(argv[0]));
char *endptr = NULL;
errno = 0;
long result = strtol(str, &endptr, radix);
Comment thread
LucasChen1108 marked this conversation as resolved.

if (endptr == str) {
return NANBOX_CANONICAL_NAN;
}

if (errno == ERANGE) {
// strtol overflowed, return as float instead
return NANBOX_OFFLOAT((float) result);
}

if (result >= NANBOX_INTMIN && result <= NANBOX_INTMAX) {
return NANBOX_OFINT((int32_t) result);
} else {
return NANBOX_OFFLOAT((float) result);
}
}

static sinanbox_t sivmfn_prim_runtime(uint8_t argc, sinanbox_t *argv) {
(void) argc; (void) argv;
if (sinter_get_time_ms) {
uint64_t t = sinter_get_time_ms();
if (t <= (uint64_t) NANBOX_INTMAX) {
return NANBOX_OFINT((int32_t) t);
}
return NANBOX_OFFLOAT((float) t);
}
return NANBOX_OFINT(0);
}


sivmfnptr_t sivmfn_primitives[] = {
sivmfn_prim_accumulate,
sivmfn_prim_append,
Expand Down Expand Up @@ -1666,11 +1731,11 @@ sivmfnptr_t sivmfn_primitives[] = {
sivmfn_prim_math_trunc,
sivmfn_prim_member,
sivmfn_prim_pair,
/* parse_int */ sivmfn_prim_unimpl, // TODO: doesn't make sense without the ability to take input (prompt)
/* parse_int */ sivmfn_prim_parse_int,
sivmfn_prim_remove,
sivmfn_prim_remove_all,
sivmfn_prim_reverse,
/* runtime */ sivmfn_prim_unimpl, // TODO: need to get time from host
/* runtime */ sivmfn_prim_runtime,
sivmfn_prim_set_head,
sivmfn_prim_set_tail,
sivmfn_prim_stream,
Expand Down
Loading