On Wed, Mar 7, 2012 at 7:43 PM, cruisercoder <[email protected]> wrote:
> Callie works - I was able to get to the prototype internal data. The
> working code is shown below.
Glad you got it to work.
>
> I'm not sure why you can't have internal fields for the function
> object itself. It would be simpler if there is a way to do this.
Agree, the api would need to allow you to specify the number of
internal fields before the function object gets created.
On that note, I believe SetHiddenValue might work for you -
functionality-wise it's similar to internal fields, just without a
fixed number of slots, more like string-keyed properties with -I
guess- slightly less performance.
>
> Matthias, the complication with the indirection suggestion is that
> there are threads involved. Thanks for the help.
>
> erik
>
>
> using namespace v8;
>
> Handle<Value> handler(const Arguments& args) {
> Handle<Function> fn = Handle<Function>::Cast(args.Callee());
> Handle<Object> proto = Handle<Object>::Cast(fn-
>>Get(String::New("prototype")));
> Local<External> ext = Local<External>::Cast(proto-
>>GetInternalField(0));
BTW: there are helpers for this common use-case of "stuff pointer into
External into internal field" :
Object::Get/SetPointerInInternalField. Saves you a little bit of code.
> int &value = * static_cast<int *>(ext->Value());
> return Undefined();
> }
>
> HandleScope handle_scope;
>
> Persistent<ObjectTemplate> global_template;
> global_template =
> Persistent<ObjectTemplate>::New(ObjectTemplate::New());
>
> Handle<FunctionTemplate> tmpl = FunctionTemplate::New(handler);
>
> Handle<ObjectTemplate> proto_t = tmpl->PrototypeTemplate();
> proto_t->SetInternalFieldCount(1);
>
> global_template->Set(String::New("myFunction"),tmpl);
>
> Persistent<Context> context = Context::New(0, global_template);
>
> Context::Scope context_scope(context);
>
> Handle<Function> fn = tmpl->GetFunction();
> Handle<Object> proto = Handle<Object>::Cast(fn-
>>Get(String::New("prototype")));
>
> void *data = new int(123);
> proto->SetInternalField(0, External::New(data));
>
>
> On Mar 7, 7:46 am, Matthias Ernst <[email protected]> wrote:
>> On Wed, Mar 7, 2012 at 3:39 PM, cruisercoder <[email protected]> wrote:
>> > That seems to work better (no SetInternalField error):
>>
>> > Handle<Object> proto = Handle<Object>::Cast(fn-
>> >>Get(String::New("prototype")));
>> > proto->SetInternalField(0, External::New(data));
>>
>> > I'm still not sure about how to access the function and it's prototype
>> > through the args object in the callback.
>>
>> Is that not args.Callee()?
>>
>>
>>
>> > The problem with the Set callback data is that it requires the data to
>> > be available a little earlier than I wanted.
>>
>> Every problem in CS can be solved by adding one layer of indirection:
>> you can set an object/array that gets later updated points to the
>> right value.
>>
>>
>>
>>
>>
>>
>>
>> > It seems like I should
>> > be able to use internal data fields for functions in the same way that
>> > I do for objects.
>>
>> > erik
>>
>> > On Mar 6, 10:29 pm, Matthias Ernst <[email protected]> wrote:
>> >> On Wed, Mar 7, 2012 at 3:16 AM, cruisercoder <[email protected]>
>> >> wrote:
>> >> > How do I get internal data for function callbacks? The approach I'm
>> >> > currently taking is to use the function's prototype object where I can
>> >> > declare an internal field and then set it at context time. However,
>> >> > I get an error about the internal field count when I retrieve the
>> >> > prototype and try to set data (code and error shown below).
>>
>> >> > I'm also not sure about how to unpack the data in the handler.
>>
>> >> > erik
>>
>> >> > v8::Handle<v8::Value> myHandler(const v8::Arguments& args) {
>> >> > nd::unused(args);
>> >> > using namespace v8;
>> >> > return Undefined();
>> >> > }
>>
>> >> > using namespace v8;
>> >> > HandleScope handle_scope;
>>
>> >> > v8::Persistent<v8::ObjectTemplate> global_template =
>> >> > Persistent<ObjectTemplate>::New(ObjectTemplate::New());
>>
>> >> > Handle<FunctionTemplate> tmpl = FunctionTemplate::New(myHandler);
>>
>> >> > Handle<ObjectTemplate> proto_t = tmpl->PrototypeTemplate();
>> >> > proto_t->SetInternalFieldCount(1);
>>
>> >> > global_template->Set(String::New("myFunction"),tmpl);
>>
>> >> > Persistent<Context> context = Context::New(0, global_template);
>>
>> >> > Context::Scope context_scope(context);
>>
>> >> > Handle<Function> fn = tmpl->GetFunction();
>> >> > Handle<Object> proto = Handle<Object>::Cast(fn->GetPrototype());
>>
>> >> GetPrototype() is a method of Object and returns object's __proto__
>> >> (which I guess is "Function.prototype" in this case). You want
>> >> fn.Get(String::New("prototype")).
>>
>> >> Not quite sure what you're trying to achieve, but you can also
>> >> register callback data in FunctionTemplate::New (the "data" parameter)
>> >> which will be passed into your callback as Arguments::Data().
>>
>> >> Matthias
>>
>> >> > void *data(0);
>> >> > proto->SetInternalField(0, External::New(data));
>>
>> >> > #
>> >> > # Fatal error in v8::Object::SetInternalField()
>> >> > # Writing internal field out of bounds
>> >> > #
>>
>> >> > --
>> >> > v8-users mailing list
>> >> > [email protected]
>> >> >http://groups.google.com/group/v8-users
>>
>> > --
>> > v8-users mailing list
>> > [email protected]
>> >http://groups.google.com/group/v8-users
>
> --
> v8-users mailing list
> [email protected]
> http://groups.google.com/group/v8-users
--
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users