MRI-Binding: Don't memcpy script data before deflating

I think the reason this was originally done was some
issue with ruby's GC where it would wrongfully sweep
the script array variable on the C stack.

This change should speed up startup a little.
This commit is contained in:
Jonas Kulla 2013-12-29 14:55:49 +01:00
parent d8e22a8b3c
commit 7f4e58fd6e
1 changed files with 11 additions and 35 deletions

View File

@ -186,15 +186,6 @@ static void runCustomScript(const char *filename)
VALUE kernelLoadDataInt(const char *filename); VALUE kernelLoadDataInt(const char *filename);
struct Script
{
std::string name;
std::string encData;
uint32_t unknown;
std::string decData;
};
static void runRMXPScripts() static void runRMXPScripts()
{ {
const std::string &scriptPack = shState->rtData().config.game.scripts; const std::string &scriptPack = shState->rtData().config.game.scripts;
@ -224,31 +215,16 @@ static void runRMXPScripts()
std::string decodeBuffer; std::string decodeBuffer;
decodeBuffer.resize(0x1000); decodeBuffer.resize(0x1000);
std::vector<Script> encScripts(scriptCount);
for (size_t i = 0; i < scriptCount; ++i) for (size_t i = 0; i < scriptCount; ++i)
{ {
VALUE script = rb_ary_entry(scriptArray, i); VALUE script = rb_ary_entry(scriptArray, i);
if (rb_type(script) != RUBY_T_ARRAY) if (rb_type(script) != RUBY_T_ARRAY)
{
continue; continue;
}
VALUE scriptUnknown = rb_ary_entry(script, 0);
VALUE scriptName = rb_ary_entry(script, 1); VALUE scriptName = rb_ary_entry(script, 1);
VALUE scriptString = rb_ary_entry(script, 2); VALUE scriptString = rb_ary_entry(script, 2);
Script &sc = encScripts[i];
sc.name = RSTRING_PTR(scriptName);
sc.encData = std::string(RSTRING_PTR(scriptString), RSTRING_LEN(scriptString));
sc.unknown = FIX2UINT(scriptUnknown);
}
for (size_t i = 0; i < scriptCount; ++i)
{
Script &sc = encScripts[i];
int result = Z_OK; int result = Z_OK;
ulong bufferLen; ulong bufferLen;
@ -257,12 +233,12 @@ static void runRMXPScripts()
unsigned char *bufferPtr = unsigned char *bufferPtr =
reinterpret_cast<unsigned char*>(const_cast<char*>(decodeBuffer.c_str())); reinterpret_cast<unsigned char*>(const_cast<char*>(decodeBuffer.c_str()));
const unsigned char *sourcePtr = const unsigned char *sourcePtr =
reinterpret_cast<const unsigned char*>(sc.encData.c_str()); reinterpret_cast<const unsigned char*>(RSTRING_PTR(scriptString));
bufferLen = decodeBuffer.length(); bufferLen = decodeBuffer.length();
result = uncompress(bufferPtr, &bufferLen, result = uncompress(bufferPtr, &bufferLen,
sourcePtr, sc.encData.length()); sourcePtr, RSTRING_LEN(scriptString));
bufferPtr[bufferLen] = '\0'; bufferPtr[bufferLen] = '\0';
@ -277,7 +253,7 @@ static void runRMXPScripts()
static char buffer[256]; static char buffer[256];
/* FIXME: '%zu' apparently gcc only? */ /* FIXME: '%zu' apparently gcc only? */
snprintf(buffer, sizeof(buffer), "Error decoding script %zu: '%s'", snprintf(buffer, sizeof(buffer), "Error decoding script %zu: '%s'",
i, sc.name.c_str()); i, RSTRING_PTR(scriptName));
showMsg(buffer); showMsg(buffer);
break; break;
@ -285,17 +261,17 @@ static void runRMXPScripts()
/* Store encoding header + the decoded script /* Store encoding header + the decoded script
* in 'sc.decData' */ * in 'sc.decData' */
sc.decData = "#encoding:utf-8\n"; std::string decData = "#encoding:utf-8\n";
size_t hdSize = sc.decData.size(); size_t hdSize = decData.size();
sc.decData.resize(hdSize + bufferLen); decData.resize(hdSize + bufferLen);
memcpy(&sc.decData[hdSize], decodeBuffer.c_str(), bufferLen); memcpy(&decData[hdSize], decodeBuffer.c_str(), bufferLen);
ruby_script(sc.name.c_str()); ruby_script(RSTRING_PTR(scriptName));
rb_gc_start(); rb_gc_start();
/* Execute code */ /* Execute code */
rb_eval_string_protect(sc.decData.c_str(), 0); rb_eval_string_protect(decData.c_str(), 0);
VALUE exc = rb_gv_get("$!"); VALUE exc = rb_gv_get("$!");
if (rb_type(exc) != RUBY_T_NIL) if (rb_type(exc) != RUBY_T_NIL)