uox3/spidermonkey/jsdbgapi.cpp

2675 lines
74 KiB
C++
Raw Permalink Normal View History

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=99:
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* JS debugging API.
*/
#include <string.h>
#include "jsprvtd.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsclist.h"
#include "jshashtable.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "jsversion.h"
#include "jsdbgapi.h"
2023-07-12 13:27:26 +10:00
#include "jsemit.h"
#include "jsfun.h"
#include "jsgc.h"
#include "jsinterp.h"
#include "jslock.h"
#include "jsobj.h"
#include "jsopcode.h"
2023-07-12 13:27:26 +10:00
#include "jsparse.h"
#include "jsscope.h"
#include "jsscript.h"
#include "jsstaticcheck.h"
#include "jsstr.h"
#include "jswrapper.h"
#include "jsatominlines.h"
#include "jsdbgapiinlines.h"
#include "jsinterpinlines.h"
#include "jsobjinlines.h"
#include "jsscopeinlines.h"
#include "jsscriptinlines.h"
#include "jsautooplen.h"
#include "methodjit/MethodJIT.h"
#include "methodjit/Retcon.h"
using namespace js;
using namespace js::gc;
typedef struct JSTrap {
JSCList links;
JSScript *script;
jsbytecode *pc;
JSOp op;
JSTrapHandler handler;
jsval closure;
} JSTrap;
2023-07-12 13:27:26 +10:00
#define DBG_LOCK(rt) JS_ACQUIRE_LOCK((rt)->debuggerLock)
#define DBG_UNLOCK(rt) JS_RELEASE_LOCK((rt)->debuggerLock)
#define DBG_LOCK_EVAL(rt,expr) (DBG_LOCK(rt), (expr), DBG_UNLOCK(rt))
JS_PUBLIC_API(JSBool)
JS_GetDebugMode(JSContext *cx)
{
return cx->compartment->debugMode;
}
JS_PUBLIC_API(JSBool)
JS_SetDebugMode(JSContext *cx, JSBool debug)
{
return JS_SetDebugModeForCompartment(cx, cx->compartment, debug);
}
JS_PUBLIC_API(void)
JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug)
{
rt->debugMode = debug;
}
#ifdef DEBUG
static bool
CompartmentHasLiveScripts(JSCompartment *comp)
{
#ifdef JS_METHODJIT
# ifdef JS_THREADSAFE
jsword currentThreadId = reinterpret_cast<jsword>(js_CurrentThreadId());
# endif
#endif
// Unsynchronized context iteration is technically a race; but this is only
// for debug asserts where such a race would be rare
JSContext *iter = NULL;
JSContext *icx;
while ((icx = JS_ContextIterator(comp->rt, &iter))) {
#ifdef JS_THREADSAFE
if (JS_GetContextThread(icx) != currentThreadId)
continue;
#endif
for (AllFramesIter i(icx); !i.done(); ++i) {
JSScript *script = i.fp()->maybeScript();
if (script && script->compartment == comp)
return JS_TRUE;
}
}
return JS_FALSE;
}
#endif
JS_FRIEND_API(JSBool)
JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, JSBool debug)
{
if (comp->debugMode == !!debug)
return JS_TRUE;
// This should only be called when no scripts are live. It would even be
// incorrect to discard just the non-live scripts' JITScripts because they
// might share ICs with live scripts (bug 632343).
JS_ASSERT(!CompartmentHasLiveScripts(comp));
// All scripts compiled from this point on should be in the requested debugMode.
comp->debugMode = !!debug;
// Discard JIT code for any scripts that change debugMode. This function
// assumes that 'comp' is in the same thread as 'cx'.
#ifdef JS_METHODJIT
JSAutoEnterCompartment ac;
for (JSScript *script = (JSScript *)comp->scripts.next;
&script->links != &comp->scripts;
script = (JSScript *)script->links.next)
{
if (!script->debugMode == !debug)
continue;
/*
* If compartment entry fails, debug mode is left partially on, leading
* to a small performance overhead but no loss of correctness. We set
* the debug flags to false so that the caller will not later attempt
* to use debugging features.
*/
if (!ac.entered() && !ac.enter(cx, script)) {
comp->debugMode = JS_FALSE;
return JS_FALSE;
}
mjit::ReleaseScriptCode(cx, script);
script->debugMode = !!debug;
}
#endif
return JS_TRUE;
}
JS_FRIEND_API(JSBool)
js_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep)
{
#ifdef JS_METHODJIT
if (!script->singleStepMode == !singleStep)
return JS_TRUE;
#endif
JS_ASSERT_IF(singleStep, cx->compartment->debugMode);
#ifdef JS_METHODJIT
/* request the next recompile to inject single step interrupts */
script->singleStepMode = !!singleStep;
js::mjit::JITScript *jit = script->jitNormal ? script->jitNormal : script->jitCtor;
if (jit && script->singleStepMode != jit->singleStepMode) {
js::mjit::Recompiler recompiler(cx, script);
if (!recompiler.recompile()) {
script->singleStepMode = !singleStep;
return JS_FALSE;
}
}
#endif
return JS_TRUE;
}
static JSBool
CheckDebugMode(JSContext *cx)
{
JSBool debugMode = JS_GetDebugMode(cx);
/*
* :TODO:
* This probably should be an assertion, since it's indicative of a severe
* API misuse.
*/
if (!debugMode) {
JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage,
NULL, JSMSG_NEED_DEBUG_MODE);
}
return debugMode;
}
JS_PUBLIC_API(JSBool)
JS_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep)
{
if (!CheckDebugMode(cx))
return JS_FALSE;
return js_SetSingleStepMode(cx, script, singleStep);
}
2023-07-12 13:27:26 +10:00
/*
* NB: FindTrap must be called with rt->debuggerLock acquired.
*/
static JSTrap *
FindTrap(JSRuntime *rt, JSScript *script, jsbytecode *pc)
{
JSTrap *trap;
for (trap = (JSTrap *)rt->trapList.next;
&trap->links != &rt->trapList;
trap = (JSTrap *)trap->links.next) {
if (trap->script == script && trap->pc == pc)
return trap;
}
return NULL;
}
2023-07-12 13:27:26 +10:00
jsbytecode *
js_UntrapScriptCode(JSContext *cx, JSScript *script)
{
2023-07-12 13:27:26 +10:00
jsbytecode *code;
JSRuntime *rt;
JSTrap *trap;
2023-07-12 13:27:26 +10:00
code = script->code;
rt = cx->runtime;
DBG_LOCK(rt);
for (trap = (JSTrap *)rt->trapList.next;
&trap->links !=
&rt->trapList;
2023-07-12 13:27:26 +10:00
trap = (JSTrap *)trap->links.next) {
if (trap->script == script &&
(size_t)(trap->pc - script->code) < script->length) {
if (code == script->code) {
jssrcnote *sn, *notes;
size_t nbytes;
nbytes = script->length * sizeof(jsbytecode);
notes = script->notes();
2023-07-12 13:27:26 +10:00
for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
continue;
nbytes += (sn - notes + 1) * sizeof *sn;
code = (jsbytecode *) cx->malloc(nbytes);
2023-07-12 13:27:26 +10:00
if (!code)
break;
memcpy(code, script->code, nbytes);
JS_PURGE_GSN_CACHE(cx);
2023-07-12 13:27:26 +10:00
}
code[trap->pc - script->code] = trap->op;
}
}
DBG_UNLOCK(rt);
return code;
}
JS_PUBLIC_API(JSBool)
JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
JSTrapHandler handler, jsval closure)
{
2023-07-12 13:27:26 +10:00
JSTrap *junk, *trap, *twin;
JSRuntime *rt;
2023-07-12 13:27:26 +10:00
uint32 sample;
if (!CheckDebugMode(cx))
return JS_FALSE;
2023-07-12 13:27:26 +10:00
JS_ASSERT((JSOp) *pc != JSOP_TRAP);
junk = NULL;
rt = cx->runtime;
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
trap = FindTrap(rt, script, pc);
if (trap) {
JS_ASSERT(trap->script == script && trap->pc == pc);
JS_ASSERT(*pc == JSOP_TRAP);
} else {
2023-07-12 13:27:26 +10:00
sample = rt->debuggerMutations;
DBG_UNLOCK(rt);
trap = (JSTrap *) cx->malloc(sizeof *trap);
2023-07-12 13:27:26 +10:00
if (!trap)
return JS_FALSE;
trap->closure = JSVAL_NULL;
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
twin = (rt->debuggerMutations != sample)
? FindTrap(rt, script, pc)
: NULL;
if (twin) {
junk = trap;
trap = twin;
} else {
JS_APPEND_LINK(&trap->links, &rt->trapList);
++rt->debuggerMutations;
trap->script = script;
trap->pc = pc;
trap->op = (JSOp)*pc;
*pc = JSOP_TRAP;
}
}
trap->handler = handler;
trap->closure = closure;
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
if (junk)
cx->free(junk);
#ifdef JS_METHODJIT
if (script->hasJITCode()) {
js::mjit::Recompiler recompiler(cx, script);
if (!recompiler.recompile())
return JS_FALSE;
}
#endif
return JS_TRUE;
}
JS_PUBLIC_API(JSOp)
JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc)
{
2023-07-12 13:27:26 +10:00
JSRuntime *rt;
JSTrap *trap;
2023-07-12 13:27:26 +10:00
JSOp op;
2023-07-12 13:27:26 +10:00
rt = cx->runtime;
DBG_LOCK(rt);
trap = FindTrap(rt, script, pc);
op = trap ? trap->op : (JSOp) *pc;
DBG_UNLOCK(rt);
return op;
}
static void
2023-07-12 13:27:26 +10:00
DestroyTrapAndUnlock(JSContext *cx, JSTrap *trap)
{
2023-07-12 13:27:26 +10:00
++cx->runtime->debuggerMutations;
JS_REMOVE_LINK(&trap->links);
*trap->pc = (jsbytecode)trap->op;
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(cx->runtime);
cx->free(trap);
}
JS_PUBLIC_API(void)
JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
JSTrapHandler *handlerp, jsval *closurep)
{
JSTrap *trap;
2023-07-12 13:27:26 +10:00
DBG_LOCK(cx->runtime);
trap = FindTrap(cx->runtime, script, pc);
if (handlerp)
*handlerp = trap ? trap->handler : NULL;
if (closurep)
*closurep = trap ? trap->closure : JSVAL_NULL;
if (trap)
2023-07-12 13:27:26 +10:00
DestroyTrapAndUnlock(cx, trap);
else
DBG_UNLOCK(cx->runtime);
#ifdef JS_METHODJIT
if (script->hasJITCode()) {
mjit::Recompiler recompiler(cx, script);
recompiler.recompile();
}
#endif
}
JS_PUBLIC_API(void)
JS_ClearScriptTraps(JSContext *cx, JSScript *script)
{
JSRuntime *rt;
JSTrap *trap, *next;
2023-07-12 13:27:26 +10:00
uint32 sample;
rt = cx->runtime;
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
for (trap = (JSTrap *)rt->trapList.next;
&trap->links != &rt->trapList;
trap = next) {
next = (JSTrap *)trap->links.next;
2023-07-12 13:27:26 +10:00
if (trap->script == script) {
sample = rt->debuggerMutations;
DestroyTrapAndUnlock(cx, trap);
DBG_LOCK(rt);
if (rt->debuggerMutations != sample + 1)
next = (JSTrap *)rt->trapList.next;
}
}
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
}
JS_PUBLIC_API(void)
JS_ClearAllTraps(JSContext *cx)
{
JSRuntime *rt;
JSTrap *trap, *next;
2023-07-12 13:27:26 +10:00
uint32 sample;
rt = cx->runtime;
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
for (trap = (JSTrap *)rt->trapList.next;
&trap->links != &rt->trapList;
trap = next) {
next = (JSTrap *)trap->links.next;
2023-07-12 13:27:26 +10:00
sample = rt->debuggerMutations;
DestroyTrapAndUnlock(cx, trap);
DBG_LOCK(rt);
if (rt->debuggerMutations != sample + 1)
next = (JSTrap *)rt->trapList.next;
}
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
}
/*
* NB: js_MarkTraps does not acquire cx->runtime->debuggerLock, since the
* debugger should never be racing with the GC (i.e., the debugger must
* respect the request model).
*/
void
js_MarkTraps(JSTracer *trc)
{
JSRuntime *rt = trc->context->runtime;
for (JSTrap *trap = (JSTrap *) rt->trapList.next;
&trap->links != &rt->trapList;
trap = (JSTrap *) trap->links.next) {
MarkValue(trc, Valueify(trap->closure), "trap->closure");
}
}
JS_PUBLIC_API(JSTrapStatus)
JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval)
{
JSTrap *trap;
jsint op;
2023-07-12 13:27:26 +10:00
JSTrapStatus status;
2023-07-12 13:27:26 +10:00
DBG_LOCK(cx->runtime);
trap = FindTrap(cx->runtime, script, pc);
2023-07-12 13:27:26 +10:00
JS_ASSERT(!trap || trap->handler);
if (!trap) {
2023-07-12 13:27:26 +10:00
op = (JSOp) *pc;
DBG_UNLOCK(cx->runtime);
/* Defend against "pc for wrong script" API usage error. */
JS_ASSERT(op != JSOP_TRAP);
#ifdef JS_THREADSAFE
/* If the API was abused, we must fail for want of the real op. */
if (op == JSOP_TRAP)
return JSTRAP_ERROR;
/* Assume a race with a debugger thread and try to carry on. */
*rval = INT_TO_JSVAL(op);
return JSTRAP_CONTINUE;
#else
/* Always fail if single-threaded (must be an API usage error). */
return JSTRAP_ERROR;
2023-07-12 13:27:26 +10:00
#endif
}
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(cx->runtime);
/*
* It's important that we not use 'trap->' after calling the callback --
* the callback might remove the trap!
*/
op = (jsint)trap->op;
status = trap->handler(cx, script, pc, rval, trap->closure);
if (status == JSTRAP_CONTINUE) {
/* By convention, return the true op to the interpreter in rval. */
*rval = INT_TO_JSVAL(op);
}
return status;
}
#ifdef JS_TRACER
static void
JITInhibitingHookChange(JSRuntime *rt, bool wasInhibited)
{
if (wasInhibited) {
if (!rt->debuggerInhibitsJIT()) {
for (JSCList *cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next)
js_ContextFromLinkField(cl)->updateJITEnabled();
}
} else if (rt->debuggerInhibitsJIT()) {
for (JSCList *cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next)
js_ContextFromLinkField(cl)->traceJitEnabled = false;
}
}
#endif
JS_PUBLIC_API(JSBool)
JS_SetInterrupt(JSRuntime *rt, JSInterruptHook hook, void *closure)
{
#ifdef JS_TRACER
{
AutoLockGC lock(rt);
bool wasInhibited = rt->debuggerInhibitsJIT();
#endif
rt->globalDebugHooks.interruptHook = hook;
rt->globalDebugHooks.interruptHookData = closure;
#ifdef JS_TRACER
JITInhibitingHookChange(rt, wasInhibited);
}
#endif
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *hoop, void **closurep)
{
#ifdef JS_TRACER
AutoLockGC lock(rt);
bool wasInhibited = rt->debuggerInhibitsJIT();
#endif
if (hoop)
*hoop = rt->globalDebugHooks.interruptHook;
if (closurep)
*closurep = rt->globalDebugHooks.interruptHookData;
rt->globalDebugHooks.interruptHook = 0;
rt->globalDebugHooks.interruptHookData = 0;
#ifdef JS_TRACER
JITInhibitingHookChange(rt, wasInhibited);
#endif
return JS_TRUE;
}
/************************************************************************/
struct JSWatchPoint {
JSCList links;
JSObject *object; /* weak link, see js_SweepWatchPoints */
const Shape *shape;
StrictPropertyOp setter;
JSWatchPointHandler handler;
JSObject *closure;
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
uintN flags;
};
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
#define JSWP_LIVE 0x1 /* live because set and not cleared */
#define JSWP_HELD 0x2 /* held while running handler/setter */
2023-07-12 13:27:26 +10:00
/*
* NB: DropWatchPointAndUnlock releases cx->runtime->debuggerLock in all cases.
*/
static JSBool
2023-07-12 13:27:26 +10:00
DropWatchPointAndUnlock(JSContext *cx, JSWatchPoint *wp, uintN flag)
{
bool ok = true;
JSRuntime *rt = cx->runtime;
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
wp->flags &= ~flag;
2023-07-12 13:27:26 +10:00
if (wp->flags != 0) {
DBG_UNLOCK(rt);
2023-07-12 13:27:26 +10:00
return ok;
}
/*
* Switch to the same compartment as the watch point, since changeProperty, below,
* needs to have a compartment.
*/
SwitchToCompartment sc(cx, wp->object);
/* Remove wp from the list, then restore wp->shape->setter from wp. */
++rt->debuggerMutations;
JS_REMOVE_LINK(&wp->links);
DBG_UNLOCK(rt);
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
/*
* If the property isn't found on wp->object, then someone else must have deleted it,
* and we don't need to change the property attributes.
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
*/
const Shape *shape = wp->shape;
const Shape *wprop = wp->object->nativeLookup(shape->id);
if (wprop &&
wprop->hasSetterValue() == shape->hasSetterValue() &&
IsWatchedProperty(cx, wprop)) {
shape = wp->object->changeProperty(cx, wprop, 0, wprop->attributes(),
wprop->getter(), wp->setter);
if (!shape)
ok = false;
}
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
cx->free(wp);
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
return ok;
}
2023-07-12 13:27:26 +10:00
/*
* NB: js_TraceWatchPoints does not acquire cx->runtime->debuggerLock, since
* the debugger should never be racing with the GC (i.e., the debugger must
* respect the request model).
*/
void
2023-07-12 13:27:26 +10:00
js_TraceWatchPoints(JSTracer *trc, JSObject *obj)
{
JSRuntime *rt;
JSWatchPoint *wp;
2023-07-12 13:27:26 +10:00
rt = trc->context->runtime;
for (wp = (JSWatchPoint *)rt->watchPointList.next;
&wp->links != &rt->watchPointList;
wp = (JSWatchPoint *)wp->links.next) {
2023-07-12 13:27:26 +10:00
if (wp->object == obj) {
wp->shape->trace(trc);
if (wp->shape->hasSetterValue() && wp->setter)
MarkObject(trc, *CastAsObject(wp->setter), "wp->setter");
MarkObject(trc, *wp->closure, "wp->closure");
2023-07-12 13:27:26 +10:00
}
}
}
2023-07-12 13:27:26 +10:00
void
js_SweepWatchPoints(JSContext *cx)
{
JSRuntime *rt;
JSWatchPoint *wp, *next;
uint32 sample;
rt = cx->runtime;
DBG_LOCK(rt);
for (wp = (JSWatchPoint *)rt->watchPointList.next;
&wp->links != &rt->watchPointList;
2023-07-12 13:27:26 +10:00
wp = next) {
next = (JSWatchPoint *)wp->links.next;
if (IsAboutToBeFinalized(cx, wp->object)) {
2023-07-12 13:27:26 +10:00
sample = rt->debuggerMutations;
/* Ignore failures. */
DropWatchPointAndUnlock(cx, wp, JSWP_LIVE);
DBG_LOCK(rt);
if (rt->debuggerMutations != sample + 1)
next = (JSWatchPoint *)rt->watchPointList.next;
}
}
DBG_UNLOCK(rt);
}
/*
* NB: LockedFindWatchPoint must be called with rt->debuggerLock acquired.
2023-07-12 13:27:26 +10:00
*/
static JSWatchPoint *
LockedFindWatchPoint(JSRuntime *rt, JSObject *obj, jsid id)
{
JSWatchPoint *wp;
for (wp = (JSWatchPoint *)rt->watchPointList.next;
&wp->links != &rt->watchPointList;
wp = (JSWatchPoint *)wp->links.next) {
if (wp->object == obj && wp->shape->id == id)
return wp;
}
return NULL;
}
static JSWatchPoint *
FindWatchPoint(JSRuntime *rt, JSObject *obj, jsid id)
{
JSWatchPoint *wp;
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
wp = LockedFindWatchPoint(rt, obj, id);
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
return wp;
}
JSBool
js_watch_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp)
{
JSRuntime *rt = cx->runtime;
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
for (JSWatchPoint *wp = (JSWatchPoint *)rt->watchPointList.next;
&wp->links != &rt->watchPointList;
wp = (JSWatchPoint *)wp->links.next) {
const Shape *shape = wp->shape;
if (wp->object == obj && SHAPE_USERID(shape) == id && !(wp->flags & JSWP_HELD)) {
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
wp->flags |= JSWP_HELD;
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
jsid propid = shape->id;
shape = obj->nativeLookup(propid);
JS_ASSERT(IsWatchedProperty(cx, shape));
jsid userid = SHAPE_USERID(shape);
/* Determine the property's old value. */
bool ok;
uint32 slot = shape->slot;
Value old = obj->containsSlot(slot) ? obj->nativeGetSlot(slot) : UndefinedValue();
const Shape *needMethodSlotWrite = NULL;
if (shape->isMethod()) {
/*
* We get here in two cases: (1) the existing watched property
* is a method; or (2) the watched property was deleted and is
* now in the middle of being re-added via JSOP_SETMETHOD. In
* both cases we must trip the method read barrier in order to
* avoid passing an uncloned function object to the handler.
*
* Case 2 is especially hairy. js_watch_set, uniquely, gets
* called in the middle of creating a method property, after
* shape is in obj but before the slot has been set. So in this
* case we must finish initializing the half-finished method
* property before triggering the method read barrier.
*
* Bonus weirdness: because this changes obj's shape,
* js_NativeSet (which is our caller) will not write to the
* slot, as it will appear the property was deleted and a new
* property added. We must write the slot ourselves -- however
* we must do it after calling the watchpoint handler. So set
* needMethodSlotWrite here and use it to write to the slot
* below, if the handler does not tinker with the property
* further.
*/
JS_ASSERT(!wp->setter);
Value method = ObjectValue(shape->methodObject());
if (old.isUndefined())
obj->nativeSetSlot(slot, method);
ok = obj->methodReadBarrier(cx, *shape, &method);
if (!ok)
goto out;
wp->shape = shape = needMethodSlotWrite = obj->nativeLookup(propid);
JS_ASSERT(shape->isDataDescriptor());
JS_ASSERT(!shape->isMethod());
if (old.isUndefined())
obj->nativeSetSlot(shape->slot, old);
else
old = method;
}
{
Conditionally<AutoShapeRooter> tvr(needMethodSlotWrite, cx, needMethodSlotWrite);
/*
* Call the handler. This invalidates shape, so re-lookup the shape.
* NB: wp is held, so we can safely dereference it still.
*/
ok = wp->handler(cx, obj, propid, Jsvalify(old), Jsvalify(vp), wp->closure);
if (!ok)
goto out;
shape = obj->nativeLookup(propid);
JS_ASSERT_IF(!shape, !wp->setter);
if (!shape) {
ok = true;
} else if (wp->setter) {
/*
* Pass the output of the handler to the setter. Security wrappers
* prevent any funny business between watchpoints and setters.
*/
ok = shape->hasSetterValue()
? ExternalInvoke(cx, ObjectValue(*obj),
ObjectValue(*CastAsObject(wp->setter)),
1, vp, vp)
: CallJSPropertyOpSetter(cx, wp->setter, obj, userid, strict, vp);
} else if (shape == needMethodSlotWrite) {
/* See comment above about needMethodSlotWrite. */
obj->nativeSetSlot(shape->slot, *vp);
ok = true;
} else {
/*
* A property with the default setter might be either a method
* or an ordinary function-valued data property subject to the
* method write barrier.
*
* It is not the setter's job to call methodWriteBarrier,
* but js_watch_set must do so, because the caller will be
* fooled into not doing it: shape does *not* have the
* default setter and therefore seems not to be a method.
*/
ok = obj->methodWriteBarrier(cx, *shape, *vp) != NULL;
2023-07-12 13:27:26 +10:00
}
}
out:
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
return DropWatchPointAndUnlock(cx, wp, JSWP_HELD) && ok;
}
}
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
return true;
}
static JSBool
js_watch_set_wrapper(JSContext *cx, uintN argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
if (!obj)
return false;
JSObject &funobj = JS_CALLEE(cx, vp).toObject();
JSFunction *wrapper = funobj.getFunctionPrivate();
jsid userid = ATOM_TO_JSID(wrapper->atom);
JS_SET_RVAL(cx, vp, argc ? JS_ARGV(cx, vp)[0] : UndefinedValue());
/*
* The strictness we pass here doesn't matter, since we know that it's
* a JS setter, which can't depend on the assigning code's strictness.
*/
return js_watch_set(cx, obj, userid, false, vp);
}
namespace js {
bool
IsWatchedProperty(JSContext *cx, const Shape *shape)
{
if (shape->hasSetterValue()) {
JSObject *funobj = shape->setterObject();
if (!funobj || !funobj->isFunction())
return false;
JSFunction *fun = funobj->getFunctionPrivate();
return fun->maybeNative() == js_watch_set_wrapper;
}
return shape->setterOp() == js_watch_set;
}
}
/*
* Return an appropriate setter to substitute for |setter| on a property
* with attributes |attrs|, to implement a watchpoint on the property named
* |id|.
*/
static StrictPropertyOp
WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, StrictPropertyOp setter)
{
JSAtom *atom;
JSFunction *wrapper;
/* Wrap a C++ setter simply by returning our own C++ setter. */
if (!(attrs & JSPROP_SETTER))
return &js_watch_set; /* & to silence schoolmarmish MSVC */
/*
* Wrap a JSObject * setter by constructing our own JSFunction * that saves the
* property id as the function name, and calls js_watch_set.
*/
if (JSID_IS_ATOM(id)) {
atom = JSID_TO_ATOM(id);
} else if (JSID_IS_INT(id)) {
if (!js_ValueToStringId(cx, IdToValue(id), &id))
return NULL;
2023-07-12 13:27:26 +10:00
atom = JSID_TO_ATOM(id);
} else {
atom = NULL;
}
wrapper = js_NewFunction(cx, NULL, js_watch_set_wrapper, 1, 0,
setter ? CastAsObject(setter)->getParent() : NULL, atom);
if (!wrapper)
return NULL;
return CastAsStrictPropertyOp(FUN_OBJECT(wrapper));
}
static const Shape *
UpdateWatchpointShape(JSContext *cx, JSWatchPoint *wp, const Shape *newShape)
{
JS_ASSERT_IF(wp->shape, wp->shape->id == newShape->id);
JS_ASSERT(!IsWatchedProperty(cx, newShape));
/* Create a watching setter we can substitute for the new shape's setter. */
StrictPropertyOp watchingSetter =
WrapWatchedSetter(cx, newShape->id, newShape->attributes(), newShape->setter());
if (!watchingSetter)
return NULL;
/*
* Save the shape's setter; we don't know whether js_ChangeNativePropertyAttrs will
* return a new shape, or mutate this one.
*/
StrictPropertyOp originalSetter = newShape->setter();
/*
* Drop the watching setter into the object, in place of newShape. Note that a single
* watchpoint-wrapped shape may correspond to more than one non-watchpoint shape: we
* wrap all (JSPropertyOp, not JSObject *) setters with js_watch_set, so shapes that
* differ only in their setter may all get wrapped to the same shape.
*/
const Shape *watchingShape =
js_ChangeNativePropertyAttrs(cx, wp->object, newShape, 0, newShape->attributes(),
newShape->getter(), watchingSetter);
if (!watchingShape)
return NULL;
/* Update the watchpoint with the new shape and its original setter. */
wp->setter = originalSetter;
wp->shape = watchingShape;
return watchingShape;
}
const Shape *
js_SlowPathUpdateWatchpointsForShape(JSContext *cx, JSObject *obj, const Shape *newShape)
{
/*
* The watchpoint code uses the normal property-modification functions to install its
* own watchpoint-aware shapes. Those functions report those changes back to the
* watchpoint code, just as they do user-level changes. So if this change is
* installing a watchpoint-aware shape, it's something we asked for ourselves, and can
* proceed without interference.
*/
if (IsWatchedProperty(cx, newShape))
return newShape;
JSWatchPoint *wp = FindWatchPoint(cx->runtime, obj, newShape->id);
if (!wp)
return newShape;
return UpdateWatchpointShape(cx, wp, newShape);
}
/*
* Return the underlying setter for |shape| on |obj|, seeing through any
* watchpoint-wrapping. Note that we need |obj| to disambiguate, since a single
* watchpoint-wrapped shape may correspond to more than one non-watchpoint shape; see the
* comments in UpdateWatchpointShape.
*/
static StrictPropertyOp
UnwrapSetter(JSContext *cx, JSObject *obj, const Shape *shape)
{
/* If it's not a watched property, its setter is not wrapped. */
if (!IsWatchedProperty(cx, shape))
return shape->setter();
/* Look up the watchpoint, from which we can retrieve the underlying setter. */
JSWatchPoint *wp = FindWatchPoint(cx->runtime, obj, shape->id);
/*
* Since we know |shape| is watched, we *must* find a watchpoint: we should never
* leave wrapped setters lying around in shapes after removing a watchpoint.
*/
JS_ASSERT(wp);
return wp->setter;
}
JS_PUBLIC_API(JSBool)
JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsid id,
JSWatchPointHandler handler, JSObject *closure)
{
JSObject *origobj;
Value v;
uintN attrs;
jsid propid;
origobj = obj;
OBJ_TO_INNER_OBJECT(cx, obj);
if (!obj)
return JS_FALSE;
AutoValueRooter idroot(cx);
if (JSID_IS_INT(id)) {
propid = id;
} else {
if (!js_ValueToStringId(cx, IdToValue(id), &propid))
return JS_FALSE;
propid = js_CheckForStringIndex(propid);
idroot.set(IdToValue(propid));
}
/*
* If, by unwrapping and innerizing, we changed the object, check
* again to make sure that we're allowed to set a watch point.
*/
if (origobj != obj && !CheckAccess(cx, obj, propid, JSACC_WATCH, &v, &attrs))
return JS_FALSE;
if (!obj->isNative()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH,
obj->getClass()->name);
return JS_FALSE;
}
JSObject *pobj;
JSProperty *prop;
if (!js_LookupProperty(cx, obj, propid, &pobj, &prop))
return JS_FALSE;
const Shape *shape = (Shape *) prop;
JSRuntime *rt = cx->runtime;
if (!shape) {
/* Check for a deleted symbol watchpoint, which holds its property. */
JSWatchPoint *wp = FindWatchPoint(rt, obj, propid);
if (!wp) {
/* Make a new property in obj so we can watch for the first set. */
if (!js_DefineNativeProperty(cx, obj, propid, UndefinedValue(), NULL, NULL,
JSPROP_ENUMERATE, 0, 0, &prop)) {
return JS_FALSE;
}
shape = (Shape *) prop;
}
} else if (pobj != obj) {
/* Clone the prototype property so we can watch the right object. */
AutoValueRooter valroot(cx);
PropertyOp getter;
StrictPropertyOp setter;
uintN attrs, flags;
intN shortid;
if (pobj->isNative()) {
valroot.set(pobj->containsSlot(shape->slot)
? pobj->nativeGetSlot(shape->slot)
: UndefinedValue());
getter = shape->getter();
setter = UnwrapSetter(cx, pobj, shape);
attrs = shape->attributes();
flags = shape->getFlags();
shortid = shape->shortid;
} else {
if (!pobj->getProperty(cx, propid, valroot.addr()) ||
!pobj->getAttributes(cx, propid, &attrs)) {
return JS_FALSE;
}
getter = NULL;
setter = NULL;
flags = 0;
shortid = 0;
}
/* Recall that obj is native, whether or not pobj is native. */
if (!js_DefineNativeProperty(cx, obj, propid, valroot.value(),
getter, setter, attrs, flags,
shortid, &prop)) {
return JS_FALSE;
}
shape = (Shape *) prop;
}
/*
* At this point, prop/shape exists in obj, obj is locked, and we must
* unlock the object before returning.
*/
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
JSWatchPoint *wp = LockedFindWatchPoint(rt, obj, propid);
if (!wp) {
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
wp = (JSWatchPoint *) cx->malloc(sizeof *wp);
if (!wp)
return JS_FALSE;
wp->handler = NULL;
wp->closure = NULL;
wp->object = obj;
wp->shape = NULL;
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
wp->flags = JSWP_LIVE;
/* XXXbe nest in obj lock here */
if (!UpdateWatchpointShape(cx, wp, shape)) {
2023-07-12 13:27:26 +10:00
/* Self-link so DropWatchPointAndUnlock can JS_REMOVE_LINK it. */
JS_INIT_CLIST(&wp->links);
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
DropWatchPointAndUnlock(cx, wp, JSWP_LIVE);
return JS_FALSE;
}
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
/*
* Now that wp is fully initialized, append it to rt's wp list.
* Because obj is locked we know that no other thread could have added
* a watchpoint for (obj, propid).
*/
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
JS_ASSERT(!LockedFindWatchPoint(rt, obj, propid));
JS_APPEND_LINK(&wp->links, &rt->watchPointList);
2023-07-12 13:27:26 +10:00
++rt->debuggerMutations;
}
/*
* Ensure that an object with watchpoints never has the same shape as an
* object without them, even if the watched properties are deleted.
*/
obj->watchpointOwnShapeChange(cx);
wp->handler = handler;
wp->closure = reinterpret_cast<JSObject*>(closure);
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id,
JSWatchPointHandler *handlerp, JSObject **closurep)
{
JSRuntime *rt;
JSWatchPoint *wp;
rt = cx->runtime;
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
for (wp = (JSWatchPoint *)rt->watchPointList.next;
&wp->links != &rt->watchPointList;
wp = (JSWatchPoint *)wp->links.next) {
if (wp->object == obj && SHAPE_USERID(wp->shape) == id) {
if (handlerp)
*handlerp = wp->handler;
if (closurep)
*closurep = wp->closure;
2023-07-12 13:27:26 +10:00
return DropWatchPointAndUnlock(cx, wp, JSWP_LIVE);
}
}
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
if (handlerp)
*handlerp = NULL;
if (closurep)
*closurep = NULL;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj)
{
JSRuntime *rt;
JSWatchPoint *wp, *next;
2023-07-12 13:27:26 +10:00
uint32 sample;
rt = cx->runtime;
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
for (wp = (JSWatchPoint *)rt->watchPointList.next;
&wp->links != &rt->watchPointList;
wp = next) {
next = (JSWatchPoint *)wp->links.next;
2023-07-12 13:27:26 +10:00
if (wp->object == obj) {
sample = rt->debuggerMutations;
if (!DropWatchPointAndUnlock(cx, wp, JSWP_LIVE))
return JS_FALSE;
DBG_LOCK(rt);
if (rt->debuggerMutations != sample + 1)
next = (JSWatchPoint *)rt->watchPointList.next;
}
}
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_ClearAllWatchPoints(JSContext *cx)
{
JSRuntime *rt;
JSWatchPoint *wp, *next;
2023-07-12 13:27:26 +10:00
uint32 sample;
rt = cx->runtime;
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
for (wp = (JSWatchPoint *)rt->watchPointList.next;
&wp->links != &rt->watchPointList;
wp = next) {
next = (JSWatchPoint *)wp->links.next;
2023-07-12 13:27:26 +10:00
sample = rt->debuggerMutations;
if (!DropWatchPointAndUnlock(cx, wp, JSWP_LIVE))
return JS_FALSE;
2023-07-12 13:27:26 +10:00
DBG_LOCK(rt);
if (rt->debuggerMutations != sample + 1)
next = (JSWatchPoint *)rt->watchPointList.next;
}
2023-07-12 13:27:26 +10:00
DBG_UNLOCK(rt);
return JS_TRUE;
}
/************************************************************************/
JS_PUBLIC_API(uintN)
JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
{
return js_PCToLineNumber(cx, script, pc);
}
JS_PUBLIC_API(jsbytecode *)
JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno)
{
return js_LineNumberToPC(script, lineno);
}
JS_PUBLIC_API(jsbytecode *)
JS_EndPC(JSContext *cx, JSScript *script)
{
return script->code + script->length;
}
JS_PUBLIC_API(uintN)
JS_GetFunctionArgumentCount(JSContext *cx, JSFunction *fun)
{
return fun->nargs;
}
JS_PUBLIC_API(JSBool)
JS_FunctionHasLocalNames(JSContext *cx, JSFunction *fun)
{
return fun->script()->bindings.hasLocalNames();
}
extern JS_PUBLIC_API(jsuword *)
JS_GetFunctionLocalNameArray(JSContext *cx, JSFunction *fun, void **markp)
{
*markp = JS_ARENA_MARK(&cx->tempPool);
return fun->script()->bindings.getLocalNameArray(cx, &cx->tempPool);
}
extern JS_PUBLIC_API(JSAtom *)
JS_LocalNameToAtom(jsuword w)
{
return JS_LOCAL_NAME_TO_ATOM(w);
}
extern JS_PUBLIC_API(JSString *)
JS_AtomKey(JSAtom *atom)
{
return ATOM_TO_STRING(atom);
}
extern JS_PUBLIC_API(void)
JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark)
{
JS_ARENA_RELEASE(&cx->tempPool, mark);
}
JS_PUBLIC_API(JSScript *)
JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
{
return FUN_SCRIPT(fun);
}
JS_PUBLIC_API(JSNative)
JS_GetFunctionNative(JSContext *cx, JSFunction *fun)
{
return Jsvalify(fun->maybeNative());
2023-07-12 13:27:26 +10:00
}
JS_PUBLIC_API(JSPrincipals *)
JS_GetScriptPrincipals(JSContext *cx, JSScript *script)
{
return script->principals;
}
/************************************************************************/
/*
* Stack Frame Iterator
*/
JS_PUBLIC_API(JSStackFrame *)
JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp)
{
*iteratorp = (*iteratorp == NULL) ? js_GetTopStackFrame(cx) : (*iteratorp)->prev();
return *iteratorp;
}
JS_PUBLIC_API(JSScript *)
JS_GetFrameScript(JSContext *cx, JSStackFrame *fp)
{
return fp->maybeScript();
}
JS_PUBLIC_API(jsbytecode *)
JS_GetFramePC(JSContext *cx, JSStackFrame *fp)
{
return fp->pc(cx);
}
JS_PUBLIC_API(JSStackFrame *)
JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp)
{
return js_GetScriptedCaller(cx, fp);
}
JSPrincipals *
js_StackFramePrincipals(JSContext *cx, JSStackFrame *fp)
{
JSSecurityCallbacks *callbacks;
if (fp->isFunctionFrame()) {
callbacks = JS_GetSecurityCallbacks(cx);
if (callbacks && callbacks->findObjectPrincipals) {
if (&fp->fun()->compiledFunObj() != &fp->callee())
return callbacks->findObjectPrincipals(cx, &fp->callee());
/* FALL THROUGH */
}
}
if (fp->isScriptFrame())
return fp->script()->principals;
return NULL;
}
JSPrincipals *
js_EvalFramePrincipals(JSContext *cx, JSObject *callee, JSStackFrame *caller)
{
JSPrincipals *principals, *callerPrincipals;
JSSecurityCallbacks *callbacks;
callbacks = JS_GetSecurityCallbacks(cx);
if (callbacks && callbacks->findObjectPrincipals)
principals = callbacks->findObjectPrincipals(cx, callee);
else
principals = NULL;
if (!caller)
return principals;
callerPrincipals = js_StackFramePrincipals(cx, caller);
return (callerPrincipals && principals &&
callerPrincipals->subsume(callerPrincipals, principals))
? principals
: callerPrincipals;
}
JS_PUBLIC_API(void *)
JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp)
{
if (fp->annotation() && fp->isScriptFrame()) {
JSPrincipals *principals = js_StackFramePrincipals(cx, fp);
if (principals && principals->globalPrivilegesEnabled(cx, principals)) {
/*
* Give out an annotation only if privileges have not been revoked
* or disabled globally.
*/
return fp->annotation();
}
}
return NULL;
}
JS_PUBLIC_API(void)
JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation)
{
fp->setAnnotation(annotation);
}
JS_PUBLIC_API(void *)
JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp)
{
JSPrincipals *principals;
principals = js_StackFramePrincipals(cx, fp);
if (!principals)
return NULL;
return principals->getPrincipalArray(cx, principals);
}
JS_PUBLIC_API(JSBool)
JS_IsScriptFrame(JSContext *cx, JSStackFrame *fp)
{
return !fp->isDummyFrame();
}
/* this is deprecated, use JS_GetFrameScopeChain instead */
JS_PUBLIC_API(JSObject *)
JS_GetFrameObject(JSContext *cx, JSStackFrame *fp)
{
return &fp->scopeChain();
}
JS_PUBLIC_API(JSObject *)
JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp)
{
JS_ASSERT(cx->stack().contains(fp));
js::AutoCompartment ac(cx, &fp->scopeChain());
if (!ac.enter())
return NULL;
/* Force creation of argument and call objects if not yet created */
(void) JS_GetFrameCallObject(cx, fp);
return GetScopeChain(cx, fp);
}
JS_PUBLIC_API(JSObject *)
JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp)
{
JS_ASSERT(cx->stack().contains(fp));
if (!fp->isFunctionFrame())
return NULL;
js::AutoCompartment ac(cx, &fp->scopeChain());
if (!ac.enter())
return NULL;
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
/* Force creation of argument object if not yet created */
(void) js_GetArgsObject(cx, fp);
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
/*
* XXX ill-defined: null return here means error was reported, unlike a
* null returned above or in the #else
*/
return js_GetCallObject(cx, fp);
}
JS_PUBLIC_API(JSBool)
JS_GetFrameThis(JSContext *cx, JSStackFrame *fp, jsval *thisv)
{
if (fp->isDummyFrame())
return false;
js::AutoCompartment ac(cx, &fp->scopeChain());
if (!ac.enter())
return false;
if (!fp->computeThis(cx))
return false;
*thisv = Jsvalify(fp->thisValue());
return true;
}
JS_PUBLIC_API(JSFunction *)
JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp)
{
return fp->maybeFun();
}
JS_PUBLIC_API(JSObject *)
JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp)
{
if (!fp->isFunctionFrame())
return NULL;
2023-07-12 13:27:26 +10:00
JS_ASSERT(fp->callee().isFunction());
JS_ASSERT(fp->callee().getPrivate() == fp->fun());
return &fp->callee();
}
JS_PUBLIC_API(JSBool)
JS_IsConstructorFrame(JSContext *cx, JSStackFrame *fp)
{
return fp->isConstructing();
}
JS_PUBLIC_API(JSObject *)
JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp)
{
return fp->maybeCallee();
}
JS_PUBLIC_API(JSBool)
JS_GetValidFrameCalleeObject(JSContext *cx, JSStackFrame *fp, jsval *vp)
{
Value v;
if (!fp->getValidCalleeObject(cx, &v))
return false;
*vp = Jsvalify(v);
return true;
}
JS_PUBLIC_API(JSBool)
JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp)
{
return fp->isDebuggerFrame();
}
JS_PUBLIC_API(jsval)
JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp)
{
return Jsvalify(fp->returnValue());
}
JS_PUBLIC_API(void)
JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval)
{
#ifdef JS_METHODJIT
JS_ASSERT_IF(fp->isScriptFrame(), fp->script()->debugMode);
#endif
assertSameCompartment(cx, fp, rval);
fp->setReturnValue(Valueify(rval));
}
/************************************************************************/
JS_PUBLIC_API(const char *)
JS_GetScriptFilename(JSContext *cx, JSScript *script)
{
return script->filename;
}
JS_PUBLIC_API(uintN)
JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script)
{
return script->lineno;
}
JS_PUBLIC_API(uintN)
JS_GetScriptLineExtent(JSContext *cx, JSScript *script)
{
return js_GetScriptLineExtent(script);
}
JS_PUBLIC_API(JSVersion)
JS_GetScriptVersion(JSContext *cx, JSScript *script)
{
return VersionNumber(script->getVersion());
}
/***************************************************************************/
JS_PUBLIC_API(void)
JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata)
{
2023-07-12 13:27:26 +10:00
rt->globalDebugHooks.newScriptHook = hook;
rt->globalDebugHooks.newScriptHookData = callerdata;
}
JS_PUBLIC_API(void)
JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
void *callerdata)
{
2023-07-12 13:27:26 +10:00
rt->globalDebugHooks.destroyScriptHook = hook;
rt->globalDebugHooks.destroyScriptHookData = callerdata;
}
/***************************************************************************/
JS_PUBLIC_API(JSBool)
JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
const jschar *chars, uintN length,
const char *filename, uintN lineno,
jsval *rval)
{
JS_ASSERT_NOT_ON_TRACE(cx);
if (!CheckDebugMode(cx))
return false;
JSObject *scobj = JS_GetFrameScopeChain(cx, fp);
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
if (!scobj)
return false;
js::AutoCompartment ac(cx, scobj);
if (!ac.enter())
return false;
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
/*
* NB: This function breaks the assumption that the compiler can see all
* calls and properly compute a static level. In order to get around this,
* we use a static level that will cause us not to attempt to optimize
* variable references made by this frame.
*/
JSScript *script = Compiler::compileScript(cx, scobj, fp, js_StackFramePrincipals(cx, fp),
TCF_COMPILE_N_GO, chars, length,
filename, lineno, cx->findVersion(),
NULL, UpvarCookie::UPVAR_LEVEL_LIMIT);
if (!script)
return false;
bool ok = Execute(cx, scobj, script, fp, JSFRAME_DEBUGGER | JSFRAME_EVAL, Valueify(rval));
js_DestroyScript(cx, script);
return ok;
}
JS_PUBLIC_API(JSBool)
JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
const char *bytes, uintN length,
const char *filename, uintN lineno,
jsval *rval)
{
jschar *chars;
JSBool ok;
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
size_t len = length;
if (!CheckDebugMode(cx))
return JS_FALSE;
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
chars = js_InflateString(cx, bytes, &len);
if (!chars)
return JS_FALSE;
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
length = (uintN) len;
ok = JS_EvaluateUCInStackFrame(cx, fp, chars, length, filename, lineno,
rval);
cx->free(chars);
return ok;
}
/************************************************************************/
/* This all should be reworked to avoid requiring JSScopeProperty types. */
JS_PUBLIC_API(JSScopeProperty *)
JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp)
{
const Shape *shape;
/* The caller passes null in *iteratorp to get things started. */
shape = (Shape *) *iteratorp;
if (!shape) {
shape = obj->lastProperty();
} else {
shape = shape->previous();
if (!shape->previous()) {
JS_ASSERT(JSID_IS_EMPTY(shape->id));
shape = NULL;
}
}
return *iteratorp = reinterpret_cast<JSScopeProperty *>(const_cast<Shape *>(shape));
}
JS_PUBLIC_API(JSBool)
JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
JSPropertyDesc *pd)
{
assertSameCompartment(cx, obj);
Shape *shape = (Shape *) sprop;
pd->id = IdToJsval(shape->id);
JSBool wasThrowing = cx->isExceptionPending();
Value lastException = UndefinedValue();
if (wasThrowing)
lastException = cx->getPendingException();
cx->clearPendingException();
if (!js_GetProperty(cx, obj, shape->id, Valueify(&pd->value))) {
if (!cx->isExceptionPending()) {
pd->flags = JSPD_ERROR;
pd->value = JSVAL_VOID;
} else {
pd->flags = JSPD_EXCEPTION;
pd->value = Jsvalify(cx->getPendingException());
}
} else {
pd->flags = 0;
}
if (wasThrowing)
cx->setPendingException(lastException);
pd->flags |= (shape->enumerable() ? JSPD_ENUMERATE : 0)
| (!shape->writable() ? JSPD_READONLY : 0)
| (!shape->configurable() ? JSPD_PERMANENT : 0);
pd->spare = 0;
if (shape->getter() == GetCallArg) {
pd->slot = shape->shortid;
2023-07-12 13:27:26 +10:00
pd->flags |= JSPD_ARGUMENT;
} else if (shape->getter() == GetCallVar) {
pd->slot = shape->shortid;
2023-07-12 13:27:26 +10:00
pd->flags |= JSPD_VARIABLE;
} else {
pd->slot = 0;
}
pd->alias = JSVAL_VOID;
if (obj->containsSlot(shape->slot)) {
for (Shape::Range r = obj->lastProperty()->all(); !r.empty(); r.popFront()) {
const Shape &aprop = r.front();
if (&aprop != shape && aprop.slot == shape->slot) {
pd->alias = IdToJsval(aprop.id);
break;
}
}
}
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
{
assertSameCompartment(cx, obj);
Class *clasp = obj->getClass();
if (!obj->isNative() || (clasp->flags & JSCLASS_NEW_ENUMERATE)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CANT_DESCRIBE_PROPS, clasp->name);
return JS_FALSE;
}
if (!clasp->enumerate(cx, obj))
return JS_FALSE;
/* Return an empty pda early if obj has no own properties. */
if (obj->nativeEmpty()) {
pda->length = 0;
pda->array = NULL;
return JS_TRUE;
}
uint32 n = obj->propertyCount();
JSPropertyDesc *pd = (JSPropertyDesc *) cx->malloc(size_t(n) * sizeof(JSPropertyDesc));
if (!pd)
return JS_FALSE;
uint32 i = 0;
for (Shape::Range r = obj->lastProperty()->all(); !r.empty(); r.popFront()) {
if (!js_AddRoot(cx, Valueify(&pd[i].id), NULL))
goto bad;
if (!js_AddRoot(cx, Valueify(&pd[i].value), NULL))
goto bad;
Shape *shape = const_cast<Shape *>(&r.front());
if (!JS_GetPropertyDesc(cx, obj, reinterpret_cast<JSScopeProperty *>(shape), &pd[i]))
goto bad;
if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, Valueify(&pd[i].alias), NULL))
goto bad;
if (++i == n)
break;
}
pda->length = i;
pda->array = pd;
return JS_TRUE;
bad:
pda->length = i + 1;
pda->array = pd;
JS_PutPropertyDescArray(cx, pda);
return JS_FALSE;
}
JS_PUBLIC_API(void)
JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
{
JSPropertyDesc *pd;
uint32 i;
pd = pda->array;
for (i = 0; i < pda->length; i++) {
js_RemoveRoot(cx->runtime, &pd[i].id);
js_RemoveRoot(cx->runtime, &pd[i].value);
if (pd[i].flags & JSPD_ALIAS)
js_RemoveRoot(cx->runtime, &pd[i].alias);
}
cx->free(pd);
}
/************************************************************************/
JS_PUBLIC_API(JSBool)
JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler handler, void *closure)
{
2023-07-12 13:27:26 +10:00
rt->globalDebugHooks.debuggerHandler = handler;
rt->globalDebugHooks.debuggerHandlerData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
{
2023-07-12 13:27:26 +10:00
rt->globalDebugHooks.sourceHandler = handler;
rt->globalDebugHooks.sourceHandlerData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
2023-07-12 13:27:26 +10:00
rt->globalDebugHooks.executeHook = hook;
rt->globalDebugHooks.executeHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
#ifdef JS_TRACER
{
AutoLockGC lock(rt);
bool wasInhibited = rt->debuggerInhibitsJIT();
#endif
rt->globalDebugHooks.callHook = hook;
rt->globalDebugHooks.callHookData = closure;
#ifdef JS_TRACER
JITInhibitingHookChange(rt, wasInhibited);
}
#endif
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure)
{
2023-07-12 13:27:26 +10:00
rt->globalDebugHooks.throwHook = hook;
rt->globalDebugHooks.throwHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
{
2023-07-12 13:27:26 +10:00
rt->globalDebugHooks.debugErrorHook = hook;
rt->globalDebugHooks.debugErrorHookData = closure;
return JS_TRUE;
}
/************************************************************************/
JS_PUBLIC_API(size_t)
JS_GetObjectTotalSize(JSContext *cx, JSObject *obj)
{
return obj->slotsAndStructSize();
}
static size_t
GetAtomTotalSize(JSContext *cx, JSAtom *atom)
{
size_t nbytes;
2023-07-12 13:27:26 +10:00
nbytes = sizeof(JSAtom *) + sizeof(JSDHashEntryStub);
nbytes += sizeof(JSString);
nbytes += (ATOM_TO_STRING(atom)->flatLength() + 1) * sizeof(jschar);
return nbytes;
}
JS_PUBLIC_API(size_t)
JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun)
{
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
size_t nbytes;
nbytes = sizeof *fun;
2023-07-12 13:27:26 +10:00
nbytes += JS_GetObjectTotalSize(cx, FUN_OBJECT(fun));
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
if (FUN_INTERPRETED(fun))
nbytes += JS_GetScriptTotalSize(cx, fun->u.i.script);
if (fun->atom)
nbytes += GetAtomTotalSize(cx, fun->atom);
return nbytes;
}
#include "jsemit.h"
JS_PUBLIC_API(size_t)
JS_GetScriptTotalSize(JSContext *cx, JSScript *script)
{
size_t nbytes, pbytes;
jsatomid i;
jssrcnote *sn, *notes;
2023-07-12 13:27:26 +10:00
JSObjectArray *objarray;
JSPrincipals *principals;
nbytes = sizeof *script;
if (script->u.object)
nbytes += JS_GetObjectTotalSize(cx, script->u.object);
nbytes += script->length * sizeof script->code[0];
nbytes += script->atomMap.length * sizeof script->atomMap.vector[0];
for (i = 0; i < script->atomMap.length; i++)
nbytes += GetAtomTotalSize(cx, script->atomMap.vector[i]);
if (script->filename)
nbytes += strlen(script->filename) + 1;
notes = script->notes();
for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
continue;
nbytes += (sn - notes + 1) * sizeof *sn;
if (JSScript::isValidOffset(script->objectsOffset)) {
objarray = script->objects();
2023-07-12 13:27:26 +10:00
i = objarray->length;
nbytes += sizeof *objarray + i * sizeof objarray->vector[0];
do {
nbytes += JS_GetObjectTotalSize(cx, objarray->vector[--i]);
} while (i != 0);
}
if (JSScript::isValidOffset(script->regexpsOffset)) {
objarray = script->regexps();
2023-07-12 13:27:26 +10:00
i = objarray->length;
nbytes += sizeof *objarray + i * sizeof objarray->vector[0];
do {
nbytes += JS_GetObjectTotalSize(cx, objarray->vector[--i]);
} while (i != 0);
}
if (JSScript::isValidOffset(script->trynotesOffset)) {
2023-07-12 13:27:26 +10:00
nbytes += sizeof(JSTryNoteArray) +
script->trynotes()->length * sizeof(JSTryNote);
}
principals = script->principals;
if (principals) {
JS_ASSERT(principals->refcount);
pbytes = sizeof *principals;
if (principals->refcount > 1)
pbytes = JS_HOWMANY(pbytes, principals->refcount);
nbytes += pbytes;
}
return nbytes;
}
JS_PUBLIC_API(uint32)
JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp)
{
if (!fp)
fp = js_GetTopStackFrame(cx);
while (fp) {
if (fp->isScriptFrame())
return JS_GetScriptFilenameFlags(fp->script());
fp = fp->prev();
}
return 0;
}
JS_PUBLIC_API(uint32)
JS_GetScriptFilenameFlags(JSScript *script)
{
JS_ASSERT(script);
if (!script->filename)
return JSFILENAME_NULL;
Numerous changes with focus on feature and stability parity across Windows, Linux and MacOS platforms Added new Makefile that handles compiling UOX3 and Spidermonkey on both Linux and MacOS (punt) Added VS solution (SpiderMonkey.sln) and VC++ project files for compiling SpiderMonkey on Windows (Xuri) Updated SpiderMonkey from v1.6.0 to v1.7.0 Added optimization flag -O2 for release build in CMakeLists.txt in project root (Xuri) Added StringUtility file with general common string manipulation functions (punt) Updated RandomNum function to use a "seedless" random number generator from C++11 instead of the old C rand() function. (punt) Overall code cleanup to remove/replace platform-dependent code (punt) Replaced potentially unsafe usage of C string stuff like sprintf, vsprintf, vsnprintf, strncat, strcpy and strlen throughout the code with calls to a format() function containing only a single, safe use of vsnprintf, ensuring there's a single place of failure if there's anything to fix and and making it easy to potentially replace this with std::format from C++20 when the time comes. (punt) Replaced usage of char in many places with std::string (punt) Started process of replacing UString usage with functions provided through StringUtility instead (punt) Replaced platform specific fileIO handling in Windows/Linux with cross-platform C++17 standard std::filesystem (punt) Replaced platform specific time handling by using cross-platform chrono library (punt) Removed UOX namespace to reduce complexity (punt) Elimitated template code approach to singletons for more modern c++ constructs, removing dependices in the process (punt) Removed ODBC support; it hasn't been touched since the initial implementation in 2008, and there is a lack of someone to maintain the code. (punt) Removed some platform specific files like uoxlinux.h, which is no longer required (punt) Removed legacy crash protection code, and removed support for cluox (punt) Removed legacy "support" for Borland compiler (punt) Removed legacy VC++ 6 Workspace/Project files, VS2005 Solution/Project files, as these are no longer supported (Xuri) Removed legacy BUILD folder with outdated compilation instructions (Xuri) Removed old Changelog file (merged into Changelog.txt) (Xuri) Fixed a pointer bug for items in multis on world load (punt) Fixed a dictionary related issue that caused segmentation faults on Linux/MacOS (punt) Fixed an issue with callbacks to JS scripts that caused segmentation faults on Linux/MacOS (punt) Paths in uox.ini should now load properly on all platforms regardless of whether those paths use slashes or backslashes, and whether or not they end in a slash/backslash. (punt) Moved to c++17 style of threading, and got rid of threadsafeobject.cpp/h (punt) Replaced parsing of UOX.INI tags with a system that's more easily maintainable (punt) Added some new commands to js/commands/custom/misc-cmd.js (Xuri) cont // Targeted item will be made a container, set to nondecay and movable 2 endfight // Targeted character (and character being fought) will stop fighting getmulti // Get multiObject for targeted item finditem // Find item at layer X movespeed // Set movement speed of target player (0x0 Normal, 0x1 Mounted, 0x2 Slow (walk only), 0x3 Hybrid ("jog"?), 0x4 Frozen) Added new HTML based documentation in docs folder, and removed many old legacy docs that are either incorporated into this document already or no longer relevant for the current UOX3 version (Xuri) Co-Authored-By: Charles Kerr <punt1959@users.noreply.github.com>
2020-09-07 18:09:55 +08:00
return js_GetScriptFilenameFlags(script->filename);
}
JS_PUBLIC_API(JSBool)
JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags)
{
if (!js_SaveScriptFilenameRT(rt, prefix, flags))
return JS_FALSE;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_IsSystemObject(JSContext *cx, JSObject *obj)
{
return obj->isSystem();
}
JS_PUBLIC_API(JSBool)
JS_MakeSystemObject(JSContext *cx, JSObject *obj)
2023-07-12 13:27:26 +10:00
{
obj->setSystem();
return true;
2023-07-12 13:27:26 +10:00
}
/************************************************************************/
JS_PUBLIC_API(JSObject *)
JS_UnwrapObject(JSContext *cx, JSObject *obj)
{
return obj->unwrap();
}
/************************************************************************/
JS_FRIEND_API(void)
js_RevertVersion(JSContext *cx)
{
cx->clearVersionOverride();
}
JS_PUBLIC_API(const JSDebugHooks *)
2023-07-12 13:27:26 +10:00
JS_GetGlobalDebugHooks(JSRuntime *rt)
{
return &rt->globalDebugHooks;
}
const JSDebugHooks js_NullDebugHooks = {};
2023-07-12 13:27:26 +10:00
JS_PUBLIC_API(JSDebugHooks *)
JS_SetContextDebugHooks(JSContext *cx, const JSDebugHooks *hooks)
2023-07-12 13:27:26 +10:00
{
JS_ASSERT(hooks);
if (hooks != &cx->runtime->globalDebugHooks && hooks != &js_NullDebugHooks)
LeaveTrace(cx);
#ifdef JS_TRACER
AutoLockGC lock(cx->runtime);
#endif
JSDebugHooks *old = const_cast<JSDebugHooks *>(cx->debugHooks);
2023-07-12 13:27:26 +10:00
cx->debugHooks = hooks;
#ifdef JS_TRACER
cx->updateJITEnabled();
#endif
2023-07-12 13:27:26 +10:00
return old;
}
JS_PUBLIC_API(JSDebugHooks *)
JS_ClearContextDebugHooks(JSContext *cx)
{
return JS_SetContextDebugHooks(cx, &js_NullDebugHooks);
}
2023-07-12 13:27:26 +10:00
JS_PUBLIC_API(JSBool)
JS_StartProfiling()
2023-07-12 13:27:26 +10:00
{
return Probes::startProfiling();
2023-07-12 13:27:26 +10:00
}
JS_PUBLIC_API(void)
JS_StopProfiling()
2023-07-12 13:27:26 +10:00
{
Probes::stopProfiling();
2023-07-12 13:27:26 +10:00
}
#ifdef MOZ_PROFILING
2023-07-12 13:27:26 +10:00
static JSBool
StartProfiling(JSContext *cx, uintN argc, jsval *vp)
2023-07-12 13:27:26 +10:00
{
JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(JS_StartProfiling()));
return true;
2023-07-12 13:27:26 +10:00
}
static JSBool
StopProfiling(JSContext *cx, uintN argc, jsval *vp)
{
JS_StopProfiling();
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
}
2023-07-12 13:27:26 +10:00
#ifdef MOZ_SHARK
2023-07-12 13:27:26 +10:00
static JSBool
IgnoreAndReturnTrue(JSContext *cx, uintN argc, jsval *vp)
{
JS_SET_RVAL(cx, vp, JSVAL_TRUE);
return true;
2023-07-12 13:27:26 +10:00
}
#endif
2023-07-12 13:27:26 +10:00
static JSFunctionSpec profiling_functions[] = {
JS_FN("startProfiling", StartProfiling, 0,0),
JS_FN("stopProfiling", StopProfiling, 0,0),
#ifdef MOZ_SHARK
/* Keep users of the old shark API happy. */
JS_FN("connectShark", IgnoreAndReturnTrue, 0,0),
JS_FN("disconnectShark", IgnoreAndReturnTrue, 0,0),
JS_FN("startShark", StartProfiling, 0,0),
JS_FN("stopShark", StopProfiling, 0,0),
#endif
JS_FS_END
};
2023-07-12 13:27:26 +10:00
#endif
2023-07-12 13:27:26 +10:00
JS_PUBLIC_API(JSBool)
JS_DefineProfilingFunctions(JSContext *cx, JSObject *obj)
{
#ifdef MOZ_PROFILING
return JS_DefineFunctions(cx, obj, profiling_functions);
#else
return true;
#endif
2023-07-12 13:27:26 +10:00
}
#ifdef MOZ_CALLGRIND
#include <valgrind/callgrind.h>
JS_FRIEND_API(JSBool)
js_StartCallgrind(JSContext *cx, uintN argc, jsval *vp)
{
CALLGRIND_START_INSTRUMENTATION;
CALLGRIND_ZERO_STATS;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}
JS_FRIEND_API(JSBool)
js_StopCallgrind(JSContext *cx, uintN argc, jsval *vp)
{
CALLGRIND_STOP_INSTRUMENTATION;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}
JS_FRIEND_API(JSBool)
js_DumpCallgrind(JSContext *cx, uintN argc, jsval *vp)
{
JSString *str;
jsval *argv = JS_ARGV(cx, vp);
if (argc > 0 && JSVAL_IS_STRING(argv[0])) {
str = JSVAL_TO_STRING(argv[0]);
JSAutoByteString bytes(cx, str);
if (!!bytes) {
CALLGRIND_DUMP_STATS_AT(bytes.ptr());
return JS_TRUE;
}
}
CALLGRIND_DUMP_STATS;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}
#endif /* MOZ_CALLGRIND */
#ifdef MOZ_VTUNE
#include <VTuneApi.h>
static const char *vtuneErrorMessages[] = {
"unknown, error #0",
"invalid 'max samples' field",
"invalid 'samples per buffer' field",
"invalid 'sample interval' field",
"invalid path",
"sample file in use",
"invalid 'number of events' field",
"unknown, error #7",
"internal error",
"bad event name",
"VTStopSampling called without calling VTStartSampling",
"no events selected for event-based sampling",
"events selected cannot be run together",
"no sampling parameters",
"sample database already exists",
"sampling already started",
"time-based sampling not supported",
"invalid 'sampling parameters size' field",
"invalid 'event size' field",
"sampling file already bound",
"invalid event path",
"invalid license",
"invalid 'global options' field",
};
JS_FRIEND_API(JSBool)
js_StartVtune(JSContext *cx, uintN argc, jsval *vp)
{
VTUNE_EVENT events[] = {
{ 1000000, 0, 0, 0, "CPU_CLK_UNHALTED.CORE" },
{ 1000000, 0, 0, 0, "INST_RETIRED.ANY" },
};
U32 n_events = sizeof(events) / sizeof(VTUNE_EVENT);
char *default_filename = "mozilla-vtune.tb5";
JSString *str;
U32 status;
VTUNE_SAMPLING_PARAMS params = {
sizeof(VTUNE_SAMPLING_PARAMS),
sizeof(VTUNE_EVENT),
0, 0, /* Reserved fields */
1, /* Initialize in "paused" state */
0, /* Max samples, or 0 for "continuous" */
4096, /* Samples per buffer */
0.1, /* Sampling interval in ms */
1, /* 1 for event-based sampling, 0 for time-based */
n_events,
events,
default_filename,
};
jsval *argv = JS_ARGV(cx, vp);
if (argc > 0 && JSVAL_IS_STRING(argv[0])) {
str = JSVAL_TO_STRING(argv[0]);
params.tb5Filename = js_DeflateString(cx, str->chars(), str->length());
}
status = VTStartSampling(&params);
if (params.tb5Filename != default_filename)
cx->free(params.tb5Filename);
if (status != 0) {
if (status == VTAPI_MULTIPLE_RUNS)
VTStopSampling(0);
if (status < sizeof(vtuneErrorMessages))
JS_ReportError(cx, "Vtune setup error: %s",
vtuneErrorMessages[status]);
else
JS_ReportError(cx, "Vtune setup error: %d",
status);
return false;
}
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
}
JS_FRIEND_API(JSBool)
js_StopVtune(JSContext *cx, uintN argc, jsval *vp)
{
U32 status = VTStopSampling(1);
if (status) {
if (status < sizeof(vtuneErrorMessages))
JS_ReportError(cx, "Vtune shutdown error: %s",
vtuneErrorMessages[status]);
else
JS_ReportError(cx, "Vtune shutdown error: %d",
status);
return false;
}
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
}
JS_FRIEND_API(JSBool)
js_PauseVtune(JSContext *cx, uintN argc, jsval *vp)
{
VTPause();
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
}
JS_FRIEND_API(JSBool)
js_ResumeVtune(JSContext *cx, uintN argc, jsval *vp)
{
VTResume();
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
}
#endif /* MOZ_VTUNE */
#ifdef MOZ_TRACEVIS
/*
* Ethogram - Javascript wrapper for TraceVis state
*
* ethology: The scientific study of animal behavior,
* especially as it occurs in a natural environment.
* ethogram: A pictorial catalog of the behavioral patterns of
* an organism or a species.
*
*/
#if defined(XP_WIN)
#include "jswin.h"
#else
#include <sys/time.h>
#endif
#include "jstracer.h"
#define ETHOGRAM_BUF_SIZE 65536
static JSBool
ethogram_construct(JSContext *cx, uintN argc, jsval *vp);
static void
ethogram_finalize(JSContext *cx, JSObject *obj);
static JSClass ethogram_class = {
"Ethogram",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, ethogram_finalize,
JSCLASS_NO_OPTIONAL_MEMBERS
};
struct EthogramEvent {
TraceVisState s;
TraceVisExitReason r;
int ts;
int tus;
JSString *filename;
int lineno;
};
static int
compare_strings(const void *k1, const void *k2)
{
return strcmp((const char *) k1, (const char *) k2) == 0;
}
class EthogramEventBuffer {
private:
EthogramEvent mBuf[ETHOGRAM_BUF_SIZE];
int mReadPos;
int mWritePos;
JSObject *mFilenames;
int mStartSecond;
struct EthogramScriptEntry {
char *filename;
JSString *jsfilename;
EthogramScriptEntry *next;
};
EthogramScriptEntry *mScripts;
public:
friend JSBool
ethogram_construct(JSContext *cx, uintN argc, jsval *vp);
inline void push(TraceVisState s, TraceVisExitReason r, char *filename, int lineno) {
mBuf[mWritePos].s = s;
mBuf[mWritePos].r = r;
#if defined(XP_WIN)
FILETIME now;
GetSystemTimeAsFileTime(&now);
unsigned long long raw_us = 0.1 *
(((unsigned long long) now.dwHighDateTime << 32ULL) |
(unsigned long long) now.dwLowDateTime);
unsigned int sec = raw_us / 1000000L;
unsigned int usec = raw_us % 1000000L;
mBuf[mWritePos].ts = sec - mStartSecond;
mBuf[mWritePos].tus = usec;
#else
struct timeval tv;
gettimeofday(&tv, NULL);
mBuf[mWritePos].ts = tv.tv_sec - mStartSecond;
mBuf[mWritePos].tus = tv.tv_usec;
#endif
JSString *jsfilename = findScript(filename);
mBuf[mWritePos].filename = jsfilename;
mBuf[mWritePos].lineno = lineno;
mWritePos = (mWritePos + 1) % ETHOGRAM_BUF_SIZE;
if (mWritePos == mReadPos) {
mReadPos = (mWritePos + 1) % ETHOGRAM_BUF_SIZE;
}
}
inline EthogramEvent *pop() {
EthogramEvent *e = &mBuf[mReadPos];
mReadPos = (mReadPos + 1) % ETHOGRAM_BUF_SIZE;
return e;
}
bool isEmpty() {
return (mReadPos == mWritePos);
}
EthogramScriptEntry *addScript(JSContext *cx, JSObject *obj, char *filename, JSString *jsfilename) {
JSHashNumber hash = JS_HashString(filename);
JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, filename);
if (*hep != NULL)
return NULL;
JS_HashTableRawAdd(traceVisScriptTable, hep, hash, filename, this);
EthogramScriptEntry * entry = (EthogramScriptEntry *) JS_malloc(cx, sizeof(EthogramScriptEntry));
if (entry == NULL)
return NULL;
entry->next = mScripts;
mScripts = entry;
entry->filename = filename;
entry->jsfilename = jsfilename;
return mScripts;
}
void removeScripts(JSContext *cx) {
EthogramScriptEntry *se = mScripts;
while (se != NULL) {
char *filename = se->filename;
JSHashNumber hash = JS_HashString(filename);
JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, filename);
JSHashEntry *he = *hep;
if (he) {
/* we hardly knew he */
JS_HashTableRawRemove(traceVisScriptTable, hep, he);
}
EthogramScriptEntry *se_head = se;
se = se->next;
JS_free(cx, se_head);
}
}
JSString *findScript(char *filename) {
EthogramScriptEntry *se = mScripts;
while (se != NULL) {
if (compare_strings(se->filename, filename))
return (se->jsfilename);
se = se->next;
}
return NULL;
}
JSObject *filenames() {
return mFilenames;
}
int length() {
if (mWritePos < mReadPos)
return (mWritePos + ETHOGRAM_BUF_SIZE) - mReadPos;
else
return mWritePos - mReadPos;
}
};
static char jstv_empty[] = "<null>";
inline char *
jstv_Filename(JSStackFrame *fp)
{
while (fp && !fp->isScriptFrame())
fp = fp->prev();
return (fp && fp->maybeScript() && fp->script()->filename)
? (char *)fp->script()->filename
: jstv_empty;
}
inline uintN
jstv_Lineno(JSContext *cx, JSStackFrame *fp)
{
while (fp && fp->pc(cx) == NULL)
fp = fp->prev();
return (fp && fp->pc(cx)) ? js_FramePCToLineNumber(cx, fp) : 0;
}
/* Collect states here and distribute to a matching buffer, if any */
JS_FRIEND_API(void)
js::StoreTraceVisState(JSContext *cx, TraceVisState s, TraceVisExitReason r)
{
JSStackFrame *fp = cx->fp();
char *script_file = jstv_Filename(fp);
JSHashNumber hash = JS_HashString(script_file);
JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, script_file);
/* update event buffer, flag if overflowed */
JSHashEntry *he = *hep;
if (he) {
EthogramEventBuffer *p;
p = (EthogramEventBuffer *) he->value;
p->push(s, r, script_file, jstv_Lineno(cx, fp));
}
}
static JSBool
ethogram_construct(JSContext *cx, uintN argc, jsval *vp)
{
EthogramEventBuffer *p;
p = (EthogramEventBuffer *) JS_malloc(cx, sizeof(EthogramEventBuffer));
if (!p)
return JS_FALSE;
p->mReadPos = p->mWritePos = 0;
p->mScripts = NULL;
p->mFilenames = JS_NewArrayObject(cx, 0, NULL);
#if defined(XP_WIN)
FILETIME now;
GetSystemTimeAsFileTime(&now);
unsigned long long raw_us = 0.1 *
(((unsigned long long) now.dwHighDateTime << 32ULL) |
(unsigned long long) now.dwLowDateTime);
unsigned int s = raw_us / 1000000L;
p->mStartSecond = s;
#else
struct timeval tv;
gettimeofday(&tv, NULL);
p->mStartSecond = tv.tv_sec;
#endif
JSObject *obj;
if (JS_IsConstructing(cx, vp)) {
obj = JS_NewObject(cx, &ethogram_class, NULL, NULL);
if (!obj)
return JS_FALSE;
} else {
obj = JS_THIS_OBJECT(cx, vp);
}
jsval filenames = OBJECT_TO_JSVAL(p->filenames());
if (!JS_DefineProperty(cx, obj, "filenames", filenames,
NULL, NULL, JSPROP_READONLY|JSPROP_PERMANENT))
return JS_FALSE;
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
JS_SetPrivate(cx, obj, p);
return JS_TRUE;
}
static void
ethogram_finalize(JSContext *cx, JSObject *obj)
{
EthogramEventBuffer *p;
p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, &ethogram_class, NULL);
if (!p)
return;
p->removeScripts(cx);
JS_free(cx, p);
}
static JSBool
ethogram_addScript(JSContext *cx, uintN argc, jsval *vp)
{
JSString *str;
char *filename = NULL;
jsval *argv = JS_ARGV(cx, vp);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return false;
if (argc < 1) {
/* silently ignore no args */
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
}
if (JSVAL_IS_STRING(argv[0])) {
str = JSVAL_TO_STRING(argv[0]);
filename = js_DeflateString(cx, str->chars(), str->length());
if (!filename)
return false;
}
EthogramEventBuffer *p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, &ethogram_class, argv);
p->addScript(cx, obj, filename, str);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
jsval dummy;
JS_CallFunctionName(cx, p->filenames(), "push", 1, argv, &dummy);
return true;
}
static JSBool
ethogram_getAllEvents(JSContext *cx, uintN argc, jsval *vp)
{
EthogramEventBuffer *p;
jsval *argv = JS_ARGV(cx, vp);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, &ethogram_class, argv);
if (!p)
return JS_FALSE;
if (p->isEmpty()) {
JS_SET_RVAL(cx, vp, JSVAL_NULL);
return JS_TRUE;
}
JSObject *rarray = JS_NewArrayObject(cx, 0, NULL);
if (rarray == NULL) {
JS_SET_RVAL(cx, vp, JSVAL_NULL);
return JS_TRUE;
}
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(rarray));
for (int i = 0; !p->isEmpty(); i++) {
JSObject *x = JS_NewObject(cx, NULL, NULL, NULL);
if (x == NULL)
return JS_FALSE;
EthogramEvent *e = p->pop();
jsval state = INT_TO_JSVAL(e->s);
jsval reason = INT_TO_JSVAL(e->r);
jsval ts = INT_TO_JSVAL(e->ts);
jsval tus = INT_TO_JSVAL(e->tus);
jsval filename = STRING_TO_JSVAL(e->filename);
jsval lineno = INT_TO_JSVAL(e->lineno);
if (!JS_SetProperty(cx, x, "state", &state))
return JS_FALSE;
if (!JS_SetProperty(cx, x, "reason", &reason))
return JS_FALSE;
if (!JS_SetProperty(cx, x, "ts", &ts))
return JS_FALSE;
if (!JS_SetProperty(cx, x, "tus", &tus))
return JS_FALSE;
if (!JS_SetProperty(cx, x, "filename", &filename))
return JS_FALSE;
if (!JS_SetProperty(cx, x, "lineno", &lineno))
return JS_FALSE;
jsval element = OBJECT_TO_JSVAL(x);
JS_SetElement(cx, rarray, i, &element);
}
return JS_TRUE;
}
static JSBool
ethogram_getNextEvent(JSContext *cx, uintN argc, jsval *vp)
{
EthogramEventBuffer *p;
jsval *argv = JS_ARGV(cx, vp);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, &ethogram_class, argv);
if (!p)
return JS_FALSE;
JSObject *x = JS_NewObject(cx, NULL, NULL, NULL);
if (x == NULL)
return JS_FALSE;
if (p->isEmpty()) {
JS_SET_RVAL(cx, vp, JSVAL_NULL);
return JS_TRUE;
}
EthogramEvent *e = p->pop();
jsval state = INT_TO_JSVAL(e->s);
jsval reason = INT_TO_JSVAL(e->r);
jsval ts = INT_TO_JSVAL(e->ts);
jsval tus = INT_TO_JSVAL(e->tus);
jsval filename = STRING_TO_JSVAL(e->filename);
jsval lineno = INT_TO_JSVAL(e->lineno);
if (!JS_SetProperty(cx, x, "state", &state))
return JS_FALSE;
if (!JS_SetProperty(cx, x, "reason", &reason))
return JS_FALSE;
if (!JS_SetProperty(cx, x, "ts", &ts))
return JS_FALSE;
if (!JS_SetProperty(cx, x, "tus", &tus))
return JS_FALSE;
if (!JS_SetProperty(cx, x, "filename", &filename))
return JS_FALSE;
if (!JS_SetProperty(cx, x, "lineno", &lineno))
return JS_FALSE;
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(x));
return JS_TRUE;
}
static JSFunctionSpec ethogram_methods[] = {
JS_FN("addScript", ethogram_addScript, 1,0),
JS_FN("getAllEvents", ethogram_getAllEvents, 0,0),
JS_FN("getNextEvent", ethogram_getNextEvent, 0,0),
JS_FS_END
};
/*
* An |Ethogram| organizes the output of a collection of files that should be
* monitored together. A single object gets events for the group.
*/
JS_FRIEND_API(JSBool)
js_InitEthogram(JSContext *cx, uintN argc, jsval *vp)
{
if (!traceVisScriptTable) {
traceVisScriptTable = JS_NewHashTable(8, JS_HashString, compare_strings,
NULL, NULL, NULL);
}
JS_InitClass(cx, JS_GetGlobalObject(cx), NULL, &ethogram_class,
ethogram_construct, 0, NULL, ethogram_methods,
NULL, NULL);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
}
JS_FRIEND_API(JSBool)
js_ShutdownEthogram(JSContext *cx, uintN argc, jsval *vp)
{
if (traceVisScriptTable)
JS_HashTableDestroy(traceVisScriptTable);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
}
#endif /* MOZ_TRACEVIS */