Using V8, Conclusion
Part 3 is here:
habrahabr.ru/blogs/development/72765Part 2 is here:
habrahabr.ru/blogs/development/72592')
Part 1 is here:
habrahabr.ru/blogs/development/72474In conclusion, we will go over all trifles.
- MemoryThe algorithm of the garbage collector in V8 is designed to work well in Chrome, that is, its main task is to minimize delays. Hence his desire to postpone the cleaning of garbage as long as possible. This is bad news for the server application. The good news is that there is a way to trigger the garbage manually. To do this, you need to fix the
flag-definitions.h file before
building v8.lib .
In the file
flag-definitions.h, you need to find the line with
expose_gc :
DEFINE_bool(expose_gc, false, "expose gc extension")
And set "
true " (instead of "
false ").
After building v8.lib in the global JavaScript object, the function "
gc () " is available, which performs the complete garbage collection. However, in my experience it is difficult to find the time of her call. If this is done after the completion of a session, then a massive session halt will cause a long delay. In a word, it is necessary to use gc () somehow cunningly, not "head on."
Attention! After fixing the
flag-definitions.h file, it will no longer be managed by subversion. Before the next source download from the trunk branch, restore the file (or delete it so that it downloads again).
- Error processingIn the example of a console application that executes JavaScript, error handling is rather primitive. In fact, the information about the error that caused the exception is more extensive. You can access the samples / shell.cc file and study the ReportException function:
void ReportException(v8::TryCatch* try_catch) {
v8::HandleScope handle_scope;
v8:: String ::Utf8Value exception(try_catch->Exception());
const char * exception_string = ToCString(exception);
v8::Handle<v8::Message> message = try_catch->Message();
if (message.IsEmpty()) {
// V8 didn't provide any extra information about this error; just
// print the exception.
printf( "%s\n" , exception_string);
} else {
// Print (filename):(line number): (message).
v8:: String ::Utf8Value filename(message->GetScriptResourceName());
const char * filename_string = ToCString(filename);
int linenum = message->GetLineNumber();
printf( "%s:%i: %s\n" , filename_string, linenum, exception_string);
// Print line of source code.
v8:: String ::Utf8Value sourceline(message->GetSourceLine());
const char * sourceline_string = ToCString(sourceline);
printf( "%s\n" , sourceline_string);
// Print wavy underline (GetUnderline is deprecated).
int start = message->GetStartColumn();
for ( int i = 0; i < start; i++) {
printf( " " );
}
int end = message->GetEndColumn();
for ( int i = start; i < end; i++) {
printf( "^" );
}
printf( "\n" );
}
}
* This source code was highlighted with Source Code Highlighter .
- Getting the current contextSometimes inside the C ++ function callback, we need to get the current V8 context. There are several methods in the Context class:
static Local<Context> GetCurrent(); // V8
static Local<Context> GetEntered(); // "" V8
static Local<Context> GetCalling(); // ,
* This source code was highlighted with Source Code Highlighter .
Normally, use GetCurrent ().
- Listing the properties of a V8 objectTo get a list of properties of a V8 object, use the GetPropertyNames () call. You can get the names and values ​​of all properties of an object as follows:
Local<Object> rec; //
Local<Array> names = rec->GetPropertyNames(); //
for (unsigned j = 0; j < names->Length(); j++)
{
//
Local< String > name = Local< String >::Cast(names->Get(Integer::New(j)));
//
Local<Value> val = rec->Get(name);
// ...
}
* This source code was highlighted with Source Code Highlighter .
- Creation of a context with a binding of a global object to a functionalIn the previous parts, we considered only the creation of an empty context (by calling Context :: New () without parameters). V8 allows you to use a warm object for a global object:
...
//
Handle<ObjectTemplate> global = ObjectTemplate::New();
//
global->Set( String ::NewSymbol( "foo" ), FunctionTemplate::New(Foo));
global->Set( String ::NewSymbol( "bar" ), FunctionTemplate::New(Bar));
//
Context::New(NULL, global);
* This source code was highlighted with Source Code Highlighter .
- ConclusionOverall, we are pleased with the embedding of the V8. If I have time, I will write about our platform. In short, we have “wrapped” JavaScript embedded SQLITE, processing HTTP requests and exchanging asynchronous messages. This is a bit like what ERLANG does, but in a more “human” language; more simple and convenient to use.
UPD: By the way, here is a link to my article about this platform:
habrahabr.ru/blogs/development/48842