Click here to Skip to main content
Email Password   helpLost your password?

Introduction

Who never wondered how virtual machines work? But, better than creating your own virtual machine, what if you can use one done by a big company focusing on improving the speed to the VM? In this article, I'll introduce how to use the V8 in your application, which is Google's open source JavaScript engine inside Chrome - Google’s new browser.

Background

This code uses the V8 as an embedded library to execute JavaScript code. To get the source of the library and more information, go to the V8 developer page. To effectively use the V8 library, you need to know C/C++ and JavaScript.

Using the Code

Let's see what is inside the demo. The demo shows:

First, let's understand how to initialize the API. Look at this simple example of embedded V8 on C++:

#include <v8.h> 
using namespace v8;
int main(int argc, char* argv[]) {
  // Create a stack-allocated handle scope. 
  HandleScope handle_scope;
  // Create a new context. 
  Handle<Context> context = Context::New();
  // Enter the created context for compiling and 
  // running the hello world script.
  Context::Scope context_scope(context);
  // Create a string containing the JavaScript source code. 
  Handle<String> source = String::New("'Hello' + ', World!'");
  // Compile the source code. 
  Handle<Script> script = Script::Compile(source);
  // Run the script to get the result. 
  Handle<Value> result = script->Run();
  // Convert the result to an ASCII string and print it. 
  String::AsciiValue ascii(result);
  printf("%s\n", *ascii);
  return 0;
}

Well, but this doesn't explain how we can control variables and functions inside the script. OK, the script does something... but, we need to get this information somehow, and have customized functions to control specific behavior inside the script.

The Global Template

First, we need a global template to control our modifications:

v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();

This creates a new global template which manages our context and our customizations. This is important because in V8, each context is separated, and can have its own global template. In V8, a context is an execution environment that allows separate, unrelated, JavaScript applications to run in a single instance of V8.

Adding Customized Functions

After that, we can add a new function named "plus":

// plus function implementation - Add two numbers
v8::Handle<v8::Value> Plus(const v8::Arguments& args)
{ 
    unsigned int A = args[0]->Uint32Value();
    unsigned int B = args[1]->Uint32Value();
    return v8_uint32(A +  B);
} 
//...
//associates plus on script to the Plus function
global->Set(v8::String::New("plus"), v8::FunctionTemplate::New(Plus));

Customized functions need to receive const v8::Arguments& as a parameter and must return v8::Handle<v8::Value>. Using the global template pointer created before, we add the function to the template, and associates the name "plus" to the callback "Plus". Now, each time we use the "plus" function on our script, the function "Plus" will be called. The Plus function does just one thing: get the first and the second parameters and return the sum.

OK, now we can use a customized function in the JavaScript side:

plus(120,44);  

and we can use this function's result inside the script:

x = plus(1,2); 
if( x == 3){
   // do something important here!
}

Accessors - Variables Accessible Inside the Script!

Now, we can create functions... but wouldn't it be cooler if we can use something defined outside inside the script? Let's do it! The V8 have a thing called Accessor, and with it, we can associate a variable with a name and two Get / Set functions, which will be used by the V8 to access the variable when running the script.

global->SetAccessor(v8::String::New("x"), XGetter, XSetter);

This associates the name "x" with the "XGetter" and "XSetter" functions. The "XGetter" will be called by V8 each time the script needs the value of the "x" variable, and the "XSetter" will be called each time the script must update the value of "x". And now, the functions:

//the x variable!
int x;
//get the value of x variable inside javascript
static v8::Handle<v8::Value> XGetter( v8::Local<v8::String> name, 
                  const v8::AccessorInfo& info) {
  return  v8::Number::New(x);
}
//set the value of x variable inside javascript
static void XSetter( v8::Local<v8::String> name, 
       v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
  x = value->Int32Value();
}

In the XGetter, we only need to convert "x" to a number type value managed by V8. In the XSetter, we need to convert the value passed as parameter to an integer value. There is one function to each basic type (NumberValue for double, BooleanValue for bool, etc.)

Now, we can do the same again for string (char*):

//the username accessible on c++ and inside the script
char username[1024];
//get the value of username variable inside javascript
v8::Handle<v8::Value> userGetter(v8::Local<v8::String> name, 
           const v8::AccessorInfo& info) {
    return v8::String::New((char*)&username,strlen((char*)&username));
}
//set the value of username variable inside javascript
void userSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value,
    const v8::AccessorInfo& info) {
    v8::Local<v8::String> s = value->ToString();
    s->WriteAscii((char*)&username);
}

For the string, things changed a little. The "userGetter" creates a new V8 string in the same way the XGetter does, but the userSetter needs first to access the internal string buffer by using the ToString function. Then, using the pointer to the internal string object, we use the WriteAscii function to write its content to our buffer. Now, just add the accessor, and voila!

//create accessor for string username
global->SetAccessor(v8::String::New("user"),userGetter,userSetter); 

Printing

The "print" function is another customized function which catches all parameters and prints them using the "printf" function. As we have done before with the "plus" function, we register our new function on the global template:

//associates print on script to the Print function
global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print)); 

"print" implementation

// The callback that is invoked by v8 whenever the JavaScript 'print'
// function is called. Prints its arguments on stdout separated by
// spaces and ending with a newline.
v8::Handle<v8::Value> Print(const v8::Arguments& args) {
    bool first = true;
    for (int i = 0; i < args.Length(); i++)
    {
        v8::HandleScope handle_scope;
        if (first)
        {
            first = false;
        }
        else
        {
            printf(" ");
        }
        //convert the args[i] type to normal char* string
        v8::String::AsciiValue str(args[i]);
        printf("%s", *str);
    }
    printf("\n");
    //returning Undefined is the same as returning void...
    return v8::Undefined();
}

For each parameter, the v8::String::AsciiValue object is constructed to create a char* representation of the passed value. With it, we can convert other types to their string representation and print them!

Sample JavaScript

Inside the demo program, we have this sample JavaScript to use what we have created so far:

print("begin script");
print(script executed by  + user);
if ( user == "John Doe"){
    print("\tuser name is invalid. Changing name to Chuck Norris");
    user = "Chuck Norris";
}
print("123 plus 27 = " + plus(123,27));
x = plus(3456789,6543211);
print("end script");

This script uses the "x" variable, the "user" variable, and the "plus" and "print" functions.

Accessors with C++ Objects!

v8_demo_object.JPG

Preparing the Environment for our Class

Now, how to map a class to the JavaScript using C++? First, the sample class:

//Sample class mapped to v8
class Point 
{ 
public: 
    //constructor
    Point(int x, int y):x_(x),y_(y){}

    //internal class functions
    //just increment x_
    void Function_A(){++x_;    }

    //increment x_ by the amount
    void Function_B(int vlr){x_+=vlr;}

    //variables
    int x_; 
};

For this class to be fully on JavaScript, we need to map both the functions and internal variable. The first step is to map a class template on our context:

Handle<FunctionTemplate> point_templ = FunctionTemplate::New();
point_templ->SetClassName(String::New("Point"));

We create a "function" template, but this can be seen as a class. This template will have the "Point" name for later usage (like create new instances of it inside the test script).

Then. we access the prototype class template to add built-in methods for our class:

Handle<ObjectTemplate> point_proto = point_templ->PrototypeTemplate();
point_proto->Set("method_a", FunctionTemplate::New(PointMethod_A));
point_proto->Set("method_b", FunctionTemplate::New(PointMethod_B));

After this, the class "knows" that it has two methods and callbacks. But, this is still in the prototype, we can't use it without accessing an instance of the class.

Handle<ObjectTemplate> point_inst = point_templ->InstanceTemplate();
point_inst->SetInternalFieldCount(1);

The SetInternalFieldCount function creates space for the C++ class pointer (will see this later).

Now, we have the class instance and can add accessors for the internal variable:

point_inst->SetAccessor(String::New("x"), GetPointX, SetPointX);

Then, we have the "ground" prepared... throw the seed:

Point* p = new Point(0, 0);

The new class is created, but can only be accessed in C++. To access it, we need:

Handle<Function> point_ctor = point_templ->GetFunction();
Local<Object> obj = point_ctor->NewInstance();
obj->SetInternalField(0, External::New(p));

Well, GetFunction returns the point constructor (on the JavaScript "side"), and with it, we can create a new instance using NewInstance. Then, we set our internal field (which we have created "space" for with SetInternalFieldCount) with the class pointer. With that, the JavaScript will have access to the object through the pointer.

Only one step is missing. We only have a class template and instance, but no name to access it from the JavaScript:

context->Global()->Set(String::New("point"), obj);

This last step links the "point" name to the instance obj. With these steps, we just emulate the creation of class Point with the name point in our script (before loading or running it!).

Accessing a Class Method Inside the JavaScript

OK, but this doesn't explain how we can access Function_A inside the Point class...

Let's look at the PointMethod_A callback:

Handle<Value> PointMethod_A(const Arguments& args)
{
    Local<Object> self = args.Holder();
    Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
    void* ptr = wrap->Value();
    static_cast<Point*>(ptr)->Function_A();
    return Integer::New(static_cast<Point*>(ptr)->x_);
}

Like a normal accessor, we must handle the arguments. But, to have access to our class, we must get the class pointer from the internal field (first one). After mapping the internal field to "wrap", we get the class pointer by retrieving its "value". Now, it's a matter of cast...

Now, we have the class pointer for the "point" class being used (which called method_a, which called the callback PointMethod_A).

The sample v8_embedded_demo_with_object.zip implements all these steps.

I hope this helps, and if something is wrong or unclear, please don't hesitate to contact.

Points of Interest

Before trying to use the V8 library, I've tried to use Lua as an embedded scripting language to support easy configuration and changes by the user. I got amazed by V8 as it's faster and easier to use than Lua to implement scripting functionality in my own software. I hope this article help others in this task.

Look also for Google's documentation on the V8 library!

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralIs it possible to embed google v8 js virtual machine (only) into my application?
jjshean
7:56 6 Feb '10  
I need to embed JS virtual machin into my code, just VM without any compilators. Is it possible to extract it from google v8 source and embed into my application (theoretically)? thanks
GeneralProblems creating a customized function (like the plus example in the article)
Phil. Roy
16:40 31 Aug '09  
I tried to follow the instructions from this article to implement a customized function, but failed (although I did succeed in exposing my C++ objects into javascript, thanks to this article).

Here's my code:

Handle<ObjectTemplate> global;

Handle<Value> JSAlert(const Arguments& args)
{
Handle<Value> result;
String::AsciiValue ascii0(args[0]);
MessageBox(NULL, *ascii0, "Javascript message", MB_OK);
return result;
}

void InitJavascriptGlobal()
{
if (global.IsEmpty())
{
global = v8::ObjectTemplate::New();
global->Set(String::New("alert"), FunctionTemplate::New(JSAlert));
}
}

Called once in the main after the creation of the context:

int _tmain(int argc, _TCHAR* argv[])
{
HandleScope handle_scope;
Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
InitJavascriptGlobal();
...
}

Result:

ExecuteString compileRed faced: Uncaught ReferenceError: alert is not defined Confused

Any advice on how to get that fixed would be welcome... Cool
GeneralRe: Problems creating a customized function (like the plus example in the article)
GabrielWF
15:03 24 Sep '09  
Hi,
sorry about my delay to answer your question. You need to remove the check:
"if (global.IsEmpty())"

This is not good as the object is not really initialized and could have "default" information which prevents your "alert" function to be initialized inside it.

Also take a look in the v8_embedded_demo functions and use it as a "template" to check if you forgot something. I think you're looking for this:

#include "stdafx.h"
#include <v8.h>
#include <string.h>

v8::Handle<v8::ObjectTemplate> global;
v8::HandleScope handle_scope;
v8::Handle<v8::Context> context;

Handle<Value> JSAlert(const Arguments& args)
{
String::AsciiValue ascii0(args[0]);
MessageBox(NULL, *ascii0, "Javascript message", MB_OK);
return v8::Undefined();
}

// Executes a string within the current v8 context.
bool ExecuteString(v8::Handle<v8::String> source,v8::Handle<v8::String> name) {
//access global context within this scope
v8::Context::Scope context_scope(context);
//exception handler
v8::TryCatch try_catch;
//compile script to binary code - JIT
v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
bool print_result = true;

//check if we got problems on compilation
if (script.IsEmpty()) {

// Print errors that happened during compilation.
v8::String::AsciiValue error(try_catch.Exception());
printf("%s\n", *error);
return false;
}
else
{
//no errors , let's continue
v8::Handle<v8::Value> result = script->Run();

//check if execution ended with errors
if(result.IsEmpty())
{
// Print errors that happened during execution.
v8::String::AsciiValue error(try_catch.Exception());
printf("%s\n", *error);
return false;
}
else
{
if (print_result && !result->IsUndefined())
{
// If all went well and the result wasn't undefined then print
// the returned value.
v8::String::AsciiValue str(result);
printf("script result [%s]\n", *str);
}
return true;
}
}
}

int _tmain(int argc, _TCHAR* argv[])
{
char *script = "alert(\"message from my script\");";

char *script_name = "internal_script";
//convert the string with the script to a v8 string
v8::Handle<v8::String> source = v8::String::New(script, strlen(script));

//each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
v8::Handle<v8::String> name = v8::String::New(script_name,strlen(script_name));

// Create a template for the global object.
global = v8::ObjectTemplate::New();

//associates "plus" on script to the Plus function
global->Set(v8::String::New("alert"), v8::FunctionTemplate::New(JSAlert));

//create context for the script
context = v8::Context::New(NULL, global);

//simple javascritp to test
ExecuteString(source,name);

return 0;
}




best regards,
Gabriel

Gabrielwf

GeneralGood article
Gavriloaie Andrei
2:11 10 Jun '09  
Excellent article. I have some questions though...

You exemplified creating a point instance and expose it to the JS. Can you give us an example where we instantiate the Point from JS?

I mean, being able to execute the following script:

var p=new Point();
p.x=100;
p.y=101;


Thanks

RFC1925

With sufficient thrust, pigs
fly just fine. However, this
is not necessarily a good
idea. It is hard to be sure
where they are going to land,
and it could be dangerous
sitting under them as they fly
overhead.

GeneralRe: Good article
GabrielWF
11:41 10 Jun '09  
Thanks! Big Grin
I've tried without success to create one example with a point instance instantiated only in the script. Cry

There's a gap I can't figure out:
if I don't use the SetInternalField function (which needs an object), then my call to GetInternalField(0) will fail and this is the only way I currently know to access the object on the c side. (I've tried a lot of different methods but always got trash )

Inside test-api.cc (v8 library source) there's a lot of examples and one may do what you need:
(line 517)
THREADED_TEST(FunctionTemplate) {
v8::HandleScope scope;
LocalContext env;
...

// Test constructor calls.
{
Local<v8::FunctionTemplate> fun_templ =
v8::FunctionTemplate::New(construct_call);
fun_templ->SetClassName(v8_str("funky"));
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
Local<Script> script = v8_compile("var s = new obj(); s.x");
CHECK_EQ(1, script->Run()->Int32Value());

Local<Value> result = v8_compile("(new obj()).toString()")->Run();
CHECK_EQ(v8_str("[object funky]"), result);
}
}

I have failed to mix this with my own code Sigh . Now I don't have time to dig further, but maybe in the future I'll look at this again. Please let me know if you have success at this and share any improovements Wink

best regards,

Gabrielwf

GeneralRe: Good article
Gavriloaie Andrei
11:48 10 Jun '09  
I figure it out in the end. And is working excellent. There is only one catch.... How do I detect that the point object is garbage collected? I need to do it because I need to free the C++ point pointer


#include <stdlib.h>
#include <v8.h>
using namespace v8;

#define FILE_NAME "/tmp/test.js"

Handle<Value> Print(const Arguments& args);
Handle<String> ReadFile(const char* name);
const char* ToCString(const String::Utf8Value& value);

Handle<Value> PointConstructor(const Arguments& args);
Handle<Value> PointGetX(Local<String> property, const AccessorInfo& info);
void PointSetX(Local<String> property, Local<Value> value, const AccessorInfo& info);
Handle<Value> PointGetY(Local<String> property, const AccessorInfo& info);
void PointSetY(Local<String> property, Local<Value> value, const AccessorInfo& info);

class Point {
private:
int _x;
int _y;
public:

Point(int x, int y) {
_x = x;
_y = y;
}

virtual ~Point() {

}

int X() {
return _x;
}

void X(int x) {
_x = x;
}

int Y() {
return _y;
}

void Y(int y) {
_y = y;
}
};

int main(int argc, char** argv) {
//1. create the maister scope
HandleScope handle_scope;

//2. Create the global objects template
Handle<ObjectTemplate> global = ObjectTemplate::New();

//3. Plug all the functions
global->Set(String::New("print"), FunctionTemplate::New(Print));

Handle<FunctionTemplate> point_templ = FunctionTemplate::New(PointConstructor);
point_templ->SetClassName(String::New("Point"));
Handle<ObjectTemplate> point_proto = point_templ->PrototypeTemplate();
point_proto->SetAccessor(String::New("x"), PointGetX, PointSetX);
point_proto->SetAccessor(String::New("y"), PointGetY, PointSetY);
Handle<ObjectTemplate> point_inst = point_templ->InstanceTemplate();
point_inst->SetInternalFieldCount(1);

global->Set(String::New("Point"), point_templ);


//4. Create a context
Handle<Context> context = Context::New(NULL, global);

//5. Enter the context
Context::Scope context_scope(context);

//6. Load the script
Handle<String> name = String::New(FILE_NAME);
Handle<String> source = ReadFile(FILE_NAME);

//7. Compile the script
Handle<Script> script = Script::Compile(source, name);

//8. Run the script
Handle<Value> result = script->Run();

return (EXIT_SUCCESS);
}

Handle<String> ReadFile(const char* name) {
FILE* file = fopen(name, "rb");
if (file == NULL) return Handle<String > ();

fseek(file, 0, SEEK_END);
int size = ftell(file);
rewind(file);

char* chars = new char[size + 1];
chars[size] = '\0';
for (int i = 0; i < size;) {
int read = fread(&chars[i], 1, size - i, file);
i += read;
}
fclose(file);
Handle<String> result = String::New(chars, size);
delete[] chars;
return result;
}

Handle<Value> Print(const Arguments& args) {
bool first = true;
for (int i = 0; i < args.Length(); i++) {
HandleScope handle_scope;
if (first) {
first = false;
} else {
printf(" ");
}
String::Utf8Value str(args[i]);
const char* cstr = ToCString(str);
printf("%s", cstr);
}
printf("\n");
fflush(stdout);
return Undefined();
}

const char* ToCString(const String::Utf8Value& value) {
return *value ? *value : "<string conversion failed>";
}

Handle<Value> PointConstructor(const Arguments& args) {
Local<Object> obj = args.This();

Point* p = new Point(args[0]->ToInteger()->Int32Value(),
args[1]->ToInteger()->Int32Value());
obj->SetInternalField(0, External::New(p));

return Undefined();
}

Handle<Value> PointGetX(Local<String> property, const AccessorInfo& info) {
Local<Object> self = info.This();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
int value = static_cast<Point*> (ptr)->X();
return Integer::New(value);
}

void PointSetX(Local<String> property, Local<Value> value, const AccessorInfo& info) {
Local<Object> self = info.This();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast<Point*> (ptr)->X(value->Int32Value());
}

Handle<Value> PointGetY(Local<String> property, const AccessorInfo& info) {
Local<Object> self = info.This();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
int value = static_cast<Point*> (ptr)->Y();
return Integer::New(value);
}

void PointSetY(Local<String> property, Local<Value> value, const AccessorInfo& info) {
Local<Object> self = info.This();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast<Point*> (ptr)->Y(value->Int32Value());
}



RFC1925

With sufficient thrust, pigs
fly just fine. However, this
is not necessarily a good
idea. It is hard to be sure
where they are going to land,
and it could be dangerous
sitting under them as they fly
overhead.

GeneralRe: Good article
GabrielWF
4:28 12 Jun '09  
Hi! Thanks for the code! Big Grin
The garbage collector of v8 is a Mark-and-Sweep. I've found this comment inside the code:

* After the handle scope of a local handle has been deleted the
* garbage collector will no longer track the object stored in the
* handle and may deallocate it. The behavior of accessing a handle
* for which the handle scope has been deleted is undefined.

I think that all objects are marked for deletion after you exit the scope inside the javascript. Also you can register a callback to be called before and after each major
garbage collection (inside V8 class):

/**
* Applications can register a callback function which is called
* before and after a major garbage collection. Allocations are not
* allowed in the callback function, you therefore cannot manipulate
* objects (set or delete properties for example) since it is possible
* such operations will result in the allocation of objects.
*/
typedef void (*GCCallback)();

/**
* Enables the host application to receive a notification before a
* major garbage colletion. Allocations are not allowed in the
* callback function, you therefore cannot manipulate objects (set
* or delete properties for example) since it is possible such
* operations will result in the allocation of objects.
*/
static void SetGlobalGCPrologueCallback(GCCallback);

/**
* Enables the host application to receive a notification after a
* major garbage collection. Allocations are not allowed in the
* callback function, you therefore cannot manipulate objects (set
* or delete properties for example) since it is possible such
* operations will result in the allocation of objects.
*/
static void SetGlobalGCEpilogueCallback(GCCallback);

/**
* Allows the host application to group objects together. If one
* object in the group is alive, all objects in the group are alive.
* After each garbage collection, object groups are removed. It is
* intended to be used in the before-garbage-collection callback
* function for istance to simulate DOM tree connections among JS
* wrapper objects.
*/
static void AddObjectToGroup(void* id, Persistent<Object> obj);

/**
* Adjusts the amount of registered external memory. Used to give
* V8 an indication of the amount of externally allocated memory
* that is kept alive by JavaScript objects. V8 uses this to decide
* when to perform global garbage collections. Registering
* externally allocated memory will trigger global garbage
* collections more often than otherwise in an attempt to garbage
* collect the JavaScript objects keeping the externally allocated
* memory alive.
*
* \param change_in_bytes the change in externally allocated memory
* that is kept alive by JavaScript objects.
* \returns the adjusted value.
*/
static int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes);

The Heap object can invoke the garbage collector:

// Performs garbage collection operation.
// Returns whether required_space bytes are available after the collection.
static bool CollectGarbage(int required_space, AllocationSpace space);

I hope this helps. Wink
best regards,

Gabrielwf

GeneralNot faster than LuaJIT
saptor
10:23 30 Oct '08  
Don't get me wrong, V8 is awesome. It's really the first fast Javascript VM that is very nicely separated from anything browser related which makes it great for embedding. It even comes with a Visual Studio project for building it and it builds 100% clean on all the platforms.

In most tests however, LuaJIT (with -O) is faster than V8. There are a few benchmarks where V8 wins but generally speaking LuaJIT is still faster, especially when it comes to larger scale general purpose programs (versus micro-sized benchmarks). Consider LuaJIT 2 should be out sometime (soon?) and it's much faster than the current LuaJIT.

Also, size-wise V8 is considerably larger than Lua which might be important when embedding.

Then there is the issue of making extensions to the engine (eg. wrapping native API's, etc). In Lua it's very straightforward and the code looks relatively nice. In V8 it's really awful with the mix of objects, templates, and various other oddities. Especially the String stuff can get very tedious. Makes for some not-so-pretty code. With that said, V8 is better than the other Javascript engines in this regard even though it's not as clean and easy as Lua.

Lua's documentation on the engine internals is better as well. That will hopefully change in time though.

Overall I really like the V8 engine and I have been working a lot with it. It has not replaced Lua for me though.
AnswerRe: Not faster than LuaJIT
GabrielWF
7:42 10 Nov '08  
Hi,
sorry on my delay to answer your email. I didn't know about LuaJIT and it looks like very interesting and could be faster / easier to use than V8. In fact V8 is not multiplatform enough for me and this is the main reason I'm using lua for some testing stuff on my work.
I'm not satisfied with the little benchmark I've done in this article and I'm building a more "fair" test based on the alioth-shootout benchmark (lua and javascript) to see V8 against Lua (and now LuaJIT too). I'll also check if I can use the LuaJIT on tru64 and hp-ux machines (if it works then I'll use LuaJIT instead of normal Lua on my work Big Grin ).
thanks!

Gabrielwf

GeneralRe: Not faster than LuaJIT
dbassett74
16:24 26 Oct '09  
Why are you even bringing up LauJIT? We're talking about JavaScript here...
GeneralThank you. Just what I was looking for.
dbbtvlzfpz
15:34 20 Oct '08  
Hi. This is just a quick note to express my thanks. I was searching for some good sample projects using v8, and this is perfect. I thank you for taking the time to make it and then to share it.
GeneralRe: Thank you. Just what I was looking for.
GabrielWF
16:39 20 Oct '08  
Thanks! Big Grin
nice to know that it was usefull! Big Grin

Gabrielwf

QuestionSobre C#
roberto lapolli
4:33 3 Oct '08  
Olá Gabriel.
Existe alguma forma de usar C# com o V8?
AnswerRe: Sobre C#
GabrielWF
4:49 3 Oct '08  
ola roberto,
tem sim, mas é necessário transformar a biblioteca v8 em dll para facilitar o processo. Eu nunca trabalhei com C# mas acho que ligacao com codigo c é algo mais facil em C# que em java.

// usando um metodo static da dll chamado "DoSomething"
void __stdcall DoSomething(HWND hWnd)

//usando:
public class InteropExample
{
[DllImport("MyDll.dll")] //v8.dll
static private extern void DoSomething(IntPtr hwnd);//mapeando metodo da dll

static public void DoSomething(Control control)
{
DoSomething(control.Handle);//usando metodo
}
}


http://www.codeguru.com/forum/showthread.php?t=357680
http://www.codeproject.com/KB/dotnet/Cdecl_CSharp_VB.aspx

Gabrielwf

GeneralWhere is the "e?
Member 3717457
9:06 9 Sep '08  
It does not compile anymore because I can't copy and paste Smile
JokeRe: Where is the "e?
GabrielWF
14:03 9 Sep '08  
the image for the source code was just a test, I changed back to the normal source-code-block Big Grin

Gabrielwf

Generalfix corrupted code
barto
3:17 9 Sep '08  
Hi, this is a nice article. Could you please fix the code in the article. Often there is &quot; instead of " and it seems some other things are missing (check the "source" in the first code)
AnswerRe: fix corrupted code
GabrielWF
5:26 9 Sep '08  
Hi,
sorry but I've tried to fix this quot; stuff everytime I update the article. It seems that the CodeProject wizard is having trouble with my post. I tried to use internet explorer, firefox and chrome and in all of them the source end with this ugly quot; istead of ".
Hope this will be fixed soon Wink

What is missing in the source? Can you point it? Thanks!

Gabrielwf

GeneralVery Nice!
Member 3717457
9:57 8 Sep '08  
Just don't forget to mention the Accessors(Dynamic) and Interceptors defined in http://code.google.com/apis/v8/embed.html   Smile
AnswerRe: Very Nice!
GabrielWF
14:14 8 Sep '08  
Hi,
thanks! I have added a demo of such construct and will explain it's usage soon. Smile

Gabrielwf

GeneralExcellent!
Iggy Natich
7:38 8 Sep '08  
Excellent article, though somewhat lacking. I'd like to see more about objects and at some performance comparison with lua and/or other scripting engines.
AnswerRe: Excellent!
GabrielWF
14:15 8 Sep '08  
Hi,
thanks! I have added a simple benchmark testing lua and v8. the lua script and v8 javascript do the same and you can write your own scripts to check the speed using this demo. I hope this helps Smile
(also I'll post the topic about object - dynamic variable access - but for now here comes an example of using it)

Gabrielwf

GeneralRe: Excellent!
Iggy Natich
11:27 9 Sep '08  
The results are impressive, but currently you do both compilation and execution in your test. Could you separate measurement of compilation time and execution time?
AnswerRe: Excellent!
GabrielWF
11:55 9 Sep '08  
Hi!
you're right! I did put the compile step inside the time measurement... lol. I know that lua do the compilation time at least one time on script execution, but I can't control it from outside (to force only one compilation). I'll put the v8 compilation outside the time measurement but this is adding 1 compilation step for lua (at least). thanks! Big Grin

Gabrielwf

GeneralRe: Excellent!
Iggy Natich
12:11 9 Sep '08  
You can try using precompiled lua script with luaL_loadfile.


Last Updated 5 Sep 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010