This article is part 2, you might want to read Part 1 first.
v8 Types
The V8 engine provides implementations of many standard types to allow inter-operatability with JavaScript. The following types are present:
-
Primitives
-
String
-
Boolean
-
Number
-
Integer
-
Int32
-
Uint32
-
-
Object
-
Object
-
Array
-
Function
-
Besides this there are a few types which aren’t directly exposed to JavaScript such as FunctionTemplate, or External.
C++ to JavaScript
All of the primitive types have a New() method which usually takes the C++ equivalent type and returns a wrapped type which you can put anywhere a Value is expected. In addition certain types like String have additional New overloads, which can be seen in the V8 documentation.
For example in Part 1, we converted a char array to v8::String using String::New( const char *, int length ).
JavaScript to C++
To convert v8 types to the C++ types, it is recommended to first check if the conversion is possible and then convert it. If you receive a v8::Value ( or any subclass ), they have:
-
IsArray()
-
IsBoolean()
-
IsDate()
-
IsExternal()
-
IsFalse()
-
IsFunction()
-
IsInt32()
-
IsNull()
-
IsNumber()
-
IsObject()
-
IsString()
-
IsTrue()
-
IsUint32()
-
IsUndefined()
after which you can call:
-
bool BooleanValue()
-
int32_t Int32Value()
-
int64_t IntegerValue()
-
double NumberValue()
-
Local<Boolean> ToBoolean()
-
Local<String> ToString()
-
Local<Int32> ToInt32()
-
Local<Integer> ToInteger()
-
Local<Number> ToNumber()
-
Local<Object> ToObject()
-
Local<Uint32> ToUint32()
In addition each of these primitive types have a Value() method which returns the appropriate C\++ type.
// obj is some type ( Handle<Value> ) received from JavaScript
// see handling arguments below.
if( obj->IsBoolean() ) {
// convert it
bool doOperation = obj->IsTrue();
// OR
bool doOperation = obj->ToBoolean()->Value();
}
Strings
v8 has two kinds of Strings, AsciiValue and Utf8Value. UTF-8 encoded strings are useful for user-displayed strings and places where non-ASCII characters are possible, while you will generally use AsciiValue when you want to use the string as an option or internal library use in your C/C++ library ( ie. passing as parameters etc. ).
To convert a v8::String to the right type, just pass the appropriate constructor the String object.
String::AsciiValue name(String::New("foo"));
Both AsciiValue and Utf8Value overload the * operator so that dereferencing them gets the value of the string as a char * or const char *.
std::cerr << "Name is " << *name;
Objects and Arrays
Array`s are just `v8::Object`s with integer based access and a `Length() method. Object can have any wrapped Value as a key. It provides the following operations with regard to accessing keys and values:
-
bool Has( Handle<String> )
-
bool Has( uint32_t )
-
Local<Value> Get( Handle<Value> key )
-
Local<Value> Get( uint32_t key )
-
void Set( Handle<Value> key, Handle<Value> value, PropertyAttribute = None )
-
void Set( uint32_t index, Handle<Value> value )
The first Set() accepts the PropertyAttribute to set advanced attributes of the property such as whether it is enumerated, read-only or deletable.
Object also has additional properties, to allow callbacks on accessors, named properties, to support prototypal inheritance and for internal v8 details not exposed to JavaScript, such as memory management. Some of which will be covered in this document.
Handling arguments
With all the type related information out of the way, we can get back to writing useful code. Part 1 covered only how to get functions to be invoked, but functions without arguments are pretty useless. So now I’ll explain how we can extract arguments in our C\++ code and use them.
Node utilities
Cover macros in node.h and simple library based on converter.h and REQ_* from http://github.com/grumdrig/node-sqlite/blob/master/sqlite3_bindings.cc
Time for Objects
Wrapping C++ objects, static methods, unwrapping