Scripting: More API cleanup

This commit is contained in:
Vicki Pfau 2022-05-19 22:32:10 -07:00
parent 7e36a71953
commit 304d8d1a4d
7 changed files with 137 additions and 108 deletions

View File

@ -20,10 +20,10 @@ CXX_GUARD_START
mLOG_DECLARE_CATEGORY(SCRIPT); mLOG_DECLARE_CATEGORY(SCRIPT);
struct mCore; struct mCore;
struct mLogger;
struct mScriptTextBuffer; struct mScriptTextBuffer;
mSCRIPT_DECLARE_STRUCT(mCore); mSCRIPT_DECLARE_STRUCT(mCore);
mSCRIPT_DECLARE_STRUCT(mLogger); mSCRIPT_DECLARE_STRUCT(mLogger);
mSCRIPT_DECLARE_STRUCT(mScriptConsole);
mSCRIPT_DECLARE_STRUCT(mScriptTextBuffer); mSCRIPT_DECLARE_STRUCT(mScriptTextBuffer);
struct mScriptBridge; struct mScriptBridge;

View File

@ -51,11 +51,11 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_FIELD_S64 s64 #define mSCRIPT_TYPE_FIELD_S64 s64
#define mSCRIPT_TYPE_FIELD_U64 u64 #define mSCRIPT_TYPE_FIELD_U64 u64
#define mSCRIPT_TYPE_FIELD_F64 f64 #define mSCRIPT_TYPE_FIELD_F64 f64
#define mSCRIPT_TYPE_FIELD_STR opaque #define mSCRIPT_TYPE_FIELD_STR string
#define mSCRIPT_TYPE_FIELD_CHARP copaque #define mSCRIPT_TYPE_FIELD_CHARP copaque
#define mSCRIPT_TYPE_FIELD_PTR opaque #define mSCRIPT_TYPE_FIELD_PTR opaque
#define mSCRIPT_TYPE_FIELD_LIST opaque #define mSCRIPT_TYPE_FIELD_LIST list
#define mSCRIPT_TYPE_FIELD_TABLE opaque #define mSCRIPT_TYPE_FIELD_TABLE table
#define mSCRIPT_TYPE_FIELD_WRAPPER opaque #define mSCRIPT_TYPE_FIELD_WRAPPER opaque
#define mSCRIPT_TYPE_FIELD_WEAKREF u32 #define mSCRIPT_TYPE_FIELD_WEAKREF u32
#define mSCRIPT_TYPE_FIELD_S(STRUCT) opaque #define mSCRIPT_TYPE_FIELD_S(STRUCT) opaque
@ -172,6 +172,9 @@ struct mScriptValue {
double f64; double f64;
void* opaque; void* opaque;
const void* copaque; const void* copaque;
struct mScriptString* string;
struct Table* table;
struct mScriptList* list;
} value; } value;
}; };
@ -270,6 +273,8 @@ void mScriptValueWrap(struct mScriptValue* val, struct mScriptValue* out);
struct mScriptValue* mScriptValueUnwrap(struct mScriptValue* val); struct mScriptValue* mScriptValueUnwrap(struct mScriptValue* val);
const struct mScriptValue* mScriptValueUnwrapConst(const struct mScriptValue* val); const struct mScriptValue* mScriptValueUnwrapConst(const struct mScriptValue* val);
struct mScriptValue* mScriptStringCreateEmpty(size_t size);
struct mScriptValue* mScriptStringCreateFromBytes(const void* string, size_t size);
struct mScriptValue* mScriptStringCreateFromUTF8(const char* string); struct mScriptValue* mScriptStringCreateFromUTF8(const char* string);
struct mScriptValue* mScriptStringCreateFromASCII(const char* string); struct mScriptValue* mScriptStringCreateFromASCII(const char* string);
struct mScriptValue* mScriptValueCreateFromUInt(uint32_t value); struct mScriptValue* mScriptValueCreateFromUInt(uint32_t value);

View File

@ -161,7 +161,8 @@ struct mScriptCoreAdapter {
struct mScriptValue memory; struct mScriptValue memory;
}; };
struct mScriptUILibrary { struct mScriptConsole {
struct mLogger* logger;
mScriptContextBufferFactory textBufferFactory; mScriptContextBufferFactory textBufferFactory;
void* textBufferContext; void* textBufferContext;
}; };
@ -201,12 +202,12 @@ static uint32_t mScriptMemoryAdapterRead32(struct mScriptMemoryAdapter* adapter,
static struct mScriptValue* mScriptMemoryAdapterReadRange(struct mScriptMemoryAdapter* adapter, uint32_t address, uint32_t length) { static struct mScriptValue* mScriptMemoryAdapterReadRange(struct mScriptMemoryAdapter* adapter, uint32_t address, uint32_t length) {
CALCULATE_SEGMENT_INFO; CALCULATE_SEGMENT_INFO;
struct mScriptValue* value = mScriptValueAlloc(mSCRIPT_TYPE_MS_LIST); struct mScriptValue* value = mScriptStringCreateEmpty(length);
struct mScriptList* list = value->value.opaque; char* buffer = value->value.string->buffer;
uint32_t i; uint32_t i;
for (i = 0; i < length; ++i, ++address) { for (i = 0; i < length; ++i, ++address) {
CALCULATE_SEGMENT_ADDRESS; CALCULATE_SEGMENT_ADDRESS;
*mScriptListAppend(list) = mSCRIPT_MAKE_U32(adapter->core->rawRead8(adapter->core, segmentAddress, segment)); buffer[i] = adapter->core->rawRead8(adapter->core, segmentAddress, segment);
} }
return value; return value;
} }
@ -268,11 +269,11 @@ static struct mScriptValue* _mScriptCoreGetGameCode(const struct mCore* core) {
} }
static struct mScriptValue* _mScriptCoreReadRange(struct mCore* core, uint32_t address, uint32_t length) { static struct mScriptValue* _mScriptCoreReadRange(struct mCore* core, uint32_t address, uint32_t length) {
struct mScriptValue* value = mScriptValueAlloc(mSCRIPT_TYPE_MS_LIST); struct mScriptValue* value = mScriptStringCreateEmpty(length);
struct mScriptList* list = value->value.opaque; char* buffer = value->value.string->buffer;
uint32_t i; uint32_t i;
for (i = 0; i < length; ++i, ++address) { for (i = 0; i < length; ++i, ++address) {
*mScriptListAppend(list) = mSCRIPT_MAKE_U32(core->busRead8(core, address)); buffer[i] = core->busRead8(core, address);
} }
return value; return value;
} }
@ -497,36 +498,70 @@ void mScriptContextDetachCore(struct mScriptContext* context) {
mScriptContextRemoveGlobal(context, "emu"); mScriptContextRemoveGlobal(context, "emu");
} }
void mScriptLog(struct mLogger* logger, struct mScriptString* msg) { static struct mScriptTextBuffer* _mScriptConsoleCreateBuffer(struct mScriptConsole* lib, const char* name) {
mLogExplicit(logger, _mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg->buffer); struct mScriptTextBuffer* buffer = lib->textBufferFactory(lib->textBufferContext);
buffer->init(buffer, name);
return buffer;
} }
void mScriptWarn(struct mLogger* logger, struct mScriptString* msg) { static void mScriptConsoleLog(struct mScriptConsole* console, struct mScriptString* msg) {
mLogExplicit(logger, _mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg->buffer); if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg->buffer);
} else {
mLog(_mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg->buffer);
}
} }
void mScriptError(struct mLogger* logger, struct mScriptString* msg) { static void mScriptConsoleWarn(struct mScriptConsole* console, struct mScriptString* msg) {
mLogExplicit(logger, _mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg->buffer); if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg->buffer);
} else {
mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg->buffer);
}
} }
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mLogger, log, mScriptLog, 1, STR, msg); static void mScriptConsoleError(struct mScriptConsole* console, struct mScriptString* msg) {
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mLogger, warn, mScriptWarn, 1, STR, msg); if (console->logger) {
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mLogger, error, mScriptError, 1, STR, msg); mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg->buffer);
} else {
mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg->buffer);
}
}
mSCRIPT_DEFINE_STRUCT(mLogger) mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, log, mScriptConsoleLog, 1, STR, msg);
mSCRIPT_DEFINE_STRUCT_METHOD(mLogger, log) mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, warn, mScriptConsoleWarn, 1, STR, msg);
mSCRIPT_DEFINE_STRUCT_METHOD(mLogger, warn) mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, error, mScriptConsoleError, 1, STR, msg);
mSCRIPT_DEFINE_STRUCT_METHOD(mLogger, error) mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptConsole, S(mScriptTextBuffer), createBuffer, _mScriptConsoleCreateBuffer, 1, CHARP, name);
mSCRIPT_DEFINE_STRUCT(mScriptConsole)
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, log)
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, warn)
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, error)
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, createBuffer)
mSCRIPT_DEFINE_END; mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptConsole, createBuffer)
mSCRIPT_MAKE_CHARP(NULL)
mSCRIPT_DEFINE_DEFAULTS_END;
void mScriptContextAttachLogger(struct mScriptContext* context, struct mLogger* logger) { void mScriptContextAttachLogger(struct mScriptContext* context, struct mLogger* logger) {
struct mScriptValue* value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mLogger)); struct mScriptValue* value = mScriptContextEnsureGlobal(context, "console", mSCRIPT_TYPE_MS_S(mScriptConsole));
value->value.opaque = logger; struct mScriptConsole* console = value->value.opaque;
mScriptContextSetGlobal(context, "console", value); if (!console) {
console = calloc(1, sizeof(*console));
value->value.opaque = console;
value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER;
}
console->logger = logger;
} }
void mScriptContextDetachLogger(struct mScriptContext* context) { void mScriptContextDetachLogger(struct mScriptContext* context) {
mScriptContextRemoveGlobal(context, "console"); struct mScriptValue* value = mScriptContextGetGlobal(context, "console");
if (!value) {
return;
}
struct mScriptConsole* console = value->value.opaque;
console->logger = mLogGetContext();
} }
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, deinit, 0); mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, deinit, 0);
@ -556,31 +591,15 @@ mSCRIPT_DEFINE_STRUCT(mScriptTextBuffer)
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setName) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setName)
mSCRIPT_DEFINE_END; mSCRIPT_DEFINE_END;
struct mScriptTextBuffer* _mScriptUICreateBuffer(struct mScriptUILibrary* lib, const char* name) {
struct mScriptTextBuffer* buffer = lib->textBufferFactory(lib->textBufferContext);
buffer->init(buffer, name);
return buffer;
}
mSCRIPT_DECLARE_STRUCT(mScriptUILibrary);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptUILibrary, S(mScriptTextBuffer), createBuffer, _mScriptUICreateBuffer, 1, CHARP, name);
mSCRIPT_DEFINE_STRUCT(mScriptUILibrary)
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptUILibrary, createBuffer)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptUILibrary, createBuffer)
mSCRIPT_MAKE_CHARP(NULL)
mSCRIPT_DEFINE_DEFAULTS_END;
void mScriptContextSetTextBufferFactory(struct mScriptContext* context, mScriptContextBufferFactory factory, void* cbContext) { void mScriptContextSetTextBufferFactory(struct mScriptContext* context, mScriptContextBufferFactory factory, void* cbContext) {
struct mScriptValue* value = mScriptContextEnsureGlobal(context, "ui", mSCRIPT_TYPE_MS_S(mScriptUILibrary)); struct mScriptValue* value = mScriptContextEnsureGlobal(context, "console", mSCRIPT_TYPE_MS_S(mScriptConsole));
struct mScriptUILibrary* uiLib = value->value.opaque; struct mScriptConsole* console = value->value.opaque;
if (!uiLib) { if (!console) {
uiLib = calloc(1, sizeof(*uiLib)); console = calloc(1, sizeof(*console));
value->value.opaque = uiLib; console->logger = mLogGetContext();
value->value.opaque = console;
value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER; value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER;
} }
uiLib->textBufferFactory = factory; console->textBufferFactory = factory;
uiLib->textBufferContext = cbContext; console->textBufferContext = cbContext;
} }

View File

@ -313,17 +313,6 @@ M_TEST_DEFINE(logging) {
assert_string_equal(logger.error, "error"); assert_string_equal(logger.error, "error");
mScriptContextDetachLogger(&context); mScriptContextDetachLogger(&context);
LOAD_PROGRAM(
"assert(not console)\n"
);
assert_true(lua->run(lua));
LOAD_PROGRAM(
"a:log(\"l2\")\n"
);
assert_false(lua->run(lua));
mScriptTestLoggerDeinit(&logger); mScriptTestLoggerDeinit(&logger);
mScriptContextDeinit(&context); mScriptContextDeinit(&context);
} }

View File

@ -195,10 +195,10 @@ void mScriptContextTriggerCallback(struct mScriptContext* context, const char* c
return; return;
} }
size_t i; size_t i;
for (i = 0; i < mScriptListSize(list->value.opaque); ++i) { for (i = 0; i < mScriptListSize(list->value.list); ++i) {
struct mScriptFrame frame; struct mScriptFrame frame;
mScriptFrameInit(&frame); mScriptFrameInit(&frame);
struct mScriptValue* fn = mScriptListGetPointer(list->value.opaque, i); struct mScriptValue* fn = mScriptListGetPointer(list->value.list, i);
if (fn->type->base == mSCRIPT_TYPE_WRAPPER) { if (fn->type->base == mSCRIPT_TYPE_WRAPPER) {
fn = mScriptValueUnwrap(fn); fn = mScriptValueUnwrap(fn);
} }
@ -216,7 +216,7 @@ void mScriptContextAddCallback(struct mScriptContext* context, const char* callb
list = mScriptValueAlloc(mSCRIPT_TYPE_MS_LIST); list = mScriptValueAlloc(mSCRIPT_TYPE_MS_LIST);
HashTableInsert(&context->callbacks, callback, list); HashTableInsert(&context->callbacks, callback, list);
} }
mScriptValueWrap(fn, mScriptListAppend(list->value.opaque)); mScriptValueWrap(fn, mScriptListAppend(list->value.list));
} }
void mScriptContextExportConstants(struct mScriptContext* context, const char* nspace, struct mScriptKVPair* constants) { void mScriptContextExportConstants(struct mScriptContext* context, const char* nspace, struct mScriptKVPair* constants) {

View File

@ -216,6 +216,8 @@ struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext) {
return NULL; return NULL;
} }
size_t size;
const void* buffer;
struct mScriptValue* value = NULL; struct mScriptValue* value = NULL;
switch (lua_type(luaContext->lua, -1)) { switch (lua_type(luaContext->lua, -1)) {
case LUA_TNUMBER: case LUA_TNUMBER:
@ -234,7 +236,8 @@ struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext) {
value->value.s32 = lua_toboolean(luaContext->lua, -1); value->value.s32 = lua_toboolean(luaContext->lua, -1);
break; break;
case LUA_TSTRING: case LUA_TSTRING:
value = mScriptStringCreateFromUTF8(lua_tostring(luaContext->lua, -1)); buffer = lua_tolstring(luaContext->lua, -1, &size);
value = mScriptStringCreateFromBytes(buffer, size);
mScriptValueWrap(value, mScriptListAppend(&luaContext->d.context->refPool)); mScriptValueWrap(value, mScriptListAppend(&luaContext->d.context->refPool));
mScriptValueDeref(value); mScriptValueDeref(value);
break; break;
@ -311,7 +314,7 @@ bool _luaWrap(struct mScriptEngineContextLua* luaContext, struct mScriptValue* v
} }
break; break;
case mSCRIPT_TYPE_STRING: case mSCRIPT_TYPE_STRING:
lua_pushstring(luaContext->lua, ((struct mScriptString*) value->value.opaque)->buffer); lua_pushlstring(luaContext->lua, value->value.string->buffer, value->value.string->size);
mScriptValueDeref(value); mScriptValueDeref(value);
break; break;
case mSCRIPT_TYPE_LIST: case mSCRIPT_TYPE_LIST:
@ -753,7 +756,7 @@ int _luaGetList(lua_State* lua) {
luaL_traceback(lua, lua, "Invalid list", 1); luaL_traceback(lua, lua, "Invalid list", 1);
lua_error(lua); lua_error(lua);
} }
struct mScriptList* list = obj->value.opaque; struct mScriptList* list = obj->value.list;
// Lua indexes from 1 // Lua indexes from 1
if (index < 1) { if (index < 1) {
@ -786,7 +789,7 @@ static int _luaLenList(lua_State* lua) {
luaL_traceback(lua, lua, "Invalid list", 1); luaL_traceback(lua, lua, "Invalid list", 1);
lua_error(lua); lua_error(lua);
} }
struct mScriptList* list = obj->value.opaque; struct mScriptList* list = obj->value.list;
lua_pushinteger(lua, mScriptListSize(list)); lua_pushinteger(lua, mScriptListSize(list));
return 1; return 1;
} }

View File

@ -182,6 +182,7 @@ const struct mScriptType mSTCharPtr = {
.hash = _hashString, .hash = _hashString,
.equal = _charpEqual, .equal = _charpEqual,
.cast = _stringCast, .cast = _stringCast,
.isConst = true,
}; };
const struct mScriptType mSTList = { const struct mScriptType mSTList = {
@ -223,24 +224,24 @@ const struct mScriptType mSTWeakref = {
DEFINE_VECTOR(mScriptList, struct mScriptValue) DEFINE_VECTOR(mScriptList, struct mScriptValue)
void _allocList(struct mScriptValue* val) { void _allocList(struct mScriptValue* val) {
val->value.opaque = malloc(sizeof(struct mScriptList)); val->value.list = malloc(sizeof(struct mScriptList));
mScriptListInit(val->value.opaque, 0); mScriptListInit(val->value.list, 0);
} }
void _freeList(struct mScriptValue* val) { void _freeList(struct mScriptValue* val) {
size_t i; size_t i;
for (i = 0; i < mScriptListSize(val->value.opaque); ++i) { for (i = 0; i < mScriptListSize(val->value.list); ++i) {
struct mScriptValue* unwrapped = mScriptValueUnwrap(mScriptListGetPointer(val->value.opaque, i)); struct mScriptValue* unwrapped = mScriptValueUnwrap(mScriptListGetPointer(val->value.list, i));
if (unwrapped) { if (unwrapped) {
mScriptValueDeref(unwrapped); mScriptValueDeref(unwrapped);
} }
} }
mScriptListDeinit(val->value.opaque); mScriptListDeinit(val->value.list);
free(val->value.opaque); free(val->value.list);
} }
void _allocTable(struct mScriptValue* val) { void _allocTable(struct mScriptValue* val) {
val->value.opaque = malloc(sizeof(struct Table)); val->value.table = malloc(sizeof(struct Table));
struct TableFunctions funcs = { struct TableFunctions funcs = {
.deinitializer = _deinitTableValue, .deinitializer = _deinitTableValue,
.hash = _valHash, .hash = _valHash,
@ -248,12 +249,12 @@ void _allocTable(struct mScriptValue* val) {
.ref = _valRef, .ref = _valRef,
.deref = _valDeref .deref = _valDeref
}; };
HashTableInitCustom(val->value.opaque, 0, &funcs); HashTableInitCustom(val->value.table, 0, &funcs);
} }
void _freeTable(struct mScriptValue* val) { void _freeTable(struct mScriptValue* val) {
HashTableDeinit(val->value.opaque); HashTableDeinit(val->value.table);
free(val->value.opaque); free(val->value.table);
} }
void _deinitTableValue(void* val) { void _deinitTableValue(void* val) {
@ -264,11 +265,11 @@ static void _allocString(struct mScriptValue* val) {
struct mScriptString* string = calloc(1, sizeof(*string)); struct mScriptString* string = calloc(1, sizeof(*string));
string->size = 0; string->size = 0;
string->buffer = NULL; string->buffer = NULL;
val->value.opaque = string; val->value.string = string;
} }
static void _freeString(struct mScriptValue* val) { static void _freeString(struct mScriptValue* val) {
struct mScriptString* string = val->value.opaque; struct mScriptString* string = val->value.string;
if (string->size) { if (string->size) {
free(string->buffer); free(string->buffer);
} }
@ -287,7 +288,7 @@ static bool _stringCast(const struct mScriptValue* in, const struct mScriptType*
out->type = type; out->type = type;
out->refs = mSCRIPT_VALUE_UNREF; out->refs = mSCRIPT_VALUE_UNREF;
out->flags = 0; out->flags = 0;
out->value.opaque = ((struct mScriptString*) in->value.opaque)->buffer; out->value.opaque = in->value.string->buffer;
return true; return true;
} }
return false; return false;
@ -297,7 +298,7 @@ static uint32_t _hashString(const struct mScriptValue* val) {
const char* buffer = 0; const char* buffer = 0;
size_t size = 0; size_t size = 0;
if (val->type == &mSTString) { if (val->type == &mSTString) {
struct mScriptString* string = val->value.opaque; struct mScriptString* string = val->value.string;
buffer = string->buffer; buffer = string->buffer;
size = string->size; size = string->size;
} else if (val->type == &mSTCharPtr) { } else if (val->type == &mSTCharPtr) {
@ -642,7 +643,7 @@ bool _charpEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
valB = b->value.opaque; valB = b->value.opaque;
lenB = strlen(valB); lenB = strlen(valB);
} else if (b->type == &mSTString) { } else if (b->type == &mSTString) {
struct mScriptString* stringB = b->value.opaque; struct mScriptString* stringB = b->value.string;
valB = stringB->buffer; valB = stringB->buffer;
lenB = stringB->size; lenB = stringB->size;
} else { } else {
@ -657,7 +658,7 @@ bool _charpEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
} }
bool _stringEqual(const struct mScriptValue* a, const struct mScriptValue* b) { bool _stringEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
struct mScriptString* stringA = a->value.opaque; struct mScriptString* stringA = a->value.string;
const char* valA = stringA->buffer; const char* valA = stringA->buffer;
const char* valB; const char* valB;
size_t lenA = stringA->size; size_t lenA = stringA->size;
@ -669,7 +670,7 @@ bool _stringEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
valB = b->value.opaque; valB = b->value.opaque;
lenB = strlen(valB); lenB = strlen(valB);
} else if (b->type == &mSTString) { } else if (b->type == &mSTString) {
struct mScriptString* stringB = b->value.opaque; struct mScriptString* stringB = b->value.string;
valB = stringB->buffer; valB = stringB->buffer;
lenB = stringB->size; lenB = stringB->size;
} else { } else {
@ -757,9 +758,30 @@ const struct mScriptValue* mScriptValueUnwrapConst(const struct mScriptValue* va
return NULL; return NULL;
} }
struct mScriptValue* mScriptStringCreateFromUTF8(const char* string) { struct mScriptValue* mScriptStringCreateEmpty(size_t size) {
struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_STR); struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_STR);
struct mScriptString* internal = val->value.opaque; struct mScriptString* internal = val->value.opaque;
internal->size = size;
internal->length = 0;
internal->buffer = malloc(size + 1);
memset(internal->buffer, 0, size + 1);
return val;
}
struct mScriptValue* mScriptStringCreateFromBytes(const void* string, size_t size) {
struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_STR);
struct mScriptString* internal = val->value.opaque;
internal->size = size;
internal->length = 0;
internal->buffer = malloc(size + 1);
memcpy(internal->buffer, string, size);
internal->buffer[size] = '\0';
return val;
}
struct mScriptValue* mScriptStringCreateFromUTF8(const char* string) {
struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_STR);
struct mScriptString* internal = val->value.string;
internal->size = strlen(string); internal->size = strlen(string);
internal->length = utf8strlen(string); internal->length = utf8strlen(string);
internal->buffer = strdup(string); internal->buffer = strdup(string);
@ -768,7 +790,7 @@ struct mScriptValue* mScriptStringCreateFromUTF8(const char* string) {
struct mScriptValue* mScriptStringCreateFromASCII(const char* string) { struct mScriptValue* mScriptStringCreateFromASCII(const char* string) {
struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_STR); struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_STR);
struct mScriptString* internal = val->value.opaque; struct mScriptString* internal = val->value.string;
internal->size = strlen(string); internal->size = strlen(string);
internal->length = strlen(string); internal->length = strlen(string);
internal->buffer = latin1ToUtf8(string, internal->size + 1); internal->buffer = latin1ToUtf8(string, internal->size + 1);
@ -794,9 +816,8 @@ bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, st
if (!key->type->hash) { if (!key->type->hash) {
return false; return false;
} }
struct Table* t = table->value.opaque;
mScriptValueRef(value); mScriptValueRef(value);
HashTableInsertCustom(t, key, value); HashTableInsertCustom(table->value.table, key, value);
return true; return true;
} }
@ -807,8 +828,7 @@ bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key) {
if (!key->type->hash) { if (!key->type->hash) {
return false; return false;
} }
struct Table* t = table->value.opaque; HashTableRemoveCustom(table->value.table, key);
HashTableRemoveCustom(t, key);
return true; return true;
} }
@ -822,16 +842,14 @@ struct mScriptValue* mScriptTableLookup(struct mScriptValue* table, struct mScri
if (!key->type->hash) { if (!key->type->hash) {
return false; return false;
} }
struct Table* t = table->value.opaque; return HashTableLookupCustom(table->value.table, key);
return HashTableLookupCustom(t, key);
} }
bool mScriptTableClear(struct mScriptValue* table) { bool mScriptTableClear(struct mScriptValue* table) {
if (table->type != mSCRIPT_TYPE_MS_TABLE) { if (table->type != mSCRIPT_TYPE_MS_TABLE) {
return false; return false;
} }
struct Table* t = table->value.opaque; HashTableClear(table->value.table);
HashTableClear(t);
return true; return true;
} }
@ -842,8 +860,7 @@ bool mScriptTableIteratorStart(struct mScriptValue* table, struct TableIterator*
if (table->type != mSCRIPT_TYPE_MS_TABLE) { if (table->type != mSCRIPT_TYPE_MS_TABLE) {
return false; return false;
} }
struct Table* t = table->value.opaque; return HashTableIteratorStart(table->value.table, iter);
return HashTableIteratorStart(t, iter);
} }
bool mScriptTableIteratorNext(struct mScriptValue* table, struct TableIterator* iter) { bool mScriptTableIteratorNext(struct mScriptValue* table, struct TableIterator* iter) {
@ -853,8 +870,7 @@ bool mScriptTableIteratorNext(struct mScriptValue* table, struct TableIterator*
if (table->type != mSCRIPT_TYPE_MS_TABLE) { if (table->type != mSCRIPT_TYPE_MS_TABLE) {
return false; return false;
} }
struct Table* t = table->value.opaque; return HashTableIteratorNext(table->value.table, iter);
return HashTableIteratorNext(t, iter);
} }
struct mScriptValue* mScriptTableIteratorGetKey(struct mScriptValue* table, struct TableIterator* iter) { struct mScriptValue* mScriptTableIteratorGetKey(struct mScriptValue* table, struct TableIterator* iter) {
@ -864,8 +880,7 @@ struct mScriptValue* mScriptTableIteratorGetKey(struct mScriptValue* table, stru
if (table->type != mSCRIPT_TYPE_MS_TABLE) { if (table->type != mSCRIPT_TYPE_MS_TABLE) {
return NULL; return NULL;
} }
struct Table* t = table->value.opaque; return HashTableIteratorGetCustomKey(table->value.table, iter);
return HashTableIteratorGetCustomKey(t, iter);
} }
struct mScriptValue* mScriptTableIteratorGetValue(struct mScriptValue* table, struct TableIterator* iter) { struct mScriptValue* mScriptTableIteratorGetValue(struct mScriptValue* table, struct TableIterator* iter) {
@ -875,8 +890,7 @@ struct mScriptValue* mScriptTableIteratorGetValue(struct mScriptValue* table, st
if (table->type != mSCRIPT_TYPE_MS_TABLE) { if (table->type != mSCRIPT_TYPE_MS_TABLE) {
return NULL; return NULL;
} }
struct Table* t = table->value.opaque; return HashTableIteratorGetValue(table->value.table, iter);
return HashTableIteratorGetValue(t, iter);
} }
bool mScriptTableIteratorLookup(struct mScriptValue* table, struct TableIterator* iter, struct mScriptValue* key) { bool mScriptTableIteratorLookup(struct mScriptValue* table, struct TableIterator* iter, struct mScriptValue* key) {
@ -886,8 +900,7 @@ bool mScriptTableIteratorLookup(struct mScriptValue* table, struct TableIterator
if (table->type != mSCRIPT_TYPE_MS_TABLE) { if (table->type != mSCRIPT_TYPE_MS_TABLE) {
return false; return false;
} }
struct Table* t = table->value.opaque; return HashTableIteratorLookupCustom(table->value.table, iter, key);
return HashTableIteratorLookupCustom(t, iter, key);
} }
void mScriptFrameInit(struct mScriptFrame* frame) { void mScriptFrameInit(struct mScriptFrame* frame) {
@ -1053,7 +1066,7 @@ static bool _accessRawMember(struct mScriptClassMember* member, void* raw, bool
val->refs = mSCRIPT_VALUE_UNREF; val->refs = mSCRIPT_VALUE_UNREF;
val->flags = 0; val->flags = 0;
val->type = mSCRIPT_TYPE_MS_WRAPPER; val->type = mSCRIPT_TYPE_MS_WRAPPER;
val->value.opaque = raw; val->value.table = raw;
break; break;
case mSCRIPT_TYPE_FUNCTION: case mSCRIPT_TYPE_FUNCTION:
val->refs = mSCRIPT_VALUE_UNREF; val->refs = mSCRIPT_VALUE_UNREF;