static void ev_handler(struct ns_connection *nc, enum ns_event ev, void *p) { struct v7 *v7 = (struct v7 *) nc->server->server_data; struct v7_val *jsconn; printf("C handler: %p %d\n", nc, ev); // Call javascript event handler v7_exec(v7, "ev_handler"); jsconn = v7_push(v7, V7_OBJ); v7_push(v7, V7_NUM)->v.num = ev; v7_push(v7, V7_NUM)->v.num = (unsigned long) p; v7_set_num(jsconn, "nc", (unsigned long) nc); v7_set_str(jsconn, "recv_buf", nc->recv_iobuf.buf, nc->recv_iobuf.len); v7_set_str(jsconn, "send_buf", nc->send_iobuf.buf, nc->send_iobuf.len); v7_set_func(jsconn, "write", js_write); v7_set_func(jsconn, "close", js_close); v7_call(v7, v7_top(v7) - 4); // Exit if we receive string 'exit' if (ev == NS_RECV && (* (int *) p) == 4 && memcmp(nc->recv_iobuf.buf + nc->recv_iobuf.len - 4, "exit", 4) == 0) { s_received_signal = 1; } }
static void call_handler(struct ns_connection *nc, const char *name) { struct v7_val *js_srv = (struct v7_val *) nc->server->server_data; struct v7_val *v, *options = v7_lookup(js_srv, "options"); if ((v = v7_lookup(options, name)) != NULL) { v7_push(s_v7, v); v7_make_and_push(s_v7, V7_OBJ); make_js_conn(v7_top(s_v7)[-1], nc); v7_call(s_v7, 1); } }
// Convert object to string, push string on stack V7_PRIVATE enum v7_err toString(struct v7 *v7, struct v7_val *obj) { struct v7_val *f = NULL; if ((f = v7_get(obj, "toString")) == NULL) { f = v7_get(&s_prototypes[V7_CLASS_OBJECT], "toString"); } CHECK(f != NULL, V7_INTERNAL_ERROR); TRY(v7_push(v7, f)); TRY(v7_call2(v7, obj, 0, 0)); return V7_OK; }
V7_PRIVATE enum v7_err check_str_re_conv(struct v7 *v7, struct v7_val **arg, int re_fl) { /* If argument is not (RegExp + re_fl) or string, do type conversion */ if (!is_string(*arg) && !(re_fl && instanceof(*arg, &s_constructors[V7_CLASS_REGEXP]))) { TRY(toString(v7, *arg)); *arg = v7_top_val(v7); INC_REF_COUNT(*arg); TRY(inc_stack(v7, -2)); TRY(v7_push(v7, *arg)); } return V7_OK; }
V7_PRIVATE enum v7_err v7_make_and_push(struct v7 *v7, enum v7_type type) { struct v7_val *v = make_value(v7, type); CHECK(v != NULL, V7_OUT_OF_MEMORY); return v7_push(v7, v); }
V7_PRIVATE enum v7_err Str_replace(struct v7_c_func_arg *cfa) { #define v7 (cfa->v7) /* Needed for TRY() macro below */ struct v7_val *result = v7_push_new_object(v7); const char *out_str = cfa->this_obj->v.str.buf; uint8_t own = 1; size_t out_len = cfa->this_obj->v.str.len; int old_sp = v7->sp; if (cfa->num_args > 1) { const char *const str_end = cfa->this_obj->v.str.buf + cfa->this_obj->v.str.len; char *p = cfa->this_obj->v.str.buf; uint32_t out_sub_num = 0; struct v7_val *re = cfa->args[0], *str_func = cfa->args[1], *arr = NULL; struct re_tok out_sub[V7_RE_MAX_REPL_SUB], *ptok = out_sub; struct Resub loot; TRY(check_str_re_conv(v7, &re, 1)); TRY(regex_check_prog(re)); if (v7_is_class(str_func, V7_CLASS_FUNCTION)) { arr = v7_push_new_object(v7); v7_set_class(arr, V7_CLASS_ARRAY); TRY(v7_push(v7, str_func)); } else TRY(check_str_re_conv(v7, &str_func, 0)); out_len = 0; do { int i; if (re_exec(re->v.str.prog, re->fl.fl, p, &loot)) break; if (p != loot.sub->start) { ptok->start = p; ptok->end = loot.sub->start; ptok++; out_len += loot.sub->start - p; out_sub_num++; } if (NULL != arr) { /* replace function */ Rune rune; int old_sp = v7->sp, utf_shift = 0; struct v7_val *rez_str; for (i = 0; i < loot.subexpr_num; i++) v7_push_string(v7, loot.sub[i].start, loot.sub[i].end - loot.sub[i].start, 1); for (i = 0; p + i < loot.sub[0].start; i += chartorune(&rune, p + i), utf_shift++) ; TRY(push_number(v7, utf_shift)); TRY(v7_push(v7, cfa->this_obj)); rez_str = v7_call(v7, cfa->this_obj, loot.subexpr_num + 2); TRY(check_str_re_conv(v7, &rez_str, 0)); if (rez_str->v.str.len) { ptok->start = rez_str->v.str.buf; ptok->end = rez_str->v.str.buf + rez_str->v.str.len; ptok++; out_len += rez_str->v.str.len; out_sub_num++; v7_append(v7, arr, rez_str); } TRY(inc_stack(v7, old_sp - v7->sp)); } else { /* replace string */ struct Resub newsub; re_rplc(&loot, p, str_func->v.str.buf, &newsub); for (i = 0; i < newsub.subexpr_num; i++) { ptok->start = newsub.sub[i].start; ptok->end = newsub.sub[i].end; ptok++; out_len += newsub.sub[i].end - newsub.sub[i].start; out_sub_num++; } } p = (char *)loot.sub->end; } while (re->fl.fl.re_g && p < str_end); if (p < str_end) { ptok->start = p; ptok->end = str_end; ptok++; out_len += str_end - p; out_sub_num++; } out_str = malloc(out_len + 1); CHECK(out_str, V7_OUT_OF_MEMORY); ptok = out_sub; p = (char *)out_str; do { size_t ln = ptok->end - ptok->start; memcpy(p, ptok->start, ln); p += ln; ptok++; } while (--out_sub_num); *p = '\0'; own = 0; } TRY(inc_stack(v7, old_sp - v7->sp)); v7_init_str(result, out_str, out_len, own); result->fl.fl.str_alloc = 1; return V7_OK; #undef v7 }