1
0
forked from mirrors/0ad

Improvements to simulation hotloading before the SM upgrade, refs #4893.

SM45 will enforce property attributes described at
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/Property_attributes.
We thus cannot hotload properties with the DontDelete attribute.
Fix an oversight in the hotloading code.
Rename a confusing parameter.

Reviewed By: wraitii
Differential Revision: https://code.wildfiregames.com/D1844
This was SVN commit r22516.
This commit is contained in:
Itms
2019-07-19 21:58:58 +00:00
parent feb88a337a
commit cca7627d88
3 changed files with 39 additions and 21 deletions
+26 -7
View File
@@ -589,21 +589,40 @@ bool ScriptInterface::SetGlobal_(const char* name, JS::HandleValue value, bool r
{
JSAutoRequest rq(m->m_cx);
JS::RootedObject global(m->m_cx, m->m_glob);
if (!replace)
bool found;
if (!JS_HasProperty(m->m_cx, global, name, &found))
return false;
if (found)
{
bool found;
if (!JS_HasProperty(m->m_cx, global, name, &found))
JS::Rooted<JSPropertyDescriptor> desc(m->m_cx);
if (!JS_GetOwnPropertyDescriptor(m->m_cx, global, name, &desc))
return false;
if (found)
if (desc.isReadonly())
{
JS_ReportError(m->m_cx, "SetGlobal \"%s\" called multiple times", name);
return false;
if (!replace)
{
JS_ReportError(m->m_cx, "SetGlobal \"%s\" called multiple times", name);
return false;
}
// This is not supposed to happen, unless the user has called SetProperty with constant = true on the global object
// instead of using SetGlobal.
if (desc.isPermanent())
{
JS_ReportError(m->m_cx, "The global \"%s\" is permanent and cannot be hotloaded", name);
return false;
}
LOGMESSAGE("Hotloading new value for global \"%s\".", name);
ENSURE(JS_DeleteProperty(m->m_cx, global, name));
}
}
uint attrs = 0;
if (constant)
attrs |= JSPROP_READONLY | JSPROP_PERMANENT;
attrs |= JSPROP_READONLY;
if (enumerate)
attrs |= JSPROP_ENUMERATE;
+11 -11
View File
@@ -135,8 +135,8 @@ public:
/**
* Set the named property on the global object.
* If @p replace is true, an existing property will be overwritten; otherwise attempts
* to set an already-defined value will fail.
* Optionally makes it {ReadOnly, DontEnum}. We do not allow to make it DontDelete, so that it can be hotloaded
* by deleting it and re-creating it, which is done by setting @p replace to true.
*/
template<typename T>
bool SetGlobal(const char* name, const T& value, bool replace = false, bool constant = true, bool enumerate = true);
@@ -360,9 +360,9 @@ private:
bool Eval_(const char* code, JS::MutableHandleValue ret) const;
bool Eval_(const wchar_t* code, JS::MutableHandleValue ret) const;
bool SetGlobal_(const char* name, JS::HandleValue value, bool replace, bool constant, bool enumerate);
bool SetProperty_(JS::HandleValue obj, const char* name, JS::HandleValue value, bool readonly, bool enumerate) const;
bool SetProperty_(JS::HandleValue obj, const wchar_t* name, JS::HandleValue value, bool readonly, bool enumerate) const;
bool SetPropertyInt_(JS::HandleValue obj, int name, JS::HandleValue value, bool readonly, bool enumerate) const;
bool SetProperty_(JS::HandleValue obj, const char* name, JS::HandleValue value, bool constant, bool enumerate) const;
bool SetProperty_(JS::HandleValue obj, const wchar_t* name, JS::HandleValue value, bool constant, bool enumerate) const;
bool SetPropertyInt_(JS::HandleValue obj, int name, JS::HandleValue value, bool constant, bool enumerate) const;
bool GetProperty_(JS::HandleValue obj, const char* name, JS::MutableHandleValue out) const;
bool GetPropertyInt_(JS::HandleValue obj, int name, JS::MutableHandleValue value) const;
static bool IsExceptionPending(JSContext* cx);
@@ -494,30 +494,30 @@ bool ScriptInterface::SetGlobal(const char* name, const T& value, bool replace,
}
template<typename T>
bool ScriptInterface::SetProperty(JS::HandleValue obj, const char* name, const T& value, bool readonly, bool enumerate) const
bool ScriptInterface::SetProperty(JS::HandleValue obj, const char* name, const T& value, bool constant, bool enumerate) const
{
JSAutoRequest rq(GetContext());
JS::RootedValue val(GetContext());
AssignOrToJSVal(GetContext(), &val, value);
return SetProperty_(obj, name, val, readonly, enumerate);
return SetProperty_(obj, name, val, constant, enumerate);
}
template<typename T>
bool ScriptInterface::SetProperty(JS::HandleValue obj, const wchar_t* name, const T& value, bool readonly, bool enumerate) const
bool ScriptInterface::SetProperty(JS::HandleValue obj, const wchar_t* name, const T& value, bool constant, bool enumerate) const
{
JSAutoRequest rq(GetContext());
JS::RootedValue val(GetContext());
AssignOrToJSVal(GetContext(), &val, value);
return SetProperty_(obj, name, val, readonly, enumerate);
return SetProperty_(obj, name, val, constant, enumerate);
}
template<typename T>
bool ScriptInterface::SetPropertyInt(JS::HandleValue obj, int name, const T& value, bool readonly, bool enumerate) const
bool ScriptInterface::SetPropertyInt(JS::HandleValue obj, int name, const T& value, bool constant, bool enumerate) const
{
JSAutoRequest rq(GetContext());
JS::RootedValue val(GetContext());
AssignOrToJSVal(GetContext(), &val, value);
return SetPropertyInt_(obj, name, val, readonly, enumerate);
return SetPropertyInt_(obj, name, val, constant, enumerate);
}
template<typename T>