V7_PRIVATE v7_val_t mk_cfunction_obj_with_proto(struct v7 *v7, v7_cfunction_t *f, int num_args, v7_val_t proto) { struct gc_tmp_frame tf = new_tmp_frame(v7); v7_val_t res = mk_cfunction_obj(v7, f, num_args); tmp_stack_push(&tf, &res); v7_def(v7, res, "prototype", 9, (V7_DESC_ENUMERABLE(0) | V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), proto); v7_def(v7, proto, "constructor", 11, V7_DESC_ENUMERABLE(0), res); tmp_frame_cleanup(&tf); return res; }
/* * `on` method on a mqtt client object registers an event handler * for a given event type. Recognized event types: * * - `connect`: invoked on sucessfull connection (mqtt connack message) * - `error`: invoked on connection error * - `close`: invoked when the connection gets closed * - `message`: invoked when a new message is received. The callback * receives (topic, message) arguments, both strings */ enum v7_err MQTT_on(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; v7_val_t evv = v7_arg(v7, 0); v7_val_t cb = v7_arg(v7, 1); const char *ev, *key = NULL; ev = v7_get_cstring(v7, &evv); if (strcmp(ev, "connect") == 0) { key = SJ_MQTT_CONNECT_CB; } else if (strcmp(ev, "message") == 0) { key = SJ_MQTT_MESSAGE_CB; } else if (strcmp(ev, "error") == 0) { key = SJ_MQTT_ERROR_CB; } else if (strcmp(ev, "close") == 0) { key = SJ_MQTT_CLOSE_CB; } else { rcode = v7_throwf(v7, "Error", "unsupported protocol"); goto clean; } v7_def(v7, v7_get_this(v7), key, ~0, V7_DESC_ENUMERABLE(0), cb); (void) res; clean: return rcode; }
V7_PRIVATE val_t mk_js_function(struct v7 *v7, struct v7_generic_object *scope, val_t proto) { struct v7_js_function *f; val_t fval = V7_NULL; struct gc_tmp_frame tf = new_tmp_frame(v7); tmp_stack_push(&tf, &proto); tmp_stack_push(&tf, &fval); f = new_function(v7); if (f == NULL) { /* fval is left `null` */ goto cleanup; } #if defined(V7_ENABLE_ENTITY_IDS) f->base.entity_id_base = V7_ENTITY_ID_PART_OBJ; f->base.entity_id_spec = V7_ENTITY_ID_PART_JS_FUNC; #endif fval = js_function_to_value(f); f->base.properties = NULL; f->scope = scope; /* * Before setting a `V7_OBJ_FUNCTION` flag, make sure we don't have * `V7_OBJ_DENSE_ARRAY` flag set */ assert(!(f->base.attributes & V7_OBJ_DENSE_ARRAY)); f->base.attributes |= V7_OBJ_FUNCTION; /* TODO(mkm): lazily create these properties on first access */ if (v7_is_object(proto)) { v7_def(v7, proto, "constructor", 11, V7_DESC_ENUMERABLE(0), fval); v7_def(v7, fval, "prototype", 9, V7_DESC_ENUMERABLE(0) | V7_DESC_CONFIGURABLE(0), proto); } cleanup: tmp_frame_cleanup(&tf); return fval; }
V7_PRIVATE v7_val_t mk_cfunction_obj(struct v7 *v7, v7_cfunction_t *f, int num_args) { val_t obj = mk_object(v7, v7->vals.function_prototype); struct gc_tmp_frame tf = new_tmp_frame(v7); tmp_stack_push(&tf, &obj); v7_def(v7, obj, "", 0, _V7_DESC_HIDDEN(1), v7_mk_cfunction(f)); if (num_args >= 0) { v7_def(v7, obj, "length", 6, (V7_DESC_ENUMERABLE(0) | V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), v7_mk_number(v7, num_args)); } tmp_frame_cleanup(&tf); return obj; }
static enum v7_err MyThing_ctor(struct v7 *v7, v7_val_t *res) { v7_val_t this_obj = v7_get_this(v7); v7_val_t arg0 = v7_arg(v7, 0); v7_def(v7, this_obj, "__arg", ~0 /* = strlen */, V7_DESC_ENUMERABLE(0), arg0); /* * A constructor function can access the newly created object with * `v7_get_this()`. The constructor can override the result of the `new` * expression by explicitly setting `res` to another object. Any non-object * value set into `res` will be ignored. This matches the JavaScript * constructor return value semantics. */ (void) res; /* no warning */ return V7_OK; }
void sj_mqtt_api_setup(struct v7 *v7) { v7_val_t mqtt_proto = v7_mk_object(v7); v7_val_t mqtt_connect = v7_mk_function_with_proto(v7, sj_mqtt_connect, mqtt_proto); v7_val_t mqtt; v7_own(v7, &mqtt_connect); mqtt = v7_mk_object(v7); v7_own(v7, &mqtt); v7_set(v7, mqtt, "connect", ~0, mqtt_connect); v7_def(v7, mqtt, "proto", ~0, V7_DESC_ENUMERABLE(0), mqtt_proto); v7_set_method(v7, mqtt_proto, "publish", MQTT_publish); v7_set_method(v7, mqtt_proto, "subscribe", MQTT_subscribe); v7_set_method(v7, mqtt_proto, "on", MQTT_on); v7_set(v7, v7_get_global(v7), "MQTT", ~0, mqtt); v7_disown(v7, &mqtt); v7_disown(v7, &mqtt_connect); }
void init_updater_clubby(struct v7 *v7) { (void) v7; #ifndef DISABLE_C_CLUBBY #ifndef CS_DISABLE_JS s_v7 = v7; v7_val_t updater = v7_mk_object(v7); v7_val_t sys = v7_get(v7, v7_get_global(v7), "Sys", ~0); s_updater_notify_cb = V7_UNDEFINED; v7_own(v7, &s_updater_notify_cb); v7_def(v7, sys, "updater", ~0, V7_DESC_ENUMERABLE(0), updater); v7_set_method(v7, updater, "notify", Updater_notify); v7_set_method(v7, updater, "start", Updater_startupdate); v7_def(s_v7, updater, "GOT_REQUEST", ~0, (V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), v7_mk_number(v7, UJS_GOT_REQUEST)); v7_def(s_v7, updater, "COMPLETED", ~0, (V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), v7_mk_number(v7, UJS_COMPLETED)); v7_def(s_v7, updater, "NOTHING_TODO", ~0, (V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), v7_mk_number(v7, UJS_NOTHING_TODO)); v7_def(s_v7, updater, "FAILED", ~0, (V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), v7_mk_number(v7, UJS_ERROR)); #endif sj_clubby_register_global_command("/v1/SWUpdate.Update", handle_update_req, NULL); sj_clubby_register_global_command(clubby_cmd_ready, handle_clubby_ready, NULL); #endif }