mirror of https://github.com/arendst/Tasmota.git
Berry fix bytecode load/save for static class members
This commit is contained in:
parent
db50783dd3
commit
1ce8dbad85
|
@ -137,14 +137,21 @@ static bstring** save_members(bvm *vm, void *fp, bclass *c, int nvar)
|
||||||
} else { /* save method's name and function */
|
} else { /* save method's name and function */
|
||||||
bproto *proto;
|
bproto *proto;
|
||||||
bvalue *value = &node->value;
|
bvalue *value = &node->value;
|
||||||
be_assert(var_isclosure(value) || var_isproto(value));
|
be_assert(var_isclosure(value) || var_isproto(value) || var_isnil(value));
|
||||||
save_string(fp, var_tostr(&node->key)); /* save method name */
|
save_string(fp, var_tostr(&node->key)); /* save method name */
|
||||||
if (var_isproto(value)) { /* the method is a prototype */
|
if (var_isproto(value)) { /* the method is a prototype */
|
||||||
proto = var_toobj(value);
|
proto = var_toobj(value);
|
||||||
} else { /* the method is a closure */
|
save_proto(vm, fp, proto); /* only save prototype */
|
||||||
proto = cast(bclosure *, var_toobj(value))->proto;
|
} else if (var_isclosure(value)) { /* the method is a closure */
|
||||||
|
proto = cast(bclosure *, var_toobj(value))->proto;
|
||||||
|
save_proto(vm, fp, proto); /* only save prototype */
|
||||||
|
} else if (var_isnil(value)) {
|
||||||
|
/* this is a static member (nil default) */
|
||||||
|
save_word(fp, 0); /* store a zero byte that will be seen as a zero length method name which is invalid */
|
||||||
|
} else {
|
||||||
|
be_raise(vm, "internal_error", "unsupported member in class");
|
||||||
|
return NULL; /* should never be executed */
|
||||||
}
|
}
|
||||||
save_proto(vm, fp, proto); /* only save prototype */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vars;
|
return vars;
|
||||||
|
@ -286,7 +293,7 @@ void be_bytecode_save(bvm *vm, const char *filename, bproto *proto)
|
||||||
#endif /* BE_USE_BYTECODE_SAVER */
|
#endif /* BE_USE_BYTECODE_SAVER */
|
||||||
|
|
||||||
#if BE_USE_BYTECODE_LOADER
|
#if BE_USE_BYTECODE_LOADER
|
||||||
static void load_proto(bvm *vm, void *fp, bproto **proto, int info, int version);
|
static bbool load_proto(bvm *vm, void *fp, bproto **proto, int info, int version);
|
||||||
|
|
||||||
static uint8_t load_byte(void *fp)
|
static uint8_t load_byte(void *fp)
|
||||||
{
|
{
|
||||||
|
@ -416,8 +423,13 @@ static void load_class(bvm *vm, void *fp, bvalue *v, int version)
|
||||||
value = vm->top;
|
value = vm->top;
|
||||||
var_setproto(value, NULL);
|
var_setproto(value, NULL);
|
||||||
be_incrtop(vm);
|
be_incrtop(vm);
|
||||||
load_proto(vm, fp, (bproto**)&var_toobj(value), -3, version);
|
if (load_proto(vm, fp, (bproto**)&var_toobj(value), -3, version)) {
|
||||||
be_method_bind(vm, c, name, var_toobj(value));
|
/* actual method */
|
||||||
|
be_method_bind(vm, c, name, var_toobj(value));
|
||||||
|
} else {
|
||||||
|
/* no proto, static member set to nil */
|
||||||
|
be_member_bind(vm, c, name, bfalse);
|
||||||
|
}
|
||||||
be_stackpop(vm, 2); /* pop the cached string and proto */
|
be_stackpop(vm, 2); /* pop the cached string and proto */
|
||||||
}
|
}
|
||||||
for (count = 0; count < nvar; ++count) { /* load member-variable table */
|
for (count = 0; count < nvar; ++count) { /* load member-variable table */
|
||||||
|
@ -509,21 +521,28 @@ static void load_upvals(bvm *vm, void *fp, bproto *proto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_proto(bvm *vm, void *fp, bproto **proto, int info, int version)
|
static bbool load_proto(bvm *vm, void *fp, bproto **proto, int info, int version)
|
||||||
{
|
{
|
||||||
*proto = be_newproto(vm);
|
/* first load the name */
|
||||||
(*proto)->name = load_string(vm, fp);
|
/* if empty, it's a static member so don't allocate an actual proto */
|
||||||
(*proto)->source = load_string(vm, fp);
|
bstring *name = load_string(vm, fp);
|
||||||
(*proto)->argc = load_byte(fp);
|
if (str_len(name)) {
|
||||||
(*proto)->nstack = load_byte(fp);
|
*proto = be_newproto(vm);
|
||||||
if (version > 1) {
|
(*proto)->name = name;
|
||||||
(*proto)->varg = load_byte(fp);
|
(*proto)->source = load_string(vm, fp);
|
||||||
load_byte(fp); /* discard reserved byte */
|
(*proto)->argc = load_byte(fp);
|
||||||
|
(*proto)->nstack = load_byte(fp);
|
||||||
|
if (version > 1) {
|
||||||
|
(*proto)->varg = load_byte(fp);
|
||||||
|
load_byte(fp); /* discard reserved byte */
|
||||||
|
}
|
||||||
|
load_bytecode(vm, fp, *proto, info);
|
||||||
|
load_constant(vm, fp, *proto, version);
|
||||||
|
load_proto_table(vm, fp, *proto, version);
|
||||||
|
load_upvals(vm, fp, *proto);
|
||||||
|
return btrue;
|
||||||
}
|
}
|
||||||
load_bytecode(vm, fp, *proto, info);
|
return bfalse; /* no proto read */
|
||||||
load_constant(vm, fp, *proto, version);
|
|
||||||
load_proto_table(vm, fp, *proto, version);
|
|
||||||
load_upvals(vm, fp, *proto);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_global_info(bvm *vm, void *fp)
|
void load_global_info(bvm *vm, void *fp)
|
||||||
|
|
Loading…
Reference in New Issue