Javascript V8:致命错误:检查(V8::ArrayBufferAllocator()!=NULL)失败

Javascript V8:致命错误:检查(V8::ArrayBufferAllocator()!=NULL)失败,javascript,v8,Javascript,V8,当我试着用V8运行一些JS代码(+)时,我遇到了这个错误(在3.23.17、3.24.40、3.25.5、3.23.0两个漏洞中尝试了master,但由于API的变化,它不再工作): 很多其他JS代码已经运行了,所以我想知道问题是什么 它在Win8上,版本为x64。V8已经按照官方文档中的描述进行了构建(使用gyp+MSVC 2012)。我不认为这是一个问题,因为它已经在大多数其他JS代码中运行良好 我认为V8本身可能有问题,但不确定 我也在邮件列表上问过 一些C++代码,但我不认为它有问题,

当我试着用V8运行一些JS代码(+)时,我遇到了这个错误(在3.23.17、3.24.40、3.25.5、3.23.0两个漏洞中尝试了master,但由于API的变化,它不再工作):

很多其他JS代码已经运行了,所以我想知道问题是什么

它在Win8上,版本为x64。V8已经按照官方文档中的描述进行了构建(使用gyp+MSVC 2012)。我不认为这是一个问题,因为它已经在大多数其他JS代码中运行良好

我认为V8本身可能有问题,但不确定

我也在邮件列表上问过


一些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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//创建一个新的隔离(完全隔离的JS VM)。
结构V8Isolate:boost::不可复制{
v8::隔离*隔离;
V8Isolate():隔离(v8::isolate::New()){}
~V8Isolate(){isolate->Dispose();}
运算符v8::Isolate*(){返回Isolate;}
v8::Isolate*运算符->(){返回Isolate;}
};
结构返回类型{
std::string err;//如果有错误,则为非空
返回类型(布尔成功){
断言(成功);
}
ReturnType(const std::string&_err):err(_err){
断言(!err.empty());
}
返回类型(常量字符*_err):err(_err){
断言(!err.empty());
}
运算符bool()常量{return err.empty();}
};
#定义CHECK_RETURN(cmd){ReturnType ret=(cmd);if(!ret)RETURN ret;}
使用名称空间std;
使用名称空间v8;
ReturnType读取文件(常量std::string和文件名,std::string和res){
res=“”;
FILE*f=fopen(filename.c_str(),“r”);
如果(!f)返回“文件”+“文件名”+“无法打开”;
而(!feof(f)和&!feror(f)){
字符缓冲区[1024*8];
size_t s=fread(缓冲区,1,sizeof(缓冲区),f);
如果(s>0)
res.append(buffer,buffer+s);
}
自动误差=ferror(f);
fclose(f);
如果(错误)
返回“读取文件“+”文件名“+”时出错”;
返回true;
}
ReturnType execJsFile(const std::string和jsSourceDir,const std::string和extfilename){
v8::TryCatch try_catch;
std::字符串sourceStr;
检查返回(readFile(jsSourceDir+“/”+extfilename,sourceStr));
Local origin=String::NewFromUtf8(隔离::GetCurrent(),&extfilename[0],String::kNormalString,(int)extfilename.size());
Local source=String::NewFromUtf8(隔离::GetCurrent(),&sourceStr[0],String::kNormalString,(int)sourceStr.size());
本地脚本=脚本::编译(源、源);
if(script.IsEmpty()){
断言(try_catch.hascapt());
返回“JS编译失败:”+jsObjToString(try_catch.Exception());
}
//运行脚本以设置其环境
本地结果=脚本->运行();
if(result.IsEmpty()){
断言(try_catch.hascapt());
返回“JS脚本执行失败:”+JSReportExceptionString(孤立::GetCurrent(),&try_-catch);
}
返回true;
}
ReturnType loadJsGit(){
V8分离物;
v8::Isolate::Scope isolateScope(隔离);
手镜手镜(隔离);
句柄上下文=上下文::新建(隔离);
Context::范围contextScope(上下文);
auto globalObj=上下文->全局();
检查返回(execJsFile(“.”,global.js”);
检查返回(execJsFile(“.”,jsgit.js”);
返回true;
}
int main(int argc,字符**argv){
ReturnType ret=loadJsGit();

如果(!ret)不能,则需要初始化数组缓冲区分配器

使用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);

您需要初始化数组缓冲区分配器

使用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);

如果不知道您在这里尝试什么,或者不知道您如何运行它,或者不看到您的任何代码,那么很难说。这是一段很长的代码,它绝对不会有帮助(因为对于其他代码,我不会得到错误).但是你可以去。我认为这样的问题最好在V8支持小组中提出。你使用的是哪个版本的节点?等等,这个节点,还是一个客户端节点样的环境来做有趣的事情?(如果是后者…你在破坏浏览器JavaScript?那一定是什么。)如果你在V8中运行它,你的V8是最新的吗?它稳定吗?@minitech:不,它只是V8。它来自两周前的Git签出-刚刚跟踪和。很难说不知道你在这里尝试什么,如何尝试运行它,或者看不到任何代码。这是一段很长的代码,绝对没有帮助(因为对于其他代码,我没有得到错误)。但是你去吧。我认为这样的问题最好在V8支持小组中提出。你使用的是哪个版本的节点?等等,这个节点,还是一个客户端节点样的环境来做有趣的事情?(如果是后者…你正在破坏浏览器JavaScript?那会很有趣。)如果你在V8中运行它,你的V8是最新的吗?它稳定吗?@minitech:不,它只是V8。它是两周前从Git签出的-刚刚跟踪和。非常感谢,这很有效!:)你的答案几乎和我在邮件列表上得到的答案是同一时间的。:)是的,指南有点过时。:)非常感谢,这很有效!:)你真的应该记录这一点。你的答案几乎和我在邮件列表上得到的答案是同一时间的。:)是的,指南有点过时过时的。:)