static void call_sum(struct v7 *v7) { v7_val_t func, result, args; func = v7_get(v7, v7_get_global_object(v7), "sum", 3); args = v7_create_array(v7); v7_array_push(v7, args, v7_create_number(123.0)); v7_array_push(v7, args, v7_create_number(456.789)); v7_apply(v7, &result, func, v7_create_undefined(), args); printf("Result: %g\n", v7_to_number(result)); }
static v7_val_t OS_prof(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { v7_val_t result = v7_create_object(v7); v7_own(v7, &result); v7_set(v7, result, "sysfree", 7, 0, v7_create_number(sj_get_free_heap_size())); v7_set(v7, result, "used_by_js", 10, 0, v7_create_number(v7_heap_stat(v7, V7_HEAP_STAT_HEAP_USED))); v7_set(v7, result, "used_by_fs", 10, 0, v7_create_number(sj_get_fs_memory_usage())); v7_disown(v7, &result); return result; }
static v7_val_t js_sum(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { double arg0 = v7_to_number(v7_array_get(v7, args, 0)); double arg1 = v7_to_number(v7_array_get(v7, args, 1)); double result = sum(arg0, arg1); (void) this_obj; /* unused */ return v7_create_number(result); }
V7_PRIVATE val_t rx_exec(struct v7 *v7, val_t rx, val_t str, int lind) { if (v7_is_regexp(rx)) { val_t s = to_string(v7, str); size_t len; struct slre_loot sub; struct slre_cap *ptok = sub.caps; char *const str = (char *) v7_to_string(v7, &s, &len); const char *const end = str + len; const char *begin = str; struct v7_regexp *rp = v7_to_regexp(rx); int flag_g = slre_get_flags(rp->compiled_regexp) & SLRE_FLAG_G; if (rp->lastIndex < 0) rp->lastIndex = 0; if (flag_g || lind) begin = utfnshift(str, rp->lastIndex); if (!slre_exec(rp->compiled_regexp, 0, begin, end, &sub)) { int i; val_t arr = v7_create_array(v7); for (i = 0; i < sub.num_captures; i++, ptok++) v7_array_push(v7, arr, v7_create_string(v7, ptok->start, ptok->end - ptok->start, 1)); if (flag_g) rp->lastIndex = utfnlen(str, sub.caps->end - str); v7_set_property(v7, arr, "index", 5, V7_PROPERTY_READ_ONLY, v7_create_number(utfnlen(str, sub.caps->start - str))); return arr; } else rp->lastIndex = 0; } return v7_create_null(); }
static val_t Regex_set_lastIndex(struct v7 *v7, val_t this_obj, val_t args) { long lastIndex = 0; if (v7_is_regexp(this_obj)) v7_to_regexp(this_obj)->lastIndex = lastIndex = arg_long(v7, args, 0, 0); return v7_create_number(lastIndex); }
/* * Returns an object describing the free memory. */ ICACHE_FLASH_ATTR static v7_val_t GC_stat(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { v7_val_t f = v7_create_object(v7); /* prevent the object from being potentially GCed */ v7_set(v7, args, "_tmp", 4, 0, f); v7_set(v7, f, "sysfree", 7, 0, v7_create_number(system_get_free_heap_size())); return f; }
ICACHE_FLASH_ATTR void init_v7() { struct v7_create_opts opts; v7_val_t wifi, gpio, dht11, gc, debug; opts.object_arena_size = 94; opts.function_arena_size = 17; opts.property_arena_size = 340; v7 = v7_create_opt(opts); v7_set_method(v7, v7_get_global_object(v7), "usleep", usleep); v7_set_method(v7, v7_get_global_object(v7), "setTimeout", set_timeout); gpio = v7_create_object(v7); v7_set(v7, v7_get_global_object(v7), "GPIO", 4, 0, gpio); v7_set_method(v7, gpio, "in", GPIO_in); v7_set_method(v7, gpio, "out", GPIO_out); wifi = v7_create_object(v7); v7_set(v7, v7_get_global_object(v7), "Wifi", 4, 0, wifi); v7_set_method(v7, wifi, "setup", Wifi_setup); v7_set_method(v7, wifi, "disconnect", Wifi_disconnect); v7_set_method(v7, wifi, "connect", Wifi_connect); v7_set_method(v7, wifi, "status", Wifi_status); v7_set_method(v7, wifi, "ip", Wifi_ip); v7_set(v7, wifi, "STATION", 7, 0, v7_create_number(0)); v7_set(v7, wifi, "SOFTAP", 6, 0, v7_create_number(1)); #if V7_ESP_ENABLE__DHT11 dht11 = v7_create_object(v7); v7_set(v7, v7_get_global_object(v7), "DHT11", 5, 0, dht11); v7_set_method(v7, dht11, "read", DHT11_read); #endif /* V7_ESP_ENABLE__DHT11 */ gc = v7_create_object(v7); v7_set(v7, v7_get_global_object(v7), "GC", 2, 0, gc); v7_set_method(v7, gc, "stat", GC_stat); v7_set_method(v7, gc, "collect", GC_collect); debug = v7_create_object(v7); v7_set(v7, v7_get_global_object(v7), "Debug", 5, 0, debug); v7_set_method(v7, debug, "setOutput", Debug_set_output); v7_set_method(v7, debug, "print", Debug_print); v7_init_http_client(v7); }
static val_t Regex_get_lastIndex(struct v7 *v7, val_t this_obj, val_t args) { long lastIndex = 0; (void) v7; (void) args; if (v7_is_regexp(this_obj)) lastIndex = v7_to_regexp(this_obj)->lastIndex; return v7_create_number(lastIndex); }
static void gpio_intr_handler_proxy(int pin, int level) { char prop_name[15]; int len; v7_val_t args; len = snprintf(prop_name, sizeof(prop_name), "_ih_%d", (int) pin); v7_val_t cb = v7_get(s_v7, v7_get_global_object(s_v7), prop_name, len); if (!v7_is_function(cb)) { return; } args = v7_create_array(s_v7); v7_array_push(s_v7, args, v7_create_number(pin)); v7_array_push(s_v7, args, v7_create_number(level)); v7_apply(s_v7, cb, v7_create_undefined(), args); }
static v7_val_t GPIO_read(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { v7_val_t pinv = v7_array_get(v7, args, 0); int pin; if (!v7_is_number(pinv)) { printf("non-numeric pin\n"); return v7_create_undefined(); } pin = v7_to_number(pinv); return v7_create_number(sj_gpio_read(pin)); }
static v7_val_t DHT11_read(struct v7 *v7) { int pin, temp, rh; v7_val_t pinv = v7_arg(v7, 0), result; if (!v7_is_number(pinv)) { printf("non-numeric pin\n"); return v7_create_undefined(); } pin = v7_to_number(pinv); if (!dht11_read(pin, &temp, &rh)) { return v7_create_null(); } result = v7_create_object(v7); v7_own(v7, &result); v7_set(v7, result, "temp", 4, 0, v7_create_number(temp)); v7_set(v7, result, "rh", 2, 0, v7_create_number(rh)); v7_disown(v7, &result); return result; }
ICACHE_FLASH_ATTR static v7_val_t DHT11_read(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { int pin, temp, rh; v7_val_t pinv = v7_array_get(v7, args, 0), result; if (!v7_is_double(pinv)) { printf("non-numeric pin\n"); return v7_create_undefined(); } pin = v7_to_double(pinv); if (!dht11_read(pin, &temp, &rh)) { return v7_create_null(); } result = v7_create_object(v7); v7_set(v7, result, "temp", 4, 0, v7_create_number(temp)); v7_set(v7, result, "rh", 2, 0, v7_create_number(rh)); /* prevent the object from being potentially GCed */ v7_set(v7, args, "_tmp", 4, 0, result); return result; }
static void gpio_intr_handler_proxy(int pin, int level) { char prop_name[15]; int len; v7_val_t res, args; len = snprintf(prop_name, sizeof(prop_name), "_ih_%d", (int) pin); v7_val_t cb = v7_get(s_v7, v7_get_global(s_v7), prop_name, len); if (!v7_is_function(cb)) { return; } args = v7_create_array(s_v7); v7_array_push(s_v7, args, v7_create_number(pin)); v7_array_push(s_v7, args, v7_create_number(level)); if (v7_apply(s_v7, cb, v7_create_undefined(), args, &res) != V7_OK) { /* TODO(mkm): make it print stack trace */ fprintf(stderr, "cb threw an exception\n"); } }
static v7_val_t gsm_call(struct v7* v7) { v7_val_t numberv = v7_arg(v7, 0); const char* number; size_t len; if(!v7_is_string(numberv)) { return v7_create_undefined(); } number = v7_to_string(v7, &numberv, &len); return v7_create_number(_gsm_call(number)); }
static enum v7_err GPIO_read(struct v7 *v7, v7_val_t *res) { v7_val_t pinv = v7_arg(v7, 0); int pin; if (!v7_is_number(pinv)) { printf("non-numeric pin\n"); *res = v7_create_undefined(); } else { pin = v7_to_number(pinv); *res = v7_create_number(sj_gpio_read(pin)); } return V7_OK; }
static enum v7_err DHT11_read(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; int pin, temp, rh; v7_val_t pinv = v7_arg(v7, 0); if (!v7_is_number(pinv)) { printf("non-numeric pin\n"); *res = v7_create_undefined(); goto clean; } pin = v7_to_number(pinv); if (!dht11_read(pin, &temp, &rh)) { *res = v7_create_null(); goto clean; } *res = v7_create_object(v7); v7_set(v7, *res, "temp", 4, 0, v7_create_number(temp)); v7_set(v7, *res, "rh", 2, 0, v7_create_number(rh)); clean: return rcode; }
/* * Sets output for debug messages. * Available modes are: * 0 - no debug output * 1 - print debug output to UART0 (V7's console) * 2 - print debug output to UART1 */ static v7_val_t Debug_mode(struct v7 *v7) { int mode, res; v7_val_t output_val = v7_arg(v7, 0); if (!v7_is_number(output_val)) { printf("Output is not a number\n"); return v7_create_undefined(); } mode = v7_to_number(output_val); uart_debug_init(0, 0); res = uart_redirect_debug(mode); return v7_create_number(res < 0 ? res : mode); }
/* * Sets output for debug messages. * Available modes are: * 0 - no debug output * 1 - print debug output to UART0 (V7's console) * 2 - print debug output to UART1 */ ICACHE_FLASH_ATTR static v7_val_t Debug_set_output(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { int mode, res; v7_val_t output_val = v7_array_get(v7, args, 0); if (!v7_is_double(output_val)) { printf("Output is not a number\n"); return v7_create_undefined(); } mode = v7_to_double(output_val); uart_debug_init(0, 0); res = uart_redirect_debug(mode); return v7_create_number(res < 0 ? res : mode); }
static v7_val_t gsm_answer(struct v7* v7) { int result; vm_gsm_tel_single_call_action_request_t req; vm_gsm_tel_call_actions_data_t data; req.action_id.sim = g_uid_info.sim; req.action_id.call_id = g_uid_info.call_id; req.action_id.group_id = g_uid_info.group_id; data.action = VM_GSM_TEL_CALL_ACTION_ACCEPT; data.data_action = (void*)&req; data.user_data = NULL; data.callback = call_voiceCall_callback; result = vm_gsm_tel_call_actions(&data); return v7_create_number(result); }
int main(void) { struct v7 *v7 = v7_create(); v7_val_t ctor_func, proto, eval_result; proto = v7_create_object(v7); ctor_func = v7_create_constructor(v7, proto, MyThing_ctor, 1); v7_set(v7, ctor_func, "MY_CONST", ~0, V7_PROPERTY_READ_ONLY | V7_PROPERTY_DONT_DELETE, v7_create_number(123)); v7_set_method(v7, proto, "myMethod", &MyThing_myMethod); v7_set(v7, v7_get_global_object(v7), "MyThing", ~0, 0, ctor_func); v7_exec(v7, &eval_result, "\ print('MyThing.MY_CONST = ', MyThing.MY_CONST); \ var t = new MyThing(456); \ print('t.MY_CONST = ', t.MY_CONST); \ print('t.myMethod = ', t.myMethod); \ print('t.myMethod() = ', t.myMethod());"); v7_destroy(v7); return 0; }
/* * Sets output for debug messages. * Available modes are: * 0 - no debug output * 1 - print debug output to UART0 (V7's console) * 2 - print debug output to UART1 */ static enum v7_err Debug_mode(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; int mode, ires; v7_val_t output_val = v7_arg(v7, 0); if (!v7_is_number(output_val)) { printf("Output is not a number\n"); *res = v7_create_undefined(); goto clean; } mode = v7_to_number(output_val); uart_debug_init(0, 0); ires = uart_redirect_debug(mode); *res = v7_create_number(ires < 0 ? ires : mode); goto clean; clean: return rcode; }
static v7_val_t gsm_text(struct v7* v7) { VMWCHAR number[42]; VMWCHAR content[100]; v7_val_t numberv = v7_arg(v7, 0); v7_val_t messagev = v7_arg(v7, 1); const char* phone_number; const char* message; size_t len, message_len; if(!v7_is_string(numberv) || !v7_is_string(messagev)) { return v7_create_undefined(); } phone_number = v7_to_string(v7, &numberv, &len); message = v7_to_string(v7, &messagev, &message_len); vm_chset_ascii_to_ucs2(content, 100 * 2, message); vm_chset_ascii_to_ucs2(number, 42 * 2, phone_number); return v7_create_number(vm_gsm_sms_send(number, content, _gsm_text_callback, NULL)); }
// JS: i2c.setup(address, speed) static v7_val_t i2c_setup(struct v7 *v7) { vm_dcl_i2c_control_config_t conf_data; int result; v7_val_t addressv = v7_arg(v7, 0); v7_val_t speedv = v7_arg(v7, 1); int address, speed; if(!v7_is_number(addressv) || !v7_is_number(speedv)) { printf("Invalid arguments\n"); return v7_create_undefined(); } address = v7_to_number(addressv); speed = v7_to_number(speedv); if(speed >= 400) { conf_data.transaction_mode = VM_DCL_I2C_TRANSACTION_HIGH_SPEED_MODE; } else { conf_data.transaction_mode = VM_DCL_I2C_TRANSACTION_FAST_MODE; } if(g_i2c_handle == VM_DCL_HANDLE_INVALID) { g_i2c_handle = vm_dcl_open(VM_DCL_I2C, 0); } conf_data.reserved_0 = (VM_DCL_I2C_OWNER)0; conf_data.get_handle_wait = TRUE; conf_data.reserved_1 = 0; conf_data.delay_length = 0; conf_data.slave_address = (address << 1); conf_data.fast_mode_speed = speed; conf_data.high_mode_speed = 0; result = vm_dcl_control(g_i2c_handle, VM_DCL_I2C_CMD_CONFIG, &conf_data); return v7_create_number(result); }
static v7_val_t gsm_hang(struct v7* v7) { int result = 0; vm_gsm_tel_single_call_action_request_t req; vm_gsm_tel_call_actions_data_t data; if(IDLE_CALL != g_call_status) { req.action_id.sim = g_uid_info.sim; req.action_id.call_id = g_uid_info.call_id; req.action_id.group_id = g_uid_info.group_id; // req.action_id.sim = 1; // req.action_id.call_id = 1; // req.action_id.group_id = 1; data.action = VM_GSM_TEL_CALL_ACTION_END_SINGLE; data.data_action = (void*)&req; data.user_data = NULL; data.callback = call_voiceCall_callback; result = vm_gsm_tel_call_actions(&data); } return v7_create_number(result); }
void sj_wifi_on_change_callback(enum sj_wifi_status event) { struct v7 *v7 = s_v7; v7_val_t cb = v7_get(v7, s_wifi, "_ccb", ~0); if (v7_is_undefined(cb) || v7_is_null(cb)) return; sj_invoke_cb1(s_v7, cb, v7_create_number(event)); }
/* * Returns an object describing the free memory. * * sysfree: free system heap bytes * jssize: size of JS heap in bytes * jsfree: free JS heap bytes * strres: size of reserved string heap in bytes * struse: portion of string heap with used data * objnfree: number of free object slots in js heap * propnfree: number of free property slots in js heap * funcnfree: number of free function slots in js heap */ static v7_val_t GC_stat(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { /* take a snapshot of the stats that would change as we populate the result */ size_t sysfree = sj_get_free_heap_size(); size_t jssize = v7_heap_stat(v7, V7_HEAP_STAT_HEAP_SIZE); size_t jsfree = jssize - v7_heap_stat(v7, V7_HEAP_STAT_HEAP_USED); size_t strres = v7_heap_stat(v7, V7_HEAP_STAT_STRING_HEAP_RESERVED); size_t struse = v7_heap_stat(v7, V7_HEAP_STAT_STRING_HEAP_USED); size_t objfree = v7_heap_stat(v7, V7_HEAP_STAT_OBJ_HEAP_FREE); size_t propnfree = v7_heap_stat(v7, V7_HEAP_STAT_PROP_HEAP_FREE); v7_val_t f = v7_create_undefined(); v7_own(v7, &f); f = v7_create_object(v7); v7_set(v7, f, "sysfree", ~0, 0, v7_create_number(sysfree)); v7_set(v7, f, "jssize", ~0, 0, v7_create_number(jssize)); v7_set(v7, f, "jsfree", ~0, 0, v7_create_number(jsfree)); v7_set(v7, f, "strres", ~0, 0, v7_create_number(strres)); v7_set(v7, f, "struse", ~0, 0, v7_create_number(struse)); v7_set(v7, f, "objfree", ~0, 0, v7_create_number(objfree)); v7_set(v7, f, "objncell", ~0, 0, v7_create_number(v7_heap_stat(v7, V7_HEAP_STAT_OBJ_HEAP_CELL_SIZE))); v7_set(v7, f, "propnfree", ~0, 0, v7_create_number(propnfree)); v7_set(v7, f, "propncell", ~0, 0, v7_create_number(v7_heap_stat(v7, V7_HEAP_STAT_PROP_HEAP_CELL_SIZE))); v7_set(v7, f, "funcnfree", ~0, 0, v7_create_number(v7_heap_stat(v7, V7_HEAP_STAT_FUNC_HEAP_FREE))); v7_set(v7, f, "funcncell", ~0, 0, v7_create_number(v7_heap_stat(v7, V7_HEAP_STAT_FUNC_HEAP_CELL_SIZE))); v7_set(v7, f, "astsize", ~0, 0, v7_create_number(v7_heap_stat(v7, V7_HEAP_STAT_FUNC_AST_SIZE))); v7_set(v7, f, "owned", ~0, 0, v7_create_number(v7_heap_stat(v7, V7_HEAP_STAT_FUNC_OWNED))); v7_set(v7, f, "owned_max", ~0, 0, v7_create_number(v7_heap_stat(v7, V7_HEAP_STAT_FUNC_OWNED_MAX))); v7_disown(v7, &f); return f; }
v7_val_t v7_file_to_val(int fd) { return v7_create_number(fd); }
ICACHE_FLASH_ATTR v7_val_t v7_file_to_val(int fd) { return v7_create_number(fd); }