Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/scriptinterface/ScriptInterface.cpp
Show All 11 Lines | |||||
* GNU General Public License for more details. | * GNU General Public License for more details. | ||||
* | * | ||||
* You should have received a copy of the GNU General Public License | * You should have received a copy of the GNU General Public License | ||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
#include "precompiled.h" | #include "precompiled.h" | ||||
#include "ScriptContext.h" | |||||
#include "ScriptInterface.h" | #include "ScriptInterface.h" | ||||
#include "ScriptRuntime.h" | |||||
#include "ScriptStats.h" | #include "ScriptStats.h" | ||||
#include "lib/debug.h" | #include "lib/debug.h" | ||||
#include "lib/utf8.h" | #include "lib/utf8.h" | ||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | ||||
#include "ps/Filesystem.h" | #include "ps/Filesystem.h" | ||||
#include "ps/Profile.h" | #include "ps/Profile.h" | ||||
#include "ps/utf16string.h" | #include "ps/utf16string.h" | ||||
Show All 19 Lines | |||||
* Abstractions of various SpiderMonkey features. | * Abstractions of various SpiderMonkey features. | ||||
* Engine code should be using functions of these interfaces rather than | * Engine code should be using functions of these interfaces rather than | ||||
* directly accessing the underlying JS api. | * directly accessing the underlying JS api. | ||||
*/ | */ | ||||
struct ScriptInterface_impl | struct ScriptInterface_impl | ||||
{ | { | ||||
ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime); | ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptContext>& context); | ||||
~ScriptInterface_impl(); | ~ScriptInterface_impl(); | ||||
void Register(const char* name, JSNative fptr, uint nargs) const; | void Register(const char* name, JSNative fptr, uint nargs) const; | ||||
// Take care to keep this declaration before heap rooted members. Destructors of heap rooted | // Take care to keep this declaration before heap rooted members. Destructors of heap rooted | ||||
// members have to be called before the runtime destructor. | // members have to be called before the context destructor. | ||||
shared_ptr<ScriptRuntime> m_runtime; | shared_ptr<ScriptContext> m_context; | ||||
friend ScriptInterface::Request; | friend ScriptInterface::Request; | ||||
private: | private: | ||||
JSContext* m_cx; | JSContext* m_cx; | ||||
JS::PersistentRootedObject m_glob; // global scope object | JS::PersistentRootedObject m_glob; // global scope object | ||||
public: | public: | ||||
boost::rand48* m_rng; | boost::rand48* m_rng; | ||||
▲ Show 20 Lines • Show All 241 Lines • ▼ Show 20 Lines | |||||
bool ScriptInterface::MathRandom(double& nbr) | bool ScriptInterface::MathRandom(double& nbr) | ||||
{ | { | ||||
if (m->m_rng == NULL) | if (m->m_rng == NULL) | ||||
return false; | return false; | ||||
nbr = generate_uniform_real(*(m->m_rng), 0.0, 1.0); | nbr = generate_uniform_real(*(m->m_rng), 0.0, 1.0); | ||||
return true; | return true; | ||||
} | } | ||||
ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime) : | ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptContext>& context) : | ||||
m_runtime(runtime), m_cx(runtime->GetGeneralJSContext()), m_glob(runtime->GetJSRuntime()), m_nativeScope(runtime->GetJSRuntime()) | m_context(context), m_cx(context->GetGeneralJSContext()), m_glob(context->GetJSRuntime()), m_nativeScope(context->GetJSRuntime()) | ||||
{ | { | ||||
JS::CompartmentOptions opt; | JS::CompartmentOptions opt; | ||||
opt.setVersion(JSVERSION_LATEST); | opt.setVersion(JSVERSION_LATEST); | ||||
// Keep JIT code during non-shrinking GCs. This brings a quite big performance improvement. | // Keep JIT code during non-shrinking GCs. This brings a quite big performance improvement. | ||||
opt.setPreserveJitCode(true); | opt.setPreserveJitCode(true); | ||||
JSAutoRequest rq(m_cx); | JSAutoRequest rq(m_cx); | ||||
m_glob = JS_NewGlobalObject(m_cx, &global_class, nullptr, JS::OnNewGlobalHookOption::FireOnNewGlobalHook, opt); | m_glob = JS_NewGlobalObject(m_cx, &global_class, nullptr, JS::OnNewGlobalHookOption::FireOnNewGlobalHook, opt); | ||||
Show All 12 Lines | ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptContext>& context) : | ||||
JS_DefineFunction(m_cx, m_glob, "error", ::error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); | JS_DefineFunction(m_cx, m_glob, "error", ::error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); | ||||
JS_DefineFunction(m_cx, m_glob, "clone", ::deepcopy, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); | JS_DefineFunction(m_cx, m_glob, "clone", ::deepcopy, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); | ||||
JS_DefineFunction(m_cx, m_glob, "deepfreeze", ::deepfreeze, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); | JS_DefineFunction(m_cx, m_glob, "deepfreeze", ::deepfreeze, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); | ||||
Register("ProfileStart", ::ProfileStart, 1); | Register("ProfileStart", ::ProfileStart, 1); | ||||
Register("ProfileStop", ::ProfileStop, 0); | Register("ProfileStop", ::ProfileStop, 0); | ||||
Register("ProfileAttribute", ::ProfileAttribute, 1); | Register("ProfileAttribute", ::ProfileAttribute, 1); | ||||
m_runtime->RegisterCompartment(js::GetObjectCompartment(m_glob)); | m_context->RegisterCompartment(js::GetObjectCompartment(m_glob)); | ||||
} | } | ||||
ScriptInterface_impl::~ScriptInterface_impl() | ScriptInterface_impl::~ScriptInterface_impl() | ||||
{ | { | ||||
m_runtime->UnRegisterCompartment(js::GetObjectCompartment(m_glob)); | m_context->UnRegisterCompartment(js::GetObjectCompartment(m_glob)); | ||||
} | } | ||||
void ScriptInterface_impl::Register(const char* name, JSNative fptr, uint nargs) const | void ScriptInterface_impl::Register(const char* name, JSNative fptr, uint nargs) const | ||||
{ | { | ||||
JSAutoRequest rq(m_cx); | JSAutoRequest rq(m_cx); | ||||
JSAutoCompartment autoCmpt(m_cx, m_glob); | JSAutoCompartment autoCmpt(m_cx, m_glob); | ||||
JS::RootedObject nativeScope(m_cx, m_nativeScope); | JS::RootedObject nativeScope(m_cx, m_nativeScope); | ||||
JS::RootedFunction func(m_cx, JS_DefineFunction(m_cx, nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)); | JS::RootedFunction func(m_cx, JS_DefineFunction(m_cx, nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)); | ||||
} | } | ||||
ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr<ScriptRuntime>& runtime) : | ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr<ScriptContext>& context) : | ||||
m(new ScriptInterface_impl(nativeScopeName, runtime)) | m(new ScriptInterface_impl(nativeScopeName, context)) | ||||
{ | { | ||||
// Profiler stats table isn't thread-safe, so only enable this on the main thread | // Profiler stats table isn't thread-safe, so only enable this on the main thread | ||||
if (ThreadUtil::IsMainThread()) | if (ThreadUtil::IsMainThread()) | ||||
{ | { | ||||
if (g_ScriptStatsTable) | if (g_ScriptStatsTable) | ||||
g_ScriptStatsTable->Add(this, debugName); | g_ScriptStatsTable->Add(this, debugName); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs) const | void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs) const | ||||
{ | { | ||||
m->Register(name, fptr, (uint)nargs); | m->Register(name, fptr, (uint)nargs); | ||||
} | } | ||||
JSRuntime* ScriptInterface::GetJSRuntime() const | JSRuntime* ScriptInterface::GetJSRuntime() const | ||||
{ | { | ||||
return m->m_runtime->GetJSRuntime(); | return m->m_context->GetJSRuntime(); | ||||
} | } | ||||
shared_ptr<ScriptRuntime> ScriptInterface::GetRuntime() const | shared_ptr<ScriptContext> ScriptInterface::GetContext() const | ||||
{ | { | ||||
return m->m_runtime; | return m->m_context; | ||||
} | } | ||||
void ScriptInterface::CallConstructor(JS::HandleValue ctor, JS::HandleValueArray argv, JS::MutableHandleValue out) const | void ScriptInterface::CallConstructor(JS::HandleValue ctor, JS::HandleValueArray argv, JS::MutableHandleValue out) const | ||||
{ | { | ||||
Request rq(this); | Request rq(this); | ||||
if (!ctor.isObject()) | if (!ctor.isObject()) | ||||
{ | { | ||||
LOGERROR("CallConstructor: ctor is not an object"); | LOGERROR("CallConstructor: ctor is not an object"); | ||||
▲ Show 20 Lines • Show All 598 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator