void sj_print_exception(struct v7 *v7, v7_val_t exc, const char *msg) { /* * TOD(mkm) add some API to hal to fetch the current debug mode * and avoid logging to stdout if according no error messages should go * there (e.g. because it's used to implement a serial protocol). */ FILE *fs[] = {stdout, stderr}; size_t i; v7_val_t msg_v = V7_UNDEFINED; /* * own because the exception could be a string, * and if not owned here, print_stack_trace could get * an unrelocated argument an ASN violation. */ v7_own(v7, &exc); v7_own(v7, &msg_v); msg_v = v7_get(v7, exc, "message", ~0); for (i = 0; i < sizeof(fs) / sizeof(fs[0]); i++) { fprintf(fs[i], "%s: ", msg); if (!v7_is_undefined(msg_v)) { v7_fprintln(fs[i], v7, msg_v); } else { v7_fprintln(fs[i], v7, exc); } v7_fprint_stack_trace(fs[i], v7, exc); } v7_disown(v7, &msg_v); v7_disown(v7, &exc); }
/* Invoke user callback as cb(data, undefined) */ static void http_disconnect_cb(void *arg) { struct espconn *conn = (struct espconn *) arg; struct http_ctx *ctx = (struct http_ctx *) conn->proto.tcp; v7_val_t data, cb_args; char *body; int i; v7_val_t res; body = ctx->resp; for (i = 0; i + 3 < ctx->resp_pos; i++) { if (memcmp(ctx->resp + i, "\r\n\r\n", 4) == 0) { body = ctx->resp + i + 4; break; } } cb_args = v7_create_object(v7); v7_own(v7, &cb_args); data = v7_create_string(v7, body, ctx->resp_pos - (body - ctx->resp), 1); v7_own(v7, &data); http_free(conn); v7_array_set(v7, cb_args, 0, ctx->cb); v7_array_set(v7, cb_args, 1, data); v7_disown(v7, &data); if (v7_exec_with(v7, &res, "this[0](this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); v7_disown(v7, &ctx->cb); }
/* * If resolved successfuly it will connect. Otherwise invokes * user callback as cb(undefined, error_message) */ static void http_get_dns_cb(const char *name, ip_addr_t *ipaddr, void *arg) { /* WIP: for now return the dns address as if it were the `get` response */ struct espconn *conn = (struct espconn *) arg; struct http_ctx *ctx = (struct http_ctx *) conn->proto.tcp; static char err_msg[] = "cannot resolve"; if (ipaddr == NULL) { v7_val_t res, cb_args = v7_create_object(v7); v7_own(v7, &cb_args); v7_array_set(v7, cb_args, 0, ctx->cb); v7_array_set(v7, cb_args, 1, v7_create_string(v7, err_msg, sizeof(err_msg), 1)); http_free(conn); if (v7_exec_with(v7, &res, "this[0](undefined, this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); v7_disown(v7, &ctx->body); /* body has not been sent yet */ v7_disown(v7, &ctx->cb); } else { memcpy(conn->proto.tcp->remote_ip, &ipaddr->addr, 4); conn->proto.tcp->remote_port = ctx->port; conn->proto.tcp->local_port = espconn_port(); espconn_regist_connectcb(conn, http_connect_cb); espconn_regist_disconcb(conn, http_disconnect_cb); espconn_regist_reconcb(conn, http_error_cb); espconn_connect(conn); } }
void _sj_invoke_cb(struct v7 *v7, v7_val_t func, v7_val_t this_obj, v7_val_t args) { v7_val_t res; if (v7_apply(v7, &res, func, this_obj, args) == V7_EXEC_EXCEPTION) { fprintf(stderr, "cb threw exception: "); v7_fprintln(stderr, v7, res); #if V7_ENABLE__StackTrace v7_fprint_stack_trace(stderr, v7, res); #endif } }
static void run_init_script(struct v7 *v7) { static const char *init_files[] = {"sys_init.js"}; size_t i; v7_val_t res; /* * Run startup scripts from the directory JS_DIR_NAME. * That directory should be located where the binary (s_argv0) lives. */ for (i = 0; i < sizeof(init_files) / sizeof(init_files[0]); i++) { if (v7_exec_file(v7, init_files[i], &res) != V7_OK) { fprintf(stderr, "Failed to run %s: ", init_files[i]); v7_fprintln(stderr, v7, res); } } }
void sj_http_error_callback(struct v7 *v7, v7_val_t cb, int err_no) { char err_msg[128]; v7_val_t res, cb_args; cb_args = v7_create_object(v7); v7_own(v7, &cb_args); snprintf(err_msg, sizeof(err_msg), "connection error: %d\n", err_no); v7_array_set(v7, cb_args, 0, cb); v7_array_set(v7, cb_args, 1, v7_create_string(v7, err_msg, sizeof(err_msg), 1)); if (v7_exec_with(v7, &res, "this[0](undefined, this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); }
/* Invoke user callback as cb(undefined, err_msg) */ static void http_error_cb(void *arg, int8_t err) { struct espconn *conn = (struct espconn *) arg; struct http_ctx *ctx = (struct http_ctx *) conn->proto.tcp; char err_msg[128]; v7_val_t res, cb_args; cb_args = v7_create_object(v7); v7_own(v7, &cb_args); snprintf(err_msg, sizeof(err_msg), "connection error: %d\n", err); v7_array_set(v7, cb_args, 0, ctx->cb); v7_array_set(v7, cb_args, 1, v7_create_string(v7, err_msg, sizeof(err_msg), 1)); http_free(conn); if (v7_exec_with(v7, &res, "this[0](undefined, this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); }
void sj_http_success_callback(struct v7 *v7, v7_val_t cb, const char *data, size_t data_len) { v7_val_t datav, cb_args; v7_val_t res; cb_args = v7_create_object(v7); v7_own(v7, &cb_args); datav = v7_create_string(v7, data, data_len, 1); v7_own(v7, &datav); v7_array_set(v7, cb_args, 0, cb); v7_array_set(v7, cb_args, 1, datav); v7_disown(v7, &datav); if (v7_exec_with(v7, &res, "this[0](this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); v7_disown(v7, &cb); }
static void pre_init(struct v7 *v7) { static const char *init_files[] = {"smart.js", "user.js"}; const char *dir = s_argv0 + strlen(s_argv0) - 1; char path[512]; size_t i; v7_val_t res; /* * Point `dir` to the right-most directory separator of the smartjs binary. * Thus string between `s_argv0` and `dir` pointers would contain a directory * name where our executable lives. */ while (dir > s_argv0 && *dir != '/' && *dir != '\\') { dir--; } snprintf(path, sizeof(path), "%.*s/%s", (int) (dir - s_argv0), s_argv0, JS_FS_ROOT); /* All the files, conf, JS, etc are addressed relative to the current dir */ if (chdir(path) != 0) { fprintf(stderr, "cannot chdir to %s\n", path); } sj_init_v7_ext(v7); init_smartjs(v7); /* * Run startup scripts from the directory JS_DIR_NAME. * That directory should be located where the binary (s_argv0) lives. */ for (i = 0; i < sizeof(init_files) / sizeof(init_files[0]); i++) { if (v7_exec_file(v7, &res, init_files[i]) != V7_OK) { fprintf(stderr, "Failed to run %s: ", init_files[i]); v7_fprintln(stderr, v7, res); } } }