Add a function to query a global object, including JS classes, from C++

The latter are not properties of the global object but stored within the
global lexical environment.
This is not currently needed, but will be useful for future diffs.
Update Vector2D/3D querying.

Taken from D2746

This was SVN commit r24406.
This commit is contained in:
wraitii 2020-12-17 17:51:18 +00:00
parent 25b8cfc6b8
commit e22a915351
3 changed files with 41 additions and 2 deletions

View File

@ -704,6 +704,36 @@ bool ScriptInterface::HasProperty(JS::HandleValue obj, const char* name) const
return found;
}
bool ScriptInterface::GetGlobalProperty(const ScriptRequest& rq, const std::string& name, JS::MutableHandleValue out)
{
// Try to get the object as a property of the global object.
JS::RootedObject global(rq.cx, rq.glob);
if (!JS_GetProperty(rq.cx, global, name.c_str(), out))
{
out.set(JS::NullHandleValue);
return false;
}
if (!out.isNullOrUndefined())
return true;
// Some objects, such as const definitions, or Class definitions, are hidden inside closures.
// We must fetch those from the correct lexical scope.
//JS::RootedValue glob(cx);
JS::RootedObject lexical_environment(rq.cx, JS_GlobalLexicalEnvironment(rq.glob));
if (!JS_GetProperty(rq.cx, lexical_environment, name.c_str(), out))
{
out.set(JS::NullHandleValue);
return false;
}
if (!out.isNullOrUndefined())
return true;
out.set(JS::NullHandleValue);
return false;
}
bool ScriptInterface::EnumeratePropertyNames(JS::HandleValue objVal, bool enumerableOnly, std::vector<std::string>& out) const
{
ScriptRequest rq(this);

View File

@ -233,6 +233,15 @@ public:
*/
bool HasProperty(JS::HandleValue obj, const char* name) const;
/**
* Get an object from the global scope or any lexical scope.
* This can return globally accessible objects even if they are not properties
* of the global object (e.g. ES6 class definitions).
* @param name - Name of the property.
* @param out The object or null.
*/
static bool GetGlobalProperty(const ScriptRequest& rq, const std::string& name, JS::MutableHandleValue out);
/**
* Returns all properties of the object, both own properties and inherited.
* This is essentially equivalent to calling Object.getOwnPropertyNames()

View File

@ -160,7 +160,7 @@ template<> void ScriptInterface::ToJSVal<CFixedVector3D>(const ScriptRequest& rq
{
JS::RootedObject global(rq.cx, rq.glob);
JS::RootedValue valueVector3D(rq.cx);
if (!JS_GetProperty(rq.cx, global, "Vector3D", &valueVector3D))
if (!ScriptInterface::GetGlobalProperty(rq, "Vector3D", &valueVector3D))
FAIL_VOID("Failed to get Vector3D constructor");
JS::RootedValueArray<3> args(rq.cx);
@ -196,7 +196,7 @@ template<> void ScriptInterface::ToJSVal<CFixedVector2D>(const ScriptRequest& rq
{
JS::RootedObject global(rq.cx, rq.glob);
JS::RootedValue valueVector2D(rq.cx);
if (!JS_GetProperty(rq.cx, global, "Vector2D", &valueVector2D))
if (!ScriptInterface::GetGlobalProperty(rq, "Vector2D", &valueVector2D))
FAIL_VOID("Failed to get Vector2D constructor");
JS::RootedValueArray<2> args(rq.cx);