#include <v8.h>
class CPoint
{
public:
CPoint() {
}
int _x;
int _y;
};
template<class T>
v8::Handle<v8::Value> Create(const v8::Arguments& args);
template<class T>
void Class_Destroy(v8::Persistent<v8::Object> self, void* parameter);
void ReportException(v8::TryCatch* try_catch) {
v8::HandleScope handle_scope;
v8::String::Utf8Value exception(try_catch->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);
} else {
// Print (filename):(line number): (message).
v8::String::Utf8Value filename(message->GetScriptResourceName());
int linenum = message->GetLineNumber();
printf("%s:%i: %s\n", *filename, linenum, *exception);
// Print line of source code.
v8::String::Utf8Value sourceline(message->GetSourceLine());
printf("%s\n", *sourceline);
// 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");
}
}
bool ExecuteString(v8::Handle<v8::String> source,
v8::Handle<v8::Value> name) {
v8::HandleScope handle_scope;
v8::TryCatch try_catch;
v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
if (script.IsEmpty()) {
// Print errors that happened during compilation.
// if (report_exceptions)
ReportException(&try_catch);
return false;
} else {
v8::Handle<v8::Value> result = script->Run();
if (result.IsEmpty()) {
// Print errors that happened during execution.
// if (report_exceptions)
ReportException(&try_catch);
return false;
} else {
if (!result->IsUndefined()) {
// If all went well and the result wasn't undefined then print
// the returned value.
v8::String::Utf8Value str(result);
const char* cstr = *str;
printf("%s\n", cstr);
}
return true;
}
}
}
char script[] =
"function Process() {\n"
" var i;\n"
" i = new Point;\n"
"}\n"
"Process();\n";
int main(int argc, char* argv[])
{
v8::HandleScope scope;
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
v8::Handle<v8::FunctionTemplate> ftPoint;
ftPoint = v8::FunctionTemplate::New(Create<CPoint>);
ftPoint->SetClassName(v8::String::New("Point"));
v8::Handle<v8::ObjectTemplate> otPoint;
otPoint = ftPoint->InstanceTemplate();
otPoint->SetInternalFieldCount(1); // create an internal field for
the C++ object
global->Set(v8::String::New("Point"), ftPoint);
v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
v8::Context::Scope context_scope(context);
ExecuteString(v8::String::New(script), v8::String::New("cmdline"));
v8::V8::Dispose();
return 0;
}
template<class T>
v8::Handle<v8::Value> Create(const v8::Arguments& args)
{
// throw if called without `new'
if (!args.IsConstructCall())
return ThrowException(v8::String::New("Cannot call constructor
as
function"));
// throw if we didn't get 0 args
if (args.Length() != 0)
return ThrowException(v8::String::New("Expected no arguments"));
// make a persistent handle for the instance and make it
// weak so we get a callback when it is garbage collected
v8::Persistent<v8::Object> self =
v8::Persistent<v8::Object>::New(args.Holder());
self.MakeWeak(NULL,
v8::WeakReferenceCallback(Class_Destroy<CPoint>));
// set internal field to the C++ point
self->SetInternalField(0, v8::External::New(NULL));
return self;
}
/**
* Called when the T object is being garbage collected
* delete the C++ object and ClearWeak on the Persistent handle.
*/
template<class T>
void Class_Destroy(v8::Persistent<v8::Object> self, void* parameter)
{
delete static_cast<T*>(parameter);
self.ClearWeak();
}
--
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users