Scripting: Add read-only struct members

This commit is contained in:
Vicki Pfau 2023-03-30 02:39:08 -07:00
parent 1306cfe15e
commit e80b533549
5 changed files with 73 additions and 2 deletions

View File

@ -212,20 +212,30 @@ CXX_GUARD_START
} \
},
#define mSCRIPT_DEFINE_STRUCT_MEMBER_NAMED(STRUCT, TYPE, EXPORTED_NAME, NAME) { \
#define _mSCRIPT_DEFINE_STRUCT_MEMBER(STRUCT, TYPE, EXPORTED_NAME, NAME, RO) { \
.type = mSCRIPT_CLASS_INIT_INSTANCE_MEMBER, \
.info = { \
.member = { \
.name = #EXPORTED_NAME, \
.type = mSCRIPT_TYPE_MS_ ## TYPE, \
.offset = offsetof(struct STRUCT, NAME) \
.offset = offsetof(struct STRUCT, NAME), \
.readonly = RO \
} \
} \
},
#define mSCRIPT_DEFINE_STRUCT_MEMBER_NAMED(STRUCT, TYPE, EXPORTED_NAME, NAME) \
_mSCRIPT_DEFINE_STRUCT_MEMBER(STRUCT, TYPE, EXPORTED_NAME, NAME, false)
#define mSCRIPT_DEFINE_STRUCT_CONST_MEMBER_NAMED(STRUCT, TYPE, EXPORTED_NAME, NAME) \
_mSCRIPT_DEFINE_STRUCT_MEMBER(STRUCT, TYPE, EXPORTED_NAME, NAME, true)
#define mSCRIPT_DEFINE_STRUCT_MEMBER(STRUCT, TYPE, NAME) \
mSCRIPT_DEFINE_STRUCT_MEMBER_NAMED(STRUCT, TYPE, NAME, NAME)
#define mSCRIPT_DEFINE_STRUCT_CONST_MEMBER(STRUCT, TYPE, NAME) \
mSCRIPT_DEFINE_STRUCT_CONST_MEMBER_NAMED(STRUCT, TYPE, NAME, NAME)
#define mSCRIPT_DEFINE_INHERIT(PARENT) { \
.type = mSCRIPT_CLASS_INIT_INHERIT, \
.info = { \

View File

@ -231,6 +231,7 @@ struct mScriptClassMember {
const char* docstring;
const struct mScriptType* type;
size_t offset;
bool readonly;
};
struct mScriptClassCastMember {

View File

@ -188,6 +188,9 @@ void explainClass(struct mScriptTypeClass* cls, int level) {
}
docstring = NULL;
}
if (details->info.member.readonly) {
fprintf(out, "%s readonly: true\n", indent);
}
fprintf(out, "%s type: %s\n", indent, details->info.member.type->name);
break;
case mSCRIPT_CLASS_INIT_END:

View File

@ -54,6 +54,11 @@ struct TestG {
const char* c;
};
struct TestH {
int32_t i;
int32_t j;
};
static int32_t testAi0(struct TestA* a) {
return a->i;
}
@ -198,6 +203,12 @@ mSCRIPT_DEFINE_STRUCT(TestG)
mSCRIPT_DEFINE_STRUCT_DEFAULT_SET(TestG, setC)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT(TestH)
mSCRIPT_DEFINE_STRUCT_MEMBER(TestH, S32, i)
mSCRIPT_DEFINE_STRUCT_CONST_MEMBER(TestH, S32, j)
mSCRIPT_DEFINE_END;
M_TEST_DEFINE(testALayout) {
struct mScriptTypeClass* cls = mSCRIPT_TYPE_MS_S(TestA)->details.cls;
assert_false(cls->init);
@ -1134,6 +1145,47 @@ M_TEST_DEFINE(testGSet) {
assert_false(cls->init);
}
M_TEST_DEFINE(testHSet) {
struct mScriptTypeClass* cls = mSCRIPT_TYPE_MS_S(TestH)->details.cls;
struct TestH s = {
.i = 1,
.j = 2,
};
struct mScriptValue sval = mSCRIPT_MAKE_S(TestH, &s);
struct mScriptValue val;
struct mScriptValue compare;
compare = mSCRIPT_MAKE_S32(1);
assert_true(mScriptObjectGet(&sval, "i", &val));
assert_true(compare.type->equal(&compare, &val));
compare = mSCRIPT_MAKE_S32(2);
assert_true(mScriptObjectGet(&sval, "j", &val));
assert_true(compare.type->equal(&compare, &val));
val = mSCRIPT_MAKE_S32(3);
assert_true(mScriptObjectSet(&sval, "i", &val));
assert_int_equal(s.i, 3);
val = mSCRIPT_MAKE_S32(4);
assert_false(mScriptObjectSet(&sval, "j", &val));
assert_int_equal(s.j, 2);
compare = mSCRIPT_MAKE_S32(3);
assert_true(mScriptObjectGet(&sval, "i", &val));
assert_true(compare.type->equal(&compare, &val));
compare = mSCRIPT_MAKE_S32(2);
assert_true(mScriptObjectGet(&sval, "j", &val));
assert_true(compare.type->equal(&compare, &val));
assert_true(cls->init);
mScriptClassDeinit(cls);
assert_false(cls->init);
}
M_TEST_SUITE_DEFINE(mScriptClasses,
cmocka_unit_test(testALayout),
cmocka_unit_test(testASignatures),
@ -1150,4 +1202,5 @@ M_TEST_SUITE_DEFINE(mScriptClasses,
cmocka_unit_test(testEGet),
cmocka_unit_test(testFDeinit),
cmocka_unit_test(testGSet),
cmocka_unit_test(testHSet),
)

View File

@ -1472,6 +1472,10 @@ bool mScriptObjectSet(struct mScriptValue* obj, const char* member, struct mScri
return true;
}
if (m->readonly) {
return false;
}
void* rawMember = (void *)((uintptr_t) obj->value.opaque + m->offset);
if (m->type != val->type) {
if (!mScriptCast(m->type, val, val)) {