C++ meets JS

Italian C++ MeetUp

24 October 2015, Rome

  • twitter.com/glmeocci
  • glmeocci@gmail.com

Me!

  • C++11/14 addicted

  • Js & web developer

  • #FP student (Scala, Elixir, Haskell)

 

I come from Florence!

 

 

 

I'm working in CommProve as

SW Engineer (BigData team)

  • Easy to integrate in any C++ application
  • Simple to teach (especially for non-programmers)
  • Very powerfull & productive programming language
  • There are a lot of well written/documented js libraries
  • ...

Why JavaScript?

  • Efficent (and quite easy) integration with C++11
  • Fast Property Access
  • Dynamic Machine Code Generation
  • Efficient Garbage Collection
  • OpenSource and wide adopted (Node.js for example)

Why Google V8?

Download the source code:

  • https://chromium.googlesource.com/v8/v8/+/master/docs/using_git.md

Compile:

  • https://chromium.googlesource.com/v8/v8/+/master/docs/building_with_gyp.md

 

  • Copy include & libs (look into out folder) where you want

 

check out V8 Hello World!

download & make

Rome V8 project

  • C++11
  • V8
  • ZeroMQ

Not production ready

Not tested!

Not completed!

Not documented :(

 

But quite easy to understand

Client

var socket = new zsocket("127.0.0.1", 9090);
socket.connect();

for (var i = 0; i < 10; i++)
{
    socket.send("test " + i);
    var reply = socket.recv();
    println(reply);
}

Server

var socket = new zsocket("*", 9090);
socket.bind();

for (var i = 0; i < 10; i++)
{
    var msg = socket.recv();
    println("Received: " + msg);
    socket.send("R: " + msg);
}

V8 Handles & Scope

rv8.h anatomy

RV8

RV8() construct & initialize

add_global_function(string, fun)

execute()

~RV8() release resources

RVObject

RVObject() constructor

add_function(string, fun)

invoke_jsfun(fname, ...)

adding global function

int main(int argc, char* argv[])
{
    RV8 rv8_engine;

    //add println function
    rv8_engine.add_global_function("println", [](js_callinfo_t args){
        HandleScope handle_scope(args.GetIsolate());
        bool first = true;
        for (int i = 0; i < args.Length(); i++)
        {
            if (first)
                first = false;
            else
                cout << " ";

            pretty_print(*args[i]);
        }

        cout << endl;
    });

...
    // execute the script
    rv8_engine.execute(script_fname);
}

using js_callinfo_t = const v8::FunctionCallbackInfo<v8::Value>&;

adding object function

class ZSocketTempl final : public RVObject<ZSocket>
{
public:
    ZSocketTempl(RV8& rv8_engine);
    ~ZSocketTempl() {
        for (auto e : v_zsocket) delete e;
    }

private:
    RV8& engine;
    std::vector<ZSocket*> v_zsocket;
};
ZSocketTempl::ZSocketTempl(RV8& rv8_engine)
: RVObject<ZSocket>{rv8_engine}, engine{rv8_engine}
{
    engine.add_global_function("zsocket", [this](js_callinfo_t args){
        // add object function here
        add_function("connect", [](js_callinfo_t args, ZSocket* obj){
            stringstream ip_connect;
            ip_connect << "tcp://" << obj->ip << ":" << obj->port;
            cerr << "connect: " <<  ip_connect.str() << endl;
            obj->socket = new zmq::socket_t{zmq_context, ZMQ_REQ};
            obj->socket->connect(ip_connect.str());
        }, c_obj);
    });
}

calling js from C++

rv8_engine.invoke_jsfun("exit_callback", "bye bye", 42);
template <typename ...Args>
bool invoke_jsfun(const std::string& function_name, Args ...args)
{
    HandleScope handle_scope(engine_isolate);
    Local<String> jf_name = rv::string(engine_isolate, function_name);
    Local<Value> jsfun;
    Local<Context> _context = Local<Context>::New(engine_isolate, context);
    if (
        !_context->Global()->Get(_context, jf_name).ToLocal(&jsfun)
        ||
        !jsfun->IsFunction()
    ) { return false; }

    const size_t args_len = sizeof...(args);
    Handle<Value> arr[args_len];

    Local<Function> fun = Local<Function>::Cast(jsfun);
    fill_parameter(arr, 0, std::forward<Args>(args)...);
    fun->Call(_context, _context->Global(), args_len, arr);

    return true;
}

Questions?

Made with Slides.com