Refactored code in Arrays.cpp and fixed save_array() script function.

* related to "corrupted" savegames in #265.
This commit is contained in:
NovaRain
2019-09-24 12:30:02 +08:00
parent a17471b624
commit 98199b4e7e
5 changed files with 120 additions and 94 deletions
+2
View File
@@ -212,9 +212,11 @@ use macros sort_array, sort_array_reverse, reverse_array, shuffle_array from sfa
- always returns 0 - always returns 0
> void save_array(mixed key, int arrayID): > void save_array(mixed key, int arrayID):
- makes the array saveable; it will be saved in sfallgv.sav file when saving the game
- arrayID is associated with given "key" - arrayID is associated with given "key"
- array becomes permanent (if it was temporary) and "saved" - array becomes permanent (if it was temporary) and "saved"
- key can be of any type (int, float or string) - key can be of any type (int, float or string)
- if you specify 0 as the key for the array ID, it will make the array "unsaved"
> int load_array(mixed key): > int load_array(mixed key):
- load array from savegame data by the same key provided in "save_array" - load array from savegame data by the same key provided in "save_array"
+1 -1
View File
@@ -653,7 +653,7 @@ void SaveGlobals(HANDLE h) {
static void ClearGlobals() { static void ClearGlobals() {
globalVars.clear(); globalVars.clear();
for (array_itr it = arrays.begin(); it != arrays.end(); ++it) { for (array_itr it = arrays.begin(); it != arrays.end(); ++it) {
it->second.clear(); it->second.clearArrayVar();
} }
arrays.clear(); arrays.clear();
savedArrays.clear(); savedArrays.clear();
+83 -59
View File
@@ -42,9 +42,9 @@ sArrayElement::sArrayElement(const long& other)
set(other); set(other);
} }
void sArrayElement::clear() void sArrayElement::clearData()
{ {
if (strVal && type == DataType::STR) delete[] strVal; if (type == DataType::STR) delete[] strVal;
} }
void sArrayElement::setByType( DWORD val, DataType dataType ) void sArrayElement::setByType( DWORD val, DataType dataType )
@@ -64,21 +64,21 @@ void sArrayElement::setByType( DWORD val, DataType dataType )
void sArrayElement::set( long val ) void sArrayElement::set( long val )
{ {
clear(); clearData();
type = DataType::INT; type = DataType::INT;
intVal = val; intVal = val;
} }
void sArrayElement::set( float val ) void sArrayElement::set( float val )
{ {
clear(); clearData();
type = DataType::FLOAT; type = DataType::FLOAT;
floatVal = val; floatVal = val;
} }
void sArrayElement::set( const char* val, int sLen /*= -1*/ ) void sArrayElement::set( const char* val, int sLen /*= -1*/ )
{ {
clear(); clearData();
type = DataType::STR; type = DataType::STR;
if (sLen == -1) sLen = strlen(val); if (sLen == -1) sLen = strlen(val);
if (sLen >= ARRAY_MAX_STRING) sLen = ARRAY_MAX_STRING - 1; // memory safety if (sLen >= ARRAY_MAX_STRING) sLen = ARRAY_MAX_STRING - 1; // memory safety
@@ -90,7 +90,7 @@ void sArrayElement::set( const char* val, int sLen /*= -1*/ )
void sArrayElement::unset() void sArrayElement::unset()
{ {
clear(); clearData();
type = DataType::NONE; type = DataType::NONE;
len = intVal = 0; len = intVal = 0;
} }
@@ -99,11 +99,11 @@ DWORD sArrayElement::getHashStatic(DWORD value, DataType type) {
switch (type) { switch (type) {
case DataType::STR: { case DataType::STR: {
const char* str = (const char*)value; const char* str = (const char*)value;
DWORD res = 0; DWORD hash = 0;
for (int i = 0; str[i] != '\0'; i++) { while (*str) {
res = ((res << 5) + res) + str[i]; hash = ((hash << 5) + hash) + *str++;
} }
return res; return hash;
} }
case DataType::INT: case DataType::INT:
case DataType::FLOAT: case DataType::FLOAT:
@@ -150,7 +150,14 @@ void sArrayVar::clearRange( int from, int to /*= -1*/ )
if (to == -1) to = val.size(); if (to == -1) to = val.size();
std::vector<sArrayElement>::iterator it, itTo = val.begin() + to; std::vector<sArrayElement>::iterator it, itTo = val.begin() + to;
for (it = val.begin() + from; it < itTo; ++it) { for (it = val.begin() + from; it < itTo; ++it) {
it->clear(); it->clearData();
}
}
void sArrayVar::clearAll()
{
for (auto it = val.begin(); it != val.end(); ++it) {
it->clearData();
} }
} }
@@ -179,6 +186,7 @@ bool LoadArrayElement(sArrayElement* el, HANDLE h)
el->strVal = nullptr; el->strVal = nullptr;
} else { } else {
ReadFile(h, &el->intVal, 4, &unused, 0); ReadFile(h, &el->intVal, 4, &unused, 0);
el->len = 0;
} }
return (el->len) ? (unused != el->len) : (unused != 4); return (el->len) ? (unused != el->len) : (unused != 4);
} }
@@ -202,8 +210,8 @@ static long LoadArraysOld(HANDLE h) {
var.types = new DWORD[var.len]; var.types = new DWORD[var.len];
var.data = new char[var.len * var.datalen]; var.data = new char[var.len * var.datalen];
ReadFile(h, var.types, (4 * var.len), &unused, 0); ReadFile(h, &var.types, (4 * var.len), &unused, 0);
ReadFile(h, var.data, (var.len * var.datalen), &unused, 0); ReadFile(h, &var.data, (var.len * var.datalen), &unused, 0);
varN.flags = 0; varN.flags = 0;
varN.val.resize(var.len); varN.val.resize(var.len);
@@ -250,7 +258,6 @@ long LoadArrays(HANDLE h) {
arrayVar.key.intVal = static_cast<long>(arrayVar.key.type); arrayVar.key.intVal = static_cast<long>(arrayVar.key.type);
arrayVar.key.type = DataType::INT; arrayVar.key.type = DataType::INT;
} }
ReadFile(h, &arrayVar.flags, 4, &unused, 0); ReadFile(h, &arrayVar.flags, 4, &unused, 0);
ReadFile(h, &elCount, 4, &unused, 0); // actual number of elements: keys+values ReadFile(h, &elCount, 4, &unused, 0); // actual number of elements: keys+values
if (unused != 4) return -1; if (unused != 4) return -1;
@@ -268,6 +275,7 @@ long LoadArrays(HANDLE h) {
arrays.insert(array_pair(nextArrayID, arrayVar)); arrays.insert(array_pair(nextArrayID, arrayVar));
savedArrays[arrayVar.key] = nextArrayID++; savedArrays[arrayVar.key] = nextArrayID++;
arrayVar.keyHash.clear(); arrayVar.keyHash.clear();
} }
return 0; return 0;
@@ -277,29 +285,29 @@ void SaveArrays(HANDLE h) {
DWORD elCount, unused, count = 0; DWORD elCount, unused, count = 0;
WriteFile(h, &count, 4, &unused, 0); // this is for backward compatibility with 3.3- WriteFile(h, &count, 4, &unused, 0); // this is for backward compatibility with 3.3-
array_itr arIt; array_itr arrayIt;
ArrayKeysMap::iterator it = savedArrays.begin(); ArrayKeysMap::iterator it = savedArrays.begin();
while (it != savedArrays.end()) { while (it != savedArrays.end()) {
arIt = arrays.find(it->second); arrayIt = arrays.find(it->second); // check the existence of an array
if (arIt == arrays.end()) { if (arrayIt == arrays.end()) {
savedArrays.erase(it++); it = savedArrays.erase(it); // array is not found, delete it [fix to C++11 https://en.cppreference.com/w/cpp/container/unordered_map/erase]
} else { } else {
++count; ++count;
++it; ++it;
} }
} }
WriteFile(h, &count, 4, &unused, 0); WriteFile(h, &count, 4, &unused, 0); // count saved arrays
if (count == 0) return;
for (it = savedArrays.begin(); it != savedArrays.end(); ++it) { for (it = savedArrays.begin(); it != savedArrays.end(); ++it) {
arIt = arrays.find(it->second); arrayIt = arrays.find(it->second);
if (arIt != arrays.end()) { if (arrayIt != arrays.end()) {
sArrayVar &var = arrays[it->second]; sArrayVar &var = arrays[it->second];
SaveArrayElement(&var.key, h); SaveArrayElement(&var.key, h); // type, key/length of key and string of key
WriteFile(h, &var.flags, 4, &unused, 0); WriteFile(h, &var.flags, 4, &unused, 0);
elCount = var.val.size(); elCount = var.val.size();
WriteFile(h, &elCount, 4, &unused, 0); WriteFile(h, &elCount, 4, &unused, 0); // number of elements in saved array
for (std::vector<sArrayElement>::iterator it = var.val.begin(); it != var.val.end(); ++it) { for (std::vector<sArrayElement>::iterator vIt = var.val.begin(); vIt != var.val.end(); ++vIt) {
SaveArrayElement(&(*it), h); SaveArrayElement(&(*vIt), h);
} }
} }
} }
@@ -371,7 +379,7 @@ void DESetArray(int id, const DWORD* types, const char* data) {
TODO: move somewhere else TODO: move somewhere else
*/ */
DWORD _stdcall CreateArray(int len, DWORD flags) { DWORD CreateArray(int len, DWORD flags) {
sArrayVar var; sArrayVar var;
var.flags = (flags & 0xFFFFFFFE); // reset 1 bit var.flags = (flags & 0xFFFFFFFE); // reset 1 bit
if (len < 0) { if (len < 0) {
@@ -395,17 +403,17 @@ DWORD _stdcall CreateArray(int len, DWORD flags) {
return nextArrayID++; return nextArrayID++;
} }
DWORD _stdcall TempArray(DWORD len, DWORD flags) { DWORD TempArray(DWORD len, DWORD flags) {
DWORD id = CreateArray(len, flags); DWORD id = CreateArray(len, flags);
tempArrays.insert(id); tempArrays.insert(id);
return id; return id;
} }
void _stdcall FreeArray(DWORD id) { void FreeArray(DWORD id) {
array_itr it = arrays.find(id); array_itr it = arrays.find(id);
if (it != arrays.end()) { if (it != arrays.end()) {
savedArrays.erase(it->second.key); if (it->second.key.intVal) savedArrays.erase(it->second.key);
it->second.clear(); it->second.clearArrayVar();
arrays.erase(id); arrays.erase(id);
} }
} }
@@ -419,7 +427,7 @@ void DeleteAllTempArrays() {
} }
} }
ScriptValue _stdcall GetArrayKey(DWORD id, int index) { ScriptValue GetArrayKey(DWORD id, int index) {
if (arrays.find(id) == arrays.end() || index < -1 || index > arrays[id].size()) { if (arrays.find(id) == arrays.end() || index < -1 || index > arrays[id].size()) {
return ScriptValue(0); return ScriptValue(0);
} }
@@ -446,7 +454,7 @@ ScriptValue _stdcall GetArrayKey(DWORD id, int index) {
} }
} }
ScriptValue _stdcall GetArray(DWORD id, const ScriptValue& key) { ScriptValue GetArray(DWORD id, const ScriptValue& key) {
if (arrays.find(id) == arrays.end()) { if (arrays.find(id) == arrays.end()) {
return 0; return 0;
} }
@@ -478,7 +486,7 @@ ScriptValue _stdcall GetArray(DWORD id, const ScriptValue& key) {
return ScriptValue(0); return ScriptValue(0);
} }
void _stdcall SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool allowUnset) { void SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool allowUnset) {
if (arrays.find(id) == arrays.end()) { if (arrays.find(id) == arrays.end()) {
return; return;
} }
@@ -529,7 +537,7 @@ void _stdcall SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val,
} }
} }
int _stdcall LenArray(DWORD id) { int LenArray(DWORD id) {
if (arrays.find(id) == arrays.end()) return -1; if (arrays.find(id) == arrays.end()) return -1;
return arrays[id].size(); return arrays[id].size();
} }
@@ -590,12 +598,16 @@ static void MapSort(sArrayVar& arr, int type) {
} }
} }
long _stdcall ResizeArray(DWORD id, int newlen) { long ResizeArray(DWORD id, int newlen) {
if (newlen == -1 || arrays.find(id) == arrays.end() || arrays[id].size() == newlen) return 0; if (newlen == -1 || arrays.find(id) == arrays.end()) return 0;
sArrayVar &arr = arrays[id]; sArrayVar &arr = arrays[id];
int arrSize = arr.size();
if (arrSize == newlen) return 0;
if (arr.isAssoc()) { if (arr.isAssoc()) {
// only allow to reduce number of elements (adding range of elements is meaningless for maps) // only allow to reduce number of elements (adding range of elements is meaningless for maps)
if (newlen >= 0 && newlen < arrays[id].size()) { if (newlen >= 0 && newlen < arrSize) {
ArrayKeysMap::iterator itHash; ArrayKeysMap::iterator itHash;
std::vector<sArrayElement>::iterator itVal; std::vector<sArrayElement>::iterator itVal;
int actualLen = newlen * 2; int actualLen = newlen * 2;
@@ -603,7 +615,10 @@ long _stdcall ResizeArray(DWORD id, int newlen) {
if ((itHash = arr.keyHash.find(*itVal)) != arr.keyHash.end()) if ((itHash = arr.keyHash.find(*itVal)) != arr.keyHash.end())
arr.keyHash.erase(itHash); arr.keyHash.erase(itHash);
} }
arr.clearRange(actualLen); if (actualLen == 0)
arr.clearAll();
else
arr.clearRange(actualLen);
arr.val.resize(actualLen); arr.val.resize(actualLen);
} else if (newlen < 0) { } else if (newlen < 0) {
if (newlen < (ARRAY_ACTION_SHUFFLE - 2)) return -1; if (newlen < (ARRAY_ACTION_SHUFFLE - 2)) return -1;
@@ -612,10 +627,12 @@ long _stdcall ResizeArray(DWORD id, int newlen) {
return 0; return 0;
} }
if (newlen >= 0) { // actual resize if (newlen >= 0) { // actual resize
if (newlen > ARRAY_MAX_SIZE) // safety if (newlen == 0) {
newlen = ARRAY_MAX_SIZE; arr.clearAll();
if (newlen < arr.size()) } else {
arr.clearRange(newlen); if (newlen > ARRAY_MAX_SIZE) newlen = ARRAY_MAX_SIZE; // safety
if (newlen < arrSize) arr.clearRange(newlen);
}
arr.val.resize(newlen); arr.val.resize(newlen);
} else { // special functions for lists... } else { // special functions for lists...
if (newlen < ARRAY_ACTION_SHUFFLE) return -1; if (newlen < ARRAY_ACTION_SHUFFLE) return -1;
@@ -624,11 +641,11 @@ long _stdcall ResizeArray(DWORD id, int newlen) {
return 0; return 0;
} }
void _stdcall FixArray(DWORD id) { void FixArray(DWORD id) {
tempArrays.erase(id); tempArrays.erase(id);
} }
ScriptValue _stdcall ScanArray(DWORD id, const ScriptValue& val) { ScriptValue ScanArray(DWORD id, const ScriptValue& val) {
if (arrays.find(id) == arrays.end()) { if (arrays.find(id) == arrays.end()) {
return ScriptValue(-1); return ScriptValue(-1);
} }
@@ -652,7 +669,7 @@ ScriptValue _stdcall ScanArray(DWORD id, const ScriptValue& val) {
return ScriptValue(-1); return ScriptValue(-1);
} }
DWORD _stdcall LoadArray(const ScriptValue& key) { DWORD LoadArray(const ScriptValue& key) {
if (!key.isInt() || key.asInt() != 0) { // returns arrayId by it's key (ignoring int(0) because it is used to "unsave" array) if (!key.isInt() || key.asInt() != 0) { // returns arrayId by it's key (ignoring int(0) because it is used to "unsave" array)
sArrayElement keyEl = sArrayElement(key.rawValue(), key.type()); sArrayElement keyEl = sArrayElement(key.rawValue(), key.type());
@@ -678,22 +695,29 @@ DWORD _stdcall LoadArray(const ScriptValue& key) {
return 0; // not found return 0; // not found
} }
void _stdcall SaveArray(const ScriptValue& key, DWORD id) { void SaveArray(const ScriptValue& key, DWORD id) {
array_itr it = arrays.find(id), it2; array_itr it, itArray = arrays.find(id); // arrayId => arrayVar
if (it != arrays.end()) { if (itArray != arrays.end()) {
if (!key.isInt() || key.asInt() != 0) { if (!key.isInt() || key.asInt() != 0) {
// make array permanent // make array permanent
FixArray(it->first); FixArray(itArray->first);
// if another array is saved under the same key, clear it // if another array is saved under the same key, clear it
ArrayKeysMap::iterator sIt = savedArrays.find(sArrayElement(key.rawValue(), key.type())); ArrayKeysMap::iterator savedIt = savedArrays.find(sArrayElement(key.rawValue(), key.type()));
if (sIt != savedArrays.end() && sIt->second != id && (it2 = arrays.find(sIt->second)) != arrays.end()) { if (savedIt != savedArrays.end()) {
it2->second.key.unset(); if (savedIt->second == id) return; // exit, array is already saveable
// arrays have different ID, search the ID of the "saved" array in collection of arrays
if ((it = arrays.find(savedIt->second)) != arrays.end()) {
// array exists, delete key value
savedArrays.erase(savedIt); /* added for fix */
it->second.key.unset();
}
} }
it->second.key.setByType(key.rawValue(), key.type()); // make "saved" array
savedArrays[it->second.key] = id; itArray->second.key.setByType(key.rawValue(), key.type());
} else { // int(0) is used to "unsave" array without destroying it savedArrays.emplace(itArray->second.key, id); // savedArrays[itArray->second.key] = id;
int num = savedArrays.erase(it->second.key); } else { // key of int(0) is used to "unsave" array without destroying it
it->second.key.unset(); savedArrays.erase(itArray->second.key);
itArray->second.key.unset();
} }
} }
} }
@@ -708,7 +732,7 @@ void _stdcall SaveArray(const ScriptValue& key, DWORD id) {
Should always return 0! Should always return 0!
*/ */
DWORD _stdcall StackArray(const ScriptValue& key, const ScriptValue& val) { long StackArray(const ScriptValue& key, const ScriptValue& val) {
DWORD id = stackArrayId; DWORD id = stackArrayId;
if (id == 0 || arrays.find(id) == arrays.end()) { if (id == 0 || arrays.find(id) == arrays.end()) {
return 0; return 0;
+22 -22
View File
@@ -40,7 +40,7 @@ public:
sArrayElement(const long&); sArrayElement(const long&);
// free string resource from memory, has to be called manually when deleting element // free string resource from memory, has to be called manually when deleting element
void clear(); void clearData();
// set* methods will actually COPY strings, use this when acquiring data from the scripting engine // set* methods will actually COPY strings, use this when acquiring data from the scripting engine
void setByType(DWORD val, DataType dataType); void setByType(DWORD val, DataType dataType);
@@ -107,15 +107,16 @@ public:
ArrayKeysMap keyHash; // key element => element index, for faster lookup ArrayKeysMap keyHash; // key element => element index, for faster lookup
std::vector<sArrayElement> val; // list of values or key=>value pairs (even - keys, odd - values) std::vector<sArrayElement> val; // list of values or key=>value pairs (even - keys, odd - values)
sArrayVar() : flags(0), key() {}
bool isAssoc() const { bool isAssoc() const {
return (flags & ARRAYFLAG_ASSOC); return (flags & ARRAYFLAG_ASSOC);
} }
// logical array size (number of elements for normal arrays; number of key=>value pairs for associative) // logical array size (number of elements for normal arrays; number of key=>value pairs for associative)
int size() const { int size() const {
return isAssoc() size_t sz = val.size();
? val.size() / 2 return isAssoc() ? sz / 2 : sz;
: val.size();
} }
// usefull when filling array from within sfall code (normal lists only) // usefull when filling array from within sfall code (normal lists only)
@@ -125,15 +126,14 @@ public:
} }
} }
sArrayVar() : flags(0), key() {}
// free memory used by strings // free memory used by strings
void clear() { void clearArrayVar() {
clearRange(0); clearAll();
key.clear(); key.clearData();
} }
void clearRange(int from, int to = -1); void clearRange(int from, int to = -1);
void clearAll();
}; };
// arrays map: arrayId => arrayVar // arrays map: arrayId => arrayVar
@@ -160,13 +160,13 @@ void DEGetArray(int id, DWORD* types, char* data);
void DESetArray(int id, const DWORD* types, const char* data); void DESetArray(int id, const DWORD* types, const char* data);
// creates new normal (persistent) array. len == -1 specifies associative array (map) // creates new normal (persistent) array. len == -1 specifies associative array (map)
DWORD _stdcall CreateArray(int len, DWORD flags); DWORD CreateArray(int len, DWORD flags);
// same as CreateArray, but creates temporary array instead (will die at the end of the frame) // same as CreateArray, but creates temporary array instead (will die at the end of the frame)
DWORD _stdcall TempArray(DWORD len, DWORD flags); DWORD TempArray(DWORD len, DWORD flags);
// destroys array // destroys array
void _stdcall FreeArray(DWORD id); void FreeArray(DWORD id);
// destroy all temp arrays // destroy all temp arrays
void DeleteAllTempArrays(); void DeleteAllTempArrays();
@@ -174,34 +174,34 @@ void DeleteAllTempArrays();
/* /*
op_get_array_key can be used to iterate over all keys in associative array op_get_array_key can be used to iterate over all keys in associative array
*/ */
ScriptValue _stdcall GetArrayKey(DWORD id, int index); ScriptValue GetArrayKey(DWORD id, int index);
// get array element by index (list) or key (map) // get array element by index (list) or key (map)
ScriptValue _stdcall GetArray(DWORD id, const ScriptValue& key); ScriptValue GetArray(DWORD id, const ScriptValue& key);
// set array element by index or key // set array element by index or key
void _stdcall SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool allowUnset); void SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool allowUnset);
// number of elements in list or pairs in map // number of elements in list or pairs in map
int _stdcall LenArray(DWORD id); int LenArray(DWORD id);
// change array size (only works with list) // change array size (only works with list)
long _stdcall ResizeArray(DWORD id, int newlen); long ResizeArray(DWORD id, int newlen);
// make temporary array persistent // make temporary array persistent
void _stdcall FixArray(DWORD id); void FixArray(DWORD id);
// searches for a given element in array and returns it's index (for list) or key (for map) or int(-1) if not found // searches for a given element in array and returns it's index (for list) or key (for map) or int(-1) if not found
ScriptValue _stdcall ScanArray(DWORD id, const ScriptValue& val); ScriptValue ScanArray(DWORD id, const ScriptValue& val);
// get saved array by it's key // get saved array by it's key
DWORD _stdcall LoadArray(const ScriptValue& key); DWORD LoadArray(const ScriptValue& key);
// make array saved into the savegame with associated key // make array saved into the savegame with associated key
void _stdcall SaveArray(const ScriptValue& key, DWORD id); void SaveArray(const ScriptValue& key, DWORD id);
// special function that powers array expressions // special function that powers array expressions
DWORD _stdcall StackArray(const ScriptValue& key, const ScriptValue& val); long StackArray(const ScriptValue& key, const ScriptValue& val);
} }
} }
+12 -12
View File
@@ -30,13 +30,13 @@ namespace script
{ {
void sf_create_array(OpcodeContext& ctx) { void sf_create_array(OpcodeContext& ctx) {
auto arrayId = CreateArray(ctx.arg(0).asInt(), ctx.arg(1).asInt()); auto arrayId = CreateArray(ctx.arg(0).rawValue(), ctx.arg(1).rawValue());
ctx.setReturn(arrayId, DataType::INT); ctx.setReturn(arrayId, DataType::INT);
} }
void sf_set_array(OpcodeContext& ctx) { void sf_set_array(OpcodeContext& ctx) {
SetArray( SetArray(
ctx.arg(0).asInt(), ctx.arg(0).rawValue(),
ctx.arg(1), ctx.arg(1),
ctx.arg(2), ctx.arg(2),
true true
@@ -65,55 +65,55 @@ void sf_get_array(OpcodeContext& ctx) {
} }
void sf_free_array(OpcodeContext& ctx) { void sf_free_array(OpcodeContext& ctx) {
FreeArray(ctx.arg(0).asInt()); FreeArray(ctx.arg(0).rawValue());
} }
void sf_len_array(OpcodeContext& ctx) { void sf_len_array(OpcodeContext& ctx) {
ctx.setReturn( ctx.setReturn(
LenArray(ctx.arg(0).asInt()) LenArray(ctx.arg(0).rawValue())
); );
} }
void sf_resize_array(OpcodeContext& ctx) { void sf_resize_array(OpcodeContext& ctx) {
if (ResizeArray(ctx.arg(0).asInt(), ctx.arg(1).asInt())) { if (ResizeArray(ctx.arg(0).rawValue(), ctx.arg(1).rawValue())) {
ctx.printOpcodeError("%s() - array sorting error.", ctx.getOpcodeName()); ctx.printOpcodeError("%s() - array sorting error.", ctx.getOpcodeName());
} }
} }
void sf_temp_array(OpcodeContext& ctx) { void sf_temp_array(OpcodeContext& ctx) {
auto arrayId = TempArray(ctx.arg(0).asInt(), ctx.arg(1).asInt()); auto arrayId = TempArray(ctx.arg(0).rawValue(), ctx.arg(1).rawValue());
ctx.setReturn(arrayId, DataType::INT); ctx.setReturn(arrayId, DataType::INT);
} }
void sf_fix_array(OpcodeContext& ctx) { void sf_fix_array(OpcodeContext& ctx) {
FixArray(ctx.arg(0).asInt()); FixArray(ctx.arg(0).rawValue());
} }
void sf_scan_array(OpcodeContext& ctx) { void sf_scan_array(OpcodeContext& ctx) {
ctx.setReturn( ctx.setReturn(
ScanArray(ctx.arg(0).asInt(), ctx.arg(1)) ScanArray(ctx.arg(0).rawValue(), ctx.arg(1))
); );
} }
void sf_save_array(OpcodeContext& ctx) { void sf_save_array(OpcodeContext& ctx) {
SaveArray(ctx.arg(0), ctx.arg(1).asInt()); SaveArray(ctx.arg(0), ctx.arg(1).rawValue());
} }
void sf_load_array(OpcodeContext& ctx) { void sf_load_array(OpcodeContext& ctx) {
ctx.setReturn( ctx.setReturn(
static_cast<int>(LoadArray(ctx.arg(0))) LoadArray(ctx.arg(0))
); );
} }
void sf_get_array_key(OpcodeContext& ctx) { void sf_get_array_key(OpcodeContext& ctx) {
ctx.setReturn( ctx.setReturn(
GetArrayKey(ctx.arg(0).asInt(), ctx.arg(1).asInt()) GetArrayKey(ctx.arg(0).rawValue(), ctx.arg(1).rawValue())
); );
} }
void sf_stack_array(OpcodeContext& ctx) { void sf_stack_array(OpcodeContext& ctx) {
ctx.setReturn( ctx.setReturn(
static_cast<int>(StackArray(ctx.arg(0), ctx.arg(1))) StackArray(ctx.arg(0), ctx.arg(1))
); );
} }