Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API to store private properties in any object #3592

Open
fatcerberus opened this issue Aug 26, 2017 · 2 comments
Open

Add API to store private properties in any object #3592

fatcerberus opened this issue Aug 26, 2017 · 2 comments

Comments

@fatcerberus
Copy link
Contributor

It's possible right now to create an "External Object" which stores a C pointer to internal native data. However, what's not possible as far as I can see is being able to store arbitrary properties on an object which refer to JS values but aren't accessible from JS. For example in Duktape it's possible to:

duk_push_object(ctx);
/* populate new object with anything needed */
duk_put_prop_string(ctx, -2, "\xff""hiddenObject");

That can be done with any object, whereas in Chakra you currently have to create an external object to store private data--and it's not possible to convert an existing standard JS object to an external one, either, which means that in native constructors for external objects, you can't use the automatic this and must instead return a fresh object from the constructor.

I propose an API that would either:

  • Add an API that converts an existing standard JS object to an External object, OR:
  • Add an API for storing "hidden" properties that could be accessed using Js[GS]etProperty() but not within JavaScript code. Perhaps something like JsCreateHiddenPropertyId().
@obastemur
Copy link
Collaborator

I'm currently experimenting on external data support for all the object types. Upcoming days will show...

@gashtio
Copy link

gashtio commented Oct 16, 2017

I'd like to add one more vote for such feature request.

The project I'm working on needs to map JS objects to C++ object and I'm experimenting moving our JS VM to ChakraCore. The external data support for all objects would be perfect. Right now I'm using code like this, setting an internal property (say, "__privdata"), which refers to an external object:

inline void SetUserDataChakraCoreImpl(JsValueRef object, JsPropertyIdRef prop, void* userData)
{
	bool hasUserData = false;
	CHAKRA_CALL(JsHasProperty(object, prop, &hasUserData));
	if (hasUserData)
	{
		// Overwrite value
		JsValueRef userObject = JS_INVALID_REFERENCE;
		CHAKRA_CALL(JsGetProperty(object, prop, &userObject));
		CHAKRA_CALL(JsSetExternalData(userObject, userData));
	}
	else
	{
		// Create new value
		JsValueRef userObject = JS_INVALID_REFERENCE;
		CHAKRA_CALL(JsCreateExternalObject(userData, nullptr, &userObject));
		CHAKRA_CALL(JsSetProperty(object, prop, userObject, true));
	}
}

That appeared to be quite expensive (mostly due to the access to the property) when I ran a profile on some performance tests that exercised going back and forth from C++ to JS. Being able to simply set external data to any object would be much more convenient (and a lot faster I suppose).

@obastemur I saw that #3639 has the "experimental" disclaimer so I haven't tried it (and it's also referencing another issue - #3717). Is that something you're considering to add in the official versions soon?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants