|
|
@@ -8,328 +8,333 @@
|
|
|
#define CODEOBJECT_VER_MINOR 0
|
|
|
|
|
|
// Forward declarations
|
|
|
-static void FuncDecl__serialize(c11_serializer* s, const FuncDecl* decl);
|
|
|
-static FuncDecl_ FuncDecl__deserialize(c11_deserializer* d);
|
|
|
-static void CodeObject__serialize(c11_serializer* s, const CodeObject* co);
|
|
|
-static void CodeObject__deserialize(c11_deserializer* d, CodeObject* co);
|
|
|
+static void FuncDecl__serialize(c11_serializer* s,
|
|
|
+ const FuncDecl* decl,
|
|
|
+ const struct SourceData* parent_src);
|
|
|
+static FuncDecl_ FuncDecl__deserialize(c11_deserializer* d, SourceData_ embedded_src);
|
|
|
+static void CodeObject__serialize(c11_serializer* s,
|
|
|
+ const CodeObject* co,
|
|
|
+ const struct SourceData* parent_src);
|
|
|
+static CodeObject CodeObject__deserialize(c11_deserializer* d, SourceData_ embedded_src);
|
|
|
|
|
|
// Serialize a py_TValue constant
|
|
|
// Supported types: None, int, float, bool, str, bytes, tuple, Ellipsis
|
|
|
-static void TValue__serialize(c11_serializer* s, const py_TValue* val) {
|
|
|
+static void TValue__serialize(c11_serializer* s, py_Ref val) {
|
|
|
c11_serializer__write_type(s, val->type);
|
|
|
+ // 1. co_consts: int | float | str
|
|
|
+ // 2. function defaults: see `read_literal()` in compiler.c
|
|
|
switch(val->type) {
|
|
|
- case tp_NoneType:
|
|
|
- case tp_ellipsis:
|
|
|
- // No additional data needed
|
|
|
- break;
|
|
|
- case tp_int:
|
|
|
- c11_serializer__write_i64(s, val->_i64);
|
|
|
- break;
|
|
|
- case tp_float:
|
|
|
- c11_serializer__write_f64(s, val->_f64);
|
|
|
- break;
|
|
|
- case tp_bool:
|
|
|
- c11_serializer__write_i8(s, val->_bool ? 1 : 0);
|
|
|
- break;
|
|
|
+ case tp_int: c11_serializer__write_i64(s, val->_i64); break;
|
|
|
+ case tp_float: c11_serializer__write_f64(s, val->_f64); break;
|
|
|
case tp_str: {
|
|
|
c11_sv sv = py_tosv((py_Ref)val);
|
|
|
- c11_serializer__write_size(s, sv.size);
|
|
|
+ c11_serializer__write_i32(s, sv.size);
|
|
|
c11_serializer__write_bytes(s, sv.data, sv.size);
|
|
|
break;
|
|
|
}
|
|
|
- case tp_bytes: {
|
|
|
- int size;
|
|
|
- unsigned char* data = py_tobytes((py_Ref)val, &size);
|
|
|
- c11_serializer__write_size(s, size);
|
|
|
- c11_serializer__write_bytes(s, data, size);
|
|
|
+ case tp_bool: {
|
|
|
+ bool value = py_tobool(val);
|
|
|
+ c11_serializer__write_i8(s, value ? 1 : 0);
|
|
|
break;
|
|
|
}
|
|
|
+ case tp_NoneType: break;
|
|
|
+ case tp_ellipsis: break;
|
|
|
case tp_tuple: {
|
|
|
- int len = py_tuple_len((py_Ref)val);
|
|
|
- c11_serializer__write_size(s, len);
|
|
|
- py_ObjectRef data = py_tuple_data((py_Ref)val);
|
|
|
+ int len = py_tuple_len(val);
|
|
|
+ c11_serializer__write_i32(s, len);
|
|
|
for(int i = 0; i < len; i++) {
|
|
|
- TValue__serialize(s, &data[i]);
|
|
|
+ py_Ref item = py_tuple_getitem(val, i);
|
|
|
+ TValue__serialize(s, item);
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
- default:
|
|
|
- c11__abort("TValue__serialize: unsupported type %d", val->type);
|
|
|
+ default: c11__abort("TValue__serialize: invalid type '%s'", py_tpname(val->type));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Deserialize a py_TValue constant
|
|
|
-static void TValue__deserialize(c11_deserializer* d, py_TValue* val) {
|
|
|
+static void TValue__deserialize(c11_deserializer* d, py_OutRef out) {
|
|
|
py_Type type = c11_deserializer__read_type(d);
|
|
|
switch(type) {
|
|
|
- case tp_NoneType:
|
|
|
- py_newnone(val);
|
|
|
- break;
|
|
|
- case tp_ellipsis:
|
|
|
- py_newellipsis(val);
|
|
|
- break;
|
|
|
case tp_int: {
|
|
|
- int64_t v = c11_deserializer__read_i64(d);
|
|
|
- py_newint(val, v);
|
|
|
+ py_i64 v = c11_deserializer__read_i64(d);
|
|
|
+ py_newint(out, v);
|
|
|
break;
|
|
|
}
|
|
|
case tp_float: {
|
|
|
- double v = c11_deserializer__read_f64(d);
|
|
|
- py_newfloat(val, v);
|
|
|
+ py_f64 v = c11_deserializer__read_f64(d);
|
|
|
+ py_newfloat(out, v);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case tp_str: {
|
|
|
+ int size = c11_deserializer__read_i32(d);
|
|
|
+ char* dst = py_newstrn(out, size);
|
|
|
+ char* src = c11_deserializer__read_bytes(d, size);
|
|
|
+ memcpy(dst, src, size);
|
|
|
break;
|
|
|
}
|
|
|
case tp_bool: {
|
|
|
- int8_t v = c11_deserializer__read_i8(d);
|
|
|
- py_newbool(val, v != 0);
|
|
|
+ bool v = c11_deserializer__read_i8(d) != 0;
|
|
|
+ py_newbool(out, v);
|
|
|
break;
|
|
|
}
|
|
|
- case tp_str: {
|
|
|
- int size = c11_deserializer__read_size(d);
|
|
|
- char* data = py_newstrn(val, size);
|
|
|
- memcpy(data, c11_deserializer__read_bytes(d, size), size);
|
|
|
+ case tp_NoneType: {
|
|
|
+ py_newnone(out);
|
|
|
break;
|
|
|
}
|
|
|
- case tp_bytes: {
|
|
|
- int size = c11_deserializer__read_size(d);
|
|
|
- unsigned char* data = py_newbytes(val, size);
|
|
|
- memcpy(data, c11_deserializer__read_bytes(d, size), size);
|
|
|
+ case tp_ellipsis: {
|
|
|
+ py_newellipsis(out);
|
|
|
break;
|
|
|
}
|
|
|
case tp_tuple: {
|
|
|
- int len = c11_deserializer__read_size(d);
|
|
|
- py_ObjectRef data = py_newtuple(val, len);
|
|
|
+ int len = c11_deserializer__read_i32(d);
|
|
|
+ py_newtuple(out, len);
|
|
|
for(int i = 0; i < len; i++) {
|
|
|
- TValue__deserialize(d, &data[i]);
|
|
|
+ py_ItemRef item = py_tuple_getitem(out, i);
|
|
|
+ TValue__deserialize(d, item);
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
default:
|
|
|
- c11__abort("TValue__deserialize: unsupported type %d", type);
|
|
|
+ c11__abort("TValue__deserialize: invalid type '%s'", py_tpname(type));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Serialize CodeObject
|
|
|
-static void CodeObject__serialize(c11_serializer* s, const CodeObject* co) {
|
|
|
+static void CodeObject__serialize(c11_serializer* s,
|
|
|
+ const CodeObject* co,
|
|
|
+ const struct SourceData* parent_src) {
|
|
|
// SourceData
|
|
|
- c11_serializer__write_cstr(s, co->src->filename->data);
|
|
|
- c11_serializer__write_cstr(s, co->src->source->data);
|
|
|
- c11_serializer__write_i8(s, (int8_t)co->src->mode);
|
|
|
- c11_serializer__write_i8(s, co->src->is_dynamic ? 1 : 0);
|
|
|
+ if(!parent_src) {
|
|
|
+ c11_serializer__write_i8(s, (int8_t)co->src->mode);
|
|
|
+ c11_serializer__write_i8(s, co->src->is_dynamic ? 1 : 0);
|
|
|
+ c11_serializer__write_cstr(s, co->src->filename->data);
|
|
|
+ } else {
|
|
|
+ c11__rtassert(co->src == parent_src);
|
|
|
+ }
|
|
|
|
|
|
// name
|
|
|
c11_serializer__write_cstr(s, co->name->data);
|
|
|
|
|
|
// codes
|
|
|
- c11_serializer__write_size(s, co->codes.length);
|
|
|
+ _Static_assert(sizeof(Bytecode) == sizeof(uint16_t) * 2, "");
|
|
|
+ c11_serializer__write_i32(s, co->codes.length);
|
|
|
c11_serializer__write_bytes(s, co->codes.data, co->codes.length * sizeof(Bytecode));
|
|
|
|
|
|
// codes_ex
|
|
|
- c11_serializer__write_size(s, co->codes_ex.length);
|
|
|
+ _Static_assert(sizeof(BytecodeEx) == sizeof(int32_t) * 2, "");
|
|
|
+ c11_serializer__write_i32(s, co->codes_ex.length);
|
|
|
c11_serializer__write_bytes(s, co->codes_ex.data, co->codes_ex.length * sizeof(BytecodeEx));
|
|
|
|
|
|
// consts
|
|
|
- c11_serializer__write_size(s, co->consts.length);
|
|
|
+ c11_serializer__write_i32(s, co->consts.length);
|
|
|
for(int i = 0; i < co->consts.length; i++) {
|
|
|
- py_TValue* val = c11__at(py_TValue, &co->consts, i);
|
|
|
+ py_Ref val = c11__at(py_TValue, &co->consts, i);
|
|
|
TValue__serialize(s, val);
|
|
|
}
|
|
|
|
|
|
// varnames (as cstr via py_name2str)
|
|
|
- c11_serializer__write_size(s, co->varnames.length);
|
|
|
+ c11_serializer__write_i32(s, co->varnames.length);
|
|
|
for(int i = 0; i < co->varnames.length; i++) {
|
|
|
py_Name name = c11__getitem(py_Name, &co->varnames, i);
|
|
|
c11_serializer__write_cstr(s, py_name2str(name));
|
|
|
}
|
|
|
|
|
|
// names (as cstr via py_name2str)
|
|
|
- c11_serializer__write_size(s, co->names.length);
|
|
|
+ c11_serializer__write_i32(s, co->names.length);
|
|
|
for(int i = 0; i < co->names.length; i++) {
|
|
|
py_Name name = c11__getitem(py_Name, &co->names, i);
|
|
|
c11_serializer__write_cstr(s, py_name2str(name));
|
|
|
}
|
|
|
|
|
|
// nlocals
|
|
|
- c11_serializer__write_size(s, co->nlocals);
|
|
|
+ c11_serializer__write_i32(s, co->nlocals);
|
|
|
|
|
|
// blocks
|
|
|
- c11_serializer__write_size(s, co->blocks.length);
|
|
|
+ _Static_assert(sizeof(CodeBlock) == sizeof(int32_t) * 5, "");
|
|
|
+ c11_serializer__write_i32(s, co->blocks.length);
|
|
|
c11_serializer__write_bytes(s, co->blocks.data, co->blocks.length * sizeof(CodeBlock));
|
|
|
|
|
|
// func_decls
|
|
|
- c11_serializer__write_size(s, co->func_decls.length);
|
|
|
+ c11_serializer__write_i32(s, co->func_decls.length);
|
|
|
for(int i = 0; i < co->func_decls.length; i++) {
|
|
|
- FuncDecl_ decl = c11__getitem(FuncDecl_, &co->func_decls, i);
|
|
|
- FuncDecl__serialize(s, decl);
|
|
|
+ const FuncDecl* decl = c11__getitem(FuncDecl_, &co->func_decls, i);
|
|
|
+ FuncDecl__serialize(s, decl, co->src);
|
|
|
}
|
|
|
|
|
|
// start_line, end_line
|
|
|
- c11_serializer__write_size(s, co->start_line);
|
|
|
- c11_serializer__write_size(s, co->end_line);
|
|
|
+ c11_serializer__write_i32(s, co->start_line);
|
|
|
+ c11_serializer__write_i32(s, co->end_line);
|
|
|
}
|
|
|
|
|
|
// Deserialize CodeObject (initialize co before calling)
|
|
|
-static void CodeObject__deserialize(c11_deserializer* d, CodeObject* co) {
|
|
|
+static CodeObject CodeObject__deserialize(c11_deserializer* d, SourceData_ embedded_src) {
|
|
|
+ CodeObject co;
|
|
|
+
|
|
|
// SourceData
|
|
|
- const char* filename = c11_deserializer__read_cstr(d);
|
|
|
- const char* source = c11_deserializer__read_cstr(d);
|
|
|
- enum py_CompileMode mode = (enum py_CompileMode)c11_deserializer__read_i8(d);
|
|
|
- bool is_dynamic = c11_deserializer__read_i8(d) != 0;
|
|
|
- SourceData_ src = SourceData__rcnew(source, filename, mode, is_dynamic);
|
|
|
+ SourceData_ src;
|
|
|
+ if(embedded_src != NULL) {
|
|
|
+ src = embedded_src;
|
|
|
+ PK_INCREF(src);
|
|
|
+ } else {
|
|
|
+ enum py_CompileMode mode = (enum py_CompileMode)c11_deserializer__read_i8(d);
|
|
|
+ bool is_dynamic = c11_deserializer__read_i8(d) != 0;
|
|
|
+ const char* filename = c11_deserializer__read_cstr(d);
|
|
|
+ src = SourceData__rcnew(NULL, filename, mode, is_dynamic);
|
|
|
+ }
|
|
|
|
|
|
// name
|
|
|
const char* name = c11_deserializer__read_cstr(d);
|
|
|
c11_sv name_sv = {name, strlen(name)};
|
|
|
|
|
|
// Initialize the CodeObject
|
|
|
- CodeObject__ctor(co, src, name_sv);
|
|
|
+ CodeObject__ctor(&co, src, name_sv);
|
|
|
PK_DECREF(src); // CodeObject__ctor increments ref count
|
|
|
-
|
|
|
// Clear the default root block that CodeObject__ctor adds
|
|
|
- c11_vector__clear(&co->blocks);
|
|
|
+ c11_vector__clear(&co.blocks);
|
|
|
|
|
|
// codes
|
|
|
- int codes_len = c11_deserializer__read_size(d);
|
|
|
- c11_vector__reserve(&co->codes, codes_len);
|
|
|
- memcpy(co->codes.data, c11_deserializer__read_bytes(d, codes_len * sizeof(Bytecode)), codes_len * sizeof(Bytecode));
|
|
|
- co->codes.length = codes_len;
|
|
|
-
|
|
|
+ int codes_len = c11_deserializer__read_i32(d);
|
|
|
+ c11_vector__extend(&co.codes,
|
|
|
+ c11_deserializer__read_bytes(d, codes_len * sizeof(Bytecode)),
|
|
|
+ codes_len);
|
|
|
// codes_ex
|
|
|
- int codes_ex_len = c11_deserializer__read_size(d);
|
|
|
- c11_vector__reserve(&co->codes_ex, codes_ex_len);
|
|
|
- memcpy(co->codes_ex.data, c11_deserializer__read_bytes(d, codes_ex_len * sizeof(BytecodeEx)), codes_ex_len * sizeof(BytecodeEx));
|
|
|
- co->codes_ex.length = codes_ex_len;
|
|
|
+ int codes_ex_len = c11_deserializer__read_i32(d);
|
|
|
+ c11_vector__extend(&co.codes_ex,
|
|
|
+ c11_deserializer__read_bytes(d, codes_ex_len * sizeof(BytecodeEx)),
|
|
|
+ codes_ex_len);
|
|
|
|
|
|
// consts
|
|
|
- int consts_len = c11_deserializer__read_size(d);
|
|
|
+ int consts_len = c11_deserializer__read_i32(d);
|
|
|
for(int i = 0; i < consts_len; i++) {
|
|
|
- py_TValue val;
|
|
|
- TValue__deserialize(d, &val);
|
|
|
- c11_vector__push(py_TValue, &co->consts, val);
|
|
|
+ py_Ref p_val = c11_vector__emplace(&co.consts);
|
|
|
+ TValue__deserialize(d, p_val);
|
|
|
}
|
|
|
|
|
|
// varnames
|
|
|
- int varnames_len = c11_deserializer__read_size(d);
|
|
|
+ int varnames_len = c11_deserializer__read_i32(d);
|
|
|
for(int i = 0; i < varnames_len; i++) {
|
|
|
const char* s = c11_deserializer__read_cstr(d);
|
|
|
py_Name n = py_name(s);
|
|
|
- c11_vector__push(py_Name, &co->varnames, n);
|
|
|
- c11_smallmap_n2d__set(&co->varnames_inv, n, i);
|
|
|
+ c11_vector__push(py_Name, &co.varnames, n);
|
|
|
+ c11_smallmap_n2d__set(&co.varnames_inv, n, i);
|
|
|
}
|
|
|
|
|
|
// names
|
|
|
- int names_len = c11_deserializer__read_size(d);
|
|
|
+ int names_len = c11_deserializer__read_i32(d);
|
|
|
for(int i = 0; i < names_len; i++) {
|
|
|
const char* s = c11_deserializer__read_cstr(d);
|
|
|
py_Name n = py_name(s);
|
|
|
- c11_vector__push(py_Name, &co->names, n);
|
|
|
- c11_smallmap_n2d__set(&co->names_inv, n, i);
|
|
|
+ c11_vector__push(py_Name, &co.names, n);
|
|
|
+ c11_smallmap_n2d__set(&co.names_inv, n, i);
|
|
|
}
|
|
|
|
|
|
// nlocals
|
|
|
- co->nlocals = c11_deserializer__read_size(d);
|
|
|
+ co.nlocals = c11_deserializer__read_i32(d);
|
|
|
|
|
|
// blocks
|
|
|
- int blocks_len = c11_deserializer__read_size(d);
|
|
|
- c11_vector__reserve(&co->blocks, blocks_len);
|
|
|
- memcpy(co->blocks.data, c11_deserializer__read_bytes(d, blocks_len * sizeof(CodeBlock)), blocks_len * sizeof(CodeBlock));
|
|
|
- co->blocks.length = blocks_len;
|
|
|
-
|
|
|
+ int blocks_len = c11_deserializer__read_i32(d);
|
|
|
+ c11_vector__extend(&co.blocks,
|
|
|
+ c11_deserializer__read_bytes(d, blocks_len * sizeof(CodeBlock)),
|
|
|
+ blocks_len);
|
|
|
// func_decls
|
|
|
- int func_decls_len = c11_deserializer__read_size(d);
|
|
|
+ int func_decls_len = c11_deserializer__read_i32(d);
|
|
|
for(int i = 0; i < func_decls_len; i++) {
|
|
|
- FuncDecl_ decl = FuncDecl__deserialize(d);
|
|
|
- c11_vector__push(FuncDecl_, &co->func_decls, decl);
|
|
|
+ FuncDecl_ decl = FuncDecl__deserialize(d, src);
|
|
|
+ c11_vector__push(FuncDecl_, &co.func_decls, decl);
|
|
|
}
|
|
|
|
|
|
// start_line, end_line
|
|
|
- co->start_line = c11_deserializer__read_size(d);
|
|
|
- co->end_line = c11_deserializer__read_size(d);
|
|
|
+ co.start_line = c11_deserializer__read_i32(d);
|
|
|
+ co.end_line = c11_deserializer__read_i32(d);
|
|
|
+
|
|
|
+ return co;
|
|
|
}
|
|
|
|
|
|
// Serialize FuncDecl
|
|
|
-static void FuncDecl__serialize(c11_serializer* s, const FuncDecl* decl) {
|
|
|
+static void FuncDecl__serialize(c11_serializer* s,
|
|
|
+ const FuncDecl* decl,
|
|
|
+ const struct SourceData* parent_src) {
|
|
|
// CodeObject (embedded)
|
|
|
- CodeObject__serialize(s, &decl->code);
|
|
|
+ CodeObject__serialize(s, &decl->code, parent_src);
|
|
|
|
|
|
// args
|
|
|
- c11_serializer__write_size(s, decl->args.length);
|
|
|
- c11_serializer__write_bytes(s, decl->args.data, decl->args.length * sizeof(int));
|
|
|
+ c11_serializer__write_i32(s, decl->args.length);
|
|
|
+ c11_serializer__write_bytes(s, decl->args.data, decl->args.length * sizeof(int32_t));
|
|
|
|
|
|
// kwargs
|
|
|
- c11_serializer__write_size(s, decl->kwargs.length);
|
|
|
+ c11_serializer__write_i32(s, decl->kwargs.length);
|
|
|
for(int i = 0; i < decl->kwargs.length; i++) {
|
|
|
FuncDeclKwArg* kw = c11__at(FuncDeclKwArg, &decl->kwargs, i);
|
|
|
- c11_serializer__write_size(s, kw->index);
|
|
|
+ c11_serializer__write_i32(s, kw->index);
|
|
|
c11_serializer__write_cstr(s, py_name2str(kw->key));
|
|
|
TValue__serialize(s, &kw->value);
|
|
|
}
|
|
|
|
|
|
// starred_arg, starred_kwarg
|
|
|
- c11_serializer__write_size(s, decl->starred_arg);
|
|
|
- c11_serializer__write_size(s, decl->starred_kwarg);
|
|
|
+ c11_serializer__write_i32(s, decl->starred_arg);
|
|
|
+ c11_serializer__write_i32(s, decl->starred_kwarg);
|
|
|
|
|
|
// nested
|
|
|
c11_serializer__write_i8(s, decl->nested ? 1 : 0);
|
|
|
|
|
|
// docstring
|
|
|
- c11_serializer__write_cstr(s, decl->docstring ? decl->docstring : "");
|
|
|
+ int has_docstring = decl->docstring != NULL ? 1 : 0;
|
|
|
+ c11_serializer__write_i8(s, has_docstring);
|
|
|
+ if(has_docstring) c11_serializer__write_cstr(s, decl->docstring);
|
|
|
|
|
|
// type
|
|
|
c11_serializer__write_i8(s, (int8_t)decl->type);
|
|
|
}
|
|
|
|
|
|
// Deserialize FuncDecl
|
|
|
-static FuncDecl_ FuncDecl__deserialize(c11_deserializer* d) {
|
|
|
- // We need to deserialize the CodeObject first to get src and name
|
|
|
- // But FuncDecl__rcnew calls CodeObject__ctor, so we deserialize differently
|
|
|
-
|
|
|
- // Allocate FuncDecl manually
|
|
|
+static FuncDecl_ FuncDecl__deserialize(c11_deserializer* d, SourceData_ embedded_src) {
|
|
|
FuncDecl* self = PK_MALLOC(sizeof(FuncDecl));
|
|
|
self->rc.count = 1;
|
|
|
-
|
|
|
- // Deserialize CodeObject directly into self->code
|
|
|
- CodeObject__deserialize(d, &self->code);
|
|
|
-
|
|
|
- // Initialize other fields
|
|
|
- c11_vector__ctor(&self->args, sizeof(int));
|
|
|
+ self->rc.dtor = (void (*)(void*))FuncDecl__dtor;
|
|
|
+
|
|
|
+ c11_vector__ctor(&self->args, sizeof(int32_t));
|
|
|
c11_vector__ctor(&self->kwargs, sizeof(FuncDeclKwArg));
|
|
|
c11_smallmap_n2d__ctor(&self->kw_to_index);
|
|
|
|
|
|
+ // CodeObject (embedded)
|
|
|
+ self->code = CodeObject__deserialize(d, embedded_src);
|
|
|
+
|
|
|
// args
|
|
|
- int args_len = c11_deserializer__read_size(d);
|
|
|
- c11_vector__reserve(&self->args, args_len);
|
|
|
- memcpy(self->args.data, c11_deserializer__read_bytes(d, args_len * sizeof(int)), args_len * sizeof(int));
|
|
|
- self->args.length = args_len;
|
|
|
+ int args_len = c11_deserializer__read_i32(d);
|
|
|
+ c11_vector__extend(&self->args,
|
|
|
+ c11_deserializer__read_bytes(d, args_len * sizeof(int32_t)),
|
|
|
+ args_len);
|
|
|
|
|
|
// kwargs
|
|
|
- int kwargs_len = c11_deserializer__read_size(d);
|
|
|
+ int kwargs_len = c11_deserializer__read_i32(d);
|
|
|
for(int i = 0; i < kwargs_len; i++) {
|
|
|
- FuncDeclKwArg kw;
|
|
|
- kw.index = c11_deserializer__read_size(d);
|
|
|
+ FuncDeclKwArg* kw = c11_vector__emplace(&self->kwargs);
|
|
|
+ kw->index = c11_deserializer__read_i32(d);
|
|
|
const char* key_str = c11_deserializer__read_cstr(d);
|
|
|
- kw.key = py_name(key_str);
|
|
|
- TValue__deserialize(d, &kw.value);
|
|
|
- c11_vector__push(FuncDeclKwArg, &self->kwargs, kw);
|
|
|
- c11_smallmap_n2d__set(&self->kw_to_index, kw.key, kw.index);
|
|
|
+ kw->key = py_name(key_str);
|
|
|
+ TValue__deserialize(d, &kw->value);
|
|
|
+ c11_smallmap_n2d__set(&self->kw_to_index, kw->key, kw->index);
|
|
|
}
|
|
|
-
|
|
|
- // starred_arg, starred_kwarg
|
|
|
- self->starred_arg = c11_deserializer__read_size(d);
|
|
|
- self->starred_kwarg = c11_deserializer__read_size(d);
|
|
|
+ // starred_arg
|
|
|
+ self->starred_arg = c11_deserializer__read_i32(d);
|
|
|
+ // starred_kwarg
|
|
|
+ self->starred_kwarg = c11_deserializer__read_i32(d);
|
|
|
|
|
|
// nested
|
|
|
self->nested = c11_deserializer__read_i8(d) != 0;
|
|
|
|
|
|
// docstring
|
|
|
- const char* docstring = c11_deserializer__read_cstr(d);
|
|
|
- self->docstring = docstring[0] ? c11_strdup(docstring) : NULL;
|
|
|
+ int has_docstring = c11_deserializer__read_i8(d);
|
|
|
+ if(has_docstring) {
|
|
|
+ const char* docstring = c11_deserializer__read_cstr(d);
|
|
|
+ self->docstring = c11_strdup(docstring);
|
|
|
+ } else {
|
|
|
+ self->docstring = NULL;
|
|
|
+ }
|
|
|
|
|
|
// type
|
|
|
self->type = (FuncType)c11_deserializer__read_i8(d);
|
|
|
-
|
|
|
- // Set destructor
|
|
|
- self->rc.dtor = NULL; // Will be set properly when used
|
|
|
-
|
|
|
return self;
|
|
|
}
|
|
|
|
|
|
@@ -337,26 +342,26 @@ static FuncDecl_ FuncDecl__deserialize(c11_deserializer* d) {
|
|
|
void* CodeObject__dumps(const CodeObject* co, int* size) {
|
|
|
c11_serializer s;
|
|
|
c11_serializer__ctor(&s, CODEOBJECT_MAGIC, CODEOBJECT_VER_MAJOR, CODEOBJECT_VER_MINOR);
|
|
|
- CodeObject__serialize(&s, co);
|
|
|
+ CodeObject__serialize(&s, co, NULL);
|
|
|
return c11_serializer__submit(&s, size);
|
|
|
}
|
|
|
|
|
|
-// Static error message buffer for CodeObject__loads
|
|
|
-static _Thread_local char s_codeobject_error_msg[64];
|
|
|
-
|
|
|
// Public API: Deserialize CodeObject from bytes
|
|
|
// Returns error message or NULL on success
|
|
|
-const char* CodeObject__loads(CodeObject* co, const void* data, int size) {
|
|
|
+char* CodeObject__loads(const void* data, int size, CodeObject* out) {
|
|
|
c11_deserializer d;
|
|
|
c11_deserializer__ctor(&d, data, size);
|
|
|
-
|
|
|
- if(!c11_deserializer__check_header(&d, CODEOBJECT_MAGIC, CODEOBJECT_VER_MAJOR, CODEOBJECT_VER_MINOR)) {
|
|
|
- memcpy(s_codeobject_error_msg, d.error_msg, sizeof(s_codeobject_error_msg));
|
|
|
+
|
|
|
+ if(!c11_deserializer__check_header(&d,
|
|
|
+ CODEOBJECT_MAGIC,
|
|
|
+ CODEOBJECT_VER_MAJOR,
|
|
|
+ CODEOBJECT_VER_MINOR)) {
|
|
|
+ char* error_msg = c11_strdup(d.error_msg);
|
|
|
c11_deserializer__dtor(&d);
|
|
|
- return s_codeobject_error_msg;
|
|
|
+ return error_msg;
|
|
|
}
|
|
|
-
|
|
|
- CodeObject__deserialize(&d, co);
|
|
|
+
|
|
|
+ *out = CodeObject__deserialize(&d, NULL);
|
|
|
c11_deserializer__dtor(&d);
|
|
|
return NULL;
|
|
|
}
|