Does V8 embedding have something like this, so not only a way to call
Javascript from C, but also a way to call C from Javacript?
This seems to be what I am looking for ... some questions:
1.) AlchemyDB is written in ANSI-C, what are the requirements for your
bindings (C++ at a minimum, any specifics on that)
2.) I just need one function wrapped, the function is called
"client()" and it can take between 1 and 6 arguments.
And on a long shot, do you know of any C programs that embedded V8 and
then the embedded v8 calls a C function via your bindings. This is
what I am trying to reproduce in AlchemyDB (the C function would be
"client()").
<huge snip>
...man-days embedding V8 and then using v8-juice to implement the JS func
"client" would take? (just ballpark: is it a day, a week, a month?)
What would be REAL helpful is if there was a hello-world for embedding
v8 in C
does vu8 fulfill all the requirements I wrote in my last reply to
Stephan?
Can you (briefly) compare and contrast vu8's strengths and weaknesses
compared to v8-juice (e.g. lightweight is GOOD for my use-case).
Do you have a simple hello-world example w/ build instructions that
works on generic linux OSes, so I can do a quick evaluation?
I think it would be pretty easy to convert your Lua intergration into
V8 intergration line by line without relying on any third party
libraries.
Let me show you a mapping between Lua and V8 APIs
Lua:
// Lua API manipulates with stack. Anything on the stack will be kept
alive when GC happens.
int code = luaL_dostring(L, s);
if (code) {
// error is on top of the stack
const char *error_message = lua_tostring(L, -1);
report(error_message);
} else {
// return values are on top of the stack
}
V8:
// V8 does not have implicit stack. Instead API is all about Handles.
// Handles keep what they reference alive during GC.
// There are two types of the Handles: Local and Persistent.
// Each Local handle is owned by a HandleScope --- when HandleScope
dies so do all Local handles it owns.
// In terms of Lua: creating HandleScope is like remembering height of
Lua stack, creating Local handle is like pushing
// value on the stack and destroying HandleScope is like poping
everything above remembered height.
v8::HandleScope handle_scope;
Local<String> v8_string = v8::String::New(s);
Local<Script> script = v8::Script::Compile(v8_string);
v8::TryCatch try_catch;
Local<Value> result = script->Run();
if (try_catch.HasCaught()) {
// exception is in try_catch.Exception()
v8::String::AsciiValue error_message(try_catch.Exception());
report(*error_message);
} else {
// returned value is in the result.
}
As you can see conversion is pretty much straighforward.
--
Vyacheslav Egorov
vu8 is header only with nothing to link against, and should be
equivalent to hand-writing the code yourself as it uses template
meta-programming heavily to optimise (the same as v8-juice). The code
size of vu8 is much smaller than v8-juice in spite of it performing
the same tasks as it re-uses components from boost. Particularly boost
fusion, boost mpl and boost preprocessor were very helpful. v8-juice
replicates many features from boost.mpl and boost.fusion, which removes
the dependency on boost but increases the size of the source code.
Additionally vu8 will take advantage of C++0x variadic template
arguments, r-value references and perfect forwarding. These improve
compile times amongst other things.
> i have no experience with vu8. i only found out about it via the above
> post. From a brief glance, it seems provide more or less the same
> features as v8-juice, but vu8 uses of function-pointer-style template
> args to make the API more readable (if i had only known how to do that
> two years ago...).
I could commit the code to v8-juice to show you if you want. Function
pointer templates can be passed easily using any type-based template
parameters, but converting this function pointer into a template
argument that accepts a member-function pointer requires either C++0x or
some pre-processor programming. The only tricky bit really is:
template <class T, [dependant on T] Q>
[dependant on T] can be worked out using a meta-program on T to
determine the type of template parameter Q is (i.e. what kind of
member function pointer it is). The trouble is without C++0x variadic
template parameters you need one copy of the meta-function to
determine [dependant] for each N where N is the number of arguments
in the member function prototype. You'd need to use preprocessor
programming to do this without C++0x variadic template arguments, and
with them the problem is trivial.
If you look at detail/Proto.hpp and Class.hpp in vu8 you'll probably
get it right away.
--
+44 (0) 7974 159 643 | ja...@chilon.net | http://chilon.net
From shell.cc:
v8::Handle<v8::Value> Version(const v8::Arguments& args) {
return v8::String::New(v8::V8::GetVersion());
}
// Create a template for the global object.
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
// Bind the 'version' function
global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
O.
>
>
> On Jan 18, 7:59 am, Stephan Beal <sgb...@googlemail.com> wrote:
>> On Tue, Jan 18, 2011 at 4:35 PM, Jak Sprats <jakspr...@gmail.com> wrote:
>> > <huge snip>
>>
>> ...man-days embedding V8 and then using v8-juice to implement the JS func
>>
>> > "client" would take? (just ballpark: is it a day, a week, a month?)
>>
>> i couldn't even guess. AlchemyDB and reddit are both foreign words to me, so
>> i couldn't even venture a guess.
>>
>> > What would be REAL helpful is if there was a hello-world for embedding
>> > v8 in C
>>
>> There is a hello-world (the shell app) in the v8 source tree. Binding that
>> with C requires a C++ middle-man API which has functions the C code can call
>> (i.e. they use export "C"). Aside from that, there should be no magic
>> involved.
>>
>> If all you want to do is wrap a single function, an add-on library like
>> v8-juice or vu8 is way overkill. i'd start by taking a look at shell.cc in
>> the v8 source tree.
>>
>> --
>> ----- stephan bealhttp://wanderinghorse.net/home/stephan/
>
#include <vu8/Module.hpp>
void jsCall_client() {
...
}
void makeModule(v8::Handle<v8::Context> ctxt) {
vu8::Module module;
module.Set<void (), &jsCall_client>("js_name")
ctxt.Set(v8::String::New("mod_name"), module.NewInstance());
// now any v8 calls in this context can use mod_name.js_name
On Wed, Jan 19, 2011 at 07:07:09AM -0800, Jak Sprats wrote:
> Hi James,
>
> i am a big fan of boost, especially when it is present in lieu of
> someone writing-their-own-boost :)
>
> do you have any examples of a C++ program that has a single C function
> {in my case jsCall_client()} that can be called in javascript by
> calling "client()"
#include <vu8/Module.hpp>
void jsCall_client() {
...
}
void makeModule(v8::Handle<v8::Context> ctxt) {
vu8::Module module;
module.Set<void (), &jsCall_client>("js_name")
ctxt->Global()->Set(v8::String::New("mod_name"), module.NewInstance());
1) In Lua you have lua_CFunction :
typedef int (*lua_CFunction) (lua_State *L);
it gets arguments on the stack, pushes results on the stack and
returns number of results.
In V8 you have v8::InvocationCallback:
typedef Handle<Value> (*InvocationCallback)(const Arguments& args);
it gets Arguments object which provides access to arguments and returns result.
2) In Lua if you want to create function value from lua_CFunction foo you do
lua_pushcfunction(L, foo);
// function object is now on top of the stack
In V8 to create function from InvocationCallback foo you do:
Local<Function> f = FunctionTemplate::New(foo)->GetFunction();
3) To set global variable bar in Lua you push the value on the stack
and then call
lua_setglobal(L, "bar"); // pop value from the stack and assign it to
global called bar
In V8 you just do:
Context::GetCurrent()->Global()->Set(v8::String::New("bar"), val); //
where val is something you want to assign to global
4) In Lua lua_register(L, name, func) is just
lua_pushcfunction(L, func); // push function on the stack
lua_setglobal(L, name); // pop function from the stack and assign it
to global called name.
This translates to V8 as:
Context::GetCurrent()->Global()->Set(v8::String::New(name),
FunctionTemplate::New(func)->GetFunction());
// Concept of global object in V8/JavaScript is a bit more complicated
than in Lua so instead of using Context::GetCurrent()->Global() you
can access it in a different ways.
--
Vyacheslav Egorov
Is there a similarly simple mechanism to register JS functions to call
defined C functions.
This is the part I am not yet fully grasping on how to code it :)