Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    xiolec
    @xiolec
    Is there anyway to turn a pre-existing object into a class and import a reference to that class? Like if I wanted the global object to have a base class. So the class
    methods could be called from the global object as though it was one of the classes
    or what would the best way of having the global object have access to those class methods?
    Pavel Medvedev
    @pmed
    I think there is no such way. You can create a v8pp::module from existing v8::ObjectTemplate and add into this v8pp::module C++ functions, objects and v8pp::class_es. And then use that object template in v8::Context::New:
    using namespace v8;
    Local<ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate);
    
    v8pp::module global(isolate, global_template);
    v8pp::class_<Some> some_class;
    ...
    global.set("aa", 123);
    global.set('rand", &rand);
    global.set("MyClass", some_class);
    
    Local<Context> context = v8::Context::New(isolate, global_template);
    Either it would be better to have a v8pp::context constructor overload with v8pp::module to use as the global object template.
    xiolec
    @xiolec

    hmm, well I ended up just adding some static functions to create the class object for the global object then set it to an internal pointer and unwrapped it from the contexts global object on the call.

    I was looking at the v8pp class functions and I was wondering if there would be a way for the global object to be recognized as that class then automatically unwrapped when those class functions were called. I wasn't exactly sure what was being done for an object to be recognized as a v8pp class.

    hia3
    @hia3
    Hello there! I'm wondering what would happen if a native method wrapped by v8pp will throw C++ exception? I'm assuming it is not allowed for C++ exception to propagate through v8. I was expecting std::current_exception (C++11) to be used in v8pp to store the exception to rethrow it later (outside of v8).
    Pavel Medvedev
    @pmed

    Hi @hia3! All wrapped native functions (both free and class members) are being called from inside of try .. catch block (see forward_function).

    Such a catched std::exception (as well all its derived types) would be converted to v8::Exception and set as the result value for the V8 function callback.

    Other C++ exception types are not supported and the program behaviour is undefined, since I don't know how V8 handles exceptions thrown out of a function callback.

    hia3
    @hia3
    @pmed Thanks for your answer! But ideally it should catch (...), store std::current_exception, ask v8 to interrupt the script (idk if it is possible in v8) returning to calling code and rethrow stored exception. Because there are exceptions like boost::thread_interrupted and boost::coroutines::detail::forced_unwind that do not inherint from std::exception and should not be ignored.
    I mean, catch (...) additionaly to catch (std::exception).
    hia3
    @hia3
    And, btw, imagine native function is throwing somethin like boost::exception (inherints from std::exception) ( http://www.boost.org/doc/libs/1_59_0/libs/exception/doc/motivation.html ) with a lot of properties attached. It is ok to use what() in forward_function if javascript actually catches this exception. But if javascript does not catch the exception, then C++ code at upper layer better get that original boost::exception. What do you think?
    Pavel Medvedev
    @pmed

    Well this try .. catch block in forward_function is a simple trap for unhandled exceptions which may be thrown from a wrapped C++ function. I'm not sure how to deal with exceptions correctly in such situations because a C++ exception may occur in the middle of V8 code flow:

    some V8 code ...
              our wrapped C++ function
    ... rest of V8 code

    The current solution with v8::Exception return allows to use try catch block in JavaScript and to resume the JS script execution there.

    Maybe I should add catch(...) block into the forward_function and return some v8::Exception("uknown") value from that catch.

    But in general, I think exception handling should be in your code, since v8pp library knows nothing about your application. In this situation you can use try catch block inside of the wrapped C++ function to manage all exceptional cases you need.

    xiolec
    @xiolec
    I was looking into exception handling a few days ago. For try catch to be properly wrapped it should grab the object that was thrown in the c++ try catch and then throw that to javascript. I.e. if I wanted to have a dom_exception class that has a member variable "code" wrapped in javascript. That would allow javascript to know which error code happened. I could just throw that in c++ then v8pp should catch it and unwrap the object.
    Haven't really tried to implement it yet though. I did change how pointers are handled when they are returned and are nullptrs though. Now in my code they return null instead of undefined. As that should be the expected return when a function fails. Instead of when it just doesn't exist.
    xiolec
    @xiolec
    the only options for doing what hia3 wants to do is to find out if there is a way to save the position of execution in the v8 script. then exit out of the stack with the position saved. Then resume after everything is running again. Other than that you would have to send an extra function to v8pp in order for it to call that function to handle the error.
    second option would be possible if you had a static object that holds the information on the type of error then checks to see how that error is handled and calls a function based on that error, but doing that is still tricky. So, best option is to ask around to see if code execution can be saved and resumed.
    xiolec
    @xiolec

    Do you know how to set constants on the class_ so that the value can be accessed without first creating a instance of the object

    ex. I've created v8pp::class_<c++_node_class> node_class and the class is on the context with context.set("Node", node_class) I want to be able to set a value on that class say .ELEMENT_TYPE = 0, but I want to be able to access that class on the main Object. So that Node.ELEMENT_TYPE would return 0. without first having to have a make a node_class object.

    Pavel Medvedev
    @pmed
    There is a 'class_::set_const' and 'v8pp::module::set_const'
    try it like this: node_class.set_const("ELEMENT_TYPE", 0)
    xiolec
    @xiolec
    I tried that but it still doesn't work
    I.e. with that Node.ELEMENT_TYPE still wont come up. it would come up as undefined.
    xiolec
    @xiolec
    Only thing I was thinking is that it could be because the object that is set on the context is just the function for the js_function_template.
    xiolec
    @xiolec
    Okay so I figured out that this actually works -- Node.prototype.ELEMENT_TYPE
    but I need to be able to access it directly without it being on the prototype
    xiolec
    @xiolec
    Okay lol I figured out how to get it to work. It had to be set directly on the js_function_template. Instead of the class_function_template
    template<typename Value>
        class_& set_js_const(char const* name, Value value)
        {
            v8::HandleScope scope(isolate());
            class_singleton_.js_function_template()->Set(v8pp::to_v8(isolate(), name),
                to_v8(isolate(), value), v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
            return *this;
        }
    and also not being set on the prototype
    xiolec
    @xiolec
    Update: it only works for the base class that its set on. So it doesn't work for inherited classes. I.e. classes that are inherited from Node wont have the const values
    though looking into what I want to do a little bit more that should be exactly how it should be
    Pavel Medvedev
    @pmed
    It's strange. I thought the inheritance in JS via prototype works this way
    Bu I never used this with derived classes
    xiolec
    @xiolec
    I guess since that gets set directly on the function instead of the prototype that it doesn't actually get inherited so It gives the objects to function itself
    xiolec
    @xiolec
    You wouldn't happen to know how to call a function within the scope of an object would you? say -- callingobject.func() = function(){this;} -- 'this' would result in the callingobject and not the global object. like I could call it from javascript with callingobject.func(); which would work fine, but if I have the function saved in c++ code and call the function it would result in the 'this' = global object.
    wait is that what the rev value on v8::function.call is for?
    *recv
    Pavel Medvedev
    @pmed
    yes, recv it is. there is also handy v8pp::call_v8() that allows to call a V8::Function with C++ arguments, converting them to V8::Values:
    v8::Local<v8::Function> fun;
    v8::Local<v8::Object> fun_this;
    
    v8::Local<v8::Value> ret = v8pp::call_v8(isolate, fun, fun_this, 11, "str", you_wrapped_cpp_object);
    This message was deleted
    xiolec
    @xiolec
    do you know how to override the in function on c++ objects
    var enumeratedArray = new Array();
            for (var n in object)
                enumeratedArray.push(n);
    So I want to be able to override "in" so that i can send the values that I want back
    Pavel Medvedev
    @pmed
    I suppose you need to have a custom keys function exposed from your wrapped C++ class. But I never tried this though.
    xiolec
    @xiolec
    nope no luck with that. I'm trying to implement the interceptors right now. Hopefully the enum interceptor is what I want
    xiolec
    @xiolec
    okay I got interceptors to work and it looks like that solves the problem
    xiolec
    @xiolec
    so interceptors seem to only work fully when on the js_function_template, but that doesn't hold the class object. What is the purpose of having both of the function templates? Would it be possible if I wanted to combine them into one? are there any problems that I would encounter?
    xiolec
    @xiolec
    okay I added a objecttemplate to the class_ and applied the interceptors to that. Everything is almost working. Though I also disabled the js_function... just to see what it would do... so far nothing. Was there a purpose for the js_function?
    Pavel Medvedev
    @pmed
    I used it as a well known way to wrap C++objects: http://create.tpsitulsa.com/blog/2009/01/29/v8-objects/
    xiolec
    @xiolec
    oh okay so it's just used for a constructor
    xiolec
    @xiolec
    so if I'm understanding it correctly. The function constructor gets called everytime a new instance of that function is created. So you need to let the function know if it's wrapping or creating a new object then wrapping.
    Do you know what happens with inherited constructors? are they just ignored?
    xiolec
    @xiolec

    so i changed the class function to this

    v8::Local<v8::FunctionTemplate> func = v8::FunctionTemplate::New(isolate_,//);
            //v8::Local<v8::FunctionTemplate> js_func = v8::FunctionTemplate::New(isolate_,
                [](v8::FunctionCallbackInfo<v8::Value> const& args)
                {
                    v8::Isolate* isolate = args.GetIsolate();
                    try
                    {
                        return args.GetReturnValue().Set(instance(isolate).wrap_object(args));
                    }
                    catch (std::exception const& ex)
                    {
                        args.GetReturnValue().Set(throw_ex(isolate, ex.what()));
                    }
                });

    setting the constructor on the class_function_template. then I'm also creating an object template after that

    func->InstanceTemplate()->SetInternalFieldCount(2);
            v8::Local<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate_, class_function_template());
            obj_temp_.Reset(isolate_, obj);

    and in the wrap function I changed it to

    v8::EscapableHandleScope scope(isolate_);
            v8::Local<v8::Object> obj = object_template()->NewInstance();
                //class_function_template()->GetFunction()->NewInstance();
            obj->SetAlignedPointerInInternalField(0, object);
            obj->SetAlignedPointerInInternalField(1, this);

    creating the new instance of the object template appears to not call the constr. I tested it out and so far I don't see any problems with this. Is there anything that you can think of that will go wrong?

    xiolec
    @xiolec
    and i just commented out the js_function to disable it