Berry loading .be file does not generated .bec anymore (#21075)

This commit is contained in:
s-hadinger 2024-03-31 21:37:26 +02:00 committed by GitHub
parent 0422b25e31
commit c19391da8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 1845 additions and 1708 deletions

View File

@ -13,7 +13,7 @@ All notable changes to this project will be documented in this file.
- Support for Domoticz non-persistent ``DzIdx5`` to ``DzIdx32`` (#21019) - Support for Domoticz non-persistent ``DzIdx5`` to ``DzIdx32`` (#21019)
### Breaking Changed ### Breaking Changed
- Berry loading .be file does not generated .bec anymore
### Changed ### Changed
- ESP32 LVGL library from v9.0.0 to v9.1.0 (#21008) - ESP32 LVGL library from v9.0.0 to v9.1.0 (#21008)

View File

@ -180,6 +180,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
add_driver, closure(Tasmota_add_driver_closure) add_driver, closure(Tasmota_add_driver_closure)
remove_driver, closure(Tasmota_remove_driver_closure) remove_driver, closure(Tasmota_remove_driver_closure)
load, closure(Tasmota_load_closure) load, closure(Tasmota_load_closure)
compile, closure(Tasmota_compile_closure)
wire_scan, closure(Tasmota_wire_scan_closure) wire_scan, closure(Tasmota_wire_scan_closure)
time_str, closure(Tasmota_time_str_closure) time_str, closure(Tasmota_time_str_closure)
urlfetch, closure(Tasmota_urlfetch_closure) urlfetch, closure(Tasmota_urlfetch_closure)

View File

@ -30,12 +30,7 @@ class Tasmota
self.settings = ctypes_bytes_dyn(introspect.toptr(settings_addr), self._settings_def) self.settings = ctypes_bytes_dyn(introspect.toptr(settings_addr), self._settings_def)
end end
self.wd = "" self.wd = ""
self._debug_present = false self._debug_present = global.contains("debug")
try
import debug
self._debug_present = true
except ..
end
# declare `UrlFetch` command # declare `UrlFetch` command
self.add_cmd('UrlFetch', def (cmd, idx, payload, payload_json) self.urlfetch_cmd(cmd, idx, payload, payload_json) end) self.add_cmd('UrlFetch', def (cmd, idx, payload, payload_json) self.urlfetch_cmd(cmd, idx, payload, payload_json) end)
end end
@ -357,7 +352,55 @@ class Tasmota
return format("%04d-%02d-%02dT%02d:%02d:%02d", tm['year'], tm['month'], tm['day'], tm['hour'], tm['min'], tm['sec']) return format("%04d-%02d-%02dT%02d:%02d:%02d", tm['year'], tm['month'], tm['day'], tm['hour'], tm['min'], tm['sec'])
end end
def load(f) # takes a .be file and compile to .bec file with the same name
# tasmota.compile("autoexec.be") -- compiles autoexec.be to autoexec.bec
#
# Returns 'true' if succesful of 'false' if file is not found or corrupt
def compile(f_name)
import string
if !string.endswith(f_name, ".be")
print(f"BRY: file '{f_name}' does not have '.be' extension")
return false
end
if string.find(f_name, "#") > 0
print(f"BRY: cannot compile file in read-only archive")
return false
end
# compile in-memory
var compiled_code
try
compiled_code = compile(f_name, 'file')
if (compiled_code == nil)
print(f"BRY: empty compiled file")
return false
end
except .. as e, m
print(f"BRY: failed to load '{f_name}' ({e} - {m})")
return false
end
# save to .bec file
var f_name_bec = f_name + "c"
try
self.save(f_name_bec, compiled_code)
except .. as e
print(format('BRY: could not save compiled file %s (%s)',f_name_bec,e))
return false
end
return true
end
# takes file name with or without suffix:
# load("autoexec.be") -- loads file from .be or .bec if .be is not here, remove .bec if .be exists
# load("autoexec") -- same as above
# load("autoexec.bec") -- load only .bec file and ignore .be
# load("app.tapp#module.be") -- loads from tapp arhive
#
# Returns 'true' if succesful of 'false' if file is not found or corrupt
def load(f_name)
# embedded functions # embedded functions
# puth_path: adds the current archive to sys.path # puth_path: adds the current archive to sys.path
def push_path(p) def push_path(p)
@ -392,7 +435,7 @@ class Tasmota
f.close() f.close()
except .. as e except .. as e
if f != nil f.close() end if f != nil f.close() end
print(format('BRY: failed to load compiled \'%s\' (%s)',fname_bec,e)) print(f"BRY: failed to load compiled '{fname_bec}' ({e})")
end end
return nil return nil
end end
@ -414,7 +457,7 @@ class Tasmota
var compiled = compile(f_name, 'file') var compiled = compile(f_name, 'file')
return compiled return compiled
except .. as e, m except .. as e, m
print(format('BRY: failed to load \'%s\' (%s - %s)',f_name,e,m)) print(f"BRY: failed to load '{f_name}' ({e} - {m})")
end end
return nil return nil
end end
@ -427,7 +470,7 @@ class Tasmota
compiled_code() compiled_code()
return true return true
except .. as e, m except .. as e, m
print(format("BRY: failed to run compiled code '%s' - %s", e, m)) print(f"BRY: failed to run compiled code ({e} - {m})")
if self._debug_present if self._debug_present
import debug import debug
debug.traceback() debug.traceback()
@ -441,51 +484,54 @@ class Tasmota
import path import path
# fail if empty string # fail if empty string
if size(f) == 0 return false end if size(f_name) == 0 return false end
# Ex: f = 'app.zip#autoexec' # Ex: f_name = 'app.zip#autoexec'
# add leading '/' if absent # add leading '/' if absent
if f[0] != '/' f = '/' + f end if !string.startswith(f_name, '/') f_name = '/' + f_name end
# Ex: f = '/app.zip#autoexec' # Ex: f_name = '/app.zip#autoexec'
var f_items = string.split(f, '#') var f_find_hash = string.find(f_name, '#')
var f_prefix = f_items[0] var f_archive = (f_find_hash > 0) # is the file in an archive
var f_suffix = f_items[-1] # last token var f_prefix = f_archive ? f_name[0..f_find_hash - 1] : f_name
var f_archive = size(f_items) > 1 # is the file in an archive var f_suffix = f_archive ? f_name[f_find_hash + 1 ..] : f_name # last token
# if no dot, add the default '.be' extension # if no dot, add the default '.be' extension
if string.find(f_suffix, '.') < 0 # does the final file has a '.' if string.find(f_suffix, '.') < 0 # does the final file has a '.'
f += ".be" f_name += ".be"
f_suffix += ".be" f_suffix += ".be"
end end
# Ex: f = '/app.zip#autoexec.be' # Ex: f_name = '/app.zip#autoexec.be'
# is the suffix .be or .bec ? # is the suffix .be or .bec ?
var suffix_be = f_suffix[-3..-1] == '.be' var suffix_be = string.endswith(f_suffix, '.be')
var suffix_bec = f_suffix[-4..-1] == '.bec' var suffix_bec = string.endswith(f_suffix, '.bec')
# Ex: f = '/app.zip#autoexec.be', f_suffix = 'autoexec.be', suffix_be = true, suffix_bec = false var f_name_bec = suffix_bec ? f_name : f_name + "c" # f_name_bec holds the bec version of the filename
# Ex: f_name = '/app.zip#autoexec.be', f_suffix = 'autoexec.be', suffix_be = true, suffix_bec = false
# check that the file ends with '.be' of '.bec' # check that the file ends with '.be' of '.bec'
if !suffix_be && !suffix_bec if !suffix_be && !suffix_bec
raise "io_error", "file extension is not '.be' or '.bec'" print("BRY: file extension is not '.be' nor '.bec'")
return false
end end
# get the last_modified time of the file or archive, returns `nil` if the file does not exist var use_bec = false # if 'true' load .bec file, if 'false' use .be file
var f_time = path.last_modified(f) if suffix_bec # we accept only .bec file, thys ignore .be
var f_name_bec = suffix_bec ? f : f + "c" # f_name_bec holds the bec version of the filename if !path.exists(f_name_bec)
return false # file does not exist
if suffix_bec end
if f_time == nil return false end # file requested is .bec but does not exist, fail use_bec = true
# from now, .bec file does exist else # suffix is .be so we can use .be or .bec
if path.exists(f_name)
# in such case remove .bec file if it exists to avoid confusion with obsolete version
if path.exists(f_name_bec)
try_remove_file(f_name_bec)
end
elif path.exists(f_name_bec)
use_bec = true
else else
var f_time_bec = path.last_modified(f_name_bec) # timestamp for .bec bytecode, nil if does not exist return false # file does not exist
if f_time == nil && f_time_bec == nil return false end # abort if neither .be nor .bec file exist
if f_time_bec != nil && (f_time == nil || f_time_bec >= f_time)
# bytecode exists and is more recent than berry source, use bytecode
##### temporarily disable loading from bec file
suffix_bec = true
end end
# print("f_time",f_time,"f_time_bec",f_time_bec,"suffix_bec",suffix_bec)
end end
# recall the working directory # recall the working directory
@ -498,16 +544,16 @@ class Tasmota
# try to load code into `compiled_code`, or `nil` if didn't succeed # try to load code into `compiled_code`, or `nil` if didn't succeed
var compiled_code var compiled_code
if suffix_bec # try the .bec version if use_bec # try the .bec version
# in this section we try to load the pre-compiled bytecode first # in this section we try to load the pre-compiled bytecode first
# (we already know that the file exists) # (we already know that the file exists)
var bec_version = try_get_bec_version(f_name_bec) var bec_version = try_get_bec_version(f_name_bec)
var version_ok = true var version_ok = true
if bec_version == nil if bec_version == nil
print(format('BRY: corrupt bytecode \'%s\'',f_name_bec)) print(f"BRY: corrupt bytecode '{f_name_bec}'")
version_ok = false version_ok = false
elif bec_version != 0x04 # -- this is the currenlty supported version elif bec_version != 0x04 # -- this is the currenlty supported version
print(format('BRY: bytecode has wrong version \'%s\' (%i)',f_name_bec,bec_version)) print(f"BRY: bytecode has wrong version '{f_name_bec}' ({bec_version})")
version_ok = false version_ok = false
end end
@ -517,25 +563,15 @@ class Tasmota
if compiled_code == nil # bytecode is bad, try to delete it and fallback if compiled_code == nil # bytecode is bad, try to delete it and fallback
try_remove_file(f_name_bec) try_remove_file(f_name_bec)
suffix_bec = false use_bec = false
end end
end end
if suffix_be && compiled_code == nil if !use_bec
# the pre-compiled is absent to failed, load the be file instead # the pre-compiled is absent to failed, load the be file instead
compiled_code = try_compile(f) compiled_code = try_compile(f_name)
end end
# save the compiled bytecode unless it's an archive
# print("compiled_code",compiled_code,"suffix_be",suffix_be,"suffix_bec",suffix_bec,"archive",f_archive,"f_name_bec",f_name_bec)
if compiled_code != nil && !suffix_bec && !f_archive
# try to save the pre-compiled version
try
self.save(f_name_bec, compiled_code)
except .. as e
print(format('BRY: could not save compiled file %s (%s)',f_name_bec,e))
end
end
# call the compiled code # call the compiled code
var run_ok = try_run_compiled(compiled_code) var run_ok = try_run_compiled(compiled_code)
# call successfuls # call successfuls