Is there a way to iterate the properties of a FunctionTemplate / ObjectTemplate?

37 views
Skip to first unread message

Ron Prestenback

unread,
Jan 4, 2021, 9:04:58 PM1/4/21
to v8-users
Since I'm very new to V8 and might be using the wrong terminology, I'll just explain what I'm trying to do  :)

I am using V8 embedded (within UnrealJS / UE4).  At startup, it iterates through UClasses (UE4 class objects) and creates a FunctionTemplate for each one.  It iterates the class's functions, creating a FunctionTemplate for each one, and adds that FunctionTemplate to the owning class's FunctionTemplate via "OwnerClassTemplate->PrototypeTemplate()->Set(function_name, function_template)".  The idea is to make it so that in javascript, you can call UE4 functions the same way you'd call them in UE4 C++, more or less.

But something goes wrong around UClass 270 or so.  I trigger an assert in V8 when calling GetFunction() on the function template for a class.

<unknown>:-1: Uncaught TypeError: Object template has duplicate property 'ExecuteUbergraph'

(ExecuteUbergraph is a function in the overall base class of UE4 - UObject)

On the surface, it seems like this should be impossible so I want to log out the properties of each of these FunctionTemplate objects to see what's been added to each one.  But I can't figure out how to do this.

I've tried a bunch of things to convert this FunctionTemplate into an object, based on the understanding that a FunctionTemplate is really a FunctionTemplateInfo object (that I retrieve via Utils::OpenHandle) and FunctionTemplateInfo is where those properties would be.  FunctionTemplateInfo appears to ultimately derive from Object (FunctionTemplateInfo -> TemplateInfo -> Struct -> HeapObject -> Object), so it seemed reasonable to try to convert the FunctionTemplate to an object, and call GetOwnPropertyNames on it.  But I'm not having any success with this approach, so I must be doing something wrong.  I can successfully convert the FunctionTemplate handle into a normal Object handle, but it triggers asserts when I try to use it, suggesting that my conversion (which involved some reinterpret_casting) is not valid.

My FunctionTemplate::ToObject function basically amounts to:
  i::Handle<i::FunctionTemplateInfo> self = Utils::OpenHandle(this);
  Local<v8::Object> Result = Utils::Convert<i::FunctionTemplateInfo, v8::Object>(self);
  return Result;


Is there a way to iterate the properties of a FunctionTemplate / ObjectTemplate?  What concept have I horribly misunderstood here?   :)

Ben Noordhuis

unread,
Jan 5, 2021, 6:19:12 AM1/5/21
to v8-users
I can understand where your confusion comes from because V8's internal
vocabulary is a little ambiguous here. :-)

A v8::FunctionTemplate is a heap object but it's not a JS object:

- v8::Object = JSObject -> JSReceiver -> HeapObject -> Object

- v8::FunctionTemplate = FunctionTemplateInfo -> TemplateInfo ->
Struct -> HeapObject -> Object

There's no public API method for retrieving the properties of a
template but the internal method is TemplateInfo::property_list(). It
returns either undefined (no properties) or a TemplateList (which is a
FixedArray) that looks like [name1, details1, value1, name2, details2,
value2, ...]. Names are strings or symbols.

Hope that helps!

Ron Prestenback

unread,
Jan 8, 2021, 2:47:15 PM1/8/21
to v8-users
Yes, that helped.  Thank you very much.
Reply all
Reply to author
Forward
0 new messages