diff --git a/include/mgba-util/macros.h b/include/mgba-util/macros.h index b2844c8c3..904c15274 100644 --- a/include/mgba-util/macros.h +++ b/include/mgba-util/macros.h @@ -9,6 +9,7 @@ #define _mCPP_CAT(A, B) A ## B #define _mIDENT(...) __VA_ARGS__ +#define _mVOID(...) #define _mCALL(FN, ...) _mIDENT(FN(__VA_ARGS__)) #define _mCAT(A, B) _mCPP_CAT(A, B) #define _mSTRINGIFY(X, ...) #X diff --git a/include/mgba/script/macros.h b/include/mgba/script/macros.h index 9ce97f067..4acf7591a 100644 --- a/include/mgba/script/macros.h +++ b/include/mgba/script/macros.h @@ -15,11 +15,11 @@ CXX_GUARD_START do { \ struct mScriptValue* _val = mScriptListGetPointer(STACK, mScriptListSize(STACK) - 1); \ bool deref = true; \ - if (!(mSCRIPT_TYPE_CMP(TYPE, _val->type))) { \ + if (!(mSCRIPT_TYPE_CMP(TYPE, _val))) { \ if (_val->type->base == mSCRIPT_TYPE_WRAPPER) { \ _val = mScriptValueUnwrap(_val); \ deref = false; \ - if (!(mSCRIPT_TYPE_CMP(TYPE, _val->type))) { \ + if (!(mSCRIPT_TYPE_CMP(TYPE, _val))) { \ return false; \ } \ } else { \ @@ -73,7 +73,8 @@ CXX_GUARD_START #define mSCRIPT_PREFIX_8(PREFIX, T0, T1, T2, T3, T4, T5, T6, T7) PREFIX ## T0, PREFIX ## T1, PREFIX ## T2, PREFIX ## T3, PREFIX ## T4, PREFIX ## T5, PREFIX ## T6, PREFIX ## T7 #define mSCRIPT_PREFIX_N(N) mSCRIPT_PREFIX_ ## N -#define _mSCRIPT_FIELD_NAME(V) (V)->name +#define _mSCRIPT_FIELD_NAME(V) (V)->type->name +#define _mSCRIPT_WRAPPED_FIELD_NAME(V) (V)->value.wrapped->type->name #define _mSCRIPT_CALL_VOID(FUNCTION, NPARAMS) FUNCTION(_mCAT(mSCRIPT_ARG_NAMES_, NPARAMS)) #define _mSCRIPT_CALL(RETURN, FUNCTION, NPARAMS) \ diff --git a/include/mgba/script/types.h b/include/mgba/script/types.h index d5a6d9947..1475f1a6e 100644 --- a/include/mgba/script/types.h +++ b/include/mgba/script/types.h @@ -108,31 +108,58 @@ CXX_GUARD_START #define mSCRIPT_TYPE_MS_CW(TYPE) (&mSTWrapperConst_ ## TYPE) #define mSCRIPT_TYPE_MS_DS(STRUCT) (&mSTStruct_doc_ ## STRUCT) -#define mSCRIPT_TYPE_CMP_GENERIC(TYPE0, TYPE1) (TYPE0 == TYPE1) -#define mSCRIPT_TYPE_CMP_U8(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U8, TYPE) -#define mSCRIPT_TYPE_CMP_S8(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_S8, TYPE) -#define mSCRIPT_TYPE_CMP_U16(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U16, TYPE) -#define mSCRIPT_TYPE_CMP_S16(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_S16, TYPE) -#define mSCRIPT_TYPE_CMP_U32(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U32, TYPE) -#define mSCRIPT_TYPE_CMP_S32(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_S32, TYPE) -#define mSCRIPT_TYPE_CMP_F32(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_F32, TYPE) -#define mSCRIPT_TYPE_CMP_U64(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U64, TYPE) -#define mSCRIPT_TYPE_CMP_S64(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_S64, TYPE) -#define mSCRIPT_TYPE_CMP_F64(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_F64, TYPE) -#define mSCRIPT_TYPE_CMP_BOOL(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_BOOL, TYPE) -#define mSCRIPT_TYPE_CMP_STR(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_STR, TYPE) -#define mSCRIPT_TYPE_CMP_CHARP(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_CHARP, TYPE) -#define mSCRIPT_TYPE_CMP_LIST(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_LIST, TYPE) -#define mSCRIPT_TYPE_CMP_TABLE(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_TABLE, TYPE) -#define mSCRIPT_TYPE_CMP_PTR(TYPE) ((TYPE)->base >= mSCRIPT_TYPE_OPAQUE) -#define mSCRIPT_TYPE_CMP_WRAPPER(TYPE) (true) -#define mSCRIPT_TYPE_CMP_NUL(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_VOID, TYPE) +#define mSCRIPT_TYPE_CMP_GENERIC(TYPE, V) (TYPE == (V)->type) +#define mSCRIPT_TYPE_CMP_U8(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U8, V) +#define mSCRIPT_TYPE_CMP_S8(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_S8, V) +#define mSCRIPT_TYPE_CMP_U16(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U16, V) +#define mSCRIPT_TYPE_CMP_S16(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_S16, V) +#define mSCRIPT_TYPE_CMP_U32(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U32, V) +#define mSCRIPT_TYPE_CMP_S32(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_S32, V) +#define mSCRIPT_TYPE_CMP_F32(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_F32, V) +#define mSCRIPT_TYPE_CMP_U64(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U64, V) +#define mSCRIPT_TYPE_CMP_S64(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_S64, V) +#define mSCRIPT_TYPE_CMP_F64(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_F64, V) +#define mSCRIPT_TYPE_CMP_BOOL(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_BOOL, V) +#define mSCRIPT_TYPE_CMP_STR(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_STR, V) +#define mSCRIPT_TYPE_CMP_CHARP(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_CHARP, V) +#define mSCRIPT_TYPE_CMP_LIST(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_LIST, V) +#define mSCRIPT_TYPE_CMP_TABLE(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_TABLE, V) +#define mSCRIPT_TYPE_CMP_PTR(V) ((V)->type->base >= mSCRIPT_TYPE_OPAQUE) +#define mSCRIPT_TYPE_CMP_WRAPPER(V) (true) +#define mSCRIPT_TYPE_CMP_NUL(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_VOID, V) #define mSCRIPT_TYPE_CMP_S(STRUCT) mSCRIPT_TYPE_MS_S(STRUCT)->name == _mSCRIPT_FIELD_NAME #define mSCRIPT_TYPE_CMP_CS(STRUCT) mSCRIPT_TYPE_MS_CS(STRUCT)->name == _mSCRIPT_FIELD_NAME -#define mSCRIPT_TYPE_CMP_WSTR(TYPE) (mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_WSTR, TYPE)) -#define mSCRIPT_TYPE_CMP_WLIST(TYPE) (mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_WLIST, TYPE)) -#define mSCRIPT_TYPE_CMP_WTABLE(TYPE) (mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_WTABLE, TYPE)) -#define mSCRIPT_TYPE_CMP(TYPE0, TYPE1) mSCRIPT_TYPE_CMP_ ## TYPE0(TYPE1) +#define mSCRIPT_TYPE_CMP_W(STRUCT) (false) _mVOID +#define mSCRIPT_TYPE_CMP_WSTR(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_WSTR, V) +#define mSCRIPT_TYPE_CMP_WLIST(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_WLIST, V) +#define mSCRIPT_TYPE_CMP_WTABLE(V) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_WTABLE, V) +#define mSCRIPT_TYPE_CMP(TYPE, V) \ + ((mSCRIPT_TYPE_CMP_ ## TYPE(V)) || ((V) && (V)->type->base == mSCRIPT_TYPE_WRAPPER && mSCRIPT_WRAPPER_CMP_ ## TYPE(V))) + +#define mSCRIPT_WRAPPER_CMP_U8(V) (false) +#define mSCRIPT_WRAPPER_CMP_S8(V) (false) +#define mSCRIPT_WRAPPER_CMP_U16(V) (false) +#define mSCRIPT_WRAPPER_CMP_S16(V) (false) +#define mSCRIPT_WRAPPER_CMP_U32(V) (false) +#define mSCRIPT_WRAPPER_CMP_S32(V) (false) +#define mSCRIPT_WRAPPER_CMP_F32(V) (false) +#define mSCRIPT_WRAPPER_CMP_U64(V) (false) +#define mSCRIPT_WRAPPER_CMP_S64(V) (false) +#define mSCRIPT_WRAPPER_CMP_F64(V) (false) +#define mSCRIPT_WRAPPER_CMP_BOOL(V) (false) +#define mSCRIPT_WRAPPER_CMP_STR(V) (false) +#define mSCRIPT_WRAPPER_CMP_CHARP(V) (false) +#define mSCRIPT_WRAPPER_CMP_LIST(V) (false) +#define mSCRIPT_WRAPPER_CMP_TABLE(V) (false) +#define mSCRIPT_WRAPPER_CMP_PTR(V) (false) +#define mSCRIPT_WRAPPER_CMP_WRAPPER(V) (false) +#define mSCRIPT_WRAPPER_CMP_NUL(V) (false) +#define mSCRIPT_WRAPPER_CMP_S(STRUCT) (false) _mVOID +#define mSCRIPT_WRAPPER_CMP_CS(STRUCT) (false) _mVOID +#define mSCRIPT_WRAPPER_CMP_W(STRUCT) mSCRIPT_TYPE_MS_S(STRUCT)->name == _mSCRIPT_WRAPPED_FIELD_NAME +#define mSCRIPT_WRAPPER_CMP_WSTR(V) (false) +#define mSCRIPT_WRAPPER_CMP_WLIST(V) (false) +#define mSCRIPT_WRAPPER_CMP_WTABLE(V) (false) enum mScriptTypeBase { mSCRIPT_TYPE_VOID = 0, @@ -210,6 +237,7 @@ struct mScriptValue { struct mScriptString* string; struct Table* table; struct mScriptList* list; + struct mScriptValue* wrapped; } value; }; diff --git a/src/script/types.c b/src/script/types.c index 16ef78df4..4a1b9f433 100644 --- a/src/script/types.c +++ b/src/script/types.c @@ -937,12 +937,12 @@ void mScriptValueWrap(struct mScriptValue* value, struct mScriptValue* out) { } out->type = mSCRIPT_TYPE_MS_WRAPPER; - out->value.opaque = value; + out->value.wrapped = value; } struct mScriptValue* mScriptValueUnwrap(struct mScriptValue* value) { if (value->type->base == mSCRIPT_TYPE_WRAPPER) { - return value->value.opaque; + return value->value.wrapped; } return NULL; } @@ -1792,7 +1792,11 @@ bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, struct mScriptList struct mScriptValue* unwrapped = NULL; if (mScriptListGetPointer(frame, i)->type->base == mSCRIPT_TYPE_WRAPPER) { unwrapped = mScriptValueUnwrap(mScriptListGetPointer(frame, i)); - if (types->entries[i] == unwrapped->type) { + if (types->entries[i]->base == mSCRIPT_TYPE_WRAPPER) { + if (types->entries[i]->details.type == unwrapped->type) { + continue; + } + } else if (types->entries[i] == unwrapped->type) { continue; } }