diff --git a/CHANGELOG.md b/CHANGELOG.md index b862f94f1..4c8c90303 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. - Berry support for `sortedmap` (#23441) - Berry `introspect.module` option to not cache module entry (#23451) - Berry `webserver.remove_route` to revert `webserver.on` (#23452) +- Berry `compile` and `tasmota.compile` option to compile in local context ### Breaking Changed diff --git a/lib/libesp32/berry/src/be_baselib.c b/lib/libesp32/berry/src/be_baselib.c index 3cc2e9f2c..2a8d36fd6 100644 --- a/lib/libesp32/berry/src/be_baselib.c +++ b/lib/libesp32/berry/src/be_baselib.c @@ -412,21 +412,21 @@ static int raise_compile_error(bvm *vm) return 0; } -static int m_compile_str(bvm *vm) +static int m_compile_str(bvm *vm, bbool islocal) { int len = be_strlen(vm, 1); const char *src = be_tostring(vm, 1); - int res = be_loadbuffer(vm, "string", src, len); + int res = be_loadbuffer_local(vm, "string", src, len, islocal); if (res == BE_OK) { be_return(vm); } return raise_compile_error(vm); } -static int m_compile_file(bvm *vm) +static int m_compile_file(bvm *vm, bbool islocal) { const char *fname = be_tostring(vm, 1); - int res = be_loadfile(vm, fname); + int res = be_loadfile_local(vm, fname, islocal); if (res == BE_OK) { be_return(vm); } else if (res == BE_IO_ERROR) { @@ -443,14 +443,18 @@ int be_baselib_compile(bvm *vm) if (be_top(vm) && be_isstring(vm, 1)) { if (be_top(vm) >= 2 && be_isstring(vm, 2)) { const char *s = be_tostring(vm, 2); + bbool islocal = bfalse; + if (be_top(vm) >= 3 && be_isbool(vm, 3)) { + islocal = be_tobool(vm, 3); + } if (!strcmp(s, "string")) { - return m_compile_str(vm); + return m_compile_str(vm, islocal); } if (!strcmp(s, "file")) { - return m_compile_file(vm); + return m_compile_file(vm, islocal); } } else { - return m_compile_str(vm); + return m_compile_str(vm, bfalse); /* default to global context */ } } #endif diff --git a/lib/libesp32/berry/src/be_exec.c b/lib/libesp32/berry/src/be_exec.c index 794987933..cdb9e80b8 100644 --- a/lib/libesp32/berry/src/be_exec.c +++ b/lib/libesp32/berry/src/be_exec.c @@ -219,6 +219,15 @@ BERRY_API int be_loadbuffer(bvm *vm, return be_protectedparser(vm, name, _sgets, &sbuf, bfalse); } +BERRY_API int be_loadbuffer_local(bvm *vm, + const char *name, const char *buffer, size_t length, bbool islocal) +{ + struct strbuf sbuf; + sbuf.s = buffer; + sbuf.len = length; + return be_protectedparser(vm, name, _sgets, &sbuf, islocal); +} + static int fileparser(bvm *vm, const char *name, bbool islocal) { int res = BE_IO_ERROR; diff --git a/lib/libesp32/berry/src/berry.h b/lib/libesp32/berry/src/berry.h index 930c0e711..c00c2e136 100644 --- a/lib/libesp32/berry/src/berry.h +++ b/lib/libesp32/berry/src/berry.h @@ -725,6 +725,16 @@ typedef int (*bctypefunc)(bvm*, const void*); /**< bctypefunc */ */ #define be_loadfile(vm, name) be_loadmode((vm), (name), 0) +/** + * @def be_loadfile + * @note FFI function + * @brief be_loadfile + * + * @param vm virtual machine instance virtual machine instance + * @param name (???) + */ +#define be_loadfile_local(vm, name, islocal) be_loadmode((vm), (name), islocal) + /** * @def be_loadmodule * @note FFI function @@ -742,12 +752,24 @@ typedef int (*bctypefunc)(bvm*, const void*); /**< bctypefunc */ * @brief be_loadstring * * @param vm virtual machine instance virtual machine instance - * @param str (???) + * @param str Berry code to be compiled in global context * */ #define be_loadstring(vm, str) \ be_loadbuffer((vm), "string", (str), strlen(str)) +/** + * @def be_loadstring_local + * @note FFI function + * @brief be_loadstring + * + * @param vm virtual machine instance virtual machine instance + * @param str Berry code to be compiled in local or global context + * + */ +#define be_loadstring_local(vm, str, islocal) \ + be_loadbuffer_local((vm), "string", (str), strlen(str), islocal) + /** * @def be_dostring * @note FFI function @@ -2190,7 +2212,7 @@ BERRY_API bctypefunc be_get_ctype_func_hanlder(bvm *vm); /** * @fn int be_loadbuffer(bvm*, const char*, const char*, size_t) * @note code load API - * @brief load a piece of source code from the buffer and compile it into bytecode + * @brief load a piece of source code from the buffer and compile it into bytecode, in global context * * f the compilation is successful, be_loadbuffer will compile the source code into a Berry function and place * it on the top of the virtual stack. If the compilation encounters an error, be_loadbuffer will return @@ -2205,6 +2227,24 @@ BERRY_API bctypefunc be_get_ctype_func_hanlder(bvm *vm); */ BERRY_API int be_loadbuffer(bvm *vm, const char *name, const char *buffer, size_t length); +/** + * @fn int be_loadbuffer_local(bvm*, const char*, const char*, size_t) + * @note code load API + * @brief load a piece of source code from the buffer and compile it into bytecode, in local or global context + * + * f the compilation is successful, be_loadbuffer will compile the source code into a Berry function and place + * it on the top of the virtual stack. If the compilation encounters an error, be_loadbuffer will return + * an error value of type berrorcode (Section errorcode), and if possible, will store the + * specific error message string at the top of the virtual stack. + * + * @param vm virtual machine instance + * @param name string, which is usually used to mark the source of the source code + * @param buffer buffer for storing the source code + * @param length length of the buffer + * @return (???) + */ +BERRY_API int be_loadbuffer_local(bvm *vm, const char *name, const char *buffer, size_t length, bbool islocal); + /** * @fn int be_loadmode(bvm *vm, const char *name, bbool islocal) * @note code load API diff --git a/lib/libesp32/berry_tasmota/src/embedded/tasmota_class.be b/lib/libesp32/berry_tasmota/src/embedded/tasmota_class.be index df6daf398..5a68b6566 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/tasmota_class.be +++ b/lib/libesp32/berry_tasmota/src/embedded/tasmota_class.be @@ -477,7 +477,7 @@ class Tasmota # compile in-memory var compiled_code try - compiled_code = compile(f_name, 'file') + compiled_code = compile(f_name, 'file', true) if (compiled_code == nil) print(f"BRY: empty compiled file") return false diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_tasmota_class.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_tasmota_class.h index 2422b1489..fa34b088b 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_tasmota_class.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_tasmota_class.h @@ -2652,7 +2652,7 @@ be_local_closure(class_Tasmota_compile, /* name */ &be_ktab_class_Tasmota, /* shared constants */ &be_const_str_compile, &be_const_str_solidified, - ( &(const binstruction[84]) { /* code */ + ( &(const binstruction[85]) { /* code */ 0xA40A7800, // 0000 IMPORT R2 K60 0x8C0C0574, // 0001 GETMET R3 R2 K116 0x5C140200, // 0002 MOVE R5 R1 @@ -2681,62 +2681,63 @@ be_local_closure(class_Tasmota_compile, /* name */ 0x500C0000, // 0019 LDBOOL R3 0 0 0x80040600, // 001A RET 1 R3 0x4C0C0000, // 001B LDNIL R3 - 0xA8020011, // 001C EXBLK 0 #002F + 0xA8020012, // 001C EXBLK 0 #0030 0x6010000D, // 001D GETGBL R4 G13 0x5C140200, // 001E MOVE R5 R1 0x58180092, // 001F LDCONST R6 K146 - 0x7C100400, // 0020 CALL R4 2 - 0x5C0C0800, // 0021 MOVE R3 R4 - 0x4C100000, // 0022 LDNIL R4 - 0x1C100604, // 0023 EQ R4 R3 R4 - 0x78120007, // 0024 JMPF R4 #002D - 0x60100001, // 0025 GETGBL R4 G1 - 0x60140018, // 0026 GETGBL R5 G24 - 0x58180093, // 0027 LDCONST R6 K147 - 0x7C140200, // 0028 CALL R5 1 - 0x7C100200, // 0029 CALL R4 1 - 0x50100000, // 002A LDBOOL R4 0 0 - 0xA8040001, // 002B EXBLK 1 1 - 0x80040800, // 002C RET 1 R4 - 0xA8040001, // 002D EXBLK 1 1 - 0x7002000D, // 002E JMP #003D - 0xAC100002, // 002F CATCH R4 0 2 - 0x7002000A, // 0030 JMP #003C - 0x60180001, // 0031 GETGBL R6 G1 - 0x601C0018, // 0032 GETGBL R7 G24 - 0x58200094, // 0033 LDCONST R8 K148 - 0x5C240200, // 0034 MOVE R9 R1 - 0x5C280800, // 0035 MOVE R10 R4 - 0x5C2C0A00, // 0036 MOVE R11 R5 - 0x7C1C0800, // 0037 CALL R7 4 - 0x7C180200, // 0038 CALL R6 1 - 0x50180000, // 0039 LDBOOL R6 0 0 - 0x80040C00, // 003A RET 1 R6 - 0x70020000, // 003B JMP #003D - 0xB0080000, // 003C RAISE 2 R0 R0 - 0x00100376, // 003D ADD R4 R1 K118 - 0xA8020005, // 003E EXBLK 0 #0045 - 0x8C14018D, // 003F GETMET R5 R0 K141 - 0x5C1C0800, // 0040 MOVE R7 R4 - 0x5C200600, // 0041 MOVE R8 R3 - 0x7C140600, // 0042 CALL R5 3 - 0xA8040001, // 0043 EXBLK 1 1 - 0x7002000C, // 0044 JMP #0052 - 0xAC140001, // 0045 CATCH R5 0 1 - 0x70020009, // 0046 JMP #0051 - 0x60180001, // 0047 GETGBL R6 G1 - 0x601C0018, // 0048 GETGBL R7 G24 - 0x58200095, // 0049 LDCONST R8 K149 - 0x5C240800, // 004A MOVE R9 R4 - 0x5C280A00, // 004B MOVE R10 R5 - 0x7C1C0600, // 004C CALL R7 3 - 0x7C180200, // 004D CALL R6 1 - 0x50180000, // 004E LDBOOL R6 0 0 - 0x80040C00, // 004F RET 1 R6 - 0x70020000, // 0050 JMP #0052 - 0xB0080000, // 0051 RAISE 2 R0 R0 - 0x50140200, // 0052 LDBOOL R5 1 0 - 0x80040A00, // 0053 RET 1 R5 + 0x501C0200, // 0020 LDBOOL R7 1 0 + 0x7C100600, // 0021 CALL R4 3 + 0x5C0C0800, // 0022 MOVE R3 R4 + 0x4C100000, // 0023 LDNIL R4 + 0x1C100604, // 0024 EQ R4 R3 R4 + 0x78120007, // 0025 JMPF R4 #002E + 0x60100001, // 0026 GETGBL R4 G1 + 0x60140018, // 0027 GETGBL R5 G24 + 0x58180093, // 0028 LDCONST R6 K147 + 0x7C140200, // 0029 CALL R5 1 + 0x7C100200, // 002A CALL R4 1 + 0x50100000, // 002B LDBOOL R4 0 0 + 0xA8040001, // 002C EXBLK 1 1 + 0x80040800, // 002D RET 1 R4 + 0xA8040001, // 002E EXBLK 1 1 + 0x7002000D, // 002F JMP #003E + 0xAC100002, // 0030 CATCH R4 0 2 + 0x7002000A, // 0031 JMP #003D + 0x60180001, // 0032 GETGBL R6 G1 + 0x601C0018, // 0033 GETGBL R7 G24 + 0x58200094, // 0034 LDCONST R8 K148 + 0x5C240200, // 0035 MOVE R9 R1 + 0x5C280800, // 0036 MOVE R10 R4 + 0x5C2C0A00, // 0037 MOVE R11 R5 + 0x7C1C0800, // 0038 CALL R7 4 + 0x7C180200, // 0039 CALL R6 1 + 0x50180000, // 003A LDBOOL R6 0 0 + 0x80040C00, // 003B RET 1 R6 + 0x70020000, // 003C JMP #003E + 0xB0080000, // 003D RAISE 2 R0 R0 + 0x00100376, // 003E ADD R4 R1 K118 + 0xA8020005, // 003F EXBLK 0 #0046 + 0x8C14018D, // 0040 GETMET R5 R0 K141 + 0x5C1C0800, // 0041 MOVE R7 R4 + 0x5C200600, // 0042 MOVE R8 R3 + 0x7C140600, // 0043 CALL R5 3 + 0xA8040001, // 0044 EXBLK 1 1 + 0x7002000C, // 0045 JMP #0053 + 0xAC140001, // 0046 CATCH R5 0 1 + 0x70020009, // 0047 JMP #0052 + 0x60180001, // 0048 GETGBL R6 G1 + 0x601C0018, // 0049 GETGBL R7 G24 + 0x58200095, // 004A LDCONST R8 K149 + 0x5C240800, // 004B MOVE R9 R4 + 0x5C280A00, // 004C MOVE R10 R5 + 0x7C1C0600, // 004D CALL R7 3 + 0x7C180200, // 004E CALL R6 1 + 0x50180000, // 004F LDBOOL R6 0 0 + 0x80040C00, // 0050 RET 1 R6 + 0x70020000, // 0051 JMP #0053 + 0xB0080000, // 0052 RAISE 2 R0 R0 + 0x50140200, // 0053 LDBOOL R5 1 0 + 0x80040A00, // 0054 RET 1 R5 }) ) );