I am using QT and v8 to develop a Javascript interpreter.
I need to create a function that can read a binary file from the specified path.
This is my C++ code to do that:
void ScriptThread::ReadFile(const v8::FunctionCallbackInfo<v8::Value>& args)
{
if (v8::V8::IsExecutionTerminating(args.GetIsolate()) || instance->m_killFlag)
return;
v8::HandleScopehandle_scope(args.GetIsolate());
if (args.Length() != 1)
{
args.GetIsolate()->ThrowException(
v8::String::NewFromUtf8(args.GetIsolate(), "Bad parameters"));
return;
}
v8::String::Utf8Value str(args[0]);
QString filepath = *str;
QFile file(filepath);
if (!file.open(QFile::ReadOnly))
{
return;
}
QByteArray data = file.readAll();
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(args.GetIsolate(), (void*)data.data(), data.size());
args.GetReturnValue().Set(ab);
}
The problem is that after calling this function in Javascript, the ArrayBuffer in the js file contains random data instead of the content of the file.
Here is my JS code:
var buffer = ReadFile("D:/Temp/myfolder/ascii.txt")
Log(buffer)
var view = new Uint8Array(buffer)
Log(view)
Log(String.fromCharCode.apply(null, view))
D:/Temp/myfolder/ascii.txt:
ABCDEF
and the output of my JS after running the script several times without changing the file path:
2016-09-15 12:42:35.847 Script Info [object ArrayBuffer]
2016-09-15 12:42:35.847 Script Info 200,29,125,195,254,136
2016-09-15 12:42:35.847 Script Info È}Ãþ
2016-09-15 12:42:35.847 Info Script Stopped
2016-09-15 12:43:41.543 Script Info [object ArrayBuffer]
2016-09-15 12:43:41.543 Script Info 238,254,238,254,238,254
2016-09-15 12:43:41.543 Script Info îþîþîþ
2016-09-15 12:43:41.543 Info Script Stopped
2016-09-15 12:47:19.588 Script Info [object ArrayBuffer]
2016-09-15 12:47:19.588 Script Info m
2016-09-15 12:47:19.588 Script Info 30,25,109,30,0,0
2016-09-15 12:47:19.588 Info Script Stopped
I checked the data inside v8::ArrayBuffer from my cpp file.
I can't use String because the function is required to read non human readable files and I don't want to include node.js in my project.
Is somehow the ArrayBuffer GCed before return? Or am I out of the scope somehow? Can you guys help me?
Thanks!
I don't know much about QT, but it looks like you're pointing the array buffer to data for a variable on the stack
QByteArray data = file.readAll();
that likely (I don't know QByteArray) gets cleaned up after you return from creating the array buffer.
From http://v8.paulfryzel.com/docs/master/classv8_1_1_array_buffer.html:
Create a new ArrayBuffer over an existing memory block. The created array buffer is by default immediately in externalized state. The memory block will not be reclaimed when a created ArrayBuffer is garbage-collected.
So I'm pretty sure it's relying on you to make sure the memory it points to remains valid, which I don't think you're doing.