Scripting: Revamp pointer handling, struct casting

This commit is contained in:
Vicki Pfau 2022-05-10 20:41:33 -07:00
parent c296ea79ff
commit aa91ffabfd
2 changed files with 156 additions and 72 deletions

View File

@ -30,12 +30,15 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_C_STR struct mScriptString*
#define mSCRIPT_TYPE_C_CHARP const char*
#define mSCRIPT_TYPE_C_PTR void*
#define mSCRIPT_TYPE_C_CPTR const void*
#define mSCRIPT_TYPE_C_TABLE Table*
#define mSCRIPT_TYPE_C_WRAPPER struct mScriptValue*
#define mSCRIPT_TYPE_C_WEAKREF uint32_t
#define mSCRIPT_TYPE_C_S(STRUCT) struct STRUCT*
#define mSCRIPT_TYPE_C_CS(STRUCT) const struct STRUCT*
#define mSCRIPT_TYPE_C_S_METHOD(STRUCT, NAME) _mSTStructFunctionType_ ## STRUCT ## _ ## NAME
#define mSCRIPT_TYPE_C_PS(X) void
#define mSCRIPT_TYPE_C_PCS(X) void
#define mSCRIPT_TYPE_FIELD_S8 s32
#define mSCRIPT_TYPE_FIELD_U8 s32
@ -48,7 +51,7 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_FIELD_U64 u64
#define mSCRIPT_TYPE_FIELD_F64 f64
#define mSCRIPT_TYPE_FIELD_STR opaque
#define mSCRIPT_TYPE_FIELD_CHARP opaque
#define mSCRIPT_TYPE_FIELD_CHARP copaque
#define mSCRIPT_TYPE_FIELD_PTR opaque
#define mSCRIPT_TYPE_FIELD_TABLE opaque
#define mSCRIPT_TYPE_FIELD_WRAPPER opaque
@ -56,6 +59,8 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_FIELD_S(STRUCT) opaque
#define mSCRIPT_TYPE_FIELD_CS(STRUCT) copaque
#define mSCRIPT_TYPE_FIELD_S_METHOD(STRUCT, NAME) copaque
#define mSCRIPT_TYPE_FIELD_PS(STRUCT) opaque
#define mSCRIPT_TYPE_FIELD_PCS(STRUCT) copaque
#define mSCRIPT_TYPE_MS_S8 (&mSTSInt8)
#define mSCRIPT_TYPE_MS_U8 (&mSTUInt8)
@ -75,6 +80,8 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_MS_S(STRUCT) (&mSTStruct_ ## STRUCT)
#define mSCRIPT_TYPE_MS_CS(STRUCT) (&mSTStructConst_ ## STRUCT)
#define mSCRIPT_TYPE_MS_S_METHOD(STRUCT, NAME) (&_mSTStructBindingType_ ## STRUCT ## _ ## NAME)
#define mSCRIPT_TYPE_MS_PS(STRUCT) (&mSTStructPtr_ ## STRUCT)
#define mSCRIPT_TYPE_MS_PCS(STRUCT) (&mSTStructConstPtr_ ## STRUCT)
#define _mSCRIPT_FIELD_NAME(V) (V)->name
@ -167,18 +174,30 @@ CXX_GUARD_START
#define mSCRIPT_DECLARE_STRUCT(STRUCT) \
extern const struct mScriptType mSTStruct_ ## STRUCT; \
extern const struct mScriptType mSTStructConst_ ## STRUCT;
extern const struct mScriptType mSTStructConst_ ## STRUCT; \
extern const struct mScriptType mSTStructPtr_ ## STRUCT; \
extern const struct mScriptType mSTStructPtrConst_ ## STRUCT;
#define mSCRIPT_DEFINE_STRUCT(STRUCT) \
const struct mScriptType mSTStruct_ ## STRUCT; \
const struct mScriptType mSTStructConst_ ## STRUCT; \
const struct mScriptType mSTStructPtr_ ## STRUCT; \
const struct mScriptType mSTStructPtrConst_ ## STRUCT; \
static struct mScriptTypeClass _mSTStructDetails_ ## STRUCT; \
static bool _mSTStructCast_ ## STRUCT(const struct mScriptValue* input, const struct mScriptType* type, struct mScriptValue* output) { \
if (input->type == type || (input->type == &mSTStruct_ ## STRUCT && type == &mSTStructConst_ ## STRUCT)) { \
static bool _mSTStructPtrCast_ ## STRUCT(const struct mScriptValue* input, const struct mScriptType* type, struct mScriptValue* output) { \
if (input->type == type || (input->type->constType == type)) { \
output->type = type; \
output->value.opaque = input->value.opaque; \
return true; \
} \
if (input->type != &mSTStructPtr_ ## STRUCT && input->type != &mSTStructPtrConst_ ## STRUCT) { \
return false; \
} \
if (type == &mSTStructConst_ ## STRUCT || (!input->type->isConst && type == &mSTStruct_ ## STRUCT)) { \
output->type = type; \
output->value.opaque = *(void**) input->value.opaque; \
return true; \
} \
return false; \
} \
const struct mScriptType mSTStruct_ ## STRUCT = { \
@ -190,7 +209,7 @@ CXX_GUARD_START
.name = "struct::" #STRUCT, \
.alloc = NULL, \
.free = NULL, \
.cast = _mSTStructCast_ ## STRUCT, \
.cast = mScriptObjectCast, \
.constType = &mSTStructConst_ ## STRUCT, \
}; \
const struct mScriptType mSTStructConst_ ## STRUCT = { \
@ -203,7 +222,25 @@ CXX_GUARD_START
.name = "const struct::" #STRUCT, \
.alloc = NULL, \
.free = NULL, \
.cast = _mSTStructCast_ ## STRUCT, \
.cast = mScriptObjectCast, \
}; \
const struct mScriptType mSTStructPtr_ ## STRUCT = { \
.base = mSCRIPT_TYPE_OPAQUE, \
.size = sizeof(void*), \
.name = "ptr struct::" #STRUCT, \
.alloc = NULL, \
.free = NULL, \
.cast = _mSTStructPtrCast_ ## STRUCT, \
.constType = &mSTStructPtrConst_ ## STRUCT, \
}; \
const struct mScriptType mSTStructPtrConst_ ## STRUCT = { \
.base = mSCRIPT_TYPE_OPAQUE, \
.isConst = true, \
.size = sizeof(void*), \
.name = "ptr const struct::" #STRUCT, \
.alloc = NULL, \
.free = NULL, \
.cast = _mSTStructPtrCast_ ## STRUCT, \
}; \
static struct mScriptTypeClass _mSTStructDetails_ ## STRUCT = { \
.init = false, \
@ -580,7 +617,9 @@ void mScriptClassInit(struct mScriptTypeClass* cls);
void mScriptClassDeinit(struct mScriptTypeClass* cls);
bool mScriptObjectGet(struct mScriptValue* obj, const char* member, struct mScriptValue*);
bool mScriptObjectGetConst(const struct mScriptValue* obj, const char* member, struct mScriptValue*);
bool mScriptObjectSet(struct mScriptValue* obj, const char* member, struct mScriptValue*);
bool mScriptObjectCast(const struct mScriptValue* input, const struct mScriptType* type, struct mScriptValue* output) ;
bool mScriptPopS32(struct mScriptList* list, int32_t* out);
bool mScriptPopU32(struct mScriptList* list, uint32_t* out);

View File

@ -816,6 +816,86 @@ void mScriptClassDeinit(struct mScriptTypeClass* cls) {
cls->init = false;
}
static bool _accessRawMember(struct mScriptClassMember* member, void* raw, bool isConst, struct mScriptValue* val) {
raw = (void*) ((uintptr_t) raw + member->offset);
switch (member->type->base) {
case mSCRIPT_TYPE_SINT:
switch (member->type->size) {
case 1:
*val = mSCRIPT_MAKE_S32(*(int8_t *) raw);
break;
case 2:
*val = mSCRIPT_MAKE_S32(*(int16_t *) raw);
break;
case 4:
*val = mSCRIPT_MAKE_S32(*(int32_t *) raw);
break;
case 8:
*val = mSCRIPT_MAKE_S64(*(int64_t *) raw);
break;
default:
return false;
}
break;
case mSCRIPT_TYPE_UINT:
switch (member->type->size) {
case 1:
*val = mSCRIPT_MAKE_U32(*(uint8_t *) raw);
break;
case 2:
*val = mSCRIPT_MAKE_U32(*(uint16_t *) raw);
break;
case 4:
*val = mSCRIPT_MAKE_U32(*(uint32_t *) raw);
break;
case 8:
*val = mSCRIPT_MAKE_U64(*(uint64_t *) raw);
break;
default:
return false;
}
break;
case mSCRIPT_TYPE_FLOAT:
switch (member->type->size) {
case 4:
*val = mSCRIPT_MAKE_F32(*(mSCRIPT_TYPE_C_F32 *) raw);
break;
case 8:
*val = mSCRIPT_MAKE_F64(*(mSCRIPT_TYPE_C_F64 *) raw);
break;
default:
return false;
}
break;
case mSCRIPT_TYPE_FUNCTION:
val->refs = mSCRIPT_VALUE_UNREF;
val->flags = 0;
val->type = member->type;
member->type->alloc(val);
break;
case mSCRIPT_TYPE_OBJECT:
val->refs = mSCRIPT_VALUE_UNREF;
val->flags = 0;
val->value.opaque = raw;
if (isConst && !member->type->isConst) {
val->type = member->type->constType;
} else {
val->type = member->type;
}
break;
case mSCRIPT_TYPE_OPAQUE:
val->refs = mSCRIPT_VALUE_UNREF;
val->flags = 0;
val->value.opaque = raw;
val->type = member->type;
break;
default:
return false;
}
return true;
}
bool mScriptObjectGet(struct mScriptValue* obj, const char* member, struct mScriptValue* val) {
if (obj->type->base == mSCRIPT_TYPE_WRAPPER) {
obj = mScriptValueUnwrap(obj);
@ -836,74 +916,28 @@ bool mScriptObjectGet(struct mScriptValue* obj, const char* member, struct mScri
return false;
}
void* rawMember = (void *)((uintptr_t) obj->value.opaque + m->offset);
switch (m->type->base) {
case mSCRIPT_TYPE_SINT:
switch (m->type->size) {
case 1:
*val = mSCRIPT_MAKE_S32(*(int8_t *) rawMember);
break;
case 2:
*val = mSCRIPT_MAKE_S32(*(int16_t *) rawMember);
break;
case 4:
*val = mSCRIPT_MAKE_S32(*(int32_t *) rawMember);
break;
case 8:
*val = mSCRIPT_MAKE_S64(*(int64_t *) rawMember);
break;
default:
return false;
}
break;
case mSCRIPT_TYPE_UINT:
switch (m->type->size) {
case 1:
*val = mSCRIPT_MAKE_U32(*(uint8_t *) rawMember);
break;
case 2:
*val = mSCRIPT_MAKE_U32(*(uint16_t *) rawMember);
break;
case 4:
*val = mSCRIPT_MAKE_U32(*(uint32_t *) rawMember);
break;
case 8:
*val = mSCRIPT_MAKE_U64(*(uint64_t *) rawMember);
break;
default:
return false;
}
break;
case mSCRIPT_TYPE_FLOAT:
switch (m->type->size) {
case 4:
*val = mSCRIPT_MAKE_F32(*(mSCRIPT_TYPE_C_F32 *) rawMember);
break;
case 8:
*val = mSCRIPT_MAKE_F64(*(mSCRIPT_TYPE_C_F64 *) rawMember);
break;
default:
return false;
}
break;
case mSCRIPT_TYPE_FUNCTION:
val->refs = mSCRIPT_VALUE_UNREF;
val->type = m->type;
m->type->alloc(val);
break;
case mSCRIPT_TYPE_OBJECT:
val->refs = mSCRIPT_VALUE_UNREF;
val->value.opaque = rawMember;
if (obj->type->isConst && !m->type->isConst) {
val->type = m->type->constType;
} else {
val->type = m->type;
}
break;
default:
return _accessRawMember(m, obj->value.opaque, obj->type->isConst, val);
}
bool mScriptObjectGetConst(const struct mScriptValue* obj, const char* member, struct mScriptValue* val) {
if (obj->type->base == mSCRIPT_TYPE_WRAPPER) {
obj = mScriptValueUnwrapConst(obj);
}
if (obj->type->base != mSCRIPT_TYPE_OBJECT) {
return false;
}
return true;
const struct mScriptTypeClass* cls = obj->type->details.cls;
if (!cls) {
return false;
}
struct mScriptClassMember* m = HashTableLookup(&cls->instanceMembers, member);
if (!m) {
return false;
}
return _accessRawMember(m, obj->value.opaque, true, val);
}
bool mScriptObjectSet(struct mScriptValue* obj, const char* member, struct mScriptValue* val) {
@ -985,6 +1019,17 @@ bool mScriptObjectSet(struct mScriptValue* obj, const char* member, struct mScri
return true;
}
bool mScriptObjectCast(const struct mScriptValue* input, const struct mScriptType* type, struct mScriptValue* output) {
if (input->type == type || (input->type->constType == type)) {
output->type = type;
output->value.opaque = input->value.opaque;
output->refs = mSCRIPT_VALUE_UNREF;
output->flags = 0;
return true;
}
return false;
}
bool mScriptPopS32(struct mScriptList* list, int32_t* out) {
mSCRIPT_POP(list, S32, val);
*out = val;