mirror of https://github.com/arendst/Tasmota.git
Merge pull request #14020 from s-hadinger/berry_mapping_1
Berry mapping step 1
This commit is contained in:
commit
0c4a5baa48
|
@ -23,6 +23,10 @@ be_extern_native_module(solidify);
|
|||
be_extern_native_module(introspect);
|
||||
be_extern_native_module(strict);
|
||||
|
||||
/* Berry extensions */
|
||||
#include "be_mapping.h"
|
||||
be_extern_native_module(cb);
|
||||
|
||||
/* Tasmota specific */
|
||||
be_extern_native_module(python_compat);
|
||||
be_extern_native_module(re);
|
||||
|
@ -85,6 +89,10 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
|
|||
#if BE_USE_STRICT_MODULE
|
||||
&be_native_module(strict),
|
||||
#endif
|
||||
|
||||
/* Berry extensions */
|
||||
&be_native_module(cb),
|
||||
|
||||
/* user-defined modules register start */
|
||||
|
||||
&be_native_module(python_compat),
|
||||
|
|
|
@ -16,7 +16,6 @@ extern int l_arch(bvm *vm);
|
|||
extern int l_publish(bvm *vm);
|
||||
extern int l_publish_result(bvm *vm);
|
||||
extern int l_cmd(bvm *vm);
|
||||
extern int l_get_cb(bvm *vm);
|
||||
extern int l_getoption(bvm *vm);
|
||||
extern int l_millis(bvm *vm);
|
||||
extern int l_timereached(bvm *vm);
|
||||
|
@ -384,7 +383,7 @@ be_local_closure(Tasmota_try_rule, /* name */
|
|||
********************************************************************/
|
||||
be_local_closure(Tasmota_gen_cb, /* name */
|
||||
be_nested_proto(
|
||||
7, /* nstack */
|
||||
6, /* nstack */
|
||||
2, /* argc */
|
||||
0, /* varg */
|
||||
0, /* has upvals */
|
||||
|
@ -392,52 +391,18 @@ be_local_closure(Tasmota_gen_cb, /* name */
|
|||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[ 7]) { /* constants */
|
||||
/* K0 */ be_nested_str(_cb),
|
||||
/* K1 */ be_const_int(0),
|
||||
/* K2 */ be_nested_str(find),
|
||||
/* K3 */ be_nested_str(_get_cb),
|
||||
/* K4 */ be_nested_str(stop_iteration),
|
||||
/* K5 */ be_nested_str(internal_error),
|
||||
/* K6 */ be_nested_str(No_X20callback_X20available),
|
||||
( &(const bvalue[ 2]) { /* constants */
|
||||
/* K0 */ be_nested_str(cb),
|
||||
/* K1 */ be_nested_str(gen_cb),
|
||||
}),
|
||||
&be_const_str_gen_cb,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[34]) { /* code */
|
||||
0x88080100, // 0000 GETMBR R2 R0 K0
|
||||
0x4C0C0000, // 0001 LDNIL R3
|
||||
0x1C080403, // 0002 EQ R2 R2 R3
|
||||
0x780A0002, // 0003 JMPF R2 #0007
|
||||
0x60080013, // 0004 GETGBL R2 G19
|
||||
0x7C080000, // 0005 CALL R2 0
|
||||
0x90020002, // 0006 SETMBR R0 K0 R2
|
||||
0x60080010, // 0007 GETGBL R2 G16
|
||||
0x540E0012, // 0008 LDINT R3 19
|
||||
0x400E0203, // 0009 CONNECT R3 K1 R3
|
||||
0x7C080200, // 000A CALL R2 1
|
||||
0xA8020010, // 000B EXBLK 0 #001D
|
||||
0x5C0C0400, // 000C MOVE R3 R2
|
||||
0x7C0C0000, // 000D CALL R3 0
|
||||
0x88100100, // 000E GETMBR R4 R0 K0
|
||||
0x8C100902, // 000F GETMET R4 R4 K2
|
||||
0x5C180600, // 0010 MOVE R6 R3
|
||||
0x7C100400, // 0011 CALL R4 2
|
||||
0x4C140000, // 0012 LDNIL R5
|
||||
0x1C100805, // 0013 EQ R4 R4 R5
|
||||
0x78120006, // 0014 JMPF R4 #001C
|
||||
0x88100100, // 0015 GETMBR R4 R0 K0
|
||||
0x98100601, // 0016 SETIDX R4 R3 R1
|
||||
0x8C100103, // 0017 GETMET R4 R0 K3
|
||||
0x5C180600, // 0018 MOVE R6 R3
|
||||
0x7C100400, // 0019 CALL R4 2
|
||||
0xA8040001, // 001A EXBLK 1 1
|
||||
0x80040800, // 001B RET 1 R4
|
||||
0x7001FFEE, // 001C JMP #000C
|
||||
0x58080004, // 001D LDCONST R2 K4
|
||||
0xAC080200, // 001E CATCH R2 1 0
|
||||
0xB0080000, // 001F RAISE 2 R0 R0
|
||||
0xB0060B06, // 0020 RAISE 1 K5 K6
|
||||
0x80000000, // 0021 RET 0
|
||||
( &(const binstruction[ 5]) { /* code */
|
||||
0xA40A0000, // 0000 IMPORT R2 K0
|
||||
0x8C0C0501, // 0001 GETMET R3 R2 K1
|
||||
0x5C140200, // 0002 MOVE R5 R1
|
||||
0x7C0C0400, // 0003 CALL R3 2
|
||||
0x80040600, // 0004 RET 1 R3
|
||||
})
|
||||
)
|
||||
);
|
||||
|
@ -1605,53 +1570,6 @@ be_local_closure(Tasmota_exec_rules, /* name */
|
|||
/*******************************************************************/
|
||||
|
||||
|
||||
/********************************************************************
|
||||
** Solidified function: cb_dispatch
|
||||
********************************************************************/
|
||||
be_local_closure(Tasmota_cb_dispatch, /* name */
|
||||
be_nested_proto(
|
||||
12, /* nstack */
|
||||
6, /* argc */
|
||||
0, /* varg */
|
||||
0, /* has upvals */
|
||||
NULL, /* no upvals */
|
||||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[ 3]) { /* constants */
|
||||
/* K0 */ be_nested_str(_cb),
|
||||
/* K1 */ be_const_int(0),
|
||||
/* K2 */ be_nested_str(find),
|
||||
}),
|
||||
&be_const_str_cb_dispatch,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[20]) { /* code */
|
||||
0x88180100, // 0000 GETMBR R6 R0 K0
|
||||
0x4C1C0000, // 0001 LDNIL R7
|
||||
0x1C180C07, // 0002 EQ R6 R6 R7
|
||||
0x781A0000, // 0003 JMPF R6 #0005
|
||||
0x80060200, // 0004 RET 1 K1
|
||||
0x88180100, // 0005 GETMBR R6 R0 K0
|
||||
0x8C180D02, // 0006 GETMET R6 R6 K2
|
||||
0x5C200200, // 0007 MOVE R8 R1
|
||||
0x7C180400, // 0008 CALL R6 2
|
||||
0x4C1C0000, // 0009 LDNIL R7
|
||||
0x201C0C07, // 000A NE R7 R6 R7
|
||||
0x781E0006, // 000B JMPF R7 #0013
|
||||
0x5C1C0C00, // 000C MOVE R7 R6
|
||||
0x5C200400, // 000D MOVE R8 R2
|
||||
0x5C240600, // 000E MOVE R9 R3
|
||||
0x5C280800, // 000F MOVE R10 R4
|
||||
0x5C2C0A00, // 0010 MOVE R11 R5
|
||||
0x7C1C0800, // 0011 CALL R7 4
|
||||
0x80040E00, // 0012 RET 1 R7
|
||||
0x80060200, // 0013 RET 1 K1
|
||||
})
|
||||
)
|
||||
);
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/********************************************************************
|
||||
** Solidified function: hs2rgb
|
||||
********************************************************************/
|
||||
|
@ -2072,7 +1990,6 @@ class be_class_tasmota (scope: global, name: Tasmota) {
|
|||
_timers, var
|
||||
_ccmd, var
|
||||
_drivers, var
|
||||
_cb, var
|
||||
wire1, var
|
||||
wire2, var
|
||||
global, var
|
||||
|
@ -2094,7 +2011,6 @@ class be_class_tasmota (scope: global, name: Tasmota) {
|
|||
publish, func(l_publish)
|
||||
publish_result, func(l_publish_result)
|
||||
_cmd, func(l_cmd)
|
||||
_get_cb, func(l_get_cb)
|
||||
get_option, func(l_getoption)
|
||||
millis, func(l_millis)
|
||||
time_reached, func(l_timereached)
|
||||
|
@ -2155,7 +2071,6 @@ class be_class_tasmota (scope: global, name: Tasmota) {
|
|||
|
||||
hs2rgb, closure(Tasmota_hs2rgb_closure)
|
||||
|
||||
cb_dispatch, closure(Tasmota_cb_dispatch_closure)
|
||||
gen_cb, closure(Tasmota_gen_cb_closure)
|
||||
|
||||
get_light, closure(Tasmota_get_light_closure)
|
||||
|
|
|
@ -65,20 +65,14 @@
|
|||
**/
|
||||
#define BE_DEBUG_VAR_INFO 0
|
||||
|
||||
/* Macro: BE_USE_OBSERVABILITY_HOOK
|
||||
* Use the obshook function to report low-level actions.
|
||||
* Default: 0
|
||||
**/
|
||||
#define BE_USE_OBSERVABILITY_HOOK 1
|
||||
|
||||
/* Macro: BE_USE_OBSERVABILITY_HOOK
|
||||
/* Macro: BE_USE_PERF_COUNTERS
|
||||
* Use the obshook function to report low-level actions.
|
||||
* Default: 0
|
||||
**/
|
||||
#define BE_USE_PERF_COUNTERS 1
|
||||
|
||||
/* Macro: BE_VM_OBSERVABILITY_SAMPLING
|
||||
* If BE_USE_OBSERVABILITY_HOOK == 1 and BE_USE_PERF_COUNTERS == 1
|
||||
* If BE_USE_PERF_COUNTERS == 1
|
||||
* then the observability hook is called regularly in the VM loop
|
||||
* allowing to stop infinite loops or too-long running code.
|
||||
* The value is a power of 2.
|
||||
|
|
|
@ -21,7 +21,6 @@ class Tasmota
|
|||
var _timers
|
||||
var _ccmd
|
||||
var _drivers
|
||||
var _cb
|
||||
var wire1
|
||||
var wire2
|
||||
var cmd_res # store the command result, nil if disables, true if capture enabled, contains return value
|
||||
|
@ -520,28 +519,11 @@ class Tasmota
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
#- dispatch callback number n, with parameters v0,v1,v2,v3 -#
|
||||
def cb_dispatch(n,v0,v1,v2,v3)
|
||||
if self._cb == nil return 0 end
|
||||
var f = self._cb.find(n)
|
||||
if f != nil
|
||||
return f(v0,v1,v2,v3)
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
#- generate a new C callback and record the associated Berry closure -#
|
||||
def gen_cb(f)
|
||||
if self._cb == nil self._cb = {} end # create map if not already initialized
|
||||
for i:0..19
|
||||
if self._cb.find(i) == nil
|
||||
#- free slot -#
|
||||
self._cb[i] = f
|
||||
return self._get_cb(i)
|
||||
end
|
||||
end
|
||||
raise "internal_error", "No callback available"
|
||||
# DEPRECATED
|
||||
import cb
|
||||
return cb.gen_cb(f)
|
||||
end
|
||||
|
||||
#- convert hue/sat to rgb -#
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
python3 tools/pycoc/main.py -o generate src default ../berry_mapping/src -c default/berry_conf.h
|
|
@ -48,7 +48,6 @@ extern const bcstring be_const_str_I2C_X3A;
|
|||
extern const bcstring be_const_str_LVG_X3A_X20call_X20to_X20unsupported_X20callback;
|
||||
extern const bcstring be_const_str_Leds;
|
||||
extern const bcstring be_const_str_MD5;
|
||||
extern const bcstring be_const_str_No_X20callback_X20available;
|
||||
extern const bcstring be_const_str_None;
|
||||
extern const bcstring be_const_str_OPTION_A;
|
||||
extern const bcstring be_const_str_OneWire;
|
||||
|
@ -175,7 +174,6 @@ extern const bcstring be_const_str__archive;
|
|||
extern const bcstring be_const_str__available;
|
||||
extern const bcstring be_const_str__begin_transmission;
|
||||
extern const bcstring be_const_str__buffer;
|
||||
extern const bcstring be_const_str__cb;
|
||||
extern const bcstring be_const_str__ccmd;
|
||||
extern const bcstring be_const_str__class;
|
||||
extern const bcstring be_const_str__cmd;
|
||||
|
@ -187,7 +185,6 @@ extern const bcstring be_const_str__end_transmission;
|
|||
extern const bcstring be_const_str__energy;
|
||||
extern const bcstring be_const_str__error;
|
||||
extern const bcstring be_const_str__filename;
|
||||
extern const bcstring be_const_str__get_cb;
|
||||
extern const bcstring be_const_str__global_addr;
|
||||
extern const bcstring be_const_str__global_def;
|
||||
extern const bcstring be_const_str__lvgl;
|
||||
|
@ -250,7 +247,7 @@ extern const bcstring be_const_str_call;
|
|||
extern const bcstring be_const_str_call_native;
|
||||
extern const bcstring be_const_str_calldepth;
|
||||
extern const bcstring be_const_str_can_show;
|
||||
extern const bcstring be_const_str_cb_dispatch;
|
||||
extern const bcstring be_const_str_cb;
|
||||
extern const bcstring be_const_str_cb_do_nothing;
|
||||
extern const bcstring be_const_str_cb_event_closure;
|
||||
extern const bcstring be_const_str_cb_obj;
|
||||
|
@ -384,6 +381,7 @@ extern const bcstring be_const_str_get_bat_power;
|
|||
extern const bcstring be_const_str_get_bat_voltage;
|
||||
extern const bcstring be_const_str_get_battery_chargin_status;
|
||||
extern const bcstring be_const_str_get_bri;
|
||||
extern const bcstring be_const_str_get_cb_list;
|
||||
extern const bcstring be_const_str_get_coords;
|
||||
extern const bcstring be_const_str_get_current_module_name;
|
||||
extern const bcstring be_const_str_get_current_module_path;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,96 +1,93 @@
|
|||
#include "be_constobj.h"
|
||||
|
||||
static be_define_const_map_slots(be_class_tasmota_map) {
|
||||
{ be_const_key(gc, -1), be_const_closure(Tasmota_gc_closure) },
|
||||
{ be_const_key(read_sensors, 7), be_const_func(l_read_sensors) },
|
||||
{ be_const_key(_get_cb, -1), be_const_func(l_get_cb) },
|
||||
{ be_const_key(response_append, 50), be_const_func(l_respAppend) },
|
||||
{ be_const_key(try_rule, 74), be_const_closure(Tasmota_try_rule_closure) },
|
||||
{ be_const_key(eth, -1), be_const_func(l_eth) },
|
||||
{ be_const_key(find_key_i, -1), be_const_closure(Tasmota_find_key_i_closure) },
|
||||
{ be_const_key(exec_tele, 73), be_const_closure(Tasmota_exec_tele_closure) },
|
||||
{ be_const_key(remove_driver, 28), be_const_closure(Tasmota_remove_driver_closure) },
|
||||
{ be_const_key(load, -1), be_const_closure(Tasmota_load_closure) },
|
||||
{ be_const_key(_settings_ptr, -1), be_const_comptr(&Settings) },
|
||||
{ be_const_key(cmd_res, -1), be_const_var(0) },
|
||||
{ be_const_key(time_str, 43), be_const_closure(Tasmota_time_str_closure) },
|
||||
{ be_const_key(set_power, -1), be_const_func(l_setpower) },
|
||||
{ be_const_key(yield, 20), be_const_func(l_yield) },
|
||||
{ be_const_key(set_light, -1), be_const_closure(Tasmota_set_light_closure) },
|
||||
{ be_const_key(find_op, 32), be_const_closure(Tasmota_find_op_closure) },
|
||||
{ be_const_key(get_power, -1), be_const_func(l_getpower) },
|
||||
{ be_const_key(add_rule, -1), be_const_closure(Tasmota_add_rule_closure) },
|
||||
{ be_const_key(cb_dispatch, -1), be_const_closure(Tasmota_cb_dispatch_closure) },
|
||||
{ be_const_key(global, -1), be_const_var(1) },
|
||||
{ be_const_key(i2c_enabled, -1), be_const_func(l_i2cenabled) },
|
||||
{ be_const_key(remove_cmd, 10), be_const_closure(Tasmota_remove_cmd_closure) },
|
||||
{ be_const_key(millis, 18), be_const_func(l_millis) },
|
||||
{ be_const_key(publish, 69), be_const_func(l_publish) },
|
||||
{ be_const_key(_drivers, -1), be_const_var(2) },
|
||||
{ be_const_key(resp_cmnd, -1), be_const_func(l_respCmnd) },
|
||||
{ be_const_key(time_dump, -1), be_const_func(l_time_dump) },
|
||||
{ be_const_key(web_send, -1), be_const_func(l_webSend) },
|
||||
{ be_const_key(hs2rgb, -1), be_const_closure(Tasmota_hs2rgb_closure) },
|
||||
{ be_const_key(memory, -1), be_const_func(l_memory) },
|
||||
{ be_const_key(gen_cb, 0), be_const_closure(Tasmota_gen_cb_closure) },
|
||||
{ be_const_key(rtc, -1), be_const_func(l_rtc) },
|
||||
{ be_const_key(get_option, -1), be_const_func(l_getoption) },
|
||||
{ be_const_key(add_cmd, -1), be_const_closure(Tasmota_add_cmd_closure) },
|
||||
{ be_const_key(init, -1), be_const_closure(Tasmota_init_closure) },
|
||||
{ be_const_key(_timers, -1), be_const_var(3) },
|
||||
{ be_const_key(_global_addr, -1), be_const_comptr(&TasmotaGlobal) },
|
||||
{ be_const_key(wd, -1), be_const_var(4) },
|
||||
{ be_const_key(exec_cmd, -1), be_const_closure(Tasmota_exec_cmd_closure) },
|
||||
{ be_const_key(wire_scan, -1), be_const_closure(Tasmota_wire_scan_closure) },
|
||||
{ be_const_key(_global_def, 61), be_const_comptr(&be_tasmota_global_struct) },
|
||||
{ be_const_key(resp_cmnd_failed, 11), be_const_func(l_respCmndFailed) },
|
||||
{ be_const_key(chars_in_string, -1), be_const_closure(Tasmota_chars_in_string_closure) },
|
||||
{ be_const_key(web_send_decimal, -1), be_const_func(l_webSendDecimal) },
|
||||
{ be_const_key(_debug_present, 4), be_const_var(5) },
|
||||
{ be_const_key(cmd, -1), be_const_closure(Tasmota_cmd_closure) },
|
||||
{ be_const_key(_cb, -1), be_const_var(6) },
|
||||
{ be_const_key(remove_rule, -1), be_const_closure(Tasmota_remove_rule_closure) },
|
||||
{ be_const_key(run_deferred, -1), be_const_closure(Tasmota_run_deferred_closure) },
|
||||
{ be_const_key(strftime, -1), be_const_func(l_strftime) },
|
||||
{ be_const_key(add_driver, 3), be_const_closure(Tasmota_add_driver_closure) },
|
||||
{ be_const_key(kv, 60), be_const_closure(Tasmota_kv_closure) },
|
||||
{ be_const_key(set_timer, 58), be_const_closure(Tasmota_set_timer_closure) },
|
||||
{ be_const_key(scale_uint, -1), be_const_func(l_scaleuint) },
|
||||
{ be_const_key(remove_timer, -1), be_const_closure(Tasmota_remove_timer_closure) },
|
||||
{ be_const_key(settings, 49), be_const_var(7) },
|
||||
{ be_const_key(arch, -1), be_const_func(l_arch) },
|
||||
{ be_const_key(_ccmd, 64), be_const_var(8) },
|
||||
{ be_const_key(wire1, 46), be_const_var(9) },
|
||||
{ be_const_key(exec_rules, 66), be_const_closure(Tasmota_exec_rules_closure) },
|
||||
{ be_const_key(strptime, -1), be_const_func(l_strptime) },
|
||||
{ be_const_key(_cmd, -1), be_const_func(l_cmd) },
|
||||
{ be_const_key(resp_cmnd_error, -1), be_const_func(l_respCmndError) },
|
||||
{ be_const_key(time_reached, -1), be_const_func(l_timereached) },
|
||||
{ be_const_key(_rules, -1), be_const_var(10) },
|
||||
{ be_const_key(publish_result, -1), be_const_func(l_publish_result) },
|
||||
{ be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
|
||||
{ be_const_key(get_switch, -1), be_const_func(l_getswitch) },
|
||||
{ be_const_key(delay, 71), be_const_func(l_delay) },
|
||||
{ be_const_key(publish, -1), be_const_func(l_publish) },
|
||||
{ be_const_key(try_rule, 5), be_const_closure(Tasmota_try_rule_closure) },
|
||||
{ be_const_key(_settings_ptr, -1), be_const_comptr(&Settings) },
|
||||
{ be_const_key(get_free_heap, 47), be_const_func(l_getFreeHeap) },
|
||||
{ be_const_key(eth, 56), be_const_func(l_eth) },
|
||||
{ be_const_key(set_power, -1), be_const_func(l_setpower) },
|
||||
{ be_const_key(exec_rules, -1), be_const_closure(Tasmota_exec_rules_closure) },
|
||||
{ be_const_key(i2c_enabled, -1), be_const_func(l_i2cenabled) },
|
||||
{ be_const_key(chars_in_string, 55), be_const_closure(Tasmota_chars_in_string_closure) },
|
||||
{ be_const_key(hs2rgb, -1), be_const_closure(Tasmota_hs2rgb_closure) },
|
||||
{ be_const_key(time_str, 0), be_const_closure(Tasmota_time_str_closure) },
|
||||
{ be_const_key(set_light, -1), be_const_closure(Tasmota_set_light_closure) },
|
||||
{ be_const_key(response_append, 1), be_const_func(l_respAppend) },
|
||||
{ be_const_key(gen_cb, -1), be_const_closure(Tasmota_gen_cb_closure) },
|
||||
{ be_const_key(remove_driver, 50), be_const_closure(Tasmota_remove_driver_closure) },
|
||||
{ be_const_key(event, -1), be_const_closure(Tasmota_event_closure) },
|
||||
{ be_const_key(exec_cmd, 2), be_const_closure(Tasmota_exec_cmd_closure) },
|
||||
{ be_const_key(rtc, 12), be_const_func(l_rtc) },
|
||||
{ be_const_key(read_sensors, -1), be_const_func(l_read_sensors) },
|
||||
{ be_const_key(resp_cmnd_str, -1), be_const_func(l_respCmndStr) },
|
||||
{ be_const_key(wifi, -1), be_const_func(l_wifi) },
|
||||
{ be_const_key(save, 15), be_const_func(l_save) },
|
||||
{ be_const_key(log, 37), be_const_func(l_logInfo) },
|
||||
{ be_const_key(set_timer, -1), be_const_closure(Tasmota_set_timer_closure) },
|
||||
{ be_const_key(resp_cmnd_error, -1), be_const_func(l_respCmndError) },
|
||||
{ be_const_key(exec_tele, -1), be_const_closure(Tasmota_exec_tele_closure) },
|
||||
{ be_const_key(_global_def, -1), be_const_comptr(&be_tasmota_global_struct) },
|
||||
{ be_const_key(cmd_res, -1), be_const_var(0) },
|
||||
{ be_const_key(_global_addr, -1), be_const_comptr(&TasmotaGlobal) },
|
||||
{ be_const_key(add_driver, 14), be_const_closure(Tasmota_add_driver_closure) },
|
||||
{ be_const_key(_timers, -1), be_const_var(1) },
|
||||
{ be_const_key(add_rule, -1), be_const_closure(Tasmota_add_rule_closure) },
|
||||
{ be_const_key(resp_cmnd_failed, -1), be_const_func(l_respCmndFailed) },
|
||||
{ be_const_key(remove_rule, 9), be_const_closure(Tasmota_remove_rule_closure) },
|
||||
{ be_const_key(web_send, 16), be_const_func(l_webSend) },
|
||||
{ be_const_key(resp_cmnd, -1), be_const_func(l_respCmnd) },
|
||||
{ be_const_key(remove_timer, 10), be_const_closure(Tasmota_remove_timer_closure) },
|
||||
{ be_const_key(memory, 52), be_const_func(l_memory) },
|
||||
{ be_const_key(global, 71), be_const_var(2) },
|
||||
{ be_const_key(find_op, -1), be_const_closure(Tasmota_find_op_closure) },
|
||||
{ be_const_key(yield, 60), be_const_func(l_yield) },
|
||||
{ be_const_key(resolvecmnd, -1), be_const_func(l_resolveCmnd) },
|
||||
{ be_const_key(resp_cmnd_done, -1), be_const_func(l_respCmndDone) },
|
||||
{ be_const_key(get_light, 5), be_const_closure(Tasmota_get_light_closure) },
|
||||
{ be_const_key(get_free_heap, -1), be_const_func(l_getFreeHeap) },
|
||||
{ be_const_key(wire2, -1), be_const_var(11) },
|
||||
{ be_const_key(event, 34), be_const_closure(Tasmota_event_closure) },
|
||||
{ be_const_key(get_option, -1), be_const_func(l_getoption) },
|
||||
{ be_const_key(kv, 43), be_const_closure(Tasmota_kv_closure) },
|
||||
{ be_const_key(wire_scan, -1), be_const_closure(Tasmota_wire_scan_closure) },
|
||||
{ be_const_key(wifi, 37), be_const_func(l_wifi) },
|
||||
{ be_const_key(_cmd, -1), be_const_func(l_cmd) },
|
||||
{ be_const_key(gc, -1), be_const_closure(Tasmota_gc_closure) },
|
||||
{ be_const_key(get_power, -1), be_const_func(l_getpower) },
|
||||
{ be_const_key(get_light, -1), be_const_closure(Tasmota_get_light_closure) },
|
||||
{ be_const_key(time_dump, -1), be_const_func(l_time_dump) },
|
||||
{ be_const_key(settings, -1), be_const_var(3) },
|
||||
{ be_const_key(cmd, 62), be_const_closure(Tasmota_cmd_closure) },
|
||||
{ be_const_key(load, -1), be_const_closure(Tasmota_load_closure) },
|
||||
{ be_const_key(strptime, -1), be_const_func(l_strptime) },
|
||||
{ be_const_key(_ccmd, -1), be_const_var(4) },
|
||||
{ be_const_key(find_key_i, 25), be_const_closure(Tasmota_find_key_i_closure) },
|
||||
{ be_const_key(delay, -1), be_const_func(l_delay) },
|
||||
{ be_const_key(time_reached, -1), be_const_func(l_timereached) },
|
||||
{ be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
|
||||
{ be_const_key(save, 36), be_const_func(l_save) },
|
||||
{ be_const_key(millis, -1), be_const_func(l_millis) },
|
||||
{ be_const_key(wire2, -1), be_const_var(5) },
|
||||
{ be_const_key(wire1, 72), be_const_var(6) },
|
||||
{ be_const_key(web_send_decimal, -1), be_const_func(l_webSendDecimal) },
|
||||
{ be_const_key(scale_uint, 51), be_const_func(l_scaleuint) },
|
||||
{ be_const_key(get_switch, -1), be_const_func(l_getswitch) },
|
||||
{ be_const_key(_debug_present, -1), be_const_var(7) },
|
||||
{ be_const_key(publish_result, -1), be_const_func(l_publish_result) },
|
||||
{ be_const_key(_drivers, -1), be_const_var(8) },
|
||||
{ be_const_key(add_cmd, -1), be_const_closure(Tasmota_add_cmd_closure) },
|
||||
{ be_const_key(strftime, -1), be_const_func(l_strftime) },
|
||||
{ be_const_key(log, -1), be_const_func(l_logInfo) },
|
||||
{ be_const_key(arch, -1), be_const_func(l_arch) },
|
||||
{ be_const_key(resp_cmnd_done, 74), be_const_func(l_respCmndDone) },
|
||||
{ be_const_key(_rules, 38), be_const_var(9) },
|
||||
{ be_const_key(remove_cmd, -1), be_const_closure(Tasmota_remove_cmd_closure) },
|
||||
{ be_const_key(init, -1), be_const_closure(Tasmota_init_closure) },
|
||||
{ be_const_key(wd, 53), be_const_var(10) },
|
||||
};
|
||||
|
||||
static be_define_const_map(
|
||||
be_class_tasmota_map,
|
||||
80
|
||||
77
|
||||
);
|
||||
|
||||
BE_EXPORT_VARIABLE be_define_const_class(
|
||||
be_class_tasmota,
|
||||
12,
|
||||
11,
|
||||
NULL,
|
||||
Tasmota
|
||||
);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#include "be_constobj.h"
|
||||
|
||||
static be_define_const_map_slots(m_libcb_map) {
|
||||
{ be_const_key(get_cb_list, -1), be_const_func(be_cb_get_cb_list) },
|
||||
{ be_const_key(gen_cb, -1), be_const_func(be_cb_gen_cb) },
|
||||
};
|
||||
|
||||
static be_define_const_map(
|
||||
m_libcb_map,
|
||||
2
|
||||
);
|
||||
|
||||
static be_define_const_module(
|
||||
m_libcb,
|
||||
"cb"
|
||||
);
|
||||
|
||||
BE_EXPORT_VARIABLE be_define_const_native_module(cb);
|
|
@ -393,10 +393,7 @@ void be_stack_expansion(bvm *vm, int n)
|
|||
stack_resize(vm, size + 1);
|
||||
be_raise(vm, "runtime_error", STACK_OVER_MSG(BE_STACK_TOTAL_MAX));
|
||||
}
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
if (vm->obshook != NULL)
|
||||
(*vm->obshook)(vm, BE_OBS_STACK_RESIZE_START, size * sizeof(bvalue), (size + n) * sizeof(bvalue));
|
||||
#endif
|
||||
if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_STACK_RESIZE_START, size * sizeof(bvalue), (size + n) * sizeof(bvalue));
|
||||
stack_resize(vm, size + n);
|
||||
}
|
||||
|
||||
|
|
|
@ -544,10 +544,7 @@ void be_gc_collect(bvm *vm)
|
|||
vm->counter_gc_kept = 0;
|
||||
vm->counter_gc_freed = 0;
|
||||
#endif
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
if (vm->obshook != NULL)
|
||||
(*vm->obshook)(vm, BE_OBS_GC_START, vm->gc.usage);
|
||||
#endif
|
||||
if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_GC_START, vm->gc.usage);
|
||||
/* step 1: set root-set reference objects to unscanned */
|
||||
premark_internal(vm); /* object internal the VM */
|
||||
premark_global(vm); /* global objects */
|
||||
|
@ -564,8 +561,5 @@ void be_gc_collect(bvm *vm)
|
|||
reset_fixedlist(vm);
|
||||
/* step 5: calculate the next GC threshold */
|
||||
vm->gc.threshold = next_threshold(vm->gc);
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
if (vm->obshook != NULL)
|
||||
(*vm->obshook)(vm, BE_OBS_GC_END, vm->gc.usage, vm->counter_gc_kept, vm->counter_gc_freed);
|
||||
#endif
|
||||
if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_GC_END, vm->gc.usage, vm->counter_gc_kept, vm->counter_gc_freed);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
#define COUNTER_HOOK()
|
||||
#endif
|
||||
|
||||
#if BE_USE_PERF_COUNTERS && BE_USE_OBSERVABILITY_HOOK
|
||||
#if BE_USE_PERF_COUNTERS
|
||||
#define VM_HEARTBEAT() \
|
||||
if ((vm->counter_ins & ((1<<(BE_VM_OBSERVABILITY_SAMPLING - 1))-1) ) == 0) { /* call every 2^BE_VM_OBSERVABILITY_SAMPLING instructions */ \
|
||||
if (vm->obshook != NULL) \
|
||||
|
@ -461,9 +461,7 @@ BERRY_API bvm* be_vm_new(void)
|
|||
be_gc_setpause(vm, 1);
|
||||
be_loadlibs(vm);
|
||||
vm->compopt = 0;
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
vm->obshook = NULL;
|
||||
#endif
|
||||
#if BE_USE_PERF_COUNTERS
|
||||
vm->counter_ins = 0;
|
||||
vm->counter_enter = 0;
|
||||
|
@ -1269,7 +1267,5 @@ BERRY_API void be_set_obs_hook(bvm *vm, bobshook hook)
|
|||
(void)vm; /* avoid comiler warning */
|
||||
(void)hook; /* avoid comiler warning */
|
||||
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
vm->obshook = hook;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -101,9 +101,7 @@ struct bvm {
|
|||
blist *registry; /* registry list */
|
||||
struct bgc gc;
|
||||
bbyte compopt; /* compilation options */
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
bobshook obshook;
|
||||
#endif
|
||||
#if BE_USE_PERF_COUNTERS
|
||||
uint32_t counter_ins; /* instructions counter */
|
||||
uint32_t counter_enter; /* counter for times the VM was entered */
|
||||
|
|
|
@ -402,6 +402,7 @@ typedef void(*bntvhook)(bvm *vm, bhookinfo *info);
|
|||
|
||||
typedef void(*bobshook)(bvm *vm, int event, ...);
|
||||
enum beobshookevents {
|
||||
BE_OBS_PCALL_ERROR, /* called when be_callp() returned an error, most likely an exception */
|
||||
BE_OBS_GC_START, /* start of GC, arg = allocated size */
|
||||
BE_OBS_GC_END, /* end of GC, arg = allocated size */
|
||||
BE_OBS_VM_HEARTBEAT, /* VM heartbeat called every million instructions */
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "Berry mapping to C",
|
||||
"version": "1.0",
|
||||
"description": "Mapping to C functions",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/arendst/Tasmota",
|
||||
"frameworks": "*",
|
||||
"platforms": "*",
|
||||
"authors":
|
||||
{
|
||||
"name": "Stephan Hadinger",
|
||||
"maintainer": true
|
||||
},
|
||||
"build": {
|
||||
"flags": [ "-I$PROJECT_DIR/include" ]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/********************************************************************
|
||||
* Callback module
|
||||
*
|
||||
* To use: `import cb`
|
||||
*
|
||||
*******************************************************************/
|
||||
#include "be_constobj.h"
|
||||
|
||||
#include "be_mapping.h"
|
||||
#include "be_gc.h"
|
||||
#include "be_exec.h"
|
||||
#include "be_vm.h"
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Callback structures
|
||||
*
|
||||
* We allow 4 parameters, or 3 if method (first arg is `self`)
|
||||
* This could be extended if needed
|
||||
\*********************************************************************************************/
|
||||
typedef int32_t (*berry_callback_t)(int32_t v0, int32_t v1, int32_t v2, int32_t v3);
|
||||
static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, int32_t v3);
|
||||
|
||||
#define BERRY_CB(n) int32_t berry_cb_##n(int32_t v0, int32_t v1, int32_t v2, int32_t v3) { return call_berry_cb(n, v0, v1, v2, v3); }
|
||||
// list the callbacks
|
||||
BERRY_CB(0);
|
||||
BERRY_CB(1);
|
||||
BERRY_CB(2);
|
||||
BERRY_CB(3);
|
||||
BERRY_CB(4);
|
||||
BERRY_CB(5);
|
||||
BERRY_CB(6);
|
||||
BERRY_CB(7);
|
||||
BERRY_CB(8);
|
||||
BERRY_CB(9);
|
||||
BERRY_CB(10);
|
||||
BERRY_CB(11);
|
||||
BERRY_CB(12);
|
||||
BERRY_CB(13);
|
||||
BERRY_CB(14);
|
||||
BERRY_CB(15);
|
||||
BERRY_CB(16);
|
||||
BERRY_CB(17);
|
||||
BERRY_CB(18);
|
||||
BERRY_CB(19);
|
||||
|
||||
// array of callbacks
|
||||
static const berry_callback_t berry_callback_array[BE_MAX_CB] = {
|
||||
berry_cb_0,
|
||||
berry_cb_1,
|
||||
berry_cb_2,
|
||||
berry_cb_3,
|
||||
berry_cb_4,
|
||||
berry_cb_5,
|
||||
berry_cb_6,
|
||||
berry_cb_7,
|
||||
berry_cb_8,
|
||||
berry_cb_9,
|
||||
berry_cb_10,
|
||||
berry_cb_11,
|
||||
berry_cb_12,
|
||||
berry_cb_13,
|
||||
berry_cb_14,
|
||||
berry_cb_15,
|
||||
berry_cb_16,
|
||||
berry_cb_17,
|
||||
berry_cb_18,
|
||||
berry_cb_19,
|
||||
};
|
||||
|
||||
typedef struct be_callback_hook {
|
||||
bvm *vm;
|
||||
bgcobject *f;
|
||||
} be_callback_hook;
|
||||
|
||||
static be_callback_hook be_cb_hooks[BE_MAX_CB] = {0};
|
||||
|
||||
/*********************************************************************************************\
|
||||
* `gen_cb`: Generate a new callback
|
||||
*
|
||||
* arg1: function (or closure)
|
||||
\*********************************************************************************************/
|
||||
static int32_t be_cb_gen_cb(bvm *vm) {
|
||||
int32_t top = be_top(vm);
|
||||
if (top >= 1 && be_isfunction(vm, 1)) {
|
||||
// find first available slot
|
||||
int32_t slot;
|
||||
for (slot = 0; slot < BE_MAX_CB; slot++) {
|
||||
if (be_cb_hooks[slot].f == NULL) break;
|
||||
}
|
||||
bvalue *v = be_indexof(vm, 1);
|
||||
if (slot < BE_MAX_CB) {
|
||||
// found a free slot
|
||||
bgcobject * f = v->v.gc;
|
||||
// mark the function as non-gc
|
||||
be_gc_fix_set(vm, f, btrue);
|
||||
// record pointers
|
||||
be_cb_hooks[slot].vm = vm;
|
||||
be_cb_hooks[slot].f = f;
|
||||
be_pushcomptr(vm, (void*) berry_callback_array[slot]);
|
||||
be_return(vm);
|
||||
} else {
|
||||
be_raise(vm, "internal_error", "no more callbacks available, increase BE_MAX_CB");
|
||||
}
|
||||
}
|
||||
be_raise(vm, "value_error", "arg must be a function");
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* `get_cb_list`: Return the list of callbacks for this vm
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
static int32_t be_cb_get_cb_list(bvm *vm) {
|
||||
be_newobject(vm, "list");
|
||||
int32_t i;
|
||||
for (uint32_t i=0; i < BE_MAX_CB; i++) {
|
||||
if (be_cb_hooks[i].vm) {
|
||||
if (vm == be_cb_hooks[i].vm) { // make sure it corresponds to this vm
|
||||
be_pushcomptr(vm, be_cb_hooks[i].f);
|
||||
be_data_push(vm, -2);
|
||||
be_pop(vm, 1);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
be_pop(vm, 1);
|
||||
be_return(vm);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Callback structures
|
||||
*
|
||||
* We allow 4 parameters, or 3 if method (first arg is `self`)
|
||||
* This could be extended if needed
|
||||
\*********************************************************************************************/
|
||||
static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, int32_t v3) {
|
||||
// call berry cb dispatcher
|
||||
int32_t ret = 0;
|
||||
// retrieve vm and function
|
||||
if (num < 0 || num >= BE_MAX_CB || be_cb_hooks[num].vm == NULL) return 0; // invalid call, avoid a crash
|
||||
|
||||
bvm * vm = be_cb_hooks[num].vm;
|
||||
bgcobject * f = be_cb_hooks[num].f;
|
||||
|
||||
// push function (don't check type)
|
||||
bvalue *top = be_incrtop(vm);
|
||||
var_setobj(top, f->type, f);
|
||||
// push args
|
||||
be_pushint(vm, v0);
|
||||
be_pushint(vm, v1);
|
||||
be_pushint(vm, v2);
|
||||
be_pushint(vm, v3);
|
||||
|
||||
ret = be_pcall(vm, 4); // 4 arguments
|
||||
if (ret != 0) {
|
||||
if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_PCALL_ERROR);
|
||||
be_pop(vm, be_top(vm)); // clear Berry stack
|
||||
return 0;
|
||||
}
|
||||
ret = be_toint(vm, -5);
|
||||
be_pop(vm, 5); // remove result
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* @const_object_info_begin
|
||||
module cb (scope: global) {
|
||||
gen_cb, func(be_cb_gen_cb)
|
||||
get_cb_list, func(be_cb_get_cb_list)
|
||||
}
|
||||
@const_object_info_end */
|
||||
#include "../../Berry/generate/be_fixed_cb.h"
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
|
||||
#ifndef __BE_MAPPING__
|
||||
#define __BE_MAPPING__
|
||||
|
||||
// include this header to force compilation fo this module
|
||||
|
||||
#define BE_MAX_CB 20 // max number of callbacks, each callback requires a distinct address
|
||||
|
||||
#endif // __BE_MAPPING__
|
|
@ -23,6 +23,7 @@
|
|||
#include <berry.h>
|
||||
#include <LList.h>
|
||||
|
||||
#include "be_mapping.h"
|
||||
#include "re1.5.h"
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
|
|
@ -45,8 +45,11 @@ extern "C" {
|
|||
* Responds to virtual constants
|
||||
\*********************************************************************************************/
|
||||
extern "C" {
|
||||
// Clear all elements on the stack
|
||||
void be_pop_all(bvm *vm) {
|
||||
#include "be_vm.h"
|
||||
// Call error handler and pop all from stack
|
||||
void be_error_pop_all(bvm *vm);
|
||||
void be_error_pop_all(bvm *vm) {
|
||||
if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_PCALL_ERROR);
|
||||
be_pop(vm, be_top(vm)); // clear Berry stack
|
||||
}
|
||||
|
||||
|
@ -267,113 +270,6 @@ extern "C" {
|
|||
* Warning, the following expect all parameters to be 32 bits wide
|
||||
\*********************************************************************************************/
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Callback structures
|
||||
*
|
||||
* We allow 4 parameters, or 3 if method (first arg is `self`)
|
||||
* This could be extended if needed
|
||||
\*********************************************************************************************/
|
||||
typedef int32_t (*berry_callback_t)(int32_t v0, int32_t v1, int32_t v2, int32_t v3);
|
||||
|
||||
extern void BerryDumpErrorAndClear(bvm *vm, bool berry_console);
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Callback structures
|
||||
*
|
||||
* We allow 4 parameters, or 3 if method (first arg is `self`)
|
||||
* This could be extended if needed
|
||||
\*********************************************************************************************/
|
||||
int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, int32_t v3) {
|
||||
// call berry cb dispatcher
|
||||
int32_t ret = 0;
|
||||
// get the 'tasmota' object (global) and call 'cb_dispatch'
|
||||
be_getglobal(berry.vm, PSTR("tasmota"));
|
||||
if (!be_isnil(berry.vm, -1)) {
|
||||
be_getmethod(berry.vm, -1, PSTR("cb_dispatch"));
|
||||
|
||||
if (!be_isnil(berry.vm, -1)) {
|
||||
be_pushvalue(berry.vm, -2); // add instance as first arg
|
||||
// push all args as ints (may be revised)
|
||||
be_pushint(berry.vm, num);
|
||||
be_pushint(berry.vm, v0);
|
||||
be_pushint(berry.vm, v1);
|
||||
be_pushint(berry.vm, v2);
|
||||
be_pushint(berry.vm, v3);
|
||||
|
||||
ret = be_pcall(berry.vm, 6); // 5 arguments
|
||||
if (ret != 0) {
|
||||
BerryDumpErrorAndClear(berry.vm, false); // log in Tasmota console only
|
||||
be_pop_all(berry.vm); // clear Berry stack
|
||||
return 0;
|
||||
}
|
||||
be_pop(berry.vm, 6);
|
||||
|
||||
if (be_isint(berry.vm, -1) || be_isnil(berry.vm, -1)) { // sanity check
|
||||
if (be_isint(berry.vm, -1)) {
|
||||
ret = be_toint(berry.vm, -1);
|
||||
}
|
||||
// All good, we can proceed
|
||||
be_pop(berry.vm, 2); // remove tasmota instance and result
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
be_pop(berry.vm, 1);
|
||||
}
|
||||
be_pop(berry.vm, 1);
|
||||
AddLog(LOG_LEVEL_ERROR, PSTR(D_LOG_BERRY "can't call 'tasmota.cb_dispatch'"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BERRY_CB(n) int32_t berry_cb_##n(int32_t v0, int32_t v1, int32_t v2, int32_t v3) { return call_berry_cb(n, v0, v1, v2, v3); }
|
||||
// list the callbacks
|
||||
BERRY_CB(0);
|
||||
BERRY_CB(1);
|
||||
BERRY_CB(2);
|
||||
BERRY_CB(3);
|
||||
BERRY_CB(4);
|
||||
BERRY_CB(5);
|
||||
BERRY_CB(6);
|
||||
BERRY_CB(7);
|
||||
BERRY_CB(8);
|
||||
BERRY_CB(9);
|
||||
BERRY_CB(10);
|
||||
BERRY_CB(11);
|
||||
BERRY_CB(12);
|
||||
BERRY_CB(13);
|
||||
BERRY_CB(14);
|
||||
BERRY_CB(15);
|
||||
BERRY_CB(16);
|
||||
BERRY_CB(17);
|
||||
BERRY_CB(18);
|
||||
BERRY_CB(19);
|
||||
|
||||
// array of callbacks
|
||||
berry_callback_t berry_callback_array[] {
|
||||
berry_cb_0,
|
||||
berry_cb_1,
|
||||
berry_cb_2,
|
||||
berry_cb_3,
|
||||
berry_cb_4,
|
||||
berry_cb_5,
|
||||
berry_cb_6,
|
||||
berry_cb_7,
|
||||
berry_cb_8,
|
||||
berry_cb_9,
|
||||
berry_cb_10,
|
||||
berry_cb_11,
|
||||
berry_cb_12,
|
||||
berry_cb_13,
|
||||
berry_cb_14,
|
||||
berry_cb_15,
|
||||
berry_cb_16,
|
||||
berry_cb_17,
|
||||
berry_cb_18,
|
||||
berry_cb_19,
|
||||
};
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Automatically parse Berry stack and call the C function accordingly
|
||||
*
|
||||
|
|
|
@ -26,25 +26,25 @@
|
|||
const uint32_t BERRY_MAX_LOGS = 16; // max number of print output recorded when outside of REPL, used to avoid infinite grow of logs
|
||||
const uint32_t BERRY_MAX_REPL_LOGS = 1024; // max number of print output recorded when inside REPL
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Return C callback from index
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
extern "C" {
|
||||
int32_t l_get_cb(struct bvm *vm);
|
||||
int32_t l_get_cb(struct bvm *vm) {
|
||||
int32_t argc = be_top(vm); // Get the number of arguments
|
||||
if (argc >= 2 && be_isint(vm, 2)) {
|
||||
int32_t idx = be_toint(vm, 2);
|
||||
if (idx >= 0 && idx < ARRAY_SIZE(berry_callback_array)) {
|
||||
const berry_callback_t c_ptr = berry_callback_array[idx];
|
||||
be_pushcomptr(vm, (void*) c_ptr);
|
||||
be_return(vm);
|
||||
}
|
||||
}
|
||||
be_raise(vm, kTypeError, nullptr);
|
||||
}
|
||||
}
|
||||
// /*********************************************************************************************\
|
||||
// * Return C callback from index
|
||||
// *
|
||||
// \*********************************************************************************************/
|
||||
// extern "C" {
|
||||
// extern int32_t be_cb__get_cb(struct bvm *vm);
|
||||
// int32_t be_cb__get_cb(struct bvm *vm) {
|
||||
// int32_t argc = be_top(vm); // Get the number of arguments
|
||||
// if (argc >= 2 && be_isint(vm, 2)) {
|
||||
// int32_t idx = be_toint(vm, 2);
|
||||
// if (idx >= 0 && idx < ARRAY_SIZE(berry_callback_array)) {
|
||||
// const berry_callback_t c_ptr = berry_callback_array[idx];
|
||||
// be_pushcomptr(vm, (void*) c_ptr);
|
||||
// be_return(vm);
|
||||
// }
|
||||
// }
|
||||
// be_raise(vm, kTypeError, nullptr);
|
||||
// }
|
||||
// }
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Native functions mapped to Berry functions
|
||||
|
|
|
@ -110,24 +110,6 @@ size_t callBerryGC(void) {
|
|||
return callBerryEventDispatcher(PSTR("gc"), nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
void BerryDumpErrorAndClear(bvm *vm, bool berry_console);
|
||||
void BerryDumpErrorAndClear(bvm *vm, bool berry_console) {
|
||||
int32_t top = be_top(vm);
|
||||
// check if we have two strings for an Exception
|
||||
if (top >= 2 && be_isstring(vm, -1) && be_isstring(vm, -2)) {
|
||||
if (berry_console) {
|
||||
berry_log_C(PSTR(D_LOG_BERRY "Exception> '%s' - %s"), be_tostring(berry.vm, -2), be_tostring(berry.vm, -1));
|
||||
be_tracestack(vm);
|
||||
top = be_top(vm); // update top after dump
|
||||
} else {
|
||||
AddLog(LOG_LEVEL_ERROR, PSTR(D_LOG_BERRY "Exception> '%s' - %s"), be_tostring(berry.vm, -2), be_tostring(berry.vm, -1));
|
||||
be_tracestack(vm);
|
||||
}
|
||||
} else {
|
||||
be_dumpstack(vm);
|
||||
}
|
||||
}
|
||||
|
||||
// void callBerryMqttData(void) {
|
||||
// AddLog(LOG_LEVEL_INFO, D_LOG_BERRY "callBerryMqttData");
|
||||
// if (nullptr == berry.vm) { return; }
|
||||
|
@ -150,53 +132,6 @@ void BerryDumpErrorAndClear(bvm *vm, bool berry_console) {
|
|||
// checkBeTop();
|
||||
// }
|
||||
|
||||
/*
|
||||
// Call a method of a global object, with n args
|
||||
// Before: stack must containt n args
|
||||
// After: stack contains return value or nil if something wrong (args removes)
|
||||
// returns true is successful, false if object or method not found
|
||||
bool callMethodObjectWithArgs(const char * objname, const char * method, size_t argc) {
|
||||
if (nullptr == berry.vm) { return false; }
|
||||
int32_t top = be_top(berry.vm);
|
||||
// stacks contains n x arg
|
||||
be_getglobal(berry.vm, objname);
|
||||
// stacks contains n x arg + object
|
||||
if (!be_isnil(berry.vm, -1)) {
|
||||
be_getmethod(berry.vm, -1, method);
|
||||
// stacks contains n x arg + object + method
|
||||
if (!be_isnil(berry.vm, -1)) {
|
||||
// reshuffle the entire stack since we want: method + object + n x arg
|
||||
be_pushvalue(berry.vm, -1); // add instance as first arg
|
||||
// stacks contains n x arg + object + method + method
|
||||
be_pushvalue(berry.vm, -3); // add instance as first arg
|
||||
// stacks contains n x arg + object + method + method + object
|
||||
// now move args 2 slots up to make room for method and object
|
||||
for (uint32_t i = 1; i <= argc; i++) {
|
||||
be_moveto(berry.vm, -4 - i, -2 - i);
|
||||
}
|
||||
// stacks contains free + free + n x arg + method + object
|
||||
be_moveto(berry.vm, -2, -4 - argc);
|
||||
be_moveto(berry.vm, -1, -3 - argc);
|
||||
// stacks contains method + object + n x arg + method + object
|
||||
be_pop(berry.vm, 2);
|
||||
// stacks contains method + object + n x arg
|
||||
be_pcall(berry.vm, argc + 1);
|
||||
// stacks contains return_val + object + n x arg
|
||||
be_pop(berry.vm, argc + 1);
|
||||
// stacks contains return_val
|
||||
return true;
|
||||
}
|
||||
be_pop(berry.vm, 1); // remove method
|
||||
// stacks contains n x arg + object
|
||||
}
|
||||
// stacks contains n x arg + object
|
||||
be_pop(berry.vm, argc + 1); // clear stack
|
||||
be_pushnil(berry.vm); // put nil object
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// call the event dispatcher from Tasmota object
|
||||
// if data_len is non-zero, the event is also sent as raw `bytes()` object because the string may lose data
|
||||
int32_t callBerryEventDispatcher(const char *type, const char *cmd, int32_t idx, const char *payload, uint32_t data_len) {
|
||||
|
@ -224,8 +159,7 @@ int32_t callBerryEventDispatcher(const char *type, const char *cmd, int32_t idx,
|
|||
}
|
||||
BrTimeoutReset();
|
||||
if (ret != 0) {
|
||||
BerryDumpErrorAndClear(vm, false); // log in Tasmota console only
|
||||
be_pop_all(berry.vm); // clear Berry stack
|
||||
be_error_pop_all(berry.vm); // clear Berry stack
|
||||
return ret;
|
||||
}
|
||||
be_pop(vm, 5);
|
||||
|
@ -252,6 +186,17 @@ void BerryObservability(bvm *vm, int event...) {
|
|||
static uint32_t gc_time = 0;
|
||||
|
||||
switch (event) {
|
||||
case BE_OBS_PCALL_ERROR: // error after be_pcall
|
||||
{
|
||||
int32_t top = be_top(vm);
|
||||
// check if we have two strings for an Exception
|
||||
if (top >= 2 && be_isstring(vm, -1) && be_isstring(vm, -2)) {
|
||||
berry_log_C(PSTR(D_LOG_BERRY "Exception> '%s' - %s"), be_tostring(berry.vm, -2), be_tostring(berry.vm, -1));
|
||||
be_tracestack(vm);
|
||||
} else {
|
||||
be_dumpstack(vm);
|
||||
}
|
||||
}
|
||||
case BE_OBS_GC_START:
|
||||
{
|
||||
gc_time = millis();
|
||||
|
@ -331,21 +276,18 @@ void BerryInit(void) {
|
|||
|
||||
ret_code1 = be_loadstring(berry.vm, berry_prog);
|
||||
if (ret_code1 != 0) {
|
||||
BerryDumpErrorAndClear(berry.vm, false);
|
||||
be_pop_all(berry.vm); // clear Berry stack
|
||||
be_error_pop_all(berry.vm); // clear Berry stack
|
||||
break;
|
||||
}
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry code loaded, RAM used=%u"), be_gc_memcount(berry.vm));
|
||||
ret_code2 = be_pcall(berry.vm, 0);
|
||||
if (ret_code1 != 0) {
|
||||
BerryDumpErrorAndClear(berry.vm, false);
|
||||
be_pop_all(berry.vm); // clear Berry stack
|
||||
be_error_pop_all(berry.vm); // clear Berry stack
|
||||
break;
|
||||
}
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry code ran, RAM used=%u"), be_gc_memcount(berry.vm));
|
||||
if (be_top(berry.vm) > 1) {
|
||||
BerryDumpErrorAndClear(berry.vm, false);
|
||||
be_pop_all(berry.vm); // clear Berry stack
|
||||
be_error_pop_all(berry.vm); // clear Berry stack
|
||||
} else {
|
||||
be_pop(berry.vm, 1);
|
||||
}
|
||||
|
@ -389,8 +331,7 @@ void BrLoad(const char * script_name) {
|
|||
|
||||
BrTimeoutStart();
|
||||
if (be_pcall(berry.vm, 1) != 0) {
|
||||
BerryDumpErrorAndClear(berry.vm, false);
|
||||
be_pop_all(berry.vm); // clear Berry stack
|
||||
be_error_pop_all(berry.vm); // clear Berry stack
|
||||
return;
|
||||
}
|
||||
BrTimeoutReset();
|
||||
|
@ -495,8 +436,7 @@ void BrREPLRun(char * cmd) {
|
|||
}
|
||||
}
|
||||
if (BE_EXCEPTION == ret_code) {
|
||||
BerryDumpErrorAndClear(berry.vm, true);
|
||||
be_pop_all(berry.vm); // clear Berry stack
|
||||
be_error_pop_all(berry.vm); // clear Berry stack
|
||||
// be_dumpstack(berry.vm);
|
||||
// char exception_s[120];
|
||||
// ext_snprintf_P(exception_s, sizeof(exception_s), PSTR("%s: %s"), be_tostring(berry.vm, -2), be_tostring(berry.vm, -1));
|
||||
|
|
Loading…
Reference in New Issue