mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
backup
This commit is contained in:
parent
a0bd1a3f3b
commit
2f2a7b53fd
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@ -2,6 +2,7 @@ name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- 'web/**'
|
||||
|
1
.github/workflows/pybind11.yml
vendored
1
.github/workflows/pybind11.yml
vendored
@ -2,6 +2,7 @@ name: PKBIND Build and Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths-ignore:
|
||||
- "docs/**"
|
||||
- "web/**"
|
||||
|
5
include/pocketpy/common/namedict.h
Normal file
5
include/pocketpy/common/namedict.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct NameDict {
|
||||
|
||||
} NameDict;
|
@ -5,7 +5,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#define SMALLMAP_T__HEADER
|
||||
#define K uint16_t
|
||||
#define K py_Name
|
||||
#define V int
|
||||
#define NAME c11_smallmap_n2i
|
||||
#include "pocketpy/xmacros/smallmap.h"
|
||||
@ -14,7 +14,7 @@
|
||||
|
||||
#define SMALLMAP_T__HEADER
|
||||
#define K c11_sv
|
||||
#define V uint16_t
|
||||
#define V py_Name
|
||||
#define NAME c11_smallmap_s2n
|
||||
#define less(a, b) (c11_sv__cmp((a), (b)) < 0)
|
||||
#define equal(a, b) (c11_sv__cmp((a), (b)) == 0)
|
||||
|
@ -4,15 +4,18 @@
|
||||
#include "pocketpy/common/smallmap.h"
|
||||
|
||||
typedef struct {
|
||||
char* data; // null-terminated data
|
||||
int size; // size of the data excluding the null-terminator
|
||||
py_TValue obj; // cached `str` object (lazy initialized)
|
||||
} RInternedEntry;
|
||||
char data[]; // null-terminated data
|
||||
} InternedEntry;
|
||||
|
||||
typedef struct {
|
||||
c11_smallmap_s2n interned;
|
||||
c11_vector /* T=RInternedEntry */ r_interned;
|
||||
} InternedNames;
|
||||
|
||||
void InternedNames__ctor(InternedNames* self);
|
||||
void InternedNames__dtor(InternedNames* self);
|
||||
|
||||
#define MAGIC_METHOD(x) extern py_Name x;
|
||||
#include "pocketpy/xmacros/magics.h"
|
||||
#undef MAGIC_METHOD
|
@ -75,9 +75,11 @@ typedef struct CodeObject {
|
||||
|
||||
c11_vector /*T=py_TValue*/ consts; // constants
|
||||
c11_vector /*T=py_Name*/ varnames; // local variables
|
||||
int nlocals; // cached varnames.size()
|
||||
c11_vector /*T=py_Name*/ names;
|
||||
int nlocals;
|
||||
|
||||
c11_smallmap_n2i varnames_inv;
|
||||
c11_smallmap_n2i names_inv;
|
||||
|
||||
c11_vector /*T=CodeBlock*/ blocks;
|
||||
c11_vector /*T=FuncDecl_*/ func_decls;
|
||||
@ -89,6 +91,7 @@ typedef struct CodeObject {
|
||||
void CodeObject__ctor(CodeObject* self, SourceData_ src, c11_sv name);
|
||||
void CodeObject__dtor(CodeObject* self);
|
||||
int CodeObject__add_varname(CodeObject* self, py_Name name);
|
||||
int CodeObject__add_name(CodeObject* self, py_Name name);
|
||||
void CodeObject__gc_mark(const CodeObject* self, c11_vector* p_stack);
|
||||
|
||||
typedef struct FuncDeclKwArg {
|
||||
|
@ -13,12 +13,12 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/************* Public Types *************/
|
||||
|
||||
/// A helper struct for `py_Name`.
|
||||
typedef struct py_OpaqueName py_OpaqueName;
|
||||
/// A pointer that represents a python identifier. For fast name resolution.
|
||||
typedef py_OpaqueName* py_Name;
|
||||
/// A opaque type that represents a python object. You cannot access its members directly.
|
||||
typedef struct py_TValue py_TValue;
|
||||
/// An integer that represents a python identifier. This is to achieve string pooling and fast name
|
||||
/// resolution.
|
||||
typedef uint16_t py_Name;
|
||||
/// An integer that represents a python type. `0` is invalid.
|
||||
typedef int16_t py_Type;
|
||||
/// A 64-bit integer type. Corresponds to `int` in python.
|
||||
@ -710,14 +710,6 @@ PK_API int py_replinput(char* buf, int max_size);
|
||||
/// %t: py_Type
|
||||
/// %n: py_Name
|
||||
|
||||
enum py_MagicName {
|
||||
py_MagicName__NULL, // 0 is reserved
|
||||
|
||||
#define MAGIC_METHOD(x) x,
|
||||
#include "pocketpy/xmacros/magics.h"
|
||||
#undef MAGIC_METHOD
|
||||
};
|
||||
|
||||
enum py_PredefinedType {
|
||||
tp_nil = 0,
|
||||
tp_object = 1,
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "pocketpy/common/smallmap.h"
|
||||
|
||||
#define SMALLMAP_T__SOURCE
|
||||
#define K uint16_t
|
||||
#define K py_Name
|
||||
#define V int
|
||||
#define NAME c11_smallmap_n2i
|
||||
#include "pocketpy/xmacros/smallmap.h"
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
#define SMALLMAP_T__SOURCE
|
||||
#define K c11_sv
|
||||
#define V uint16_t
|
||||
#define V py_Name
|
||||
#define NAME c11_smallmap_s2n
|
||||
#define less(a, b) (c11_sv__cmp((a), (b)) < 0)
|
||||
#define equal(a, b) (c11_sv__cmp((a), (b)) == 0)
|
||||
|
@ -61,9 +61,9 @@ typedef struct Ctx {
|
||||
int level;
|
||||
int curr_iblock;
|
||||
bool is_compiling_class;
|
||||
c11_vector /*T=Expr* */ s_expr;
|
||||
c11_vector /*T=Expr_p*/ s_expr;
|
||||
c11_smallmap_n2i global_names;
|
||||
c11_smallmap_s2n co_consts_string_dedup_map;
|
||||
c11_smallmap_s2n co_consts_string_dedup_map; // this stores 0-based index instead of pointer
|
||||
} Ctx;
|
||||
|
||||
typedef struct Expr Expr;
|
||||
@ -75,11 +75,12 @@ static int Ctx__enter_block(Ctx* self, CodeBlockType type);
|
||||
static void Ctx__exit_block(Ctx* self);
|
||||
static int Ctx__emit_(Ctx* self, Opcode opcode, uint16_t arg, int line);
|
||||
static int Ctx__emit_virtual(Ctx* self, Opcode opcode, uint16_t arg, int line, bool virtual);
|
||||
static void Ctx__revert_last_emit_(Ctx* self);
|
||||
// static void Ctx__revert_last_emit_(Ctx* self);
|
||||
static int Ctx__emit_int(Ctx* self, int64_t value, int line);
|
||||
static void Ctx__patch_jump(Ctx* self, int index);
|
||||
static void Ctx__emit_jump(Ctx* self, int target, int line);
|
||||
static int Ctx__add_varname(Ctx* self, py_Name name);
|
||||
static int Ctx__add_name(Ctx* self, py_Name name);
|
||||
static int Ctx__add_const(Ctx* self, py_Ref);
|
||||
static int Ctx__add_const_string(Ctx* self, c11_sv);
|
||||
static void Ctx__emit_store_name(Ctx* self, NameScope scope, py_Name name, int line);
|
||||
@ -117,7 +118,7 @@ void NameExpr__emit_(Expr* self_, Ctx* ctx) {
|
||||
}
|
||||
}
|
||||
}
|
||||
Ctx__emit_(ctx, op, self->name, self->line);
|
||||
Ctx__emit_(ctx, op, Ctx__add_name(ctx, self->name), self->line);
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +130,7 @@ bool NameExpr__emit_del(Expr* self_, Ctx* ctx) {
|
||||
break;
|
||||
case NAME_GLOBAL: {
|
||||
Opcode op = ctx->co->src->is_dynamic ? OP_DELETE_NAME : OP_DELETE_GLOBAL;
|
||||
Ctx__emit_(ctx, op, self->name, self->line);
|
||||
Ctx__emit_(ctx, op, Ctx__add_name(ctx, self->name), self->line);
|
||||
break;
|
||||
}
|
||||
default: c11__unreachable();
|
||||
@ -140,7 +141,7 @@ bool NameExpr__emit_del(Expr* self_, Ctx* ctx) {
|
||||
bool NameExpr__emit_store(Expr* self_, Ctx* ctx) {
|
||||
NameExpr* self = (NameExpr*)self_;
|
||||
if(ctx->is_compiling_class) {
|
||||
Ctx__emit_(ctx, OP_STORE_CLASS_ATTR, self->name, self->line);
|
||||
Ctx__emit_(ctx, OP_STORE_CLASS_ATTR, Ctx__add_name(ctx, self->name), self->line);
|
||||
return true;
|
||||
}
|
||||
Ctx__emit_store_name(ctx, self->scope, self->name, self->line);
|
||||
@ -710,7 +711,7 @@ static void BinaryExpr__dtor(Expr* self_) {
|
||||
vtdelete(self->rhs);
|
||||
}
|
||||
|
||||
static py_Name cmp_token2name(TokenIndex token) {
|
||||
static uint16_t cmp_token2name(TokenIndex token) {
|
||||
switch(token) {
|
||||
case TK_LT: return __lt__;
|
||||
case TK_LE: return __le__;
|
||||
@ -945,20 +946,20 @@ void AttribExpr__dtor(Expr* self_) {
|
||||
void AttribExpr__emit_(Expr* self_, Ctx* ctx) {
|
||||
AttribExpr* self = (AttribExpr*)self_;
|
||||
vtemit_(self->child, ctx);
|
||||
Ctx__emit_(ctx, OP_LOAD_ATTR, self->name, self->line);
|
||||
Ctx__emit_(ctx, OP_LOAD_ATTR, Ctx__add_name(ctx, self->name), self->line);
|
||||
}
|
||||
|
||||
bool AttribExpr__emit_del(Expr* self_, Ctx* ctx) {
|
||||
AttribExpr* self = (AttribExpr*)self_;
|
||||
vtemit_(self->child, ctx);
|
||||
Ctx__emit_(ctx, OP_DELETE_ATTR, self->name, self->line);
|
||||
Ctx__emit_(ctx, OP_DELETE_ATTR, Ctx__add_name(ctx, self->name), self->line);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AttribExpr__emit_store(Expr* self_, Ctx* ctx) {
|
||||
AttribExpr* self = (AttribExpr*)self_;
|
||||
vtemit_(self->child, ctx);
|
||||
Ctx__emit_(ctx, OP_STORE_ATTR, self->name, self->line);
|
||||
Ctx__emit_(ctx, OP_STORE_ATTR, Ctx__add_name(ctx, self->name), self->line);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -966,14 +967,14 @@ void AttribExpr__emit_inplace(Expr* self_, Ctx* ctx) {
|
||||
AttribExpr* self = (AttribExpr*)self_;
|
||||
vtemit_(self->child, ctx);
|
||||
Ctx__emit_(ctx, OP_DUP_TOP, BC_NOARG, self->line);
|
||||
Ctx__emit_(ctx, OP_LOAD_ATTR, self->name, self->line);
|
||||
Ctx__emit_(ctx, OP_LOAD_ATTR, Ctx__add_name(ctx, self->name), self->line);
|
||||
}
|
||||
|
||||
bool AttribExpr__emit_istore(Expr* self_, Ctx* ctx) {
|
||||
// [a, val] -> [val, a]
|
||||
AttribExpr* self = (AttribExpr*)self_;
|
||||
Ctx__emit_(ctx, OP_ROT_TWO, BC_NOARG, self->line);
|
||||
Ctx__emit_(ctx, OP_STORE_ATTR, self->name, self->line);
|
||||
Ctx__emit_(ctx, OP_STORE_ATTR, Ctx__add_name(ctx, self->name), self->line);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1031,7 +1032,7 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) {
|
||||
if(self->callable->vt->is_attrib) {
|
||||
AttribExpr* p = (AttribExpr*)self->callable;
|
||||
vtemit_(p->child, ctx);
|
||||
Ctx__emit_(ctx, OP_LOAD_METHOD, p->name, p->line);
|
||||
Ctx__emit_(ctx, OP_LOAD_METHOD, Ctx__add_name(ctx, p->name), p->line);
|
||||
} else {
|
||||
vtemit_(self->callable, ctx);
|
||||
Ctx__emit_(ctx, OP_LOAD_NULL, BC_NOARG, BC_KEEPLINE);
|
||||
@ -1046,7 +1047,7 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) {
|
||||
|
||||
c11__foreach(Expr*, &self->args, e) { vtemit_(*e, ctx); }
|
||||
c11__foreach(CallExprKwArg, &self->kwargs, e) {
|
||||
Ctx__emit_int(ctx, e->key, self->line);
|
||||
Ctx__emit_int(ctx, (uintptr_t)e->key, self->line);
|
||||
vtemit_(e->val, ctx);
|
||||
}
|
||||
int KWARGC = self->kwargs.length;
|
||||
@ -1166,10 +1167,10 @@ static int Ctx__emit_(Ctx* self, Opcode opcode, uint16_t arg, int line) {
|
||||
return Ctx__emit_virtual(self, opcode, arg, line, false);
|
||||
}
|
||||
|
||||
static void Ctx__revert_last_emit_(Ctx* self) {
|
||||
c11_vector__pop(&self->co->codes);
|
||||
c11_vector__pop(&self->co->codes_ex);
|
||||
}
|
||||
// static void Ctx__revert_last_emit_(Ctx* self) {
|
||||
// c11_vector__pop(&self->co->codes);
|
||||
// c11_vector__pop(&self->co->codes_ex);
|
||||
// }
|
||||
|
||||
static int Ctx__emit_int(Ctx* self, int64_t value, int line) {
|
||||
if(INT16_MIN <= value && value <= INT16_MAX) {
|
||||
@ -1199,6 +1200,10 @@ static int Ctx__add_varname(Ctx* self, py_Name name) {
|
||||
return CodeObject__add_varname(self->co, name);
|
||||
}
|
||||
|
||||
static int Ctx__add_name(Ctx* self, py_Name name) {
|
||||
return CodeObject__add_name(self->co, name);
|
||||
}
|
||||
|
||||
static int Ctx__add_const_string(Ctx* self, c11_sv key) {
|
||||
if(key.size > 100) {
|
||||
py_Ref tmp = c11_vector__emplace(&self->co->consts);
|
||||
@ -1206,7 +1211,7 @@ static int Ctx__add_const_string(Ctx* self, c11_sv key) {
|
||||
int index = self->co->consts.length - 1;
|
||||
return index;
|
||||
}
|
||||
uint16_t* val = c11_smallmap_s2n__try_get(&self->co_consts_string_dedup_map, key);
|
||||
uintptr_t* val = c11_smallmap_s2n__try_get(&self->co_consts_string_dedup_map, key);
|
||||
if(val) {
|
||||
return *val;
|
||||
} else {
|
||||
@ -1235,7 +1240,7 @@ static void Ctx__emit_store_name(Ctx* self, NameScope scope, py_Name name, int l
|
||||
case NAME_LOCAL: Ctx__emit_(self, OP_STORE_FAST, Ctx__add_varname(self, name), line); break;
|
||||
case NAME_GLOBAL: {
|
||||
Opcode op = self->co->src->is_dynamic ? OP_STORE_NAME : OP_STORE_GLOBAL;
|
||||
Ctx__emit_(self, op, name, line);
|
||||
Ctx__emit_(self, op, Ctx__add_name(self, name), line);
|
||||
} break;
|
||||
default: c11__unreachable();
|
||||
}
|
||||
@ -2409,7 +2414,7 @@ static Error* compile_class(Compiler* self, int decorators) {
|
||||
ctx()->is_compiling_class = false;
|
||||
|
||||
Ctx__s_emit_decorators(ctx(), decorators);
|
||||
Ctx__emit_(ctx(), OP_END_CLASS, name, BC_KEEPLINE);
|
||||
Ctx__emit_(ctx(), OP_END_CLASS, Ctx__add_name(ctx(), name), BC_KEEPLINE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2517,7 +2522,7 @@ __EAT_DOTS_END:
|
||||
Ctx__emit_(ctx(), OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
|
||||
consume(TK_ID);
|
||||
c11_sv name = Token__sv(prev());
|
||||
Ctx__emit_(ctx(), OP_LOAD_ATTR, py_namev(name), prev()->line);
|
||||
Ctx__emit_(ctx(), OP_LOAD_ATTR, Ctx__add_name(ctx(), py_namev(name)), prev()->line);
|
||||
if(match(TK_AS)) {
|
||||
consume(TK_ID);
|
||||
name = Token__sv(prev());
|
||||
@ -2783,7 +2788,7 @@ static Error* compile_stmt(Compiler* self) {
|
||||
NameExpr* ne = (NameExpr*)Ctx__s_top(ctx());
|
||||
int index = Ctx__add_const_string(ctx(), type_hint);
|
||||
Ctx__emit_(ctx(), OP_LOAD_CONST, index, BC_KEEPLINE);
|
||||
Ctx__emit_(ctx(), OP_ADD_CLASS_ANNOTATION, ne->name, BC_KEEPLINE);
|
||||
Ctx__emit_(ctx(), OP_ADD_CLASS_ANNOTATION, Ctx__add_name(ctx(), ne->name), BC_KEEPLINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,13 +211,13 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
PUSH(val);
|
||||
DISPATCH();
|
||||
}
|
||||
py_Name name = c11__getitem(uint16_t, &frame->co->varnames, byte.arg);
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->varnames, byte.arg);
|
||||
UnboundLocalError(name);
|
||||
goto __ERROR;
|
||||
}
|
||||
case OP_LOAD_NAME: {
|
||||
assert(frame->is_locals_special);
|
||||
py_Name name = byte.arg;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
// locals
|
||||
switch(frame->locals->type) {
|
||||
case tp_locals: {
|
||||
@ -261,7 +261,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
goto __ERROR;
|
||||
}
|
||||
case OP_LOAD_NONLOCAL: {
|
||||
py_Name name = byte.arg;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
py_Ref tmp = Frame__getclosure(frame, name);
|
||||
if(tmp != NULL) {
|
||||
PUSH(tmp);
|
||||
@ -283,7 +283,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
goto __ERROR;
|
||||
}
|
||||
case OP_LOAD_GLOBAL: {
|
||||
py_Name name = byte.arg;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
int res = Frame__getglobal(frame, name);
|
||||
if(res == 1) {
|
||||
PUSH(&self->last_retval);
|
||||
@ -308,7 +308,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
case OP_LOAD_CLASS_GLOBAL: {
|
||||
assert(self->curr_class);
|
||||
py_Name name = byte.arg;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
py_Ref tmp = py_getdict(self->curr_class, name);
|
||||
if(tmp) {
|
||||
PUSH(tmp);
|
||||
@ -368,7 +368,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
case OP_STORE_NAME: {
|
||||
assert(frame->is_locals_special);
|
||||
py_Name name = byte.arg;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
switch(frame->locals->type) {
|
||||
case tp_locals: {
|
||||
py_Frame* noproxy = frame->locals->_ptr;
|
||||
@ -435,7 +435,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
case OP_DELETE_NAME: {
|
||||
assert(frame->is_locals_special);
|
||||
py_Name name = byte.arg;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
switch(frame->locals->type) {
|
||||
case tp_locals: {
|
||||
py_Frame* noproxy = frame->locals->_ptr;
|
||||
@ -464,7 +464,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
}
|
||||
case OP_DELETE_GLOBAL: {
|
||||
py_Name name = byte.arg;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
int res = Frame__delglobal(frame, name);
|
||||
if(res == 1) DISPATCH();
|
||||
if(res == -1) goto __ERROR;
|
||||
@ -473,7 +473,8 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
|
||||
case OP_DELETE_ATTR: {
|
||||
if(!py_delattr(TOP(), byte.arg)) goto __ERROR;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
if(!py_delattr(TOP(), name)) goto __ERROR;
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
@ -999,7 +1000,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
///////////
|
||||
case OP_BEGIN_CLASS: {
|
||||
// [base]
|
||||
py_Name name = byte.arg;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
py_Type base;
|
||||
if(py_isnone(TOP())) {
|
||||
base = tp_object;
|
||||
@ -1027,7 +1028,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
case OP_END_CLASS: {
|
||||
// [cls or decorated]
|
||||
py_Name name = byte.arg;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
if(!Frame__setglobal(frame, name, TOP())) goto __ERROR;
|
||||
|
||||
if(py_istype(TOP(), tp_type)) {
|
||||
@ -1052,7 +1053,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
case OP_STORE_CLASS_ATTR: {
|
||||
assert(self->curr_class);
|
||||
py_Name name = byte.arg;
|
||||
py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg);
|
||||
// TOP() can be a function, classmethod or custom decorator
|
||||
py_Ref actual_func = TOP();
|
||||
if(actual_func->type == tp_classmethod) {
|
||||
|
@ -1,23 +1,25 @@
|
||||
#include "pocketpy/interpreter/name.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
|
||||
#define MAGIC_METHOD(x) py_Name x;
|
||||
#include "pocketpy/xmacros/magics.h"
|
||||
#undef MAGIC_METHOD
|
||||
|
||||
void InternedNames__ctor(InternedNames* self) {
|
||||
c11_smallmap_s2n__ctor(&self->interned);
|
||||
c11_vector__ctor(&self->r_interned, sizeof(RInternedEntry));
|
||||
|
||||
// initialize all magic names
|
||||
#define MAGIC_METHOD(x) \
|
||||
if(x != py_name(#x)) abort();
|
||||
#define MAGIC_METHOD(x) x = py_name(#x);
|
||||
#include "pocketpy/xmacros/magics.h"
|
||||
#undef MAGIC_METHOD
|
||||
}
|
||||
|
||||
void InternedNames__dtor(InternedNames* self) {
|
||||
for(int i = 0; i < self->r_interned.length; i++) {
|
||||
PK_FREE(c11__getitem(RInternedEntry, &self->r_interned, i).data);
|
||||
for(int i = 0; i < self->interned.length; i++) {
|
||||
c11_smallmap_s2n_KV* kv = c11__at(c11_smallmap_s2n_KV, &self->interned, i);
|
||||
PK_FREE((void*)kv->value);
|
||||
}
|
||||
c11_smallmap_s2n__dtor(&self->interned);
|
||||
c11_vector__dtor(&self->r_interned);
|
||||
}
|
||||
|
||||
py_Name py_name(const char* name) {
|
||||
@ -29,47 +31,37 @@ py_Name py_name(const char* name) {
|
||||
|
||||
py_Name py_namev(c11_sv name) {
|
||||
InternedNames* self = &pk_current_vm->names;
|
||||
uint16_t index = c11_smallmap_s2n__get(&self->interned, name, 0);
|
||||
py_Name index = c11_smallmap_s2n__get(&self->interned, name, 0);
|
||||
if(index != 0) return index;
|
||||
// generate new index
|
||||
if(self->interned.length > 65530) c11__abort("py_Name index overflow");
|
||||
// NOTE: we must allocate the string in the heap so iterators are not invalidated
|
||||
char* p = PK_MALLOC(name.size + 1);
|
||||
memcpy(p, name.data, name.size);
|
||||
p[name.size] = '\0';
|
||||
RInternedEntry* entry = c11_vector__emplace(&self->r_interned);
|
||||
entry->data = p;
|
||||
entry->size = name.size;
|
||||
memset(&entry->obj, 0, sizeof(py_TValue));
|
||||
index = self->r_interned.length; // 1-based
|
||||
InternedEntry* p = PK_MALLOC(sizeof(InternedEntry) + name.size + 1);
|
||||
p->size = name.size;
|
||||
memcpy(p->data, name.data, name.size);
|
||||
p->data[name.size] = '\0';
|
||||
memset(&p->obj, 0, sizeof(py_TValue));
|
||||
index = (py_Name)p;
|
||||
// save to _interned
|
||||
c11_smallmap_s2n__set(&self->interned, (c11_sv){p, name.size}, index);
|
||||
assert(self->interned.length == self->r_interned.length);
|
||||
c11_smallmap_s2n__set(&self->interned, (c11_sv){p->data, name.size}, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
const char* py_name2str(py_Name index) {
|
||||
InternedNames* self = &pk_current_vm->names;
|
||||
assert(index > 0 && index <= self->interned.length);
|
||||
return c11__getitem(RInternedEntry, &self->r_interned, index - 1).data;
|
||||
InternedEntry* p = (InternedEntry*)index;
|
||||
return p->data;
|
||||
}
|
||||
|
||||
c11_sv py_name2sv(py_Name index) {
|
||||
InternedNames* self = &pk_current_vm->names;
|
||||
assert(index > 0 && index <= self->interned.length);
|
||||
RInternedEntry entry = c11__getitem(RInternedEntry, &self->r_interned, index - 1);
|
||||
return (c11_sv){entry.data, entry.size};
|
||||
InternedEntry* p = (InternedEntry*)index;
|
||||
return (c11_sv){p->data, p->size};
|
||||
}
|
||||
|
||||
py_GlobalRef py_name2ref(py_Name index) {
|
||||
InternedNames* self = &pk_current_vm->names;
|
||||
assert(index > 0 && index <= self->interned.length);
|
||||
RInternedEntry* entry = c11__at(RInternedEntry, &self->r_interned, index - 1);
|
||||
if(entry->obj.type == tp_nil) {
|
||||
InternedEntry* p = (InternedEntry*)index;
|
||||
if(p->obj.type == tp_nil) {
|
||||
c11_sv sv;
|
||||
sv.data = entry->data;
|
||||
sv.size = entry->size;
|
||||
py_newstrv(&entry->obj, sv);
|
||||
sv.data = p->data;
|
||||
sv.size = p->size;
|
||||
py_newstrv(&p->obj, sv);
|
||||
}
|
||||
return &entry->obj;
|
||||
return &p->obj;
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ static bool
|
||||
if(decl->starred_kwarg != -1) py_newdict(&buffer[decl->starred_kwarg]);
|
||||
|
||||
for(int j = 0; j < kwargc; j++) {
|
||||
py_Name key = py_toint(&p1[2 * j]);
|
||||
py_Name key = (py_Name)py_toint(&p1[2 * j]);
|
||||
int index = c11_smallmap_n2i__get(&decl->kw_to_index, key, -1);
|
||||
// if key is an explicit key, set as local variable
|
||||
if(index >= 0) {
|
||||
@ -681,8 +681,9 @@ void ManagedHeap__mark(ManagedHeap* self) {
|
||||
pk__mark_value(&vm->reg[i]);
|
||||
}
|
||||
// mark interned names
|
||||
for(int i = 0; i < vm->names.r_interned.length; i++) {
|
||||
RInternedEntry* entry = c11__at(RInternedEntry, &vm->names.r_interned, i);
|
||||
for(int i = 0; i < vm->names.interned.length; i++) {
|
||||
c11_smallmap_s2n_KV* kv = c11__at(c11_smallmap_s2n_KV, &vm->names.interned, i);
|
||||
InternedEntry* entry = (InternedEntry*)kv->value;
|
||||
pk__mark_value(&entry->obj);
|
||||
}
|
||||
|
||||
|
@ -123,10 +123,12 @@ void CodeObject__ctor(CodeObject* self, SourceData_ src, c11_sv name) {
|
||||
c11_vector__ctor(&self->codes_ex, sizeof(BytecodeEx));
|
||||
|
||||
c11_vector__ctor(&self->consts, sizeof(py_TValue));
|
||||
c11_vector__ctor(&self->varnames, sizeof(uint16_t));
|
||||
c11_vector__ctor(&self->varnames, sizeof(py_Name));
|
||||
c11_vector__ctor(&self->names, sizeof(py_Name));
|
||||
self->nlocals = 0;
|
||||
|
||||
c11_smallmap_n2i__ctor(&self->varnames_inv);
|
||||
c11_smallmap_n2i__ctor(&self->names_inv);
|
||||
|
||||
c11_vector__ctor(&self->blocks, sizeof(CodeBlock));
|
||||
c11_vector__ctor(&self->func_decls, sizeof(FuncDecl_));
|
||||
@ -147,8 +149,10 @@ void CodeObject__dtor(CodeObject* self) {
|
||||
|
||||
c11_vector__dtor(&self->consts);
|
||||
c11_vector__dtor(&self->varnames);
|
||||
c11_vector__dtor(&self->names);
|
||||
|
||||
c11_smallmap_n2i__dtor(&self->varnames_inv);
|
||||
c11_smallmap_n2i__dtor(&self->names_inv);
|
||||
|
||||
c11_vector__dtor(&self->blocks);
|
||||
|
||||
@ -172,13 +176,22 @@ void Function__ctor(Function* self, FuncDecl_ decl, py_GlobalRef module, py_Ref
|
||||
int CodeObject__add_varname(CodeObject* self, py_Name name) {
|
||||
int index = c11_smallmap_n2i__get(&self->varnames_inv, name, -1);
|
||||
if(index >= 0) return index;
|
||||
c11_vector__push(uint16_t, &self->varnames, name);
|
||||
c11_vector__push(py_Name, &self->varnames, name);
|
||||
self->nlocals++;
|
||||
index = self->varnames.length - 1;
|
||||
c11_smallmap_n2i__set(&self->varnames_inv, name, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
int CodeObject__add_name(CodeObject* self, py_Name name) {
|
||||
int index = c11_smallmap_n2i__get(&self->names_inv, name, -1);
|
||||
if(index >= 0) return index;
|
||||
c11_vector__push(py_Name, &self->names, name);
|
||||
index = self->names.length - 1;
|
||||
c11_smallmap_n2i__set(&self->names_inv, name, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
void Function__dtor(Function* self) {
|
||||
// printf("%s() in %s freed!\n", self->decl->code.name->data,
|
||||
// self->decl->code.src->filename->data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user