0

V8 コンテキストにアタッチする関数 AttachToContext を持つクラス「V8BaseClass」を作成したいと考えています。このクラスでは、プロトタイプとインスタンス テンプレートを使用して仮想関数 AttachAdditionalMembers を呼び出し、後継クラスがメンバーを追加できるようにします。コードの主要部分は次のようになります。

void V8BaseClass::AttachToContext(v8::Handle<v8::Context> context)
{
    //working in this scope under this context.
    v8::Context::Scope scopedContext(context);

    //create a pointer to a class template
    v8::Handle<v8::FunctionTemplate> bs_templ = v8::FunctionTemplate::New();

    //assign the "bsInfo" name to the new class template (this is the name of the JS class not the name of the JS instance.)
    bs_templ->SetClassName(v8::String::New("bsInfo"));

    //access the class prototype template
    v8::Handle<v8::ObjectTemplate> bs_proto = bs_templ->PrototypeTemplate();

    //access the instance pointer of our new class template
    v8::Handle<v8::ObjectTemplate> bs_inst = bs_templ->InstanceTemplate();

    //set the internal fields of the class as we have the BsInfo class internally
    bs_inst->SetInternalFieldCount(1);

    //Attached the m_result var of the class with a result member in JS.
    bs_inst->SetAccessor(v8::String::New("result"), JSGetResult, JSSetResult);

    /* ==rg== just for testing reason... */
    std::vector<std::string> tempVec;
    tempVec.push_back("one");
    tempVec.push_back("two");
    bs_proto->Set("tempVec", cvv8::CastToJS(tempVec));// <== this is working fine.
    /* <<< ==rg== */

    //Call the inherited class method.
    AttachAdditionalMembers(bs_proto, bs_inst);//<== calling the virtual function

    //get the constructor function
    v8::Handle<v8::Function> bs_ctor = bs_templ->GetFunction();

    //get class instance
    m_obj = bs_ctor->NewInstance();

    //build the "bridge" between c++ and javascript by associating the bsInfo to `this` class.
    m_obj->SetInternalField(0, v8::External::New(this));

    //associates our internal field pointing to `this` with the "BsInfo" name inside the context
    //this enable usage of BsInfo inside this context without need to create a new one
    context->Global()->Set(v8::String::New("BsInfo"), m_obj);
}

後継クラスは次のようになります。

class V8Extend : public V8BaseClass
{
public: 
    std::vector<std::string>                    m_conversionTags;
    std::map<std::string, std::string>          m_scripts;
    std::map<std::string, std::string>          m_tokens;
    std::map<std::string, std::string>          m_urlTokens;

private:
    inline virtual void AttachAdditionalMembers(const v8::Handle<v8::ObjectTemplate>& proto, const v8::Handle<v8::ObjectTemplate>& inst)
    {
        //set test data:
        m_conversionTags.push_back("conversion1");
        m_conversionTags.push_back("conversion2");
        m_conversionTags.push_back("conversion3");
        m_scripts["script1"] = "This is script1!";
        m_scripts["script2"] = "This is script2!";
        m_scripts["script3"] = "This is script3!";
        m_tokens["T1"] = "Token1";
        m_tokens["T2"] = "Token2";
        m_urlTokens["UT1"] = "UT-1";
        m_urlTokens["UT2"] = "UT-2";
        //end of setting test data.

        proto->Set("conversionTags", cvv8::CastToJS(m_conversionTags));//<==throwing exception
        proto->Set("tokens", cvv8::CastToJS(m_tokens));
        proto->Set("scripts", cvv8::CastToJS(m_scripts));
        proto->Set("urlTokens", cvv8::CastToJS(m_urlTokens));
    };
};

この呼び出しは、基本クラスから呼び出されたときに正常に機能し、後続クラスから呼び出されたときに失敗したのはなぜですか?

==編集==これが役立つ場合は、例外が呼び出されたときのコールスタックです:

ModuleManagementTest.exe!v8::internal::FixedArrayBase::length()  Line 2188 + 0xe bytes  C++  
ModuleManagementTest.exe!v8::internal::FixedArray::get(int index=3)  Line 1661 + 0x11 bytes C++  
ModuleManagementTest.exe!v8::internal::Context::global()  Line 324 + 0xf bytes  C++  
ModuleManagementTest.exe!v8::internal::Context::global_context()  Line 62 + 0xa bytes   C++  
ModuleManagementTest.exe!v8::internal::Heap::AllocateJSArray(v8::internal::ElementsKind elements_kind=FAST_ELEMENTS, v8::internal::PretenureFlag pretenure=NOT_TENURED) Line   4412 + 0x1a bytes    C++  
ModuleManagementTest.exe!v8::internal::Heap::AllocateJSArrayAndStorage(v8::internal::ElementsKind elements_kind=FAST_ELEMENTS, int length=0, int capacity=3, v8::internal::ArrayStorageAllocationMode mode=INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, v8::internal::PretenureFlag pretenure=NOT_TENURED)  Line 3838 + 0x13 bytes  C++  
ModuleManagementTest.exe!v8::internal::Factory::NewJSArray(int capacity=3, v8::internal::ElementsKind elements_kind=FAST_ELEMENTS, v8::internal::PretenureFlag pretenure=NOT_TENURED)  Line 958 + 0x62 bytes    C++  
ModuleManagementTest.exe!v8::Array::New(int length=3)  Line 5012    C++  
ModuleManagementTest.exe!cvv8::NativeToJS_list<std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >::operator()(const std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > & li=[3]("conversion1","conversion2","conversion3"))  Line 1453 + 0xe bytes    C++  
ModuleManagementTest.exe!cvv8::CastToJS<std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >(const std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > & v=[3]("conversion1","conversion2","conversion3"))  Line 444 + 0x14 bytes    C++  
ModuleManagementTest.exe!V8Extend::AttachAdditionalMembers(const v8::Handle<v8::ObjectTemplate> & proto={...}, const v8::Handle<v8::ObjectTemplate> & inst={...})  Line 43 + 0x2c bytes C++  

v8::internal::FixedArray::get(int index=3)アサート行の関数で失敗しますASSERT(index >= 0 && index < this->length());

==編集 2== V8BaseClass に「AttachAdditionalMembers」関数を実装しようとしましたが、同じ問題が発生しましたが、関数を変更するとうまくいきませんでしvirtualた。
何か案は???

4

0 に答える 0