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
27 changes: 21 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,27 @@ ifdef CONFIG_ARM32
MQJS_BUILD_FLAGS=-m32
endif

PROGS=mqjs$(EXE) example$(EXE)
PROGS=mqjs$(EXE) mqjsc$(EXE) example$(EXE)
TEST_PROGS=dtoa_test libm_test

all: $(PROGS)

MQJS_OBJS=mqjs.o readline_tty.o readline.o mquickjs.o dtoa.o libm.o cutils.o
MQJS_OBJS=mqjs.o readline_tty.o readline.o mqjs_runtime.o mquickjs.o dtoa.o libm.o cutils.o
MQUICKJS_LIB_OBJS=mquickjs.o mqjs_runtime.o dtoa.o libm.o cutils.o
LIBS=-lm

mqjs$(EXE): $(MQJS_OBJS)
mqjs$(EXE): mqjs.o readline_tty.o readline.o libmquickjs.a
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

mqjsc$(EXE): mqjsc.o libmquickjs.a
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

mqjs_runtime.o: mqjs.c
$(CC) $(CFLAGS) -DMQJS_RUNTIME_ONLY -c -o $@ $<

libmquickjs.a: $(MQUICKJS_LIB_OBJS)
$(AR) rcs $@ $^

mquickjs.o: mquickjs_atom.h

mqjs_stdlib: mqjs_stdlib.host.o mquickjs_build.host.o
Expand All @@ -98,11 +108,12 @@ mqjs_stdlib.h: mqjs_stdlib
./mqjs_stdlib $(MQJS_BUILD_FLAGS) > $@

mqjs.o: mqjs_stdlib.h
mqjsc.o: mqjs_stdlib.h

# C API example
example.o: example_stdlib.h

example$(EXE): example.o mquickjs.o dtoa.o libm.o cutils.o
example$(EXE): example.o libmquickjs.a
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

example_stdlib: example_stdlib.host.o mquickjs_build.host.o
Expand All @@ -117,7 +128,7 @@ example_stdlib.h: example_stdlib
%.host.o: %.c
$(HOST_CC) $(HOST_CFLAGS) -c -o $@ $<

test: mqjs example
test: mqjs mqjsc example
./mqjs tests/test_closure.js
./mqjs tests/test_language.js
./mqjs tests/test_loop.js
Expand All @@ -127,6 +138,10 @@ test: mqjs example
# @sha256sum -c test_builtin.sha256
./mqjs -b test_builtin.bin
./example tests/test_rect.js
# test standalone compiler
./mqjsc -o test_standalone tests/test_builtin.js
./test_standalone
rm -f test_standalone

microbench: mqjs
./mqjs tests/microbench.js
Expand All @@ -147,6 +162,6 @@ rempio2_test: tests/rempio2_test.o libm.o
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

clean:
rm -f *.o *.d *~ tests/*.o tests/*.d tests/*~ test_builtin.bin mqjs_stdlib mqjs_stdlib.h mquickjs_build_atoms mquickjs_atom.h mqjs_example example_stdlib example_stdlib.h $(PROGS) $(TEST_PROGS)
rm -f *.o *.a *.d *~ tests/*.o tests/*.d tests/*~ test_builtin.bin mqjs_stdlib mqjs_stdlib.h mquickjs_build_atoms mquickjs_atom.h mqjs_example example_stdlib example_stdlib.h $(PROGS) $(TEST_PROGS)

-include $(wildcard *.d)
75 changes: 1 addition & 74 deletions example.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include "cutils.h"
#include "mquickjs.h"
#include "mqjs_runtime.h"

#define JS_CLASS_RECTANGLE (JS_CLASS_USER + 0)
#define JS_CLASS_FILLED_RECTANGLE (JS_CLASS_USER + 1)
Expand Down Expand Up @@ -168,87 +169,13 @@ static JSValue js_filled_rectangle_get_color(JSContext *ctx, JSValue *this_val,
return JS_NewInt32(ctx, d->color);
}

static JSValue js_print(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
{
int i;
JSValue v;

for(i = 0; i < argc; i++) {
if (i != 0)
putchar(' ');
v = argv[i];
if (JS_IsString(ctx, v)) {
JSCStringBuf buf;
const char *str;
size_t len;
str = JS_ToCStringLen(ctx, &len, v, &buf);
fwrite(str, 1, len, stdout);
} else {
JS_PrintValueF(ctx, argv[i], JS_DUMP_LONG);
}
}
putchar('\n');
return JS_UNDEFINED;
}

#if defined(__linux__) || defined(__APPLE__)
static int64_t get_time_ms(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t)ts.tv_sec * 1000 + (ts.tv_nsec / 1000000);
}
#else
static int64_t get_time_ms(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000);
}
#endif

static JSValue js_date_now(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return JS_NewInt64(ctx, (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000));
}

static JSValue js_performance_now(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
{
return JS_NewInt64(ctx, get_time_ms());
}

#include "example_stdlib.h"

static void js_log_func(void *opaque, const void *buf, size_t buf_len)
{
fwrite(buf, 1, buf_len, stdout);
}

static uint8_t *load_file(const char *filename, int *plen)
{
FILE *f;
uint8_t *buf;
int buf_len;

f = fopen(filename, "rb");
if (!f) {
perror(filename);
exit(1);
}
fseek(f, 0, SEEK_END);
buf_len = ftell(f);
fseek(f, 0, SEEK_SET);
buf = malloc(buf_len + 1);
fread(buf, 1, buf_len, f);
buf[buf_len] = '\0';
fclose(f);
if (plen)
*plen = buf_len;
return buf;
}

int main(int argc, const char **argv)
{
size_t mem_size;
Expand Down
99 changes: 53 additions & 46 deletions mqjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,51 @@
#include <sys/time.h>
#include <math.h>
#include <fcntl.h>
#include <unistd.h>

#include "cutils.h"
#ifndef MQJS_RUNTIME_ONLY
#include "readline_tty.h"
#endif
#include "mquickjs.h"
#include "mqjs_runtime.h"

static uint8_t *load_file(const char *filename, int *plen);
static void dump_error(JSContext *ctx);
uint8_t *load_file(const char *filename, int *plen)
{
FILE *f;
uint8_t *buf;
int buf_len;

static JSValue js_print(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
f = fopen(filename, "rb");
if (!f) {
perror(filename);
exit(1);
}
fseek(f, 0, SEEK_END);
buf_len = ftell(f);
fseek(f, 0, SEEK_SET);
buf = malloc(buf_len + 1);
if (!buf) {
fclose(f);
return NULL;
}
if (fread(buf, 1, buf_len, f) != (size_t)buf_len) {
free(buf);
fclose(f);
return NULL;
}
buf[buf_len] = '\0';
fclose(f);
if (plen)
*plen = buf_len;
return buf;
}

JSValue js_print(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
{
int i;
JSValue v;

for(i = 0; i < argc; i++) {
if (i != 0)
putchar(' ');
Expand All @@ -65,7 +97,7 @@ static JSValue js_print(JSContext *ctx, JSValue *this_val, int argc, JSValue *ar
return JS_UNDEFINED;
}

static JSValue js_gc(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
JSValue js_gc(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
{
JS_GC(ctx);
return JS_UNDEFINED;
Expand All @@ -87,54 +119,48 @@ static int64_t get_time_ms(void)
}
#endif

static JSValue js_date_now(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
JSValue js_date_now(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return JS_NewInt64(ctx, (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000));
}

static JSValue js_performance_now(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
JSValue js_performance_now(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
{
return JS_NewInt64(ctx, get_time_ms());
}

/* load a script */
static JSValue js_load(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
JSValue js_load(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
{
const char *filename;
JSCStringBuf buf_str;
uint8_t *buf;
int buf_len;
JSValue ret;

filename = JS_ToCString(ctx, argv[0], &buf_str);
if (!filename)
return JS_EXCEPTION;
buf = load_file(filename, &buf_len);
if (!buf)
return JS_ThrowInternalError(ctx, "could not load file");

ret = JS_Eval(ctx, (const char *)buf, buf_len, filename, 0);
free(buf);
return ret;
}

/* timers */
typedef struct {
BOOL allocated;
JSGCRef func;
int64_t timeout; /* in ms */
} JSTimer;

#define MAX_TIMERS 16

static JSTimer js_timer_list[MAX_TIMERS];

static JSValue js_setTimeout(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
JSValue js_setTimeout(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
{
JSTimer *th;
int delay, i;
JSValue *pfunc;

if (!JS_IsFunction(ctx, argv[0]))
return JS_ThrowTypeError(ctx, "not a function");
if (JS_ToInt32(ctx, &delay, argv[1]))
Expand All @@ -152,7 +178,7 @@ static JSValue js_setTimeout(JSContext *ctx, JSValue *this_val, int argc, JSValu
return JS_ThrowInternalError(ctx, "too many timers");
}

static JSValue js_clearTimeout(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
JSValue js_clearTimeout(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
{
int timer_id;
JSTimer *th;
Expand All @@ -169,7 +195,7 @@ static JSValue js_clearTimeout(JSContext *ctx, JSValue *this_val, int argc, JSVa
return JS_UNDEFINED;
}

static void run_timers(JSContext *ctx)
void run_timers(JSContext *ctx)
{
int64_t min_delay, delay, cur_time;
BOOL has_timer;
Expand All @@ -193,14 +219,14 @@ static void run_timers(JSContext *ctx)
goto fail;
JS_PushArg(ctx, th->func.val); /* func name */
JS_PushArg(ctx, JS_NULL); /* this */

JS_DeleteGCRef(ctx, &th->func);
th->allocated = FALSE;

ret = JS_Call(ctx, 0);
if (JS_IsException(ret)) {
fail:
dump_error(ctx);
/* Error message should be dumped by the caller if needed */
exit(1);
}
min_delay = 0;
Expand All @@ -220,6 +246,8 @@ static void run_timers(JSContext *ctx)
}
}

#ifndef MQJS_RUNTIME_ONLY

#include "mqjs_stdlib.h"

#define STYLE_DEFAULT COLOR_BRIGHT_GREEN
Expand All @@ -235,28 +263,6 @@ static void run_timers(JSContext *ctx)
#define STYLE_RESULT COLOR_BRIGHT_WHITE
#define STYLE_ERROR_MSG COLOR_BRIGHT_RED

static uint8_t *load_file(const char *filename, int *plen)
{
FILE *f;
uint8_t *buf;
int buf_len;

f = fopen(filename, "rb");
if (!f) {
perror(filename);
exit(1);
}
fseek(f, 0, SEEK_END);
buf_len = ftell(f);
fseek(f, 0, SEEK_SET);
buf = malloc(buf_len + 1);
fread(buf, 1, buf_len, f);
buf[buf_len] = '\0';
fclose(f);
if (plen)
*plen = buf_len;
return buf;
}

static int js_log_err_flag;

Expand Down Expand Up @@ -772,3 +778,4 @@ int main(int argc, const char **argv)
free(mem_buf);
return 1;
}
#endif /* !MQJS_RUNTIME_ONLY */
Loading