This commit is contained in:
blueloveTH 2025-06-04 02:09:03 +08:00
parent 0ba44fc3cd
commit c5a70ec4aa
10 changed files with 124 additions and 68 deletions

View File

@ -0,0 +1,10 @@
#pragma once
#include "pocketpy/pocketpy.h"
void pk_names_initialize();
void pk_names_finalize();
#define MAGIC_METHOD(x) extern py_Name x;
#include "pocketpy/xmacros/magics.h"
#undef MAGIC_METHOD

View File

@ -60,6 +60,7 @@ int c11_sv__index2(c11_sv self, c11_sv sub, int start);
int c11_sv__count(c11_sv self, c11_sv sub);
bool c11_sv__startswith(c11_sv self, c11_sv prefix);
bool c11_sv__endswith(c11_sv self, c11_sv suffix);
uint64_t c11_sv__hash(c11_sv self);
c11_string* c11_sv__replace(c11_sv self, char old, char new_);
c11_string* c11_sv__replace2(c11_sv self, c11_sv old, c11_sv new_);

View File

@ -57,7 +57,7 @@
#endif
#if defined(__GNUC__) || defined(__clang__)
#define PK_DEPRECATED [[deprecated]]
#define PK_DEPRECATED __attribute__((deprecated))
#else
#define PK_DEPRECATED
#endif

View File

@ -1,21 +0,0 @@
#pragma once
#include "pocketpy/objects/base.h"
#include "pocketpy/common/smallmap.h"
typedef struct {
int size; // size of the data excluding the null-terminator
py_TValue obj; // cached `str` object (lazy initialized)
char data[]; // null-terminated data
} InternedEntry;
typedef struct {
c11_smallmap_v2n 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

View File

@ -51,7 +51,25 @@ OPCODE(BUILD_SET)
OPCODE(BUILD_SLICE)
OPCODE(BUILD_STRING)
/**************************/
OPCODE(BINARY_OP)
OPCODE(BINARY_ADD)
OPCODE(BINARY_SUB)
OPCODE(BINARY_MUL)
OPCODE(BINARY_TRUEDIV)
OPCODE(BINARY_FLOORDIV)
OPCODE(BINARY_MOD)
OPCODE(BINARY_POW)
OPCODE(BINARY_LSHIFT)
OPCODE(BINARY_RSHIFT)
OPCODE(BINARY_AND)
OPCODE(BINARY_OR)
OPCODE(BINARY_XOR)
OPCODE(BINARY_MATMUL)
OPCODE(COMPARE_LT)
OPCODE(COMPARE_LE)
OPCODE(COMPARE_EQ)
OPCODE(COMPARE_NE)
OPCODE(COMPARE_GT)
OPCODE(COMPARE_GE)
OPCODE(IS_OP)
OPCODE(CONTAINS_OP)
/**************************/

25
src/common/name.c Normal file
View File

@ -0,0 +1,25 @@
#include "pocketpy/common/name.h"
#include <stdatomic.h>
typedef struct InternedEntry InternedEntry;
typedef struct InternedEntry{
InternedEntry* prev;
InternedEntry* next;
py_i64 hash;
int size; // size of the data excluding the null-terminator
char data[]; // null-terminated data
} InternedEntry;
typedef struct {
InternedEntry* table[1 << 16];
atomic_bool lock;
} InternedNames;
void pk_names_initialize() {
}
void pk_names_finalize() {
}

View File

@ -181,6 +181,15 @@ bool c11_sv__endswith(c11_sv self, c11_sv suffix) {
return memcmp(self.data + self.size - suffix.size, suffix.data, suffix.size) == 0;
}
uint64_t c11_sv__hash(c11_sv self) {
uint64_t hash = 5381;
for(int i = 0; i < self.size; i++) {
// hash * 33 + c
hash = ((hash << 5) + hash) + (unsigned char)self.data[i];
}
return hash;
}
c11_vector /* T=c11_sv */ c11_sv__split(c11_sv self, char sep) {
c11_vector retval;
c11_vector__ctor(&retval, sizeof(c11_sv));

View File

@ -711,19 +711,19 @@ static void BinaryExpr__dtor(Expr* self_) {
vtdelete(self->rhs);
}
static py_Name cmp_token2name(TokenIndex token) {
static Opcode cmp_token2op(TokenIndex token) {
switch(token) {
case TK_LT: return __lt__;
case TK_LE: return __le__;
case TK_EQ: return __eq__;
case TK_NE: return __ne__;
case TK_GT: return __gt__;
case TK_GE: return __ge__;
case TK_LT: return OP_COMPARE_LT;
case TK_LE: return OP_COMPARE_LE;
case TK_EQ: return OP_COMPARE_EQ;
case TK_NE: return OP_COMPARE_NE;
case TK_GT: return OP_COMPARE_GT;
case TK_GE: return OP_COMPARE_GE;
default: return 0;
}
}
#define is_compare_expr(e) ((e)->vt->is_binary && cmp_token2name(((BinaryExpr*)(e))->op))
#define is_compare_expr(e) ((e)->vt->is_binary && cmp_token2op(((BinaryExpr*)(e))->op))
static void _emit_compare(BinaryExpr* self, Ctx* ctx, c11_vector* jmps) {
if(is_compare_expr(self->lhs)) {
@ -734,7 +734,7 @@ static void _emit_compare(BinaryExpr* self, Ctx* ctx, c11_vector* jmps) {
vtemit_(self->rhs, ctx); // [a, b]
Ctx__emit_(ctx, OP_DUP_TOP, BC_NOARG, self->line); // [a, b, b]
Ctx__emit_(ctx, OP_ROT_THREE, BC_NOARG, self->line); // [b, a, b]
Ctx__emit_(ctx, OP_BINARY_OP, cmp_token2name(self->op), self->line);
Ctx__emit_(ctx, cmp_token2op(self->op), BC_NOARG, self->line);
// [b, RES]
int index = Ctx__emit_(ctx, OP_SHORTCUT_IF_FALSE_OR_POP, BC_NOARG, self->line);
c11_vector__push(int, jmps, index);
@ -744,7 +744,7 @@ static void BinaryExpr__emit_(Expr* self_, Ctx* ctx) {
BinaryExpr* self = (BinaryExpr*)self_;
c11_vector /*T=int*/ jmps;
c11_vector__ctor(&jmps, sizeof(int));
if(cmp_token2name(self->op) && is_compare_expr(self->lhs)) {
if(cmp_token2op(self->op) && is_compare_expr(self->lhs)) {
// (a < b) < c
BinaryExpr* e = (BinaryExpr*)self->lhs;
_emit_compare(e, ctx, &jmps);
@ -760,24 +760,24 @@ static void BinaryExpr__emit_(Expr* self_, Ctx* ctx) {
vtemit_(self->rhs, ctx);
Opcode opcode = OP_BINARY_OP;
Opcode opcode;
uint16_t arg = BC_NOARG;
switch(self->op) {
case TK_ADD: arg = __add__ | (__radd__ << 8); break;
case TK_SUB: arg = __sub__ | (__rsub__ << 8); break;
case TK_MUL: arg = __mul__ | (__rmul__ << 8); break;
case TK_DIV: arg = __truediv__ | (__rtruediv__ << 8); break;
case TK_FLOORDIV: arg = __floordiv__ | (__rfloordiv__ << 8); break;
case TK_MOD: arg = __mod__ | (__rmod__ << 8); break;
case TK_POW: arg = __pow__ | (__rpow__ << 8); break;
case TK_ADD: opcode = OP_BINARY_ADD; break;
case TK_SUB: opcode = OP_BINARY_SUB; break;
case TK_MUL: opcode = OP_BINARY_MUL; break;
case TK_DIV: opcode = OP_BINARY_TRUEDIV; break;
case TK_FLOORDIV: opcode = OP_BINARY_FLOORDIV; break;
case TK_MOD: opcode = OP_BINARY_MOD; break;
case TK_POW: opcode = OP_BINARY_POW; break;
case TK_LT: arg = __lt__ | (__gt__ << 8); break;
case TK_LE: arg = __le__ | (__ge__ << 8); break;
case TK_EQ: arg = __eq__ | (__eq__ << 8); break;
case TK_NE: arg = __ne__ | (__ne__ << 8); break;
case TK_GT: arg = __gt__ | (__lt__ << 8); break;
case TK_GE: arg = __ge__ | (__le__ << 8); break;
case TK_LT: opcode = OP_COMPARE_LT; break;
case TK_LE: opcode = OP_COMPARE_LE; break;
case TK_EQ: opcode = OP_COMPARE_EQ; break;
case TK_NE: opcode = OP_COMPARE_NE; break;
case TK_GT: opcode = OP_COMPARE_GT; break;
case TK_GE: opcode = OP_COMPARE_GE; break;
case TK_IN:
opcode = OP_CONTAINS_OP;
@ -796,13 +796,13 @@ static void BinaryExpr__emit_(Expr* self_, Ctx* ctx) {
arg = 1;
break;
case TK_LSHIFT: arg = __lshift__; break;
case TK_RSHIFT: arg = __rshift__; break;
case TK_AND: arg = __and__; break;
case TK_OR: arg = __or__; break;
case TK_XOR: arg = __xor__; break;
case TK_DECORATOR: arg = __matmul__; break;
default: assert(false);
case TK_LSHIFT: opcode = OP_BINARY_LSHIFT; break;
case TK_RSHIFT: opcode = OP_BINARY_RSHIFT; break;
case TK_AND: opcode = OP_BINARY_AND; break;
case TK_OR: opcode = OP_BINARY_OR; break;
case TK_XOR: opcode = OP_BINARY_XOR; break;
case TK_DECORATOR: opcode = OP_BINARY_MATMUL; break;
default: c11__unreachable();
}
Ctx__emit_(ctx, opcode, arg, self->line);

View File

@ -601,14 +601,33 @@ FrameResult VM__run_top_frame(VM* self) {
DISPATCH();
}
/*****************************/
case OP_BINARY_OP: {
py_Name op = byte.arg & 0xFF;
py_Name rop = byte.arg >> 8;
if(!pk_stack_binaryop(self, op, rop)) goto __ERROR;
POP();
*TOP() = self->last_retval;
DISPATCH();
#define CASE_BINARY_OP(label, op, rop)\
case label: {\
if(!pk_stack_binaryop(self, op, rop)) goto __ERROR;\
POP();\
*TOP() = self->last_retval;\
DISPATCH();\
}
CASE_BINARY_OP(OP_BINARY_ADD, __add__, __radd__)
CASE_BINARY_OP(OP_BINARY_SUB, __sub__, __rsub__)
CASE_BINARY_OP(OP_BINARY_MUL, __mul__, __rmul__)
CASE_BINARY_OP(OP_BINARY_TRUEDIV, __truediv__, __rtruediv__)
CASE_BINARY_OP(OP_BINARY_FLOORDIV, __floordiv__, __rfloordiv__)
CASE_BINARY_OP(OP_BINARY_MOD, __mod__, __rmod__)
CASE_BINARY_OP(OP_BINARY_POW, __pow__, __rpow__)
CASE_BINARY_OP(OP_BINARY_LSHIFT, __lshift__, 0)
CASE_BINARY_OP(OP_BINARY_RSHIFT, __rshift__, 0)
CASE_BINARY_OP(OP_BINARY_AND, __and__, 0)
CASE_BINARY_OP(OP_BINARY_OR, __or__, 0)
CASE_BINARY_OP(OP_BINARY_XOR, __xor__, 0)
CASE_BINARY_OP(OP_BINARY_MATMUL, __matmul__, 0)
CASE_BINARY_OP(OP_COMPARE_LT, __lt__, __gt__)
CASE_BINARY_OP(OP_COMPARE_LE, __le__, __ge__)
CASE_BINARY_OP(OP_COMPARE_EQ, __eq__, __eq__)
CASE_BINARY_OP(OP_COMPARE_NE, __ne__, __ne__)
CASE_BINARY_OP(OP_COMPARE_GT, __gt__, __lt__)
CASE_BINARY_OP(OP_COMPARE_GE, __ge__, __le__)
#undef CASE_BINARY_OP
case OP_IS_OP: {
bool res = py_isidentical(SECOND(), TOP());
POP();

View File

@ -103,13 +103,8 @@ static bool str__new__(int argc, py_Ref argv) {
static bool str__hash__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
int size;
const char* data = py_tostrn(&argv[0], &size);
uint64_t res = 0;
for(int i = 0; i < size; i++) {
res = res * 31 + data[i];
}
py_newint(py_retval(), res);
uint64_t res = c11_sv__hash(py_tosv(argv));
py_newint(py_retval(), (py_i64)res);
return true;
}