Update v8 specification.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13747 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Oliver Buchtala 2012-09-08 00:48:24 +00:00
commit 90bbc6430b

View file

@ -26,7 +26,7 @@ The generated code consists of the following blocks:
- `FUNCTION_WRAPPERS`: dynamically growing, on method declarations - `FUNCTION_WRAPPERS`: dynamically growing, on method declarations
- `INITIALIZER`: dynamically growing, aggregates everything (to be specified in more detail) - `INITIALIZER`: dynamically growing, aggregates everything (to be specified in more detail)
## INCLUDES ### INCLUDES
~~~~ ~~~~
#include <v8.h> #include <v8.h>
@ -36,7 +36,7 @@ The generated code consists of the following blocks:
`USER_DEFINED_INCLUDES`: a module property `USER_DEFINED_INCLUDES`: a module property
## CLASS_TEMPLATES ### CLASS_TEMPLATES
Static references to class templates which are (should be) read-only and can be reused. Static references to class templates which are (should be) read-only and can be reused.
@ -55,16 +55,28 @@ Notes:
There are different types of function wrappers: There are different types of function wrappers:
- Static Functions (global/namespace/class) - Global Functions (global/namespace/class)
- Constructors / Destructors - Constructors / Destructors
- Getters / Settters - Getters / Settters
- Member Functions - Member Functions
## Static Functions ### Global Functions
TODO ~~~~
v8::Handle<v8::Value> wrap_${NAME_MANGLED}(const v8::Arguments &args) {
v8::HandleScope scope;
v8::Handle<v8::Value> ret;
## Constructors ${LOCALS}
${MARSHAL_INPUT}
${ACTION}
${MARSHAL_OUTPUT}
return scope.Close(ret);
}
~~~~
### Constructors
~~~~ ~~~~
v8::Handle<v8::Value> ${NAME_MANGLED}_new(const v8::Arguments& args) { v8::Handle<v8::Value> ${NAME_MANGLED}_new(const v8::Arguments& args) {
@ -82,11 +94,11 @@ v8::Handle<v8::Value> ${NAME_MANGLED}_new(const v8::Arguments& args) {
- `MARSHAL_INPUT`: code is generated by applying input typemaps - `MARSHAL_INPUT`: code is generated by applying input typemaps
- `ACTION`: the C/C++ ctor to be executed - `ACTION`: the C/C++ ctor to be executed
## Destructors ### Destructors
TODO: I haven't found out yet how a descrtuctor can be registered TODO: I haven't found out yet how a descrtuctor can be registered
## Getters ### Getters
~~~~ ~~~~
v8::Handle<v8::Value> ${NAME_MANGLED}_get(v8::Local<v8::String> property, const v8::AccessorInfo& info) { v8::Handle<v8::Value> ${NAME_MANGLED}_get(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
@ -103,7 +115,7 @@ v8::Handle<v8::Value> ${NAME_MANGLED}_get(v8::Local<v8::String> property, const
- `LOCALS`: declare C return variable - `LOCALS`: declare C return variable
- `MARSHAL_OUTPUT`: code is generated by applying output typemaps - `MARSHAL_OUTPUT`: code is generated by applying output typemaps
## Setters ### Setters
~~~~ ~~~~
void ${NAME_MANGLED}_set(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { void ${NAME_MANGLED}_set(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
@ -116,7 +128,7 @@ void ${NAME_MANGLED}_set(v8::Local<v8::String> property, v8::Local<v8::Value> va
- `LOCALS`: declarations for input arguments - `LOCALS`: declarations for input arguments
- `MARSHAL_INPUT`: code is generated by applying input typemaps - `MARSHAL_INPUT`: code is generated by applying input typemaps
## Functions ### Functions
~~~~ ~~~~
v8::Handle<v8::Value> ${NAME_MANGLED}(const Arguments &args) { v8::Handle<v8::Value> ${NAME_MANGLED}(const Arguments &args) {
@ -132,12 +144,13 @@ v8::Handle<v8::Value> ${NAME_MANGLED}(const Arguments &args) {
- if the function does not have a return value, return v8::Undefined - if the function does not have a return value, return v8::Undefined
## Overloading ### Overloading
TODO: if a function or a ctor is overloaded, a dispatcher function TODO: if a function or a ctor is overloaded, a dispatcher function
must be generated which calls overloading wrappers depending on number must be generated which calls overloading wrappers depending on number
and type of input arguments. and type of input arguments.
## Initializer ## Initializer
~~~~ ~~~~
@ -160,7 +173,7 @@ void ${MODULE}_Initialize(v8::Handle<v8::Context> context)
} }
~~~~ ~~~~
## Namespaces ### Namespaces
Namespaces are objects without class templates. I.e., instances are created, Namespaces are objects without class templates. I.e., instances are created,
referenced locally, used as contexts for other registrations, and stored referenced locally, used as contexts for other registrations, and stored
@ -170,7 +183,7 @@ in the according parent contexts.
v8::Handle<v8::ObjectTemplate> ${NAME_MANGLED} = v8::ObjectTemplate::New(); v8::Handle<v8::ObjectTemplate> ${NAME_MANGLED} = v8::ObjectTemplate::New();
~~~~~ ~~~~~
## Create Class Template ### Class Templates
~~~~ ~~~~
SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NAME_MANGLED}_new); SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NAME_MANGLED}_new);
@ -178,26 +191,7 @@ SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NA
- `NAME_UNQUALIFIED`: the class name without context, i.e., namespaces - `NAME_UNQUALIFIED`: the class name without context, i.e., namespaces
## Add Member Function ### Inheritance
~~~~
SWIGV8_AddClassMethod(SWIGV8_$CLASSNAME, "$METHODNAME", $METHOD_WRAPPER);
~~~~
- `METHODNAME`: the name of the function as in C++
- `METHOD_WRAPPER`: the name of the generated wrapper function, which
should have the form `wrap_<mangled_classname>_<method_name>`
## Add Property
~~~~
SWIGV8_AddProperty(SWIGV8_$CLASSNAME, "$VARNAME", $GET_WRAPPER, $SET_WRAPPER);
~~~~
- `GET_WRAPPER`: the name of the generated wrapper for the property getter
- `SET_WRAPPER`: the name of the generated wrapper for property setter; optional (i.e., maybe `NULL`)
## Inheritance
~~~~ ~~~~
SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS}); SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS});
@ -205,13 +199,13 @@ SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS});
- Note: multiple inheritance is not possible; thus we will always take the first parent class - Note: multiple inheritance is not possible; thus we will always take the first parent class
## Registration ### Registration
The registration part consists of registering classes at contexts (i.e., global or namespace), The registration part consists of registering classes at contexts (i.e., global or namespace),
methods and properties at classes or contexts, and namespaces as objects at methods and properties at classes or contexts, and namespaces as objects at
parent contexts. parent contexts.
### Global Variable #### Global Variable
~~~~ ~~~~
${CONTEXT}->SetAccessor(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), ${GETTER}, ${SETTER}); ${CONTEXT}->SetAccessor(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), ${GETTER}, ${SETTER});
@ -220,9 +214,15 @@ ${CONTEXT}->SetAccessor(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), ${GETTER},
- `CONTEXT`: either global, or the according namespace template - `CONTEXT`: either global, or the according namespace template
- `${SETTER} = 0` for read-only variables - `${SETTER} = 0` for read-only variables
### Global Function #### Global Function
### Class ~~~~
${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), v8::FunctionTemplate::New(wrap_${NAME_QUALIFIED})->GetFunction());
~~~~
- `CONTEXT`: either global, or the according namespace template
#### Class
~~~~ ~~~~
${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGLED}->GetFunction())); ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGLED}->GetFunction()));
@ -231,11 +231,24 @@ ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGL
- Note: every class template has an associated ctor function wrapper, which is registered here - Note: every class template has an associated ctor function wrapper, which is registered here
- `CONTEXT`: either global, or the according namespace instance - `CONTEXT`: either global, or the according namespace instance
### Class method #### Class method
### Class variable ~~~~
SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED});
~~~~
## Namespace Note: implemented in static helper function
#### Class variable
~~~~
SWIGV8_AddProperty(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER});
~~~~
- `GETTER`: the name of the generated wrapper for the property getter
- `SETTER`: the name of the generated wrapper for property setter; optional (i.e., maybe `NULL`)
### Namespace
~~~~ ~~~~
${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance())); ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance()));
@ -319,7 +332,128 @@ void V8GeneratorUtils::AddProperty(v8::Handle<v8::FunctionTemplate> class_templ,
~~~~ ~~~~
# Control flow analysis -------------------------
Examples
========
In this chapter manually coded wrappers are presented.
This has been useful for studying the addressed code generation on basis
of examples.
## Global variable
~~~~~
static double Foo = 42.0;
void Foo_set(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
v8::HandleScope scope;
double arg1 ;
arg1 = value->NumberValue();
Foo = arg1;
}
v8::Handle<v8::Value> Foo_get(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
v8::HandleScope scope;
v8::Handle<v8::Value> ret;
double result;
result = Foo;
ret = v8::Number::New(result);
return scope.Close(ret);
}
int GlobalVar_Initialize(v8::Handle<v8::Context> context) {
v8::Local<v8::Object> global = context->Global();
global->SetAccessor(v8::String::New("Foo"), Foo_get, Foo_set);
return 0;
}
~~~~~
## Global functions
~~~~~
static double foo(int bla) {
return (bla * 2.1);
}
v8::Handle<v8::Value> wrap_foo(const v8::Arguments &args) {
v8::HandleScope scope;
v8::Handle<v8::Value> ret;
int arg1 ;
double result;
arg1 = args[0]->Int32Value();
result = foo(arg1);
ret = v8::Number::New(result);
return scope.Close(ret);
}
int GlobalFunc_Initialize(v8::Handle<v8::Context> context) {
v8::Local<v8::Object> global = context->Global();
global->Set(v8::String::NewSymbol("foo"), v8::FunctionTemplate::New(wrap_foo)->GetFunction());
return 0;
}
~~~~~
## Namespaces
~~~~~
namespace foo {
static double bar = 42.0;
}
void foo_bar_set(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
v8::HandleScope scope;
double arg1 ;
arg1 = value->NumberValue();
foo::bar = arg1;
}
v8::Handle<v8::Value> foo_bar_get(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
v8::HandleScope scope;
v8::Handle<v8::Value> ret;
double result;
result = foo::bar;
ret = v8::Number::New(result);
return scope.Close(ret);
}
int Namespace_Initialize(v8::Handle<v8::Context> context) {
v8::Local<v8::Object> global = context->Global();
v8::Handle<v8::ObjectTemplate> foo = v8::ObjectTemplate::New();
foo->SetAccessor(v8::String::New("bar"), foo_bar_get, foo_bar_set);
global->Set(v8::String::New("foo"), foo->NewInstance());
return 0;
}
~~~~~
-------------------------
Control flow analysis
=====================
## Global variables ## Global variables
@ -636,115 +770,3 @@ enter classHandler() of B
exit classHandler() of B exit classHandler() of B
exit top() of example exit top() of example
~~~~ ~~~~
Examples
========
## Global variable
~~~~~
static double Foo = 42.0;
void Foo_set(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
v8::HandleScope scope;
double arg1 ;
arg1 = value->NumberValue();
Foo = arg1;
}
v8::Handle<v8::Value> Foo_get(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
v8::HandleScope scope;
v8::Handle<v8::Value> ret;
double result;
result = Foo;
ret = v8::Number::New(result);
return scope.Close(ret);
}
int GlobalVar_Initialize(v8::Handle<v8::Context> context) {
v8::Local<v8::Object> global = context->Global();
global->SetAccessor(v8::String::New("Foo"), Foo_get, Foo_set);
return 0;
}
~~~~~
## Global functions
~~~~~
static double foo(int bla) {
return (bla * 2.1);
}
v8::Handle<v8::Value> wrap_foo(const v8::Arguments &args) {
v8::HandleScope scope;
v8::Handle<v8::Value> ret;
int arg1 ;
double result;
arg1 = args[0]->Int32Value();
result = foo(arg1);
ret = v8::Number::New(result);
return scope.Close(ret);
}
int GlobalFunc_Initialize(v8::Handle<v8::Context> context) {
v8::Local<v8::Object> global = context->Global();
global->Set(v8::String::NewSymbol("foo"), v8::FunctionTemplate::New(wrap_foo)->GetFunction());
return 0;
}
~~~~~
## Namespaces
~~~~~
namespace foo {
static double bar = 42.0;
}
void foo_bar_set(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
v8::HandleScope scope;
double arg1 ;
arg1 = value->NumberValue();
foo::bar = arg1;
}
v8::Handle<v8::Value> foo_bar_get(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
v8::HandleScope scope;
v8::Handle<v8::Value> ret;
double result;
result = foo::bar;
ret = v8::Number::New(result);
return scope.Close(ret);
}
int Namespace_Initialize(v8::Handle<v8::Context> context) {
v8::Local<v8::Object> global = context->Global();
v8::Handle<v8::ObjectTemplate> foo = v8::ObjectTemplate::New();
foo->SetAccessor(v8::String::New("bar"), foo_bar_get, foo_bar_set);
global->Set(v8::String::New("foo"), foo->NewInstance());
return 0;
}
~~~~~