当我尝试用V8运行一些JS代码(this + this)时,我得到了这个错误(从两个弱点前尝试过主,3.23.17,3.24.40,3.25.5;由于API的变化,3.23.0不再起作用了):
#
# Fatal error in ..\..\src\runtime.cc, line 785
# CHECK(V8::ArrayBufferAllocator() != NULL) failed
#
许多其他JS代码已经有效,所以我想知道问题是什么。
它在Win8上,带有x64版本。 V8的构建正如官方文档中所述(使用gyp + MSVC 2012)。我不认为存在问题,因为它已经与大多数其他JS代码一起运行良好。
我认为V8本身可能存在问题,但不确定......
我还在邮件列表here上询问。
一些C ++代码,但我不认为它存在问题,因为它可以与其他JS代码一起使用:
#include <string>
#include <assert.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <boost/noncopyable.hpp>
#include <v8.h>
// Create a new isolate (completely isolated JS VM).
struct V8Isolate : boost::noncopyable {
v8::Isolate* isolate;
V8Isolate() : isolate(v8::Isolate::New()) {}
~V8Isolate() { isolate->Dispose(); }
operator v8::Isolate*() { return isolate; }
v8::Isolate* operator->() { return isolate; }
};
struct ReturnType {
std::string err; // non-empty if there is an error
ReturnType(bool success) {
assert(success);
}
ReturnType(const std::string& _err) : err(_err) {
assert(!err.empty());
}
ReturnType(const char* _err) : err(_err) {
assert(!err.empty());
}
operator bool() const { return err.empty(); }
};
#define CHECK_RETURN(cmd) { ReturnType ret = (cmd); if(!ret) return ret; }
using namespace std;
using namespace v8;
ReturnType readFile(const std::string& filename, std::string& res) {
res = "";
FILE* f = fopen(filename.c_str(), "r");
if(!f) return "File '" + filename + "' cannot be opened";
while(!feof(f) && !ferror(f)) {
char buffer[1024 * 8];
size_t s = fread(buffer, 1, sizeof(buffer), f);
if(s > 0)
res.append(buffer, buffer + s);
}
auto err = ferror(f);
fclose(f);
if(err)
return "Error while reading file '" + filename + "'";
return true;
}
ReturnType execJsFile(const std::string& jsSourceDir, const std::string& extfilename) {
v8::TryCatch try_catch;
std::string sourceStr;
CHECK_RETURN(readFile(jsSourceDir + "/" + extfilename, sourceStr));
Local<String> origin = String::NewFromUtf8(Isolate::GetCurrent(), &extfilename[0], String::kNormalString, (int)extfilename.size());
Local<String> source = String::NewFromUtf8(Isolate::GetCurrent(), &sourceStr[0], String::kNormalString, (int)sourceStr.size());
Local<v8::Script> script = Script::Compile(source, origin);
if(script.IsEmpty()) {
assert(try_catch.HasCaught());
return "JS compile failed: " + jsObjToString(try_catch.Exception());
}
// Run the script to setup its environment
Local<Value> result = script->Run();
if(result.IsEmpty()) {
assert(try_catch.HasCaught());
return "JS script execution failed: " + jsReportExceptionToString(Isolate::GetCurrent(), &try_catch);
}
return true;
}
ReturnType loadJsGit() {
V8Isolate isolate;
v8::Isolate::Scope isolateScope(isolate);
HandleScope handleScope(isolate);
Handle<Context> context = Context::New(isolate);
Context::Scope contextScope(context);
auto globalObj = context->Global();
CHECK_RETURN(execJsFile(".", "global.js"));
CHECK_RETURN(execJsFile(".", "jsgit.js"));
return true;
}
int main(int argc, char** argv) {
ReturnType ret = loadJsGit();
if(!ret) cout << "error: " << ret.err << endl;
}
答案 0 :(得分:6)
您需要初始化数组缓冲区分配器。
使用malloc,例如:
class MallocArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
public:
virtual void* Allocate(size_t length) { return malloc(length); }
virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
virtual void Free(void* data, size_t length) { free(data); }
};
初始化:
v8::V8::SetArrayBufferAllocator(new MallocArrayBufferAllocator);