mirror of https://github.com/mgba-emu/mgba.git
Scripting: Adapt Table type to use HashTableCustom
This commit is contained in:
parent
9d6f424623
commit
34752e95d5
|
@ -195,7 +195,7 @@ struct mScriptType {
|
||||||
const char* name;
|
const char* name;
|
||||||
void (*alloc)(const struct mScriptType*, struct mScriptValue*);
|
void (*alloc)(const struct mScriptType*, struct mScriptValue*);
|
||||||
void (*free)(const struct mScriptType*, struct mScriptValue*);
|
void (*free)(const struct mScriptType*, struct mScriptValue*);
|
||||||
uint32_t (*hash)(const struct mScriptType*, struct mScriptValue*);
|
uint32_t (*hash)(const struct mScriptType*, const struct mScriptValue*);
|
||||||
union {
|
union {
|
||||||
struct mScriptTypeTuple tuple;
|
struct mScriptTypeTuple tuple;
|
||||||
struct mScriptTypeFunction function;
|
struct mScriptTypeFunction function;
|
||||||
|
|
|
@ -11,7 +11,12 @@ static void _allocTable(const struct mScriptType*, struct mScriptValue*);
|
||||||
static void _freeTable(const struct mScriptType*, struct mScriptValue*);
|
static void _freeTable(const struct mScriptType*, struct mScriptValue*);
|
||||||
static void _deinitTableValue(void*);
|
static void _deinitTableValue(void*);
|
||||||
|
|
||||||
static uint32_t _hashScalar(const struct mScriptType*, struct mScriptValue*);
|
static uint32_t _hashScalar(const struct mScriptType*, const struct mScriptValue*);
|
||||||
|
|
||||||
|
static uint32_t _valHash(const void* val, size_t len, uint32_t seed);
|
||||||
|
static bool _valEqual(const void* a, const void* b);
|
||||||
|
static void* _valRef(void*);
|
||||||
|
static void _valDeref(void*);
|
||||||
|
|
||||||
const struct mScriptType mSTVoid = {
|
const struct mScriptType mSTVoid = {
|
||||||
.base = mSCRIPT_TYPE_VOID,
|
.base = mSCRIPT_TYPE_VOID,
|
||||||
|
@ -63,12 +68,19 @@ DEFINE_VECTOR(mScriptList, struct mScriptValue)
|
||||||
void _allocTable(const struct mScriptType* type, struct mScriptValue* val) {
|
void _allocTable(const struct mScriptType* type, struct mScriptValue* val) {
|
||||||
UNUSED(type);
|
UNUSED(type);
|
||||||
val->value.opaque = malloc(sizeof(struct Table));
|
val->value.opaque = malloc(sizeof(struct Table));
|
||||||
TableInit(val->value.opaque, 0, _deinitTableValue);
|
struct TableFunctions funcs = {
|
||||||
|
.deinitializer = _deinitTableValue,
|
||||||
|
.hash = _valHash,
|
||||||
|
.equal = _valEqual,
|
||||||
|
.ref = _valRef,
|
||||||
|
.deref = _valDeref
|
||||||
|
};
|
||||||
|
HashTableInitCustom(val->value.opaque, 0, &funcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _freeTable(const struct mScriptType* type, struct mScriptValue* val) {
|
void _freeTable(const struct mScriptType* type, struct mScriptValue* val) {
|
||||||
UNUSED(type);
|
UNUSED(type);
|
||||||
TableDeinit(val->value.opaque);
|
HashTableDeinit(val->value.opaque);
|
||||||
free(val->value.opaque);
|
free(val->value.opaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +88,7 @@ void _deinitTableValue(void* val) {
|
||||||
mScriptValueDeref(val);
|
mScriptValueDeref(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t _hashScalar(const struct mScriptType* type, struct mScriptValue* val) {
|
uint32_t _hashScalar(const struct mScriptType* type, const struct mScriptValue* val) {
|
||||||
// From https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key
|
// From https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
switch (type->base) {
|
switch (type->base) {
|
||||||
|
@ -93,6 +105,43 @@ uint32_t _hashScalar(const struct mScriptType* type, struct mScriptValue* val) {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t _valHash(const void* val, size_t len, uint32_t seed) {
|
||||||
|
UNUSED(len);
|
||||||
|
const struct mScriptValue* value = val;
|
||||||
|
uint32_t hash = value->type->hash(value->type, value);
|
||||||
|
return hash ^ seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _valEqual(const void* a, const void* b) {
|
||||||
|
const struct mScriptValue* valueA = a;
|
||||||
|
const struct mScriptValue* valueB = b;
|
||||||
|
// TODO: Move equality into type
|
||||||
|
if (valueA->type != valueB->type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch (valueA->type->base) {
|
||||||
|
case mSCRIPT_TYPE_VOID:
|
||||||
|
return true;
|
||||||
|
case mSCRIPT_TYPE_SINT:
|
||||||
|
return valueA->value.s32 == valueB->value.s32;
|
||||||
|
case mSCRIPT_TYPE_UINT:
|
||||||
|
return valueA->value.u32 == valueB->value.u32;
|
||||||
|
case mSCRIPT_TYPE_FLOAT:
|
||||||
|
return valueA->value.f32 == valueB->value.f32;
|
||||||
|
default:
|
||||||
|
return valueA->value.opaque == valueB->value.opaque;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* _valRef(void* val) {
|
||||||
|
mScriptValueRef(val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _valDeref(void* val) {
|
||||||
|
mScriptValueDeref(val);
|
||||||
|
}
|
||||||
|
|
||||||
struct mScriptValue* mScriptValueAlloc(const struct mScriptType* type) {
|
struct mScriptValue* mScriptValueAlloc(const struct mScriptType* type) {
|
||||||
// TODO: Use an arena instead of just the generic heap
|
// TODO: Use an arena instead of just the generic heap
|
||||||
struct mScriptValue* val = malloc(sizeof(*val));
|
struct mScriptValue* val = malloc(sizeof(*val));
|
||||||
|
@ -121,6 +170,7 @@ void mScriptValueDeref(struct mScriptValue* val) {
|
||||||
return;
|
return;
|
||||||
} else if (val->refs < 0) {
|
} else if (val->refs < 0) {
|
||||||
val->refs = mSCRIPT_VALUE_UNREF;
|
val->refs = mSCRIPT_VALUE_UNREF;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (val->type->free) {
|
if (val->type->free) {
|
||||||
val->type->free(val->type, val);
|
val->type->free(val->type, val);
|
||||||
|
@ -136,9 +186,8 @@ bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, st
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
struct Table* t = table->value.opaque;
|
struct Table* t = table->value.opaque;
|
||||||
uint32_t hash = key->type->hash(key->type, key);
|
|
||||||
mScriptValueRef(value);
|
mScriptValueRef(value);
|
||||||
TableInsert(t, hash, value);
|
HashTableInsertCustom(t, key, value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,8 +199,7 @@ bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
struct Table* t = table->value.opaque;
|
struct Table* t = table->value.opaque;
|
||||||
uint32_t hash = key->type->hash(key->type, key);
|
HashTableRemoveCustom(t, key);
|
||||||
TableRemove(t, hash);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +211,7 @@ struct mScriptValue* mScriptTableLookup(struct mScriptValue* table, struct mScri
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
struct Table* t = table->value.opaque;
|
struct Table* t = table->value.opaque;
|
||||||
uint32_t hash = key->type->hash(key->type, key);
|
return HashTableLookupCustom(t, key);
|
||||||
return TableLookup(t, hash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mScriptFrameInit(struct mScriptFrame* frame) {
|
void mScriptFrameInit(struct mScriptFrame* frame) {
|
||||||
|
|
Loading…
Reference in New Issue