Writing internal field out of bounds

322 views
Skip to first unread message

vampi

unread,
Jun 25, 2010, 6:15:51 PM6/25/10
to v8-users
hi guys. i'm trying to make an IRCClient class. it has a method called
"connect". Here's my code

v8::Handle<v8::Value> IRCClient(const v8::Arguments& args) {
v8::HandleScope handle_scope;
v8::Local<v8::Object> self = args.Holder();
printf("IRCClient called, internal field count=%d\n", self-
>InternalFieldCount());
IRC::Client *c = new IRC::Client;
self->SetInternalField(0, v8::External::New(c));
return v8::Undefined();
}

v8::Handle<v8::Value> IRCClientConnect(const v8::Arguments& args) {
printf("IRCClientConnect called\n");
v8::HandleScope handle_scope;
v8::Local<v8::Object> self = args.Holder();
v8::Local<v8::External> wrap = v8::Local<v8::External>::Cast(self-
>GetInternalField(0));
IRC::Client *c = (IRC::Client *)wrap->Value();
v8::String::Utf8Value host(args[0]);
printf("host: %s\n", ToCString(host));
return v8::Undefined();
}

int initjs(int argc, char* argv[]) {
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
v8::HandleScope handle_scope;
// Create a template for the global object.
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
// Bind the global 'print' function to the C++ Print callback.
global->Set(v8::String::New("print"),
v8::FunctionTemplate::New(Print));
// Bind the 'quit' function
global->Set(v8::String::New("quit"),
v8::FunctionTemplate::New(Quit));
// Bind the 'version' function
global->Set(v8::String::New("version"),
v8::FunctionTemplate::New(Version));

v8::Local<v8::FunctionTemplate> irct =
v8::FunctionTemplate::New(IRCClient);
v8::Local<v8::ObjectTemplate> ircpt = irct->PrototypeTemplate();
ircpt->SetInternalFieldCount(1);
ircpt->Set("connect", v8::FunctionTemplate::New(IRCClientConnect));
global->Set(v8::String::New("IRCClient"), irct);

// Create a new execution environment containing the built-in
// functions
context = v8::Context::New(NULL, global);
// Enter the newly created execution environment.
return 0;
}
// I'm also using some functions from the sample code


and here's the error i get:

irc = new IRCClient; // this is the code i run
IRCClient called, internal field count=0

#
# Fatal error in v8::Object::SetInternalField()
# Writing internal field out of bounds
#

Aborted

vampi

unread,
Jun 26, 2010, 7:59:45 AM6/26/10
to v8-users
Alright, nevermind that, i fixed it by using ->InstanceTemplate()
instead. But now i have another issue:

I'm receiving an async C++ callback. It can have a void * pointer
attached to it. I need to use this pointer to access the instance of
the IRCClient object that corresponds to it. I.e. in js i want to do
this:

irc = new IRCClient;
irc.connect("irc.example.net", 6667, "jsbot"); // connect to server
irc.join("irc.example.net", "#example"); // join a channel
irc.channel_message_fn = function(chan, nick, msg) { print("received
"+msg+" on "+chan+" by "+nick); };

So i want to have a javascript callback that gets called when i
receive the C++ callback.
I have no idea how to go about this, here's what i've tried so far:

// this is the constructor function.
v8::Handle<v8::Value> IRCClient(const v8::Arguments& args) {
v8::HandleScope handle_scope;
v8::Local<v8::Object> self = args.Holder();
IRC::Client *c = new IRC::Client(evbase, dnsbase);
c->channel_message_cb = irc_channel_message_cb;

// this is where i need to store the pointer.
// i tried 'self' instead of 3, but i get a compiler error even if i
typecast to void*.
// so my guess is i need some sort of global pointer... not sure how
these handles work yet.
c->channel_message_ptr = (void *)3;
self->SetInternalField(0, v8::External::New(c));
return v8::Undefined();
}

int initjs(int *argc, char* argv[]) {
v8::V8::SetFlagsFromCommandLine(argc, argv, true);
v8::HandleScope handle_scope;
// Create a template for the global object.
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
// Bind the global 'print' function to the C++ Print callback.
global->Set(v8::String::New("print"),
v8::FunctionTemplate::New(Print));
// Bind the 'quit' function
global->Set(v8::String::New("quit"),
v8::FunctionTemplate::New(Quit));
// Bind the 'version' function
global->Set(v8::String::New("version"),
v8::FunctionTemplate::New(Version));

v8::Local<v8::FunctionTemplate> irct =
v8::FunctionTemplate::New(IRCClient);
v8::Local<v8::Template> ircpt = irct->PrototypeTemplate();
ircpt->Set("connect", v8::FunctionTemplate::New(IRCClientConnect));
ircpt->Set("join", v8::FunctionTemplate::New(IRCClientJoin));
ircpt->Set("speak", v8::FunctionTemplate::New(IRCClientSpeak));
v8::Local<v8::ObjectTemplate> ircot = irct->InstanceTemplate();
ircot->SetInternalFieldCount(1);
global->Set(v8::String::New("IRCClient"), irct);

// Create a new execution environment containing the built-in
// functions
context = v8::Context::New(NULL, global);
// Enter the newly created execution environment.
v8::Context::Scope context_scope(context);
for(int i = 1; i < *argc; i++) {
printf("reading file %s\n", argv[i]);
ExecuteString(ReadFile(argv[i]), v8::String::New(argv[i]), true,
true);
}
return 0;
}

my C++ async cb looks like this:

static void irc_channel_message_cb(IRC::Source *s, char *msg, void
*ptr) {
printf("channel message cb [%s] %p\n", msg, ptr);
}
Reply all
Reply to author
Forward
0 new messages