Compare commits

..

No commits in common. "40d922e896523f6caef5ba5f21a822dcf18c5a10" and "ea81d3539dce0a9a9174ec6bb7d7588687c8b6b1" have entirely different histories.

13 changed files with 74 additions and 189 deletions

View File

@ -12,9 +12,9 @@
#define PK_HEX_TABLE "0123456789abcdef"
#ifdef _MSC_VER
#define c11__unreachable() __assume(0)
#define c11__unreachedable() __assume(0)
#else
#define c11__unreachable() __builtin_unreachable()
#define c11__unreachedable() __builtin_unreachable()
#endif
#define c11__abort(...) \

View File

@ -1,45 +0,0 @@
import numba
from typing import List
@numba.jit(nopython=True)
def sieve_of_eratosthenes(n: int) -> List[int]:
assert n >= 2
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False # 0 和 1 不是素数
for start in range(2, int(n**0.5) + 1):
if is_prime[start]:
for multiple in range(start*start, n + 1, start):
is_prime[multiple] = False
primes = [num for num, prime in enumerate(is_prime) if prime]
return primes
all_primes = sieve_of_eratosthenes(2**30)
print(len(all_primes), all_primes[:10], all_primes[-10:])
index = 3
caps = [all_primes[index]]
while True:
for i in range(index+1, len(all_primes)):
last_cap = caps[-1]
if last_cap < 1000:
min_cap = last_cap * 2
else:
min_cap = last_cap * 1.5
if all_primes[i] >= min_cap:
caps.append(all_primes[i])
index = i
break
else:
break
print('-'*20)
print(caps)
print('switch(cap) {')
for i in range(len(caps)-1):
print(f' case {caps[i]}:', f'return {caps[i+1]};')
print(' default: c11__unreachable();')
print('}')

View File

@ -128,7 +128,7 @@ bool NameExpr__emit_del(Expr* self_, Ctx* ctx) {
break;
case NAME_GLOBAL: Ctx__emit_(ctx, OP_DELETE_GLOBAL, self->name, self->line); break;
case NAME_GLOBAL_UNKNOWN: Ctx__emit_(ctx, OP_DELETE_NAME, self->name, self->line); break;
default: c11__unreachable();
default: c11__unreachedable();
}
return true;
}
@ -327,7 +327,7 @@ void LiteralExpr__emit_(Expr* self_, Ctx* ctx) {
Ctx__emit_(ctx, OP_LOAD_CONST, index, self->line);
break;
}
default: c11__unreachable();
default: c11__unreachedable();
}
}
@ -355,7 +355,7 @@ void Literal0Expr__emit_(Expr* self_, Ctx* ctx) {
case TK_TRUE: opcode = OP_LOAD_TRUE; break;
case TK_FALSE: opcode = OP_LOAD_FALSE; break;
case TK_DOTDOTDOT: opcode = OP_LOAD_ELLIPSIS; break;
default: c11__unreachable();
default: c11__unreachedable();
}
Ctx__emit_(ctx, opcode, BC_NOARG, self->line);
}
@ -1245,7 +1245,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: Ctx__emit_(self, OP_STORE_GLOBAL, name, line); break;
case NAME_GLOBAL_UNKNOWN: Ctx__emit_(self, OP_STORE_NAME, name, line); break;
default: c11__unreachable();
default: c11__unreachedable();
}
}
@ -2182,7 +2182,7 @@ static Error* read_literal(Compiler* self, py_Ref out) {
} else if(value->index == TokenValue_F64) {
py_newfloat(out, negated ? -value->_f64 : value->_f64);
} else {
c11__unreachable();
c11__unreachedable();
}
return NULL;
}

View File

@ -60,7 +60,7 @@ static bool stack_format_object(VM* self, c11_sv spec);
case RES_RETURN: PUSH(&self->last_retval); break; \
case RES_CALL: frame = self->top_frame; goto __NEXT_FRAME; \
case RES_ERROR: goto __ERROR; \
default: c11__unreachable(); \
default: c11__unreachedable(); \
} \
} while(0)
@ -1101,10 +1101,10 @@ FrameResult VM__run_top_frame(VM* self) {
if(!ok) goto __ERROR;
DISPATCH();
}
default: c11__unreachable();
default: c11__unreachedable();
}
c11__unreachable();
c11__unreachedable();
__ERROR:
py_BaseException__stpush(&self->curr_exception,
@ -1340,7 +1340,7 @@ static bool stack_format_object(VM* self, c11_sv spec) {
c11_sbuf__write_pad(&buf, pad_right, pad_c);
break;
}
default: c11__unreachable();
default: c11__unreachedable();
}
} else {
c11_sbuf__write_sv(&buf, c11_string__sv(body));

View File

@ -502,10 +502,10 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
self->stack.sp = p0; // reset the stack
return RES_RETURN;
}
default: c11__unreachable();
default: c11__unreachedable();
};
c11__unreachable();
c11__unreachedable();
/*****************_py_call*****************/
}

View File

@ -61,7 +61,7 @@ static bool disassemble(CodeObject* co) {
case OP_LOAD_CONST: {
py_Ref value = c11__at(py_TValue, &co->consts, byte.arg);
if(py_repr(value)) {
pk_sprintf(&ss, " (%v)", py_tosv(py_retval()));
pk_sprintf(&ss, " (%s)", py_tosv(py_retval()));
} else {
return false;
}

View File

@ -298,32 +298,21 @@ DEF_VECTOR_OPS(3)
sum += a.data[i] * b.data[i]; \
py_newint(py_retval(), sum); \
return true; \
} \
static bool vec##D##i##__hash__(int argc, py_Ref argv) { \
PY_CHECK_ARGC(1); \
const uint32_t C = 2654435761; \
c11_vec##D##i v = py_tovec##D##i(argv); \
uint64_t hash = 0; \
for(int i = 0; i < D; i++) \
hash = hash * 31 + (uint32_t)v.data[i] * C; \
py_newint(py_retval(), (py_i64)hash); \
return true; \
}
DEF_VECTOR_INT_OPS(2)
DEF_VECTOR_INT_OPS(3)
static bool vec2i__hash__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
c11_vec2i v = py_tovec2i(argv);
uint64_t x_part = (uint32_t)v.x & 0xFFFFFFFF;
uint64_t y_part = (uint32_t)v.y & 0xFFFFFFFF;
uint64_t hash = (x_part << 32) | y_part;
py_newint(py_retval(), (py_i64)hash);
return true;
}
static bool vec3i__hash__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
c11_vec3i v = py_tovec3i(argv);
uint64_t x_part = (uint32_t)v.x & 0xFFFFFF;
uint64_t y_part = (uint32_t)v.y & 0xFFFFFF;
uint64_t z_part = (uint32_t)v.z & 0xFFFF;
uint64_t hash = (x_part << 40) | (y_part << 16) | z_part;
py_newint(py_retval(), (py_i64)hash);
return true;
}
static bool vec2__repr__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
char buf[64];

View File

@ -64,7 +64,7 @@ bool pk_exec(CodeObject* co, py_Ref module) {
FrameResult res = VM__run_top_frame(vm);
if(res == RES_ERROR) return false;
if(res == RES_RETURN) return true;
c11__unreachable();
c11__unreachedable();
}
bool py_exec(const char* source, const char* filename, enum py_CompileMode mode, py_Ref module) {

View File

@ -210,7 +210,7 @@ bool pk_loadmethod(py_StackRef self, py_Name name) {
self[0] = *py_getslot(cls_var, 0);
self[1] = pk__type_info(type)->self;
break;
default: c11__unreachable();
default: c11__unreachedable();
}
return true;
}

View File

@ -7,54 +7,8 @@
#define PK_DICT_MAX_COLLISION 4
static uint32_t Dict__next_cap(uint32_t cap) {
switch(cap) {
case 7: return 17;
case 17: return 37;
case 37: return 79;
case 79: return 163;
case 163: return 331;
case 331: return 673;
case 673: return 1361;
case 1361: return 2053;
case 2053: return 3083;
case 3083: return 4637;
case 4637: return 6959;
case 6959: return 10453;
case 10453: return 15683;
case 15683: return 23531;
case 23531: return 35311;
case 35311: return 52967;
case 52967: return 79451;
case 79451: return 119179;
case 119179: return 178781;
case 178781: return 268189;
case 268189: return 402299;
case 402299: return 603457;
case 603457: return 905189;
case 905189: return 1357787;
case 1357787: return 2036687;
case 2036687: return 3055043;
case 3055043: return 4582577;
case 4582577: return 6873871;
case 6873871: return 10310819;
case 10310819: return 15466229;
case 15466229: return 23199347;
case 23199347: return 34799021;
case 34799021: return 52198537;
case 52198537: return 78297827;
case 78297827: return 117446801;
case 117446801: return 176170229;
case 176170229: return 264255353;
case 264255353: return 396383041;
case 396383041: return 594574583;
case 594574583: return 891861923;
default: c11__unreachable();
}
}
typedef struct {
uint64_t hash;
py_i64 hash;
py_TValue key;
py_TValue val;
} DictEntry;
@ -65,7 +19,7 @@ typedef struct {
typedef struct {
int length;
uint32_t capacity;
int capacity;
DictIndex* indices;
c11_vector /*T=DictEntry*/ entries;
} Dict;
@ -75,13 +29,13 @@ typedef struct {
DictEntry* end;
} DictIterator;
static void Dict__ctor(Dict* self, uint32_t capacity, int entries_capacity) {
static void Dict__ctor(Dict* self, int capacity) {
self->length = 0;
self->capacity = capacity;
self->indices = malloc(self->capacity * sizeof(DictIndex));
memset(self->indices, -1, self->capacity * sizeof(DictIndex));
c11_vector__ctor(&self->entries, sizeof(DictEntry));
c11_vector__reserve(&self->entries, entries_capacity);
c11_vector__reserve(&self->entries, capacity);
}
static void Dict__dtor(Dict* self) {
@ -94,7 +48,7 @@ static void Dict__dtor(Dict* self) {
static bool Dict__try_get(Dict* self, py_TValue* key, DictEntry** out) {
py_i64 hash;
if(!py_hash(key, &hash)) return false;
int idx = (uint64_t)hash % self->capacity;
int idx = hash & (self->capacity - 1);
for(int i = 0; i < PK_DICT_MAX_COLLISION; i++) {
int idx2 = self->indices[idx]._[i];
if(idx2 == -1) continue;
@ -118,37 +72,38 @@ static void Dict__clear(Dict* self) {
static void Dict__rehash_2x(Dict* self) {
Dict old_dict = *self;
uint32_t new_capacity = self->capacity;
__RETRY:
// use next capacity
new_capacity = Dict__next_cap(new_capacity);
// create a new dict with new capacity
Dict__ctor(self, new_capacity, old_dict.entries.capacity);
// move entries from old dict to new dict
for(int i = 0; i < old_dict.entries.length; i++) {
DictEntry* entry = c11__at(DictEntry, &old_dict.entries, i);
if(py_isnil(&entry->key)) continue;
int idx = entry->hash % new_capacity;
bool success = false;
for(int i = 0; i < PK_DICT_MAX_COLLISION; i++) {
int idx2 = self->indices[idx]._[i];
if(idx2 == -1) {
// insert new entry (empty slot)
c11_vector__push(DictEntry, &self->entries, *entry);
self->indices[idx]._[i] = self->entries.length - 1;
self->length++;
success = true;
break;
int new_capacity = self->capacity * 2;
do {
Dict__ctor(self, new_capacity);
for(int i = 0; i < old_dict.entries.length; i++) {
DictEntry* entry = c11__at(DictEntry, &old_dict.entries, i);
if(py_isnil(&entry->key)) continue;
int idx = entry->hash & (new_capacity - 1);
bool success = false;
for(int i = 0; i < PK_DICT_MAX_COLLISION; i++) {
int idx2 = self->indices[idx]._[i];
if(idx2 == -1) {
// insert new entry (empty slot)
c11_vector__push(DictEntry, &self->entries, *entry);
self->indices[idx]._[i] = self->entries.length - 1;
self->length++;
success = true;
break;
}
}
if(!success) {
Dict__dtor(self);
new_capacity *= 2;
continue;
}
}
if(!success) {
Dict__dtor(self);
goto __RETRY;
}
}
// done
Dict__dtor(&old_dict);
// resize complete
Dict__dtor(&old_dict);
return;
} while(1);
}
static void Dict__compact_entries(Dict* self) {
@ -180,13 +135,13 @@ static void Dict__compact_entries(Dict* self) {
static bool Dict__set(Dict* self, py_TValue* key, py_TValue* val) {
py_i64 hash;
if(!py_hash(key, &hash)) return false;
int idx = (uint64_t)hash % self->capacity;
int idx = hash & (self->capacity - 1);
for(int i = 0; i < PK_DICT_MAX_COLLISION; i++) {
int idx2 = self->indices[idx]._[i];
if(idx2 == -1) {
// insert new entry
DictEntry* new_entry = c11_vector__emplace(&self->entries);
new_entry->hash = (uint64_t)hash;
new_entry->hash = hash;
new_entry->key = *key;
new_entry->val = *val;
self->indices[idx]._[i] = self->entries.length - 1;
@ -204,11 +159,7 @@ static bool Dict__set(Dict* self, py_TValue* key, py_TValue* val) {
}
// no empty slot found
if(self->capacity >= self->entries.length * 10) {
// raise error if we reach the minimum load factor (10%)
return RuntimeError("dict has too much collision: %d/%d/%d",
self->entries.length,
self->entries.capacity,
self->capacity);
return RuntimeError("dict has too much collision: %d/%d", self->entries.length, self->capacity);
}
Dict__rehash_2x(self);
return Dict__set(self, key, val);
@ -219,7 +170,7 @@ static bool Dict__set(Dict* self, py_TValue* key, py_TValue* val) {
static int Dict__pop(Dict* self, py_Ref key) {
py_i64 hash;
if(!py_hash(key, &hash)) return -1;
int idx = (uint64_t)hash % self->capacity;
int idx = hash & (self->capacity - 1);
for(int i = 0; i < PK_DICT_MAX_COLLISION; i++) {
int idx2 = self->indices[idx]._[i];
if(idx2 == -1) continue;
@ -257,13 +208,13 @@ static bool dict__new__(int argc, py_Ref argv) {
py_Type cls = py_totype(argv);
int slots = cls == tp_dict ? 0 : -1;
Dict* ud = py_newobject(py_retval(), cls, slots, sizeof(Dict));
Dict__ctor(ud, 7, 8);
Dict__ctor(ud, 8);
return true;
}
void py_newdict(py_Ref out) {
Dict* ud = py_newobject(out, tp_dict, 0, sizeof(Dict));
Dict__ctor(ud, 7, 8);
Dict__ctor(ud, 8);
}
static bool dict__init__(int argc, py_Ref argv) {
@ -584,7 +535,7 @@ int py_dict_delitem(py_Ref self, py_Ref key) {
return Dict__pop(ud, key);
}
int py_dict_getitem_by_str(py_Ref self, const char* key) {
int py_dict_getitem_by_str(py_Ref self, const char *key){
py_Ref tmp = py_pushtmp();
py_newstr(tmp, key);
int res = py_dict_getitem(self, tmp);
@ -592,7 +543,7 @@ int py_dict_getitem_by_str(py_Ref self, const char* key) {
return res;
}
bool py_dict_setitem_by_str(py_Ref self, const char* key, py_Ref val) {
bool py_dict_setitem_by_str(py_Ref self, const char *key, py_Ref val){
py_Ref tmp = py_pushtmp();
py_newstr(tmp, key);
bool res = py_dict_setitem(self, tmp, val);
@ -600,7 +551,7 @@ bool py_dict_setitem_by_str(py_Ref self, const char* key, py_Ref val) {
return res;
}
int py_dict_delitem_by_str(py_Ref self, const char* key) {
int py_dict_delitem_by_str(py_Ref self, const char *key){
py_Ref tmp = py_pushtmp();
py_newstr(tmp, key);
int res = py_dict_delitem(self, tmp);

View File

@ -244,7 +244,9 @@ static py_i64 c11_8bytes__hash(union c11_8bytes u) {
static bool int__hash__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
py_assign(py_retval(), argv);
py_i64 val = py_toint(&argv[0]);
union c11_8bytes u = {._i64 = val};
py_newint(py_retval(), c11_8bytes__hash(u));
return true;
}

View File

@ -138,13 +138,3 @@ for i in range(n):
# if i % 3 == 0:
# y = b.pop()
# delattr(a, y)
d = {}
for i in range(-1000, 1000):
d[i] = i
assert d[i] == i
e = {}
for i in range(-10000, 10000, 3):
e[i] = i
assert e[i] == i

View File

@ -408,17 +408,15 @@ assert x == 3.0 and y == 4.0
x, y, z = vec3(1.0, 2.0, 3.0)
assert x == 1.0 and y == 2.0 and z == 3.0
assert hash(vec2i(11, -1)) == 51539607551
assert hash(vec3i(11, -1, 0)) == 13194139467776
d = {vec2i(12, 12): 1035.313708305359, vec2i(12, 11): 2059.313708305359, vec2i(12, 13): 2059.313708305359, vec2i(11, 12): 2059.313708305359, vec2i(13, 12): 2059.313708305359, vec2i(13, 11): 3083.313708305359, vec2i(13, 13): 3083.313708305359, vec2i(14, 12): 3083.313708305359, vec2i(12, 14): 3083.313708305359, vec2i(11, 13): 3083.313708305359, vec2i(12, 10): 3083.313708305359, vec2i(11, 11): 3083.313708305359, vec2i(10, 12): 3083.313708305359, vec2i(13, 14): 4107.313708305359, vec2i(14, 13): 4107.313708305359, vec2i(14, 11): 4107.313708305359, vec2i(15, 12): 4107.313708305359, vec2i(12, 15): 4107.313708305359, vec2i(11, 14): 4107.313708305359, vec2i(13, 10): 4107.313708305359, vec2i(10, 13): 4107.313708305359, vec2i(11, 10): 4107.313708305359, vec2i(10, 11): 4107.313708305359, vec2i(12, 9): 4107.313708305359, vec2i(9, 12): 4107.313708305359, vec2i(14, 14): 5131.313708305359, vec2i(15, 13): 5131.313708305359, vec2i(13, 15): 5131.313708305359, vec2i(15, 11): 5131.313708305359, vec2i(16, 12): 5131.313708305359, vec2i(12, 16): 5131.313708305359, vec2i(11, 15): 5131.313708305359, vec2i(14, 10): 5131.313708305359, vec2i(10, 14): 5131.313708305359, vec2i(13, 9): 5131.313708305359, vec2i(9, 13): 5131.313708305359}
d[vec2i(11, 9)] = 1
e = {}
for i in range(-1000, 10000):
for i in range(10000):
e[vec2i(12, i)] = i
e[vec2i(11, i)] = i
e[vec2i(13, i)] = i
e[vec2i(i, 12)] = i
e[vec2i(i, 11)] = i
e[vec2i(i, 13)] = i
e[vec2i(i, 13)] = i