Bug 581263 - remove slow natives (r=waldo,mrbkap)

This commit is contained in:
Luke Wagner 2010-08-16 12:35:04 -07:00
Родитель bf43b6fba4
Коммит fb78ed07aa
89 изменённых файлов: 1953 добавлений и 2136 удалений

Просмотреть файл

@ -111,11 +111,14 @@ getUTF8StringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum,
} }
static JSBool static JSBool
netscape_security_isPrivilegeEnabled(JSContext *cx, JSObject *obj, uintN argc, netscape_security_isPrivilegeEnabled(JSContext *cx, uintN argc, jsval *vp)
jsval *argv, jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
JSBool result = JS_FALSE; JSBool result = JS_FALSE;
char *cap = getStringArgument(cx, obj, 0, argc, argv); char *cap = getStringArgument(cx, obj, 0, argc, JS_ARGV(cx, vp));
if (cap) { if (cap) {
nsresult rv; nsresult rv;
nsCOMPtr<nsIScriptSecurityManager> securityManager = nsCOMPtr<nsIScriptSecurityManager> securityManager =
@ -128,16 +131,19 @@ netscape_security_isPrivilegeEnabled(JSContext *cx, JSObject *obj, uintN argc,
result = JS_FALSE; result = JS_FALSE;
} }
} }
*rval = BOOLEAN_TO_JSVAL(result); JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(result));
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
netscape_security_enablePrivilege(JSContext *cx, JSObject *obj, uintN argc, netscape_security_enablePrivilege(JSContext *cx, uintN argc, jsval *vp)
jsval *argv, jsval *rval)
{ {
char *cap = getStringArgument(cx, obj, 0, argc, argv); JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
char *cap = getStringArgument(cx, obj, 0, argc, JS_ARGV(cx, vp));
if (!cap) if (!cap)
return JS_FALSE; return JS_FALSE;
@ -152,14 +158,18 @@ netscape_security_enablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
rv = securityManager->EnableCapability(cap); rv = securityManager->EnableCapability(cap);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return JS_FALSE; return JS_FALSE;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
netscape_security_disablePrivilege(JSContext *cx, JSObject *obj, uintN argc, netscape_security_disablePrivilege(JSContext *cx, uintN argc, jsval *vp)
jsval *argv, jsval *rval)
{ {
char *cap = getStringArgument(cx, obj, 0, argc, argv); JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
char *cap = getStringArgument(cx, obj, 0, argc, JS_ARGV(cx, vp));
if (!cap) if (!cap)
return JS_FALSE; return JS_FALSE;
@ -174,14 +184,18 @@ netscape_security_disablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
rv = securityManager->DisableCapability(cap); rv = securityManager->DisableCapability(cap);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return JS_FALSE; return JS_FALSE;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
netscape_security_revertPrivilege(JSContext *cx, JSObject *obj, uintN argc, netscape_security_revertPrivilege(JSContext *cx, uintN argc, jsval *vp)
jsval *argv, jsval *rval)
{ {
char *cap = getStringArgument(cx, obj, 0, argc, argv); JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
char *cap = getStringArgument(cx, obj, 0, argc, JS_ARGV(cx, vp));
if (!cap) if (!cap)
return JS_FALSE; return JS_FALSE;
@ -196,17 +210,21 @@ netscape_security_revertPrivilege(JSContext *cx, JSObject *obj, uintN argc,
rv = securityManager->RevertCapability(cap); rv = securityManager->RevertCapability(cap);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return JS_FALSE; return JS_FALSE;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
netscape_security_setCanEnablePrivilege(JSContext *cx, JSObject *obj, uintN argc, netscape_security_setCanEnablePrivilege(JSContext *cx, uintN argc, jsval *vp)
jsval *argv, jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
if (argc < 2) return JS_FALSE; if (argc < 2) return JS_FALSE;
nsCAutoString principalFingerprint; nsCAutoString principalFingerprint;
getUTF8StringArgument(cx, obj, 0, argc, argv, principalFingerprint); getUTF8StringArgument(cx, obj, 0, argc, JS_ARGV(cx, vp), principalFingerprint);
char *cap = getStringArgument(cx, obj, 1, argc, argv); char *cap = getStringArgument(cx, obj, 1, argc, JS_ARGV(cx, vp));
if (principalFingerprint.IsEmpty() || !cap) if (principalFingerprint.IsEmpty() || !cap)
return JS_FALSE; return JS_FALSE;
@ -222,15 +240,19 @@ netscape_security_setCanEnablePrivilege(JSContext *cx, JSObject *obj, uintN argc
nsIPrincipal::ENABLE_GRANTED); nsIPrincipal::ENABLE_GRANTED);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return JS_FALSE; return JS_FALSE;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
netscape_security_invalidate(JSContext *cx, JSObject *obj, uintN argc, netscape_security_invalidate(JSContext *cx, uintN argc, jsval *vp)
jsval *argv, jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
nsCAutoString principalFingerprint; nsCAutoString principalFingerprint;
getUTF8StringArgument(cx, obj, 0, argc, argv, principalFingerprint); getUTF8StringArgument(cx, obj, 0, argc, JS_ARGV(cx, vp), principalFingerprint);
if (principalFingerprint.IsEmpty()) if (principalFingerprint.IsEmpty())
return JS_FALSE; return JS_FALSE;
@ -247,19 +269,20 @@ netscape_security_invalidate(JSContext *cx, JSObject *obj, uintN argc,
nsIPrincipal::ENABLE_GRANTED); nsIPrincipal::ENABLE_GRANTED);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return JS_FALSE; return JS_FALSE;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSFunctionSpec PrivilegeManager_static_methods[] = { static JSFunctionSpec PrivilegeManager_static_methods[] = {
{ "isPrivilegeEnabled", netscape_security_isPrivilegeEnabled, 1,0,0}, { "isPrivilegeEnabled", netscape_security_isPrivilegeEnabled, 1,0},
{ "enablePrivilege", netscape_security_enablePrivilege, 1,0,0}, { "enablePrivilege", netscape_security_enablePrivilege, 1,0},
{ "disablePrivilege", netscape_security_disablePrivilege, 1,0,0}, { "disablePrivilege", netscape_security_disablePrivilege, 1,0},
{ "revertPrivilege", netscape_security_revertPrivilege, 1,0,0}, { "revertPrivilege", netscape_security_revertPrivilege, 1,0},
//-- System Cert Functions //-- System Cert Functions
{ "setCanEnablePrivilege", netscape_security_setCanEnablePrivilege, { "setCanEnablePrivilege", netscape_security_setCanEnablePrivilege,
2,0,0}, 2,0},
{ "invalidate", netscape_security_invalidate, 1,0,0}, { "invalidate", netscape_security_invalidate, 1,0},
{nsnull,nsnull,0,0,0} {nsnull,nsnull,0,0}
}; };
/* /*

Просмотреть файл

@ -6527,10 +6527,13 @@ nsCommonWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
// Native code for window._content getter, this simply maps // Native code for window._content getter, this simply maps
// window._content to window.content for backwards compatibility only. // window._content to window.content for backwards compatibility only.
static JSBool static JSBool
ContentWindowGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, ContentWindowGetter(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
return ::JS_GetProperty(cx, obj, "content", rval); JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
return ::JS_GetProperty(cx, obj, "content", vp);
} }
PRBool PRBool
@ -8723,16 +8726,20 @@ ResolveImpl(JSContext *cx, nsIXPConnectWrappedNative *wrapper, jsid id,
// static // static
JSBool JSBool
nsHTMLDocumentSH::DocumentOpen(JSContext *cx, JSObject *obj, uintN argc, nsHTMLDocumentSH::DocumentOpen(JSContext *cx, uintN argc, jsval *vp)
jsval *argv, jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
jsval *argv = JS_ARGV(cx, vp);
if (argc > 2) { if (argc > 2) {
JSObject *global = ::JS_GetGlobalForObject(cx, obj); JSObject *global = ::JS_GetGlobalForObject(cx, obj);
// DOM0 quirk that makes document.open() call window.open() if // DOM0 quirk that makes document.open() call window.open() if
// called with 3 or more arguments. // called with 3 or more arguments.
return ::JS_CallFunctionName(cx, global, "open", argc, argv, rval); return ::JS_CallFunctionName(cx, global, "open", argc, JS_ARGV(cx, vp), vp);
} }
nsCOMPtr<nsISupports> native = do_QueryWrapper(cx, obj); nsCOMPtr<nsISupports> native = do_QueryWrapper(cx, obj);
@ -8785,7 +8792,7 @@ nsHTMLDocumentSH::DocumentOpen(JSContext *cx, JSObject *obj, uintN argc,
} }
nsCOMPtr<nsIXPConnectJSObjectHolder> holder; nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = WrapNative(cx, obj, retval, PR_FALSE, rval, rv = WrapNative(cx, obj, retval, PR_FALSE, vp,
getter_AddRefs(holder)); getter_AddRefs(holder));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to wrap native!"); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to wrap native!");
@ -9061,8 +9068,7 @@ nsHTMLDocumentSH::ReleaseDocument(JSContext *cx, JSObject *obj)
} }
JSBool JSBool
nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, JSObject *obj, uintN argc, nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, uintN argc, jsval *vp)
jsval *argv, jsval *rval)
{ {
// Handle document.all("foo") style access to document.all. // Handle document.all("foo") style access to document.all.
@ -9076,28 +9082,30 @@ nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, JSObject *obj, uintN argc,
} }
// Convert all types to string. // Convert all types to string.
JSString *str = ::JS_ValueToString(cx, argv[0]); JSString *str = ::JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) { if (!str) {
return JS_FALSE; return JS_FALSE;
} }
JSObject *self; JSObject *self;
if (::JS_TypeOfValue(cx, argv[-2]) == JSTYPE_FUNCTION) { if (::JS_TypeOfValue(cx, JS_CALLEE(cx, vp)) == JSTYPE_FUNCTION) {
// If argv[-2] is a function, we're called through // If the callee is a function, we're called through
// document.all.item() or something similar. In such a case, self // document.all.item() or something similar. In such a case, self
// is passed as obj. // is passed as obj.
self = obj; self = JS_THIS_OBJECT(cx, vp);
if (!self)
return JS_FALSE;
} else { } else {
// In other cases (i.e. document.all("foo")), self is passed as // In other cases (i.e. document.all("foo")), self is passed as
// argv[-2]. // the callee
self = JSVAL_TO_OBJECT(argv[-2]); self = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
} }
return ::JS_GetUCProperty(cx, self, ::JS_GetStringChars(str), return ::JS_GetUCProperty(cx, self, ::JS_GetStringChars(str),
::JS_GetStringLength(str), rval); ::JS_GetStringLength(str), vp);
} }

Просмотреть файл

@ -999,8 +999,7 @@ protected:
{ {
} }
static JSBool DocumentOpen(JSContext *cx, JSObject *obj, uintN argc, static JSBool DocumentOpen(JSContext *cx, uintN argc, jsval *vp);
jsval *argv, jsval *rval);
static JSBool GetDocumentAllNodeList(JSContext *cx, JSObject *obj, static JSBool GetDocumentAllNodeList(JSContext *cx, JSObject *obj,
nsDocument *doc, nsDocument *doc,
nsContentList **nodeList); nsContentList **nodeList);
@ -1011,8 +1010,7 @@ public:
static JSBool DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsid id, static JSBool DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsid id,
uintN flags, JSObject **objp); uintN flags, JSObject **objp);
static void ReleaseDocument(JSContext *cx, JSObject *obj); static void ReleaseDocument(JSContext *cx, JSObject *obj);
static JSBool CallToGetPropMapper(JSContext *cx, JSObject *obj, uintN argc, static JSBool CallToGetPropMapper(JSContext *cx, uintN argc, jsval *vp);
jsval *argv, jsval *rval);
static JSBool DocumentAllHelperGetProperty(JSContext *cx, JSObject *obj, static JSBool DocumentAllHelperGetProperty(JSContext *cx, JSObject *obj,
jsid id, jsval *vp); jsid id, jsval *vp);
static JSBool DocumentAllHelperNewResolve(JSContext *cx, JSObject *obj, static JSBool DocumentAllHelperNewResolve(JSContext *cx, JSObject *obj,

Просмотреть файл

@ -559,7 +559,7 @@ NS_ScriptErrorReporter(JSContext *cx,
if (!JSREPORT_IS_WARNING(report->flags)) { if (!JSREPORT_IS_WARNING(report->flags)) {
JSStackFrame * fp = nsnull; JSStackFrame * fp = nsnull;
while ((fp = JS_FrameIterator(cx, &fp))) { while ((fp = JS_FrameIterator(cx, &fp))) {
if (!JS_IsNativeFrame(cx, fp)) { if (JS_IsScriptFrame(cx, fp)) {
return; return;
} }
} }
@ -3161,21 +3161,23 @@ static JSClass OptionsClass = {
#include "nsTraceMalloc.h" #include "nsTraceMalloc.h"
static JSBool static JSBool
TraceMallocDisable(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) TraceMallocDisable(JSContext *cx, uintN argc, jsval *vp)
{ {
NS_TraceMallocDisable(); NS_TraceMallocDisable();
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
TraceMallocEnable(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) TraceMallocEnable(JSContext *cx, uintN argc, jsval *vp)
{ {
NS_TraceMallocEnable(); NS_TraceMallocEnable();
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
TraceMallocOpenLogFile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) TraceMallocOpenLogFile(JSContext *cx, uintN argc, jsval *vp)
{ {
int fd; int fd;
JSString *str; JSString *str;
@ -3184,7 +3186,7 @@ TraceMallocOpenLogFile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js
if (argc == 0) { if (argc == 0) {
fd = -1; fd = -1;
} else { } else {
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
filename = JS_GetStringBytes(str); filename = JS_GetStringBytes(str);
@ -3194,19 +3196,19 @@ TraceMallocOpenLogFile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js
return JS_FALSE; return JS_FALSE;
} }
} }
*rval = INT_TO_JSVAL(fd); JS_SET_RVAL(cx, vp, INT_TO_JSVAL(fd));
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
TraceMallocChangeLogFD(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) TraceMallocChangeLogFD(JSContext *cx, uintN argc, jsval *vp)
{ {
int32 fd, oldfd; int32 fd, oldfd;
if (argc == 0) { if (argc == 0) {
oldfd = -1; oldfd = -1;
} else { } else {
if (!JS_ValueToECMAInt32(cx, argv[0], &fd)) if (!JS_ValueToECMAInt32(cx, JS_ARGV(cx, vp)[0], &fd))
return JS_FALSE; return JS_FALSE;
oldfd = NS_TraceMallocChangeLogFD(fd); oldfd = NS_TraceMallocChangeLogFD(fd);
if (oldfd == -2) { if (oldfd == -2) {
@ -3214,44 +3216,46 @@ TraceMallocChangeLogFD(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js
return JS_FALSE; return JS_FALSE;
} }
} }
*rval = INT_TO_JSVAL(oldfd); JS_SET_RVAL(cx, vp, INT_TO_JSVAL(oldfd));
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
TraceMallocCloseLogFD(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) TraceMallocCloseLogFD(JSContext *cx, uintN argc, jsval *vp)
{ {
int32 fd; int32 fd;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
if (argc == 0) if (argc == 0)
return JS_TRUE; return JS_TRUE;
if (!JS_ValueToECMAInt32(cx, argv[0], &fd)) if (!JS_ValueToECMAInt32(cx, JS_ARGV(cx, vp)[0], &fd))
return JS_FALSE; return JS_FALSE;
NS_TraceMallocCloseLogFD((int) fd); NS_TraceMallocCloseLogFD((int) fd);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
TraceMallocLogTimestamp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) TraceMallocLogTimestamp(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
const char *caption; const char *caption;
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
caption = JS_GetStringBytes(str); caption = JS_GetStringBytes(str);
NS_TraceMallocLogTimestamp(caption); NS_TraceMallocLogTimestamp(caption);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
TraceMallocDumpAllocations(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) TraceMallocDumpAllocations(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
const char *pathname; const char *pathname;
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
pathname = JS_GetStringBytes(str); pathname = JS_GetStringBytes(str);
@ -3259,18 +3263,19 @@ TraceMallocDumpAllocations(JSContext *cx, JSObject *obj, uintN argc, jsval *argv
JS_ReportError(cx, "can't dump to %s: %s", pathname, strerror(errno)); JS_ReportError(cx, "can't dump to %s: %s", pathname, strerror(errno));
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSFunctionSpec TraceMallocFunctions[] = { static JSFunctionSpec TraceMallocFunctions[] = {
{"TraceMallocDisable", TraceMallocDisable, 0, 0, 0}, {"TraceMallocDisable", TraceMallocDisable, 0, 0},
{"TraceMallocEnable", TraceMallocEnable, 0, 0, 0}, {"TraceMallocEnable", TraceMallocEnable, 0, 0},
{"TraceMallocOpenLogFile", TraceMallocOpenLogFile, 1, 0, 0}, {"TraceMallocOpenLogFile", TraceMallocOpenLogFile, 1, 0},
{"TraceMallocChangeLogFD", TraceMallocChangeLogFD, 1, 0, 0}, {"TraceMallocChangeLogFD", TraceMallocChangeLogFD, 1, 0},
{"TraceMallocCloseLogFD", TraceMallocCloseLogFD, 1, 0, 0}, {"TraceMallocCloseLogFD", TraceMallocCloseLogFD, 1, 0},
{"TraceMallocLogTimestamp", TraceMallocLogTimestamp, 1, 0, 0}, {"TraceMallocLogTimestamp", TraceMallocLogTimestamp, 1, 0},
{"TraceMallocDumpAllocations", TraceMallocDumpAllocations, 1, 0, 0}, {"TraceMallocDumpAllocations", TraceMallocDumpAllocations, 1, 0},
{nsnull, nsnull, 0, 0, 0} {nsnull, nsnull, 0, 0}
}; };
#endif /* NS_TRACE_MALLOC */ #endif /* NS_TRACE_MALLOC */
@ -3353,11 +3358,11 @@ static JSFunctionSpec JProfFunctions[] = {
#ifdef MOZ_SHARK #ifdef MOZ_SHARK
static JSFunctionSpec SharkFunctions[] = { static JSFunctionSpec SharkFunctions[] = {
{"startShark", js_StartShark, 0, 0, 0}, {"startShark", js_StartShark, 0, 0},
{"stopShark", js_StopShark, 0, 0, 0}, {"stopShark", js_StopShark, 0, 0},
{"connectShark", js_ConnectShark, 0, 0, 0}, {"connectShark", js_ConnectShark, 0, 0},
{"disconnectShark", js_DisconnectShark, 0, 0, 0}, {"disconnectShark", js_DisconnectShark, 0, 0},
{nsnull, nsnull, 0, 0, 0} {nsnull, nsnull, 0, 0}
}; };
#endif #endif

Просмотреть файл

@ -74,45 +74,38 @@ public:
// Same as window.dump(). // Same as window.dump().
static JSBool static JSBool
Dump(JSContext* aCx, JSObject* aObj, uintN aArgc, jsval* aArgv, jsval* aRval); Dump(JSContext* aCx, uintN aArgc, jsval* aVp);
// Same as window.setTimeout(). // Same as window.setTimeout().
static JSBool static JSBool
SetTimeout(JSContext* aCx, JSObject* aObj, uintN aArgc, jsval* aArgv, SetTimeout(JSContext* aCx, uintN aArgc, jsval* aVp) {
jsval* aRval) { return MakeTimeout(aCx, aArgc, aVp, PR_FALSE);
return MakeTimeout(aCx, aObj, aArgc, aArgv, aRval, PR_FALSE);
} }
// Same as window.setInterval(). // Same as window.setInterval().
static JSBool static JSBool
SetInterval(JSContext* aCx, JSObject* aObj, uintN aArgc, jsval* aArgv, SetInterval(JSContext* aCx, uintN aArgc, jsval* aVp) {
jsval* aRval) { return MakeTimeout(aCx, aArgc, aVp, PR_TRUE);
return MakeTimeout(aCx, aObj, aArgc, aArgv, aRval, PR_TRUE);
} }
// Used for both clearTimeout() and clearInterval(). // Used for both clearTimeout() and clearInterval().
static JSBool static JSBool
KillTimeout(JSContext* aCx, JSObject* aObj, uintN aArgc, jsval* aArgv, KillTimeout(JSContext* aCx, uintN aArgc, jsval* aVp);
jsval* aRval);
static JSBool static JSBool
LoadScripts(JSContext* aCx, JSObject* aObj, uintN aArgc, jsval* aArgv, LoadScripts(JSContext* aCx, uintN aArgc, jsval* aVp);
jsval* aRval);
static JSBool static JSBool
NewXMLHttpRequest(JSContext* aCx, JSObject* aObj, uintN aArgc, jsval* aArgv, NewXMLHttpRequest(JSContext* aCx, uintN aArgc, jsval* aVp);
jsval* aRval);
static JSBool static JSBool
NewWorker(JSContext* aCx, JSObject* aObj, uintN aArgc, jsval* aArgv, NewWorker(JSContext* aCx, uintN aArgc, jsval* aVp) {
jsval* aRval) { return MakeNewWorker(aCx, aArgc, aVp, nsDOMWorker::CONTENT);
return MakeNewWorker(aCx, aObj, aArgc, aArgv, aRval, nsDOMWorker::CONTENT);
} }
// Chrome-only functions // Chrome-only functions
static JSBool static JSBool
NewChromeWorker(JSContext* aCx, JSObject* aObj, uintN aArgc, jsval* aArgv, NewChromeWorker(JSContext* aCx, uintN aArgc, jsval* aVp);
jsval* aRval);
#ifdef BUILD_CTYPES #ifdef BUILD_CTYPES
static JSBool static JSBool
@ -122,27 +115,25 @@ public:
private: private:
// Internal helper for SetTimeout and SetInterval. // Internal helper for SetTimeout and SetInterval.
static JSBool static JSBool
MakeTimeout(JSContext* aCx, JSObject* aObj, uintN aArgc, jsval* aArgv, MakeTimeout(JSContext* aCx, uintN aArgc, jsval* aVp, PRBool aIsInterval);
jsval* aRval, PRBool aIsInterval);
static JSBool static JSBool
MakeNewWorker(JSContext* aCx, JSObject* aObj, uintN aArgc, jsval* aArgv, MakeNewWorker(JSContext* aCx, uintN aArgc, jsval* aVp,
jsval* aRval, WorkerPrivilegeModel aPrivilegeModel); WorkerPrivilegeModel aPrivilegeModel);
}; };
JSBool JSBool
nsDOMWorkerFunctions::Dump(JSContext* aCx, nsDOMWorkerFunctions::Dump(JSContext* aCx,
JSObject* /* aObj */,
uintN aArgc, uintN aArgc,
jsval* aArgv, jsval* aVp)
jsval* /* aRval */)
{ {
JS_SET_RVAL(cx, aVp, JSVAL_VOID);
if (!nsGlobalWindow::DOMWindowDumpEnabled()) { if (!nsGlobalWindow::DOMWindowDumpEnabled()) {
return JS_TRUE; return JS_TRUE;
} }
JSString* str; JSString* str;
if (aArgc && (str = JS_ValueToString(aCx, aArgv[0])) && str) { if (aArgc && (str = JS_ValueToString(aCx, JS_ARGV(aCx, aVp)[0])) && str) {
nsDependentJSString string(str); nsDependentJSString string(str);
fputs(NS_ConvertUTF16toUTF8(nsDependentJSString(str)).get(), stderr); fputs(NS_ConvertUTF16toUTF8(nsDependentJSString(str)).get(), stderr);
fflush(stderr); fflush(stderr);
@ -152,10 +143,8 @@ nsDOMWorkerFunctions::Dump(JSContext* aCx,
JSBool JSBool
nsDOMWorkerFunctions::MakeTimeout(JSContext* aCx, nsDOMWorkerFunctions::MakeTimeout(JSContext* aCx,
JSObject* /* aObj */,
uintN aArgc, uintN aArgc,
jsval* aArgv, jsval* aVp,
jsval* aRval,
PRBool aIsInterval) PRBool aIsInterval)
{ {
nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx)); nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx));
@ -169,7 +158,7 @@ nsDOMWorkerFunctions::MakeTimeout(JSContext* aCx,
if (worker->IsClosing()) { if (worker->IsClosing()) {
// Timeouts won't run in the close handler, fake success and bail. // Timeouts won't run in the close handler, fake success and bail.
*aRval = INT_TO_JSVAL(id); JS_SET_RVAL(aCx, aVp, INT_TO_JSVAL(id));
return JS_TRUE; return JS_TRUE;
} }
@ -179,7 +168,7 @@ nsDOMWorkerFunctions::MakeTimeout(JSContext* aCx,
return JS_FALSE; return JS_FALSE;
} }
nsresult rv = timeout->Init(aCx, aArgc, aArgv, aIsInterval); nsresult rv = timeout->Init(aCx, aArgc, JS_ARGV(aCx, aVp), aIsInterval);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
JS_ReportError(aCx, "Failed to initialize timeout!"); JS_ReportError(aCx, "Failed to initialize timeout!");
return JS_FALSE; return JS_FALSE;
@ -197,16 +186,14 @@ nsDOMWorkerFunctions::MakeTimeout(JSContext* aCx,
return JS_FALSE; return JS_FALSE;
} }
*aRval = INT_TO_JSVAL(id); JS_SET_RVAL(aCx, aVp, INT_TO_JSVAL(id));
return JS_TRUE; return JS_TRUE;
} }
JSBool JSBool
nsDOMWorkerFunctions::KillTimeout(JSContext* aCx, nsDOMWorkerFunctions::KillTimeout(JSContext* aCx,
JSObject* /* aObj */,
uintN aArgc, uintN aArgc,
jsval* aArgv, jsval* aVp)
jsval* /* aRval */)
{ {
nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx)); nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx));
NS_ASSERTION(worker, "This should be set by the DOM thread service!"); NS_ASSERTION(worker, "This should be set by the DOM thread service!");
@ -221,21 +208,20 @@ nsDOMWorkerFunctions::KillTimeout(JSContext* aCx,
} }
uint32 id; uint32 id;
if (!JS_ValueToECMAUint32(aCx, aArgv[0], &id)) { if (!JS_ValueToECMAUint32(aCx, JS_ARGV(aCx, aVp)[0], &id)) {
JS_ReportError(aCx, "First argument must be a timeout id"); JS_ReportError(aCx, "First argument must be a timeout id");
return JS_FALSE; return JS_FALSE;
} }
worker->CancelTimeoutWithId(PRUint32(id)); worker->CancelTimeoutWithId(PRUint32(id));
JS_SET_RVAL(aCx, aVp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
JSBool JSBool
nsDOMWorkerFunctions::LoadScripts(JSContext* aCx, nsDOMWorkerFunctions::LoadScripts(JSContext* aCx,
JSObject* /* aObj */,
uintN aArgc, uintN aArgc,
jsval* aArgv, jsval* aVp)
jsval* /* aRval */)
{ {
nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx)); nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx));
NS_ASSERTION(worker, "This should be set by the DOM thread service!"); NS_ASSERTION(worker, "This should be set by the DOM thread service!");
@ -256,8 +242,9 @@ nsDOMWorkerFunctions::LoadScripts(JSContext* aCx,
return JS_FALSE; return JS_FALSE;
} }
jsval* argv = JS_ARGV(aCx, aVp);
for (uintN index = 0; index < aArgc; index++) { for (uintN index = 0; index < aArgc; index++) {
jsval val = aArgv[index]; jsval val = argv[index];
if (!JSVAL_IS_STRING(val)) { if (!JSVAL_IS_STRING(val)) {
JS_ReportError(aCx, "Argument %d must be a string", index); JS_ReportError(aCx, "Argument %d must be a string", index);
@ -297,16 +284,20 @@ nsDOMWorkerFunctions::LoadScripts(JSContext* aCx,
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(aCx, aVp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
JSBool JSBool
nsDOMWorkerFunctions::NewXMLHttpRequest(JSContext* aCx, nsDOMWorkerFunctions::NewXMLHttpRequest(JSContext* aCx,
JSObject* aObj,
uintN aArgc, uintN aArgc,
jsval* /* aArgv */, jsval* aVp)
jsval* aRval)
{ {
JSObject *obj = JS_THIS_OBJECT(aCx, aVp);
if (!obj) {
return JS_FALSE;
}
nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx)); nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx));
NS_ASSERTION(worker, "This should be set by the DOM thread service!"); NS_ASSERTION(worker, "This should be set by the DOM thread service!");
@ -339,7 +330,7 @@ nsDOMWorkerFunctions::NewXMLHttpRequest(JSContext* aCx,
nsCOMPtr<nsIXPConnectJSObjectHolder> xhrWrapped; nsCOMPtr<nsIXPConnectJSObjectHolder> xhrWrapped;
jsval v; jsval v;
rv = nsContentUtils::WrapNative(aCx, aObj, rv = nsContentUtils::WrapNative(aCx, obj,
static_cast<nsIXMLHttpRequest*>(xhr), &v, static_cast<nsIXMLHttpRequest*>(xhr), &v,
getter_AddRefs(xhrWrapped)); getter_AddRefs(xhrWrapped));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@ -347,16 +338,14 @@ nsDOMWorkerFunctions::NewXMLHttpRequest(JSContext* aCx,
return JS_FALSE; return JS_FALSE;
} }
*aRval = v; JS_SET_RVAL(aCs, aVp, v);
return JS_TRUE; return JS_TRUE;
} }
JSBool JSBool
nsDOMWorkerFunctions::NewChromeWorker(JSContext* aCx, nsDOMWorkerFunctions::NewChromeWorker(JSContext* aCx,
JSObject* aObj,
uintN aArgc, uintN aArgc,
jsval* aArgv, jsval* aVp)
jsval* aRval)
{ {
nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx)); nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx));
NS_ASSERTION(worker, "This should be set by the DOM thread service!"); NS_ASSERTION(worker, "This should be set by the DOM thread service!");
@ -366,17 +355,20 @@ nsDOMWorkerFunctions::NewChromeWorker(JSContext* aCx,
return JS_FALSE; return JS_FALSE;
} }
return MakeNewWorker(aCx, aObj, aArgc, aArgv, aRval, nsDOMWorker::CHROME); return MakeNewWorker(aCx, aArgc, aVp, nsDOMWorker::CHROME);
} }
JSBool JSBool
nsDOMWorkerFunctions::MakeNewWorker(JSContext* aCx, nsDOMWorkerFunctions::MakeNewWorker(JSContext* aCx,
JSObject* aObj,
uintN aArgc, uintN aArgc,
jsval* aArgv, jsval* aVp,
jsval* aRval,
WorkerPrivilegeModel aPrivilegeModel) WorkerPrivilegeModel aPrivilegeModel)
{ {
JSObject *obj = JS_THIS_OBJECT(aCx, aVp);
if (!obj) {
return JS_FALSE;
}
nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx)); nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx));
NS_ASSERTION(worker, "This should be set by the DOM thread service!"); NS_ASSERTION(worker, "This should be set by the DOM thread service!");
@ -411,7 +403,8 @@ nsDOMWorkerFunctions::MakeNewWorker(JSContext* aCx,
return JS_FALSE; return JS_FALSE;
} }
nsresult rv = newWorker->InitializeInternal(owner, aCx, aObj, aArgc, aArgv); nsresult rv = newWorker->InitializeInternal(owner, aCx, obj, aArgc,
JS_ARGV(aCx, aVp));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
JS_ReportError(aCx, "Couldn't initialize new worker!"); JS_ReportError(aCx, "Couldn't initialize new worker!");
return JS_FALSE; return JS_FALSE;
@ -419,14 +412,14 @@ nsDOMWorkerFunctions::MakeNewWorker(JSContext* aCx,
nsCOMPtr<nsIXPConnectJSObjectHolder> workerWrapped; nsCOMPtr<nsIXPConnectJSObjectHolder> workerWrapped;
jsval v; jsval v;
rv = nsContentUtils::WrapNative(aCx, aObj, static_cast<nsIWorker*>(newWorker), rv = nsContentUtils::WrapNative(aCx, obj, static_cast<nsIWorker*>(newWorker),
&v, getter_AddRefs(workerWrapped)); &v, getter_AddRefs(workerWrapped));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
JS_ReportError(aCx, "Failed to wrap new worker!"); JS_ReportError(aCx, "Failed to wrap new worker!");
return JS_FALSE; return JS_FALSE;
} }
*aRval = v; JS_SET_RVAL(aCx, aVp, v);
return JS_TRUE; return JS_TRUE;
} }
@ -460,26 +453,26 @@ nsDOMWorkerFunctions::CTypesLazyGetter(JSContext* aCx,
#endif #endif
JSFunctionSpec gDOMWorkerFunctions[] = { JSFunctionSpec gDOMWorkerFunctions[] = {
{ "dump", nsDOMWorkerFunctions::Dump, 1, 0, 0 }, { "dump", nsDOMWorkerFunctions::Dump, 1, 0 },
{ "setTimeout", nsDOMWorkerFunctions::SetTimeout, 1, 0, 0 }, { "setTimeout", nsDOMWorkerFunctions::SetTimeout, 1, 0 },
{ "clearTimeout", nsDOMWorkerFunctions::KillTimeout, 1, 0, 0 }, { "clearTimeout", nsDOMWorkerFunctions::KillTimeout, 1, 0 },
{ "setInterval", nsDOMWorkerFunctions::SetInterval, 1, 0, 0 }, { "setInterval", nsDOMWorkerFunctions::SetInterval, 1, 0 },
{ "clearInterval", nsDOMWorkerFunctions::KillTimeout, 1, 0, 0 }, { "clearInterval", nsDOMWorkerFunctions::KillTimeout, 1, 0 },
{ "importScripts", nsDOMWorkerFunctions::LoadScripts, 1, 0, 0 }, { "importScripts", nsDOMWorkerFunctions::LoadScripts, 1, 0 },
{ "XMLHttpRequest", nsDOMWorkerFunctions::NewXMLHttpRequest, 0, 0, 0 }, { "XMLHttpRequest", nsDOMWorkerFunctions::NewXMLHttpRequest, 0, 0 },
{ "Worker", nsDOMWorkerFunctions::NewWorker, 1, 0, 0 }, { "Worker", nsDOMWorkerFunctions::NewWorker, 1, 0 },
#ifdef MOZ_SHARK #ifdef MOZ_SHARK
{ "startShark", js_StartShark, 0, 0, 0 }, { "startShark", js_StartShark, 0, 0 },
{ "stopShark", js_StopShark, 0, 0, 0 }, { "stopShark", js_StopShark, 0, 0 },
{ "connectShark", js_ConnectShark, 0, 0, 0 }, { "connectShark", js_ConnectShark, 0, 0 },
{ "disconnectShark", js_DisconnectShark, 0, 0, 0 }, { "disconnectShark", js_DisconnectShark, 0, 0 },
#endif #endif
{ nsnull, nsnull, 0, 0, 0 } { nsnull, nsnull, 0, 0 }
}; };
JSFunctionSpec gDOMWorkerChromeFunctions[] = { JSFunctionSpec gDOMWorkerChromeFunctions[] = {
{ "ChromeWorker", nsDOMWorkerFunctions::NewChromeWorker, 1, 0, 0 }, { "ChromeWorker", nsDOMWorkerFunctions::NewChromeWorker, 1, 0 },
{ nsnull, nsnull, 0, 0, 0 } { nsnull, nsnull, 0, 0 }
}; };
nsDOMWorkerScope::nsDOMWorkerScope(nsDOMWorker* aWorker) nsDOMWorkerScope::nsDOMWorkerScope(nsDOMWorker* aWorker)

Просмотреть файл

@ -140,7 +140,7 @@ ScriptErrorReporter(JSContext *cx,
// Don't report an exception from inner JS frames as the callers may intend // Don't report an exception from inner JS frames as the callers may intend
// to handle it. // to handle it.
while ((fp = JS_FrameIterator(cx, &fp))) { while ((fp = JS_FrameIterator(cx, &fp))) {
if (!JS_IsNativeFrame(cx, fp)) { if (JS_IsScriptFrame(cx, fp)) {
return; return;
} }
} }
@ -243,14 +243,13 @@ ContextCallback(JSContext *cx,
static JSBool static JSBool
Print(JSContext *cx, Print(JSContext *cx,
JSObject *obj,
uintN argc, uintN argc,
jsval *argv, jsval *vp)
jsval *rval)
{ {
uintN i, n; uintN i, n;
JSString *str; JSString *str;
jsval *argv = JS_ARGV(cx, vp);
for (i = n = 0; i < argc; i++) { for (i = n = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]); str = JS_ValueToString(cx, argv[i]);
if (!str) if (!str)
@ -261,6 +260,7 @@ Print(JSContext *cx,
n++; n++;
if (n) if (n)
fputc('\n', stdout); fputc('\n', stdout);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -280,16 +280,16 @@ GetLine(char *bufp,
static JSBool static JSBool
Dump(JSContext *cx, Dump(JSContext *cx,
JSObject *obj,
uintN argc, uintN argc,
jsval *argv, jsval *vp)
jsval *rval)
{ {
JS_SET_RVAL(cx, vp, JSVAL_VOID);
JSString *str; JSString *str;
if (!argc) if (!argc)
return JS_TRUE; return JS_TRUE;
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
@ -300,10 +300,8 @@ Dump(JSContext *cx,
static JSBool static JSBool
Load(JSContext *cx, Load(JSContext *cx,
JSObject *obj,
uintN argc, uintN argc,
jsval *argv, jsval *vp)
jsval *rval)
{ {
uintN i; uintN i;
JSString *str; JSString *str;
@ -313,6 +311,11 @@ Load(JSContext *cx,
jsval result; jsval result;
FILE *file; FILE *file;
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]); str = JS_ValueToString(cx, argv[i]);
if (!str) if (!str)
@ -337,25 +340,25 @@ Load(JSContext *cx,
if (!ok) if (!ok)
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Version(JSContext *cx, Version(JSContext *cx,
JSObject *obj,
uintN argc, uintN argc,
jsval *argv, jsval *vp)
jsval *rval)
{ {
jsval *argv = JS_ARGV(cx, vp);
if (argc > 0 && JSVAL_IS_INT(argv[0])) if (argc > 0 && JSVAL_IS_INT(argv[0]))
*rval = INT_TO_JSVAL(JS_SetVersion(cx, JSVersion(JSVAL_TO_INT(argv[0])))); JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_SetVersion(cx, JSVersion(JSVAL_TO_INT(argv[0])))));
else else
*rval = INT_TO_JSVAL(JS_GetVersion(cx)); JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_GetVersion(cx)));
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
BuildDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) BuildDate(JSContext *cx, uintN argc, jsval *vp)
{ {
fprintf(stdout, "built on %s at %s\n", __DATE__, __TIME__); fprintf(stdout, "built on %s at %s\n", __DATE__, __TIME__);
return JS_TRUE; return JS_TRUE;
@ -363,13 +366,11 @@ BuildDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
static JSBool static JSBool
Quit(JSContext *cx, Quit(JSContext *cx,
JSObject *obj,
uintN argc, uintN argc,
jsval *argv, jsval *vp)
jsval *rval)
{ {
int exitCode = 0; int exitCode = 0;
JS_ConvertArguments(cx, argc, argv, "/ i", &exitCode); JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/ i", &exitCode);
XPCShellEnvironment* env = Environment(cx); XPCShellEnvironment* env = Environment(cx);
env->SetExitCode(exitCode); env->SetExitCode(exitCode);
@ -380,30 +381,27 @@ Quit(JSContext *cx,
static JSBool static JSBool
DumpXPC(JSContext *cx, DumpXPC(JSContext *cx,
JSObject *obj,
uintN argc, uintN argc,
jsval *argv, jsval *vp)
jsval *rval)
{ {
int32 depth = 2; int32 depth = 2;
if (argc > 0) { if (argc > 0) {
if (!JS_ValueToInt32(cx, argv[0], &depth)) if (!JS_ValueToInt32(cx, JS_ARGV(cx, vp)[0], &depth))
return JS_FALSE; return JS_FALSE;
} }
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID()); nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
if(xpc) if(xpc)
xpc->DebugDump((int16)depth); xpc->DebugDump((int16)depth);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
GC(JSContext *cx, GC(JSContext *cx,
JSObject *obj,
uintN argc, uintN argc,
jsval *argv, jsval *vp)
jsval *rval)
{ {
JSRuntime *rt; JSRuntime *rt;
uint32 preBytes; uint32 preBytes;
@ -422,6 +420,7 @@ GC(JSContext *cx,
#ifdef JS_GCMETER #ifdef JS_GCMETER
js_DumpGCStats(rt, stdout); js_DumpGCStats(rt, stdout);
#endif #endif
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -429,10 +428,8 @@ GC(JSContext *cx,
static JSBool static JSBool
DumpHeap(JSContext *cx, DumpHeap(JSContext *cx,
JSObject *obj,
uintN argc, uintN argc,
jsval *argv, jsval *vp)
jsval *rval)
{ {
char *fileName = NULL; char *fileName = NULL;
void* startThing = NULL; void* startThing = NULL;
@ -440,12 +437,14 @@ DumpHeap(JSContext *cx,
void *thingToFind = NULL; void *thingToFind = NULL;
size_t maxDepth = (size_t)-1; size_t maxDepth = (size_t)-1;
void *thingToIgnore = NULL; void *thingToIgnore = NULL;
jsval *vp;
FILE *dumpFile; FILE *dumpFile;
JSBool ok; JSBool ok;
vp = &argv[0]; jsval *argv = JS_ARGV(cx, vp);
if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) { JS_SET_RVAL(cx, vp, JSVAL_VOID);
vp = argv + 0;
if (argc > 0 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
JSString *str; JSString *str;
str = JS_ValueToString(cx, *vp); str = JS_ValueToString(cx, *vp);
@ -455,23 +454,23 @@ DumpHeap(JSContext *cx,
fileName = JS_GetStringBytes(str); fileName = JS_GetStringBytes(str);
} }
vp = &argv[1]; vp = argv + 1;
if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) { if (argc > 1 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
if (!JSVAL_IS_TRACEABLE(*vp)) if (!JSVAL_IS_TRACEABLE(*vp))
goto not_traceable_arg; goto not_traceable_arg;
startThing = JSVAL_TO_TRACEABLE(*vp); startThing = JSVAL_TO_TRACEABLE(*vp);
startTraceKind = JSVAL_TRACE_KIND(*vp); startTraceKind = JSVAL_TRACE_KIND(*vp);
} }
vp = &argv[2]; vp = argv + 2;
if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) { if (argc > 2 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
if (!JSVAL_IS_TRACEABLE(*vp)) if (!JSVAL_IS_TRACEABLE(*vp))
goto not_traceable_arg; goto not_traceable_arg;
thingToFind = JSVAL_TO_TRACEABLE(*vp); thingToFind = JSVAL_TO_TRACEABLE(*vp);
} }
vp = &argv[3]; vp = argv + 3;
if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) { if (argc > 3 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
uint32 depth; uint32 depth;
if (!JS_ValueToECMAUint32(cx, *vp, &depth)) if (!JS_ValueToECMAUint32(cx, *vp, &depth))
@ -479,8 +478,8 @@ DumpHeap(JSContext *cx,
maxDepth = depth; maxDepth = depth;
} }
vp = &argv[4]; vp = argv + 4;
if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) { if (argc > 4 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
if (!JSVAL_IS_TRACEABLE(*vp)) if (!JSVAL_IS_TRACEABLE(*vp))
goto not_traceable_arg; goto not_traceable_arg;
thingToIgnore = JSVAL_TO_TRACEABLE(*vp); thingToIgnore = JSVAL_TO_TRACEABLE(*vp);
@ -514,46 +513,46 @@ DumpHeap(JSContext *cx,
static JSBool static JSBool
Clear(JSContext *cx, Clear(JSContext *cx,
JSObject *obj,
uintN argc, uintN argc,
jsval *argv, jsval *vp)
jsval *rval)
{ {
jsval *argv = JS_ARGV(cx, vp);
if (argc > 0 && !JSVAL_IS_PRIMITIVE(argv[0])) { if (argc > 0 && !JSVAL_IS_PRIMITIVE(argv[0])) {
JS_ClearScope(cx, JSVAL_TO_OBJECT(argv[0])); JS_ClearScope(cx, JSVAL_TO_OBJECT(argv[0]));
} else { } else {
JS_ReportError(cx, "'clear' requires an object"); JS_ReportError(cx, "'clear' requires an object");
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
JSFunctionSpec gGlobalFunctions[] = JSFunctionSpec gGlobalFunctions[] =
{ {
{"print", Print, 0,0,0}, {"print", Print, 0,0},
{"load", Load, 1,0,0}, {"load", Load, 1,0},
{"quit", Quit, 0,0,0}, {"quit", Quit, 0,0},
{"version", Version, 1,0,0}, {"version", Version, 1,0},
{"build", BuildDate, 0,0,0}, {"build", BuildDate, 0,0},
{"dumpXPC", DumpXPC, 1,0,0}, {"dumpXPC", DumpXPC, 1,0},
{"dump", Dump, 1,0,0}, {"dump", Dump, 1,0},
{"gc", GC, 0,0,0}, {"gc", GC, 0,0},
{"clear", Clear, 1,0,0}, {"clear", Clear, 1,0},
#ifdef DEBUG #ifdef DEBUG
{"dumpHeap", DumpHeap, 5,0,0}, {"dumpHeap", DumpHeap, 5,0},
#endif #endif
#ifdef MOZ_SHARK #ifdef MOZ_SHARK
{"startShark", js_StartShark, 0,0,0}, {"startShark", js_StartShark, 0,0},
{"stopShark", js_StopShark, 0,0,0}, {"stopShark", js_StopShark, 0,0},
{"connectShark", js_ConnectShark, 0,0,0}, {"connectShark", js_ConnectShark, 0,0},
{"disconnectShark", js_DisconnectShark, 0,0,0}, {"disconnectShark", js_DisconnectShark, 0,0},
#endif #endif
#ifdef MOZ_CALLGRIND #ifdef MOZ_CALLGRIND
{"startCallgrind", js_StartCallgrind, 0,0,0}, {"startCallgrind", js_StartCallgrind, 0,0},
{"stopCallgrind", js_StopCallgrind, 0,0,0}, {"stopCallgrind", js_StopCallgrind, 0,0},
{"dumpCallgrind", js_DumpCallgrind, 1,0,0}, {"dumpCallgrind", js_DumpCallgrind, 1,0},
#endif #endif
{nsnull,nsnull,0,0,0} {nsnull,nsnull,0,0}
}; };
typedef enum JSShellErrNum typedef enum JSShellErrNum
@ -566,25 +565,6 @@ typedef enum JSShellErrNum
#undef MSGDEF #undef MSGDEF
} JSShellErrNum; } JSShellErrNum;
JSErrorFormatString gErrorFormatString[JSErr_Limit] =
{
#define MSG_DEF(name, number, count, exception, format) \
{ format, count } ,
#include "jsshell.msg"
#undef MSG_DEF
};
static const JSErrorFormatString *
GetErrorMessage(void *userRef,
const char *locale,
const uintN errorNumber)
{
if ((errorNumber > 0) && (errorNumber < JSShellErr_Limit))
return &gErrorFormatString[errorNumber];
return NULL;
}
static void static void
ProcessFile(JSContext *cx, ProcessFile(JSContext *cx,
JSObject *obj, JSObject *obj,

Просмотреть файл

@ -642,19 +642,22 @@ ObjectWrapperParent::CPOW_Finalize(JSContext* cx, JSObject* obj)
} }
/*static*/ JSBool /*static*/ JSBool
ObjectWrapperParent::CPOW_Call(JSContext* cx, JSObject* obj, uintN argc, ObjectWrapperParent::CPOW_Call(JSContext* cx, uintN argc, jsval* vp)
jsval* argv, jsval* rval)
{ {
CPOW_LOG(("Calling CPOW_Call...")); CPOW_LOG(("Calling CPOW_Call..."));
JSObject* thisobj = JS_THIS_OBJECT(cx, vp);
if (!thisobj)
return JS_FALSE;
ObjectWrapperParent* function = ObjectWrapperParent* function =
Unwrap(cx, JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv))); Unwrap(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
if (!function) if (!function)
return with_error(cx, JS_FALSE, "Could not unwrap CPOW function"); return with_error(cx, JS_FALSE, "Could not unwrap CPOW function");
AutoCheckOperation aco(cx, function); AutoCheckOperation aco(cx, function);
ObjectWrapperParent* receiver = Unwrap(cx, obj); ObjectWrapperParent* receiver = Unwrap(cx, thisobj);
if (!receiver) { if (!receiver) {
// Substitute child global for parent global object. // Substitute child global for parent global object.
// TODO First make sure we're really replacing the global object? // TODO First make sure we're really replacing the global object?
@ -664,6 +667,7 @@ ObjectWrapperParent::CPOW_Call(JSContext* cx, JSObject* obj, uintN argc,
} }
nsTArray<JSVariant> in_argv(argc); nsTArray<JSVariant> in_argv(argc);
jsval* argv = JS_ARGV(cx, vp);
for (uintN i = 0; i < argc; i++) for (uintN i = 0; i < argc; i++)
if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement())) if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement()))
return JS_FALSE; return JS_FALSE;
@ -674,23 +678,22 @@ ObjectWrapperParent::CPOW_Call(JSContext* cx, JSObject* obj, uintN argc,
function->CallCall(receiver, in_argv, function->CallCall(receiver, in_argv,
aco.StatusPtr(), &out_rval) && aco.StatusPtr(), &out_rval) &&
aco.Ok() && aco.Ok() &&
jsval_from_JSVariant(cx, out_rval, rval)); jsval_from_JSVariant(cx, out_rval, vp));
} }
/*static*/ JSBool /*static*/ JSBool
ObjectWrapperParent::CPOW_Construct(JSContext *cx, JSObject *obj, uintN argc, ObjectWrapperParent::CPOW_Construct(JSContext* cx, uintN argc, jsval* vp)
jsval *argv, jsval *rval)
{ {
CPOW_LOG(("Calling CPOW_Construct...")); CPOW_LOG(("Calling CPOW_Construct..."));
ObjectWrapperParent* constructor = ObjectWrapperParent* constructor = Unwrap(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
Unwrap(cx, JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)));
if (!constructor) if (!constructor)
return with_error(cx, JS_FALSE, "Could not unwrap CPOW constructor function"); return with_error(cx, JS_FALSE, "Could not unwrap CPOW constructor function");
AutoCheckOperation aco(cx, constructor); AutoCheckOperation aco(cx, constructor);
nsTArray<JSVariant> in_argv(argc); nsTArray<JSVariant> in_argv(argc);
jsval* argv = JS_ARGV(cx, vp);
for (uintN i = 0; i < argc; i++) for (uintN i = 0; i < argc; i++)
if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement())) if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement()))
return JS_FALSE; return JS_FALSE;
@ -698,10 +701,9 @@ ObjectWrapperParent::CPOW_Construct(JSContext *cx, JSObject *obj, uintN argc,
PObjectWrapperParent* out_powp; PObjectWrapperParent* out_powp;
return (constructor->Manager()->RequestRunToCompletion() && return (constructor->Manager()->RequestRunToCompletion() &&
constructor->CallConstruct(in_argv, constructor->CallConstruct(in_argv, aco.StatusPtr(), &out_powp) &&
aco.StatusPtr(), &out_powp) &&
aco.Ok() && aco.Ok() &&
jsval_from_PObjectWrapperParent(cx, out_powp, rval)); jsval_from_PObjectWrapperParent(cx, out_powp, vp));
} }
/*static*/ JSBool /*static*/ JSBool

Просмотреть файл

@ -118,12 +118,10 @@ private:
CPOW_Finalize(JSContext* cx, JSObject* obj); CPOW_Finalize(JSContext* cx, JSObject* obj);
static JSBool static JSBool
CPOW_Call(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, CPOW_Call(JSContext* cx, uintN argc, jsval* vp);
jsval* rval);
static JSBool static JSBool
CPOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, CPOW_Construct(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static JSBool static JSBool
CPOW_HasInstance(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp); CPOW_HasInstance(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);

Просмотреть файл

@ -347,8 +347,7 @@ Handle<BaseType>::sHandle_Properties[] = {
#undef HANDLE_PROP_FLAGS #undef HANDLE_PROP_FLAGS
#define HANDLE_FUN_FLAGS (JSFUN_FAST_NATIVE | \ #define HANDLE_FUN_FLAGS (JSPROP_READONLY | \
JSPROP_READONLY | \
JSPROP_PERMANENT) JSPROP_PERMANENT)
template <class BaseType> template <class BaseType>

Просмотреть файл

@ -57,8 +57,7 @@ JetpackChild::~JetpackChild()
{ {
} }
#define IMPL_METHOD_FLAGS (JSFUN_FAST_NATIVE | \ #define IMPL_METHOD_FLAGS (JSPROP_ENUMERATE | \
JSPROP_ENUMERATE | \
JSPROP_READONLY | \ JSPROP_READONLY | \
JSPROP_PERMANENT) JSPROP_PERMANENT)
const JSFunctionSpec const JSFunctionSpec

Просмотреть файл

@ -792,10 +792,6 @@ interface jsdIStackFrame : jsdIEphemeral
/** Internal use only. */ /** Internal use only. */
[noscript] readonly attribute JSDStackFrameInfo JSDStackFrameInfo; [noscript] readonly attribute JSDStackFrameInfo JSDStackFrameInfo;
/**
* True if stack frame represents a native frame.
*/
readonly attribute boolean isNative;
/** /**
* True if stack frame represents a frame created as a result of a debugger * True if stack frame represents a frame created as a result of a debugger
* evaluation. * evaluation.

Просмотреть файл

@ -707,11 +707,6 @@ jsd_GetScopeChainForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate, JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe); JSDStackFrameInfo* jsdframe);
extern JSBool
jsd_IsStackFrameNative(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSBool extern JSBool
jsd_IsStackFrameDebugger(JSDContext* jsdc, jsd_IsStackFrameDebugger(JSDContext* jsdc,
JSDThreadState* jsdthreadstate, JSDThreadState* jsdthreadstate,

Просмотреть файл

@ -144,7 +144,7 @@ jsd_Constructing(JSDContext* jsdc, JSContext *cx, JSObject *obj,
JSD_LOCK_OBJECTS(jsdc); JSD_LOCK_OBJECTS(jsdc);
jsdobj = jsd_GetJSDObjectForJSObject(jsdc, obj); jsdobj = jsd_GetJSDObjectForJSObject(jsdc, obj);
if( jsdobj && !jsdobj->ctorURL && !JS_IsNativeFrame(cx, fp) ) if( jsdobj && !jsdobj->ctorURL && JS_IsScriptFrame(cx, fp) )
{ {
script = JS_GetFrameScript(cx, fp); script = JS_GetFrameScript(cx, fp);
if( script ) if( script )

Просмотреть файл

@ -65,7 +65,7 @@ _addNewFrame(JSDContext* jsdc,
JSDStackFrameInfo* jsdframe; JSDStackFrameInfo* jsdframe;
JSDScript* jsdscript = NULL; JSDScript* jsdscript = NULL;
if (!JS_IsNativeFrame(jsdthreadstate->context, fp)) if (JS_IsScriptFrame(jsdthreadstate->context, fp))
{ {
JSD_LOCK_SCRIPTS(jsdc); JSD_LOCK_SCRIPTS(jsdc);
jsdscript = jsd_FindJSDScript(jsdc, script); jsdscript = jsd_FindJSDScript(jsdc, script);
@ -133,7 +133,7 @@ jsd_NewThreadState(JSDContext* jsdc, JSContext *cx )
*/ */
if (JS_GetFrameThis(cx, fp) && if (JS_GetFrameThis(cx, fp) &&
((jsdc->flags & JSD_INCLUDE_NATIVE_FRAMES) || ((jsdc->flags & JSD_INCLUDE_NATIVE_FRAMES) ||
!JS_IsNativeFrame(cx, fp))) JS_IsScriptFrame(cx, fp)))
{ {
JSDStackFrameInfo *frame; JSDStackFrameInfo *frame;
@ -374,28 +374,6 @@ jsd_GetNameForStackFrame(JSDContext* jsdc,
return rv; return rv;
} }
JSBool
jsd_IsStackFrameNative(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe)
{
JSBool rv;
JSD_LOCK_THREADSTATES(jsdc);
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
{
rv = JS_IsNativeFrame(jsdthreadstate->context, jsdframe->fp);
}
else
{
rv = JS_FALSE;
}
JSD_UNLOCK_THREADSTATES(jsdc);
return rv;
}
JSBool JSBool
jsd_IsStackFrameDebugger(JSDContext* jsdc, jsd_IsStackFrameDebugger(JSDContext* jsdc,
JSDThreadState* jsdthreadstate, JSDThreadState* jsdthreadstate,

Просмотреть файл

@ -1840,14 +1840,6 @@ jsdStackFrame::GetFunctionName(nsACString &_rval)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
jsdStackFrame::GetIsNative(PRBool *_rval)
{
ASSERT_VALID_EPHEMERAL;
*_rval = JSD_IsStackFrameNative (mCx, mThreadState, mStackFrameInfo);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
jsdStackFrame::GetIsDebugger(PRBool *_rval) jsdStackFrame::GetIsDebugger(PRBool *_rval)
{ {
@ -1902,9 +1894,7 @@ jsdStackFrame::GetLine(PRUint32 *_rval)
jsuword pc = JSD_GetPCForStackFrame (mCx, mThreadState, mStackFrameInfo); jsuword pc = JSD_GetPCForStackFrame (mCx, mThreadState, mStackFrameInfo);
*_rval = JSD_GetClosestLine (mCx, script, pc); *_rval = JSD_GetClosestLine (mCx, script, pc);
} else { } else {
if (!JSD_IsStackFrameNative(mCx, mThreadState, mStackFrameInfo)) return NS_ERROR_FAILURE;
return NS_ERROR_FAILURE;
*_rval = 1;
} }
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -750,15 +750,6 @@ JSD_GetNameForStackFrame(JSDContext* jsdc,
return jsd_GetNameForStackFrame(jsdc, jsdthreadstate, jsdframe); return jsd_GetNameForStackFrame(jsdc, jsdthreadstate, jsdframe);
} }
JSD_PUBLIC_API(JSBool)
JSD_IsStackFrameNative(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_IsStackFrameNative(jsdc, jsdthreadstate, jsdframe);
}
JSD_PUBLIC_API(JSBool) JSD_PUBLIC_API(JSBool)
JSD_IsStackFrameDebugger(JSDContext* jsdc, JSD_IsStackFrameDebugger(JSDContext* jsdc,
JSDThreadState* jsdthreadstate, JSDThreadState* jsdthreadstate,

Просмотреть файл

@ -950,14 +950,6 @@ JSD_GetNameForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate, JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe); JSDStackFrameInfo* jsdframe);
/*
* True if stack frame represents a native frame.
*/
extern JSD_PUBLIC_API(JSBool)
JSD_IsStackFrameNative(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
/* /*
* True if stack frame represents a frame created as a result of a debugger * True if stack frame represents a frame created as a result of a debugger
* evaluation. * evaluation.

Просмотреть файл

@ -76,14 +76,11 @@ private:
** JSAPI function prototypes ** JSAPI function prototypes
*******************************************************************************/ *******************************************************************************/
static JSBool ConstructAbstract(JSContext* cx, JSObject* obj, uintN argc, static JSBool ConstructAbstract(JSContext* cx, uintN argc, jsval* vp);
jsval* argv, jsval* rval);
namespace CType { namespace CType {
static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, static JSBool ConstructData(JSContext* cx, uintN argc, jsval* vp);
jsval* argv, jsval* rval); static JSBool ConstructBasic(JSContext* cx, JSObject* obj, uintN argc, jsval* vp);
static JSBool ConstructBasic(JSContext* cx, JSObject* obj, uintN argc,
jsval* argv, jsval* rval);
static void Trace(JSTracer* trc, JSObject* obj); static void Trace(JSTracer* trc, JSObject* obj);
static void Finalize(JSContext* cx, JSObject* obj); static void Finalize(JSContext* cx, JSObject* obj);
@ -99,13 +96,12 @@ namespace CType {
static JSBool CreateArray(JSContext* cx, uintN argc, jsval* vp); static JSBool CreateArray(JSContext* cx, uintN argc, jsval* vp);
static JSBool ToString(JSContext* cx, uintN argc, jsval* vp); static JSBool ToString(JSContext* cx, uintN argc, jsval* vp);
static JSBool ToSource(JSContext* cx, uintN argc, jsval* vp); static JSBool ToSource(JSContext* cx, uintN argc, jsval* vp);
static JSBool HasInstance(JSContext* cx, JSObject* obj, const jsval *v, JSBool* bp); static JSBool HasInstance(JSContext* cx, JSObject* obj, const jsval* v, JSBool* bp);
} }
namespace PointerType { namespace PointerType {
static JSBool Create(JSContext* cx, uintN argc, jsval* vp); static JSBool Create(JSContext* cx, uintN argc, jsval* vp);
static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, jsval* vp);
jsval* argv, jsval* rval);
static JSBool TargetTypeGetter(JSContext* cx, JSObject* obj, jsid idval, static JSBool TargetTypeGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
@ -118,8 +114,7 @@ namespace PointerType {
namespace ArrayType { namespace ArrayType {
static JSBool Create(JSContext* cx, uintN argc, jsval* vp); static JSBool Create(JSContext* cx, uintN argc, jsval* vp);
static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, jsval* vp);
jsval* argv, jsval* rval);
static JSBool ElementTypeGetter(JSContext* cx, JSObject* obj, jsid idval, static JSBool ElementTypeGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
@ -132,8 +127,7 @@ namespace ArrayType {
namespace StructType { namespace StructType {
static JSBool Create(JSContext* cx, uintN argc, jsval* vp); static JSBool Create(JSContext* cx, uintN argc, jsval* vp);
static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, jsval* vp);
jsval* argv, jsval* rval);
static JSBool FieldsArrayGetter(JSContext* cx, JSObject* obj, jsid idval, static JSBool FieldsArrayGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
@ -150,8 +144,7 @@ namespace FunctionType {
static JSBool ConstructData(JSContext* cx, JSObject* typeObj, static JSBool ConstructData(JSContext* cx, JSObject* typeObj,
JSObject* dataObj, JSObject* fnObj, JSObject* thisObj); JSObject* dataObj, JSObject* fnObj, JSObject* thisObj);
static JSBool Call(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, static JSBool Call(JSContext* cx, uintN argc, jsval* vp);
jsval* rval);
static JSBool ArgTypesGetter(JSContext* cx, JSObject* obj, jsid idval, static JSBool ArgTypesGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
@ -200,8 +193,7 @@ namespace Int64Base {
} }
namespace Int64 { namespace Int64 {
static JSBool Construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, static JSBool Construct(JSContext* cx, uintN argc, jsval* vp);
jsval* rval);
static JSBool ToString(JSContext* cx, uintN argc, jsval* vp); static JSBool ToString(JSContext* cx, uintN argc, jsval* vp);
static JSBool ToSource(JSContext* cx, uintN argc, jsval* vp); static JSBool ToSource(JSContext* cx, uintN argc, jsval* vp);
@ -213,8 +205,7 @@ namespace Int64 {
} }
namespace UInt64 { namespace UInt64 {
static JSBool Construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, static JSBool Construct(JSContext* cx, uintN argc, jsval* vp);
jsval* rval);
static JSBool ToString(JSContext* cx, uintN argc, jsval* vp); static JSBool ToString(JSContext* cx, uintN argc, jsval* vp);
static JSBool ToSource(JSContext* cx, uintN argc, jsval* vp); static JSBool ToSource(JSContext* cx, uintN argc, jsval* vp);
@ -284,13 +275,16 @@ static JSClass sCClosureClass = {
}; };
#define CTYPESFN_FLAGS \ #define CTYPESFN_FLAGS \
(JSFUN_FAST_NATIVE | JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) (JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)
#define CTYPESCTOR_FLAGS \
(CTYPESFN_FLAGS | JSFUN_CONSTRUCTOR)
#define CTYPESPROP_FLAGS \ #define CTYPESPROP_FLAGS \
(JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)
#define CDATAFN_FLAGS \ #define CDATAFN_FLAGS \
(JSFUN_FAST_NATIVE | JSPROP_READONLY | JSPROP_PERMANENT) (JSPROP_READONLY | JSPROP_PERMANENT)
static JSPropertySpec sCTypeProps[] = { static JSPropertySpec sCTypeProps[] = {
{ "name", 0, CTYPESPROP_FLAGS, CType::NameGetter, NULL }, { "name", 0, CTYPESPROP_FLAGS, CType::NameGetter, NULL },
@ -322,7 +316,7 @@ static JSFunctionSpec sCDataFunctions[] = {
}; };
static JSFunctionSpec sPointerFunction = static JSFunctionSpec sPointerFunction =
JS_FN("PointerType", PointerType::Create, 1, CTYPESFN_FLAGS); JS_FN("PointerType", PointerType::Create, 1, CTYPESCTOR_FLAGS);
static JSPropertySpec sPointerProps[] = { static JSPropertySpec sPointerProps[] = {
{ "targetType", 0, CTYPESPROP_FLAGS, PointerType::TargetTypeGetter, NULL }, { "targetType", 0, CTYPESPROP_FLAGS, PointerType::TargetTypeGetter, NULL },
@ -341,7 +335,7 @@ static JSPropertySpec sPointerInstanceProps[] = {
}; };
static JSFunctionSpec sArrayFunction = static JSFunctionSpec sArrayFunction =
JS_FN("ArrayType", ArrayType::Create, 1, CTYPESFN_FLAGS); JS_FN("ArrayType", ArrayType::Create, 1, CTYPESCTOR_FLAGS);
static JSPropertySpec sArrayProps[] = { static JSPropertySpec sArrayProps[] = {
{ "elementType", 0, CTYPESPROP_FLAGS, ArrayType::ElementTypeGetter, NULL }, { "elementType", 0, CTYPESPROP_FLAGS, ArrayType::ElementTypeGetter, NULL },
@ -361,7 +355,7 @@ static JSPropertySpec sArrayInstanceProps[] = {
}; };
static JSFunctionSpec sStructFunction = static JSFunctionSpec sStructFunction =
JS_FN("StructType", StructType::Create, 2, CTYPESFN_FLAGS); JS_FN("StructType", StructType::Create, 2, CTYPESCTOR_FLAGS);
static JSPropertySpec sStructProps[] = { static JSPropertySpec sStructProps[] = {
{ "fields", 0, CTYPESPROP_FLAGS, StructType::FieldsArrayGetter, NULL }, { "fields", 0, CTYPESPROP_FLAGS, StructType::FieldsArrayGetter, NULL },
@ -379,7 +373,7 @@ static JSFunctionSpec sStructInstanceFunctions[] = {
}; };
static JSFunctionSpec sFunctionFunction = static JSFunctionSpec sFunctionFunction =
JS_FN("FunctionType", FunctionType::Create, 2, CTYPESFN_FLAGS); JS_FN("FunctionType", FunctionType::Create, 2, CTYPESCTOR_FLAGS);
static JSPropertySpec sFunctionProps[] = { static JSPropertySpec sFunctionProps[] = {
{ "argTypes", 0, CTYPESPROP_FLAGS, FunctionType::ArgTypesGetter, NULL }, { "argTypes", 0, CTYPESPROP_FLAGS, FunctionType::ArgTypesGetter, NULL },
@ -536,7 +530,7 @@ static JSObject*
InitCTypeClass(JSContext* cx, JSObject* parent) InitCTypeClass(JSContext* cx, JSObject* parent)
{ {
JSFunction* fun = JS_DefineFunction(cx, parent, "CType", ConstructAbstract, 0, JSFunction* fun = JS_DefineFunction(cx, parent, "CType", ConstructAbstract, 0,
CTYPESFN_FLAGS); CTYPESCTOR_FLAGS);
if (!fun) if (!fun)
return NULL; return NULL;
@ -574,7 +568,7 @@ static JSObject*
InitCDataClass(JSContext* cx, JSObject* parent, JSObject* CTypeProto) InitCDataClass(JSContext* cx, JSObject* parent, JSObject* CTypeProto)
{ {
JSFunction* fun = JS_DefineFunction(cx, parent, "CData", ConstructAbstract, 0, JSFunction* fun = JS_DefineFunction(cx, parent, "CData", ConstructAbstract, 0,
CTYPESFN_FLAGS); CTYPESCTOR_FLAGS);
if (!fun) if (!fun)
return NULL; return NULL;
@ -2483,10 +2477,8 @@ BuildDataSource(JSContext* cx,
JSBool JSBool
ConstructAbstract(JSContext* cx, ConstructAbstract(JSContext* cx,
JSObject* obj,
uintN argc, uintN argc,
jsval* argv, jsval* vp)
jsval* rval)
{ {
// Calling an abstract base class constructor is disallowed. // Calling an abstract base class constructor is disallowed.
JS_ReportError(cx, "cannot construct from abstract type"); JS_ReportError(cx, "cannot construct from abstract type");
@ -2499,13 +2491,11 @@ ConstructAbstract(JSContext* cx,
JSBool JSBool
CType::ConstructData(JSContext* cx, CType::ConstructData(JSContext* cx,
JSObject* obj,
uintN argc, uintN argc,
jsval* argv, jsval* vp)
jsval* rval)
{ {
// get the callee object... // get the callee object...
obj = JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)); JSObject* obj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
if (!CType::IsCType(cx, obj)) { if (!CType::IsCType(cx, obj)) {
JS_ReportError(cx, "not a CType"); JS_ReportError(cx, "not a CType");
return JS_FALSE; return JS_FALSE;
@ -2523,13 +2513,13 @@ CType::ConstructData(JSContext* cx,
JS_ReportError(cx, "cannot construct from FunctionType; use FunctionType.ptr instead"); JS_ReportError(cx, "cannot construct from FunctionType; use FunctionType.ptr instead");
return JS_FALSE; return JS_FALSE;
case TYPE_pointer: case TYPE_pointer:
return PointerType::ConstructData(cx, obj, argc, argv, rval); return PointerType::ConstructData(cx, obj, argc, vp);
case TYPE_array: case TYPE_array:
return ArrayType::ConstructData(cx, obj, argc, argv, rval); return ArrayType::ConstructData(cx, obj, argc, vp);
case TYPE_struct: case TYPE_struct:
return StructType::ConstructData(cx, obj, argc, argv, rval); return StructType::ConstructData(cx, obj, argc, vp);
default: default:
return ConstructBasic(cx, obj, argc, argv, rval); return ConstructBasic(cx, obj, argc, vp);
} }
} }
@ -2537,8 +2527,7 @@ JSBool
CType::ConstructBasic(JSContext* cx, CType::ConstructBasic(JSContext* cx,
JSObject* obj, JSObject* obj,
uintN argc, uintN argc,
jsval* argv, jsval* vp)
jsval* rval)
{ {
if (argc > 1) { if (argc > 1) {
JS_ReportError(cx, "CType constructor takes zero or one argument"); JS_ReportError(cx, "CType constructor takes zero or one argument");
@ -2550,13 +2539,12 @@ CType::ConstructBasic(JSContext* cx,
if (!result) if (!result)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(result);
if (argc == 1) { if (argc == 1) {
if (!ExplicitConvert(cx, argv[0], obj, CData::GetData(cx, result))) if (!ExplicitConvert(cx, JS_ARGV(cx, vp)[0], obj, CData::GetData(cx, result)))
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));
return JS_TRUE; return JS_TRUE;
} }
@ -3065,7 +3053,7 @@ CType::PtrGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
} }
JSBool JSBool
CType::CreateArray(JSContext* cx, uintN argc, jsval *vp) CType::CreateArray(JSContext* cx, uintN argc, jsval* vp)
{ {
JSObject* baseType = JS_THIS_OBJECT(cx, vp); JSObject* baseType = JS_THIS_OBJECT(cx, vp);
JS_ASSERT(baseType); JS_ASSERT(baseType);
@ -3098,7 +3086,7 @@ CType::CreateArray(JSContext* cx, uintN argc, jsval *vp)
} }
JSBool JSBool
CType::ToString(JSContext* cx, uintN argc, jsval *vp) CType::ToString(JSContext* cx, uintN argc, jsval* vp)
{ {
JSObject* obj = JS_THIS_OBJECT(cx, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp);
JS_ASSERT(obj); JS_ASSERT(obj);
@ -3121,7 +3109,7 @@ CType::ToString(JSContext* cx, uintN argc, jsval *vp)
} }
JSBool JSBool
CType::ToSource(JSContext* cx, uintN argc, jsval *vp) CType::ToSource(JSContext* cx, uintN argc, jsval* vp)
{ {
JSObject* obj = JS_THIS_OBJECT(cx, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp);
JS_ASSERT(obj); JS_ASSERT(obj);
@ -3142,7 +3130,7 @@ CType::ToSource(JSContext* cx, uintN argc, jsval *vp)
} }
JSBool JSBool
CType::HasInstance(JSContext* cx, JSObject* obj, const jsval *v, JSBool* bp) CType::HasInstance(JSContext* cx, JSObject* obj, const jsval* v, JSBool* bp)
{ {
JS_ASSERT(CType::IsCType(cx, obj)); JS_ASSERT(CType::IsCType(cx, obj));
@ -3233,8 +3221,7 @@ JSBool
PointerType::ConstructData(JSContext* cx, PointerType::ConstructData(JSContext* cx,
JSObject* obj, JSObject* obj,
uintN argc, uintN argc,
jsval* argv, jsval* vp)
jsval* rval)
{ {
if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_pointer) { if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_pointer) {
JS_ReportError(cx, "not a PointerType"); JS_ReportError(cx, "not a PointerType");
@ -3250,13 +3237,15 @@ PointerType::ConstructData(JSContext* cx,
if (!result) if (!result)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(result); // Set return value early, must not observe *vp after
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));
if (argc == 0) { if (argc == 0) {
// Construct a null pointer. // Construct a null pointer.
return JS_TRUE; return JS_TRUE;
} }
jsval* argv = JS_ARGV(cx, vp);
if (argc >= 1) { if (argc >= 1) {
JSObject* baseObj = PointerType::GetBaseType(cx, obj); JSObject* baseObj = PointerType::GetBaseType(cx, obj);
if (CType::GetTypeCode(cx, baseObj) == TYPE_function && if (CType::GetTypeCode(cx, baseObj) == TYPE_function &&
@ -3503,8 +3492,7 @@ JSBool
ArrayType::ConstructData(JSContext* cx, ArrayType::ConstructData(JSContext* cx,
JSObject* obj, JSObject* obj,
uintN argc, uintN argc,
jsval* argv, jsval* vp)
jsval* rval)
{ {
if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_array) { if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_array) {
JS_ReportError(cx, "not an ArrayType"); JS_ReportError(cx, "not an ArrayType");
@ -3531,6 +3519,7 @@ ArrayType::ConstructData(JSContext* cx,
JSObject* baseType = GetBaseType(cx, obj); JSObject* baseType = GetBaseType(cx, obj);
jsval* argv = JS_ARGV(cx, vp);
size_t length; size_t length;
if (jsvalToSize(cx, argv[0], false, &length)) { if (jsvalToSize(cx, argv[0], false, &length)) {
// Have a length, rather than an object to initialize from. // Have a length, rather than an object to initialize from.
@ -3591,10 +3580,10 @@ ArrayType::ConstructData(JSContext* cx,
if (!result) if (!result)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(result); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));
if (convertObject) { if (convertObject) {
if (!ExplicitConvert(cx, argv[0], obj, CData::GetData(cx, result))) if (!ExplicitConvert(cx, JS_ARGV(cx, vp)[0], obj, CData::GetData(cx, result)))
return JS_FALSE; return JS_FALSE;
} }
@ -3801,7 +3790,7 @@ ArrayType::Setter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
} }
JSBool JSBool
ArrayType::AddressOfElement(JSContext* cx, uintN argc, jsval *vp) ArrayType::AddressOfElement(JSContext* cx, uintN argc, jsval* vp)
{ {
JSObject* obj = JS_THIS_OBJECT(cx, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp);
JS_ASSERT(obj); JS_ASSERT(obj);
@ -4217,8 +4206,7 @@ JSBool
StructType::ConstructData(JSContext* cx, StructType::ConstructData(JSContext* cx,
JSObject* obj, JSObject* obj,
uintN argc, uintN argc,
jsval* argv, jsval* vp)
jsval* rval)
{ {
if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_struct) { if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_struct) {
JS_ReportError(cx, "not a StructType"); JS_ReportError(cx, "not a StructType");
@ -4234,7 +4222,7 @@ StructType::ConstructData(JSContext* cx,
if (!result) if (!result)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(result); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));
if (argc == 0) if (argc == 0)
return JS_TRUE; return JS_TRUE;
@ -4242,6 +4230,7 @@ StructType::ConstructData(JSContext* cx,
char* buffer = static_cast<char*>(CData::GetData(cx, result)); char* buffer = static_cast<char*>(CData::GetData(cx, result));
const FieldInfoHash* fields = GetFieldInfo(cx, obj); const FieldInfoHash* fields = GetFieldInfo(cx, obj);
jsval* argv = JS_ARGV(cx, vp);
if (argc == 1) { if (argc == 1) {
// There are two possible interpretations of the argument: // There are two possible interpretations of the argument:
// 1) It may be an object '{ ... }' with properties representing the // 1) It may be an object '{ ... }' with properties representing the
@ -4429,7 +4418,7 @@ StructType::FieldSetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
} }
JSBool JSBool
StructType::AddressOfField(JSContext* cx, uintN argc, jsval *vp) StructType::AddressOfField(JSContext* cx, uintN argc, jsval* vp)
{ {
JSObject* obj = JS_THIS_OBJECT(cx, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp);
JS_ASSERT(obj); JS_ASSERT(obj);
@ -4925,13 +4914,11 @@ ConvertArgument(JSContext* cx,
JSBool JSBool
FunctionType::Call(JSContext* cx, FunctionType::Call(JSContext* cx,
JSObject* obj,
uintN argc, uintN argc,
jsval* argv, jsval* vp)
jsval* rval)
{ {
// get the callee object... // get the callee object...
obj = JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)); JSObject* obj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
if (!CData::IsCData(cx, obj)) { if (!CData::IsCData(cx, obj)) {
JS_ReportError(cx, "not a CData"); JS_ReportError(cx, "not a CData");
return false; return false;
@ -4977,6 +4964,7 @@ FunctionType::Call(JSContext* cx,
return false; return false;
} }
jsval* argv = JS_ARGV(cx, vp);
for (jsuint i = 0; i < argcFixed; ++i) for (jsuint i = 0; i < argcFixed; ++i)
if (!ConvertArgument(cx, argv[i], fninfo->mArgTypes[i], &values[i], &strings)) if (!ConvertArgument(cx, argv[i], fninfo->mArgTypes[i], &values[i], &strings))
return false; return false;
@ -5053,7 +5041,7 @@ FunctionType::Call(JSContext* cx,
// prepare a JS object from the result // prepare a JS object from the result
return ConvertToJS(cx, fninfo->mReturnType, NULL, returnValue.mData, return ConvertToJS(cx, fninfo->mReturnType, NULL, returnValue.mData,
false, true, rval); false, true, vp);
} }
FunctionInfo* FunctionInfo*
@ -5573,7 +5561,7 @@ CData::ValueSetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
} }
JSBool JSBool
CData::Address(JSContext* cx, uintN argc, jsval *vp) CData::Address(JSContext* cx, uintN argc, jsval* vp)
{ {
if (argc != 0) { if (argc != 0) {
JS_ReportError(cx, "address takes zero arguments"); JS_ReportError(cx, "address takes zero arguments");
@ -5608,7 +5596,7 @@ CData::Address(JSContext* cx, uintN argc, jsval *vp)
} }
JSBool JSBool
CData::Cast(JSContext* cx, uintN argc, jsval *vp) CData::Cast(JSContext* cx, uintN argc, jsval* vp)
{ {
if (argc != 2) { if (argc != 2) {
JS_ReportError(cx, "cast takes two arguments"); JS_ReportError(cx, "cast takes two arguments");
@ -5651,7 +5639,7 @@ CData::Cast(JSContext* cx, uintN argc, jsval *vp)
} }
JSBool JSBool
CData::ReadString(JSContext* cx, uintN argc, jsval *vp) CData::ReadString(JSContext* cx, uintN argc, jsval* vp)
{ {
if (argc != 0) { if (argc != 0) {
JS_ReportError(cx, "readString takes zero arguments"); JS_ReportError(cx, "readString takes zero arguments");
@ -5744,7 +5732,7 @@ CData::ReadString(JSContext* cx, uintN argc, jsval *vp)
} }
JSBool JSBool
CData::ToSource(JSContext* cx, uintN argc, jsval *vp) CData::ToSource(JSContext* cx, uintN argc, jsval* vp)
{ {
if (argc != 0) { if (argc != 0) {
JS_ReportError(cx, "toSource takes zero arguments"); JS_ReportError(cx, "toSource takes zero arguments");
@ -5839,7 +5827,7 @@ JSBool
Int64Base::ToString(JSContext* cx, Int64Base::ToString(JSContext* cx,
JSObject* obj, JSObject* obj,
uintN argc, uintN argc,
jsval *vp, jsval* vp,
bool isUnsigned) bool isUnsigned)
{ {
if (argc > 1) { if (argc > 1) {
@ -5877,7 +5865,7 @@ JSBool
Int64Base::ToSource(JSContext* cx, Int64Base::ToSource(JSContext* cx,
JSObject* obj, JSObject* obj,
uintN argc, uintN argc,
jsval *vp, jsval* vp,
bool isUnsigned) bool isUnsigned)
{ {
if (argc != 0) { if (argc != 0) {
@ -5906,10 +5894,8 @@ Int64Base::ToSource(JSContext* cx,
JSBool JSBool
Int64::Construct(JSContext* cx, Int64::Construct(JSContext* cx,
JSObject* obj,
uintN argc, uintN argc,
jsval* argv, jsval* vp)
jsval* rval)
{ {
// Construct and return a new Int64 object. // Construct and return a new Int64 object.
if (argc != 1) { if (argc != 1) {
@ -5917,13 +5903,14 @@ Int64::Construct(JSContext* cx,
return JS_FALSE; return JS_FALSE;
} }
jsval* argv = JS_ARGV(cx, vp);
JSInt64 i = 0; JSInt64 i = 0;
if (!jsvalToBigInteger(cx, argv[0], true, &i)) if (!jsvalToBigInteger(cx, argv[0], true, &i))
return TypeError(cx, "int64", argv[0]); return TypeError(cx, "int64", argv[0]);
// Get ctypes.Int64.prototype from the 'prototype' property of the ctor. // Get ctypes.Int64.prototype from the 'prototype' property of the ctor.
jsval slot; jsval slot;
ASSERT_OK(JS_GetProperty(cx, JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)), ASSERT_OK(JS_GetProperty(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)),
"prototype", &slot)); "prototype", &slot));
JSObject* proto = JSVAL_TO_OBJECT(slot); JSObject* proto = JSVAL_TO_OBJECT(slot);
JS_ASSERT(JS_GET_CLASS(cx, proto) == &sInt64ProtoClass); JS_ASSERT(JS_GET_CLASS(cx, proto) == &sInt64ProtoClass);
@ -5932,7 +5919,7 @@ Int64::Construct(JSContext* cx,
if (!result) if (!result)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(result); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));
return JS_TRUE; return JS_TRUE;
} }
@ -5943,7 +5930,7 @@ Int64::IsInt64(JSContext* cx, JSObject* obj)
} }
JSBool JSBool
Int64::ToString(JSContext* cx, uintN argc, jsval *vp) Int64::ToString(JSContext* cx, uintN argc, jsval* vp)
{ {
JSObject* obj = JS_THIS_OBJECT(cx, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp);
if (!Int64::IsInt64(cx, obj)) { if (!Int64::IsInt64(cx, obj)) {
@ -5955,7 +5942,7 @@ Int64::ToString(JSContext* cx, uintN argc, jsval *vp)
} }
JSBool JSBool
Int64::ToSource(JSContext* cx, uintN argc, jsval *vp) Int64::ToSource(JSContext* cx, uintN argc, jsval* vp)
{ {
JSObject* obj = JS_THIS_OBJECT(cx, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp);
if (!Int64::IsInt64(cx, obj)) { if (!Int64::IsInt64(cx, obj)) {
@ -6062,7 +6049,7 @@ Int64::Join(JSContext* cx, uintN argc, jsval* vp)
JSInt64 i = (JSInt64(hi) << 32) + JSInt64(lo); JSInt64 i = (JSInt64(hi) << 32) + JSInt64(lo);
// Get Int64.prototype from the function's reserved slot. // Get Int64.prototype from the function's reserved slot.
JSObject* callee = JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)); JSObject* callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
jsval slot; jsval slot;
ASSERT_OK(JS_GetReservedSlot(cx, callee, SLOT_FN_INT64PROTO, &slot)); ASSERT_OK(JS_GetReservedSlot(cx, callee, SLOT_FN_INT64PROTO, &slot));
@ -6079,10 +6066,8 @@ Int64::Join(JSContext* cx, uintN argc, jsval* vp)
JSBool JSBool
UInt64::Construct(JSContext* cx, UInt64::Construct(JSContext* cx,
JSObject* obj,
uintN argc, uintN argc,
jsval* argv, jsval* vp)
jsval* rval)
{ {
// Construct and return a new UInt64 object. // Construct and return a new UInt64 object.
if (argc != 1) { if (argc != 1) {
@ -6090,13 +6075,14 @@ UInt64::Construct(JSContext* cx,
return JS_FALSE; return JS_FALSE;
} }
jsval* argv = JS_ARGV(cx, vp);
JSUint64 u = 0; JSUint64 u = 0;
if (!jsvalToBigInteger(cx, argv[0], true, &u)) if (!jsvalToBigInteger(cx, argv[0], true, &u))
return TypeError(cx, "uint64", argv[0]); return TypeError(cx, "uint64", argv[0]);
// Get ctypes.UInt64.prototype from the 'prototype' property of the ctor. // Get ctypes.UInt64.prototype from the 'prototype' property of the ctor.
jsval slot; jsval slot;
ASSERT_OK(JS_GetProperty(cx, JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)), ASSERT_OK(JS_GetProperty(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)),
"prototype", &slot)); "prototype", &slot));
JSObject* proto = JSVAL_TO_OBJECT(slot); JSObject* proto = JSVAL_TO_OBJECT(slot);
JS_ASSERT(JS_GET_CLASS(cx, proto) == &sUInt64ProtoClass); JS_ASSERT(JS_GET_CLASS(cx, proto) == &sUInt64ProtoClass);
@ -6105,7 +6091,7 @@ UInt64::Construct(JSContext* cx,
if (!result) if (!result)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(result); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));
return JS_TRUE; return JS_TRUE;
} }
@ -6116,7 +6102,7 @@ UInt64::IsUInt64(JSContext* cx, JSObject* obj)
} }
JSBool JSBool
UInt64::ToString(JSContext* cx, uintN argc, jsval *vp) UInt64::ToString(JSContext* cx, uintN argc, jsval* vp)
{ {
JSObject* obj = JS_THIS_OBJECT(cx, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp);
if (!UInt64::IsUInt64(cx, obj)) { if (!UInt64::IsUInt64(cx, obj)) {
@ -6128,7 +6114,7 @@ UInt64::ToString(JSContext* cx, uintN argc, jsval *vp)
} }
JSBool JSBool
UInt64::ToSource(JSContext* cx, uintN argc, jsval *vp) UInt64::ToSource(JSContext* cx, uintN argc, jsval* vp)
{ {
JSObject* obj = JS_THIS_OBJECT(cx, vp); JSObject* obj = JS_THIS_OBJECT(cx, vp);
if (!UInt64::IsUInt64(cx, obj)) { if (!UInt64::IsUInt64(cx, obj)) {
@ -6231,7 +6217,7 @@ UInt64::Join(JSContext* cx, uintN argc, jsval* vp)
JSUint64 u = (JSUint64(hi) << 32) + JSUint64(lo); JSUint64 u = (JSUint64(hi) << 32) + JSUint64(lo);
// Get UInt64.prototype from the function's reserved slot. // Get UInt64.prototype from the function's reserved slot.
JSObject* callee = JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)); JSObject* callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
jsval slot; jsval slot;
ASSERT_OK(JS_GetReservedSlot(cx, callee, SLOT_FN_INT64PROTO, &slot)); ASSERT_OK(JS_GetReservedSlot(cx, callee, SLOT_FN_INT64PROTO, &slot));

Просмотреть файл

@ -71,7 +71,7 @@ static JSClass sLibraryClass = {
}; };
#define CTYPESFN_FLAGS \ #define CTYPESFN_FLAGS \
(JSFUN_FAST_NATIVE | JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) (JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)
static JSFunctionSpec sLibraryFunctions[] = { static JSFunctionSpec sLibraryFunctions[] = {
JS_FN("close", Library::Close, 0, CTYPESFN_FLAGS), JS_FN("close", Library::Close, 0, CTYPESFN_FLAGS),

Просмотреть файл

@ -16,8 +16,12 @@ static JSBool test_prop_get( JSContext *cx, JSObject *obj, jsid id, jsval *vp )
} }
static JSBool static JSBool
PTest(JSContext* cx, JSObject* obj, uintN argc, jsval *argv, jsval* rval) PTest(JSContext* cx, uintN argc, jsval *vp)
{ {
JSObject *obj = JS_NewObjectForConstructor(cx, vp);
if (!obj)
return JS_FALSE;
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
return JS_TRUE; return JS_TRUE;
} }
@ -36,14 +40,14 @@ static JSClass ptestClass = {
JSCLASS_NO_OPTIONAL_MEMBERS JSCLASS_NO_OPTIONAL_MEMBERS
}; };
static JSBool test_fn(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) static JSBool test_fn(JSContext *cx, uintN argc, jsval *vp)
{ {
called_test_fn++; called_test_fn++;
return JS_TRUE; return JS_TRUE;
} }
static JSFunctionSpec ptestFunctions[] = { static JSFunctionSpec ptestFunctions[] = {
JS_FS( "test_fn", test_fn, 0, 0, 0 ), JS_FS( "test_fn", test_fn, 0, 0 ),
JS_FS_END JS_FS_END
}; };

Просмотреть файл

@ -11,7 +11,7 @@ BEGIN_TEST(testContexts_IsRunning)
return true; return true;
} }
static JSBool chk(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) static JSBool chk(JSContext *cx, uintN argc, jsval *vp)
{ {
JSRuntime *rt = JS_GetRuntime(cx); JSRuntime *rt = JS_GetRuntime(cx);
JSContext *acx = JS_NewContext(rt, 8192); JSContext *acx = JS_NewContext(rt, 8192);

Просмотреть файл

@ -6,7 +6,7 @@
#include "jsxdrapi.h" #include "jsxdrapi.h"
static JSBool static JSBool
native(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) native(JSContext *cx, uintN argc, jsval *vp)
{ {
return JS_TRUE; return JS_TRUE;
} }

Просмотреть файл

@ -8,15 +8,17 @@ const size_t N = 1000;
static jsval argv[N]; static jsval argv[N];
static JSBool static JSBool
constructHook(JSContext *cx, JSObject *thisobj, uintN argc, jsval *argv, jsval *rval) constructHook(JSContext *cx, uintN argc, jsval *vp)
{ {
// Check that arguments were passed properly from JS_New. // Check that arguments were passed properly from JS_New.
JSObject *callee = JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)); JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
if (!thisobj) {
JS_ReportError(cx, "test failed, null 'this'"); JSObject *obj = JS_NewObjectForConstructor(cx, vp);
if (!obj) {
JS_ReportError(cx, "test failed, could not construct object");
return false; return false;
} }
if (strcmp(JS_GET_CLASS(cx, thisobj)->name, "Object") != 0) { if (strcmp(JS_GET_CLASS(cx, obj)->name, "Object") != 0) {
JS_ReportError(cx, "test failed, wrong class for 'this'"); JS_ReportError(cx, "test failed, wrong class for 'this'");
return false; return false;
} }
@ -28,7 +30,7 @@ constructHook(JSContext *cx, JSObject *thisobj, uintN argc, jsval *argv, jsval *
JS_ReportError(cx, "test failed, wrong value in argv[2]"); JS_ReportError(cx, "test failed, wrong value in argv[2]");
return false; return false;
} }
if (!JS_IsConstructing(cx)) { if (!JS_IsConstructing(cx, vp)) {
JS_ReportError(cx, "test failed, not constructing"); JS_ReportError(cx, "test failed, not constructing");
return false; return false;
} }
@ -37,7 +39,7 @@ constructHook(JSContext *cx, JSObject *thisobj, uintN argc, jsval *argv, jsval *
if (!JS_SetElement(cx, callee, 0, &argv[0])) if (!JS_SetElement(cx, callee, 0, &argv[0]))
return false; return false;
*rval = OBJECT_TO_JSVAL(callee); // return the callee, perversely *vp = OBJECT_TO_JSVAL(obj);
argv[0] = argv[1] = argv[2] = JSVAL_VOID; // trash the argv, perversely argv[0] = argv[1] = argv[2] = JSVAL_VOID; // trash the argv, perversely
return true; return true;
} }
@ -91,11 +93,8 @@ BEGIN_TEST(testNewObject_1)
jsvalRoot rt2(cx, OBJECT_TO_JSVAL(ctor)); jsvalRoot rt2(cx, OBJECT_TO_JSVAL(ctor));
obj = JS_New(cx, ctor, 3, argv); obj = JS_New(cx, ctor, 3, argv);
CHECK(obj); CHECK(obj);
CHECK(obj == ctor); // constructHook returns ctor, perversely
CHECK(JS_GetElement(cx, ctor, 0, &v)); CHECK(JS_GetElement(cx, ctor, 0, &v));
CHECK_SAME(v, JSVAL_ZERO); CHECK_SAME(v, JSVAL_ZERO);
CHECK_SAME(argv[0], JSVAL_ZERO); // original argv should not have been trashed
CHECK_SAME(argv[1], JSVAL_ONE);
return true; return true;
} }
END_TEST(testNewObject_1) END_TEST(testNewObject_1)

Просмотреть файл

@ -23,14 +23,14 @@ static JSClass myClass = {
}; };
static JSBool static JSBool
createMyObject(JSContext* context, JSObject* obj, uintN argc, jsval *argv, jsval* rval) createMyObject(JSContext* context, uintN argc, jsval *vp)
{ {
JS_BeginRequest(context); JS_BeginRequest(context);
//JS_GC(context); //<- if we make GC here, all is ok //JS_GC(context); //<- if we make GC here, all is ok
JSObject* myObject = JS_NewObject(context, &myClass, NULL, NULL); JSObject* myObject = JS_NewObject(context, &myClass, NULL, NULL);
*rval = OBJECT_TO_JSVAL(myObject); *vp = OBJECT_TO_JSVAL(myObject);
JS_EndRequest(context); JS_EndRequest(context);
@ -40,7 +40,7 @@ createMyObject(JSContext* context, JSObject* obj, uintN argc, jsval *argv, jsval
static JSFunctionSpec s_functions[] = static JSFunctionSpec s_functions[] =
{ {
{ "createMyObject", createMyObject, 0 }, { "createMyObject", createMyObject, 0 },
{ 0,0,0,0,0 } { 0,0,0,0 }
}; };
BEGIN_TEST(testOps_bug559006) BEGIN_TEST(testOps_bug559006)

Просмотреть файл

@ -2929,6 +2929,15 @@ JS_NewObjectWithGivenProto(JSContext *cx, JSClass *jsclasp, JSObject *proto, JSO
return NewNonFunction<WithProto::Given>(cx, clasp, proto, parent); return NewNonFunction<WithProto::Given>(cx, clasp, proto, parent);
} }
JS_PUBLIC_API(JSObject *)
JS_NewObjectForConstructor(JSContext *cx, const jsval *vp)
{
CHECK_REQUEST(cx);
assertSameCompartment(cx, *vp);
return js_NewInstance(cx, JSVAL_TO_OBJECT(*vp));
}
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep) JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep)
{ {
@ -4148,14 +4157,14 @@ JS_ObjectIsFunction(JSContext *cx, JSObject *obj)
} }
static JSBool static JSBool
js_generic_fast_native_method_dispatcher(JSContext *cx, uintN argc, Value *vp) js_generic_native_method_dispatcher(JSContext *cx, uintN argc, Value *vp)
{ {
JSFunctionSpec *fs; JSFunctionSpec *fs;
JSObject *tmp; JSObject *tmp;
FastNative native; Native native;
fs = (JSFunctionSpec *) vp->toObject().getReservedSlot(0).toPrivate(); fs = (JSFunctionSpec *) vp->toObject().getReservedSlot(0).toPrivate();
JS_ASSERT((~fs->flags & (JSFUN_FAST_NATIVE | JSFUN_GENERIC_NATIVE)) == 0); JS_ASSERT((fs->flags & JSFUN_GENERIC_NATIVE) != 0);
if (argc < 1) { if (argc < 1) {
js_ReportMissingArg(cx, *vp, 0); js_ReportMissingArg(cx, *vp, 0);
@ -4193,62 +4202,13 @@ js_generic_fast_native_method_dispatcher(JSContext *cx, uintN argc, Value *vp)
native = native =
#ifdef JS_TRACER #ifdef JS_TRACER
(fs->flags & JSFUN_TRCINFO) (fs->flags & JSFUN_TRCINFO)
? (FastNative) JS_FUNC_TO_DATA_PTR(JSNativeTraceInfo *, fs->call)->native ? JS_FUNC_TO_DATA_PTR(JSNativeTraceInfo *, fs->call)->native
: :
#endif #endif
(FastNative) fs->call; Valueify(fs->call);
return native(cx, argc, vp); return native(cx, argc, vp);
} }
static JSBool
js_generic_native_method_dispatcher(JSContext *cx, JSObject *obj,
uintN argc, Value *argv, Value *rval)
{
JSFunctionSpec *fs;
JSObject *tmp;
fs = (JSFunctionSpec *) argv[-2].toObject().getReservedSlot(0).toPrivate();
JS_ASSERT((fs->flags & (JSFUN_FAST_NATIVE | JSFUN_GENERIC_NATIVE)) ==
JSFUN_GENERIC_NATIVE);
if (argc < 1) {
js_ReportMissingArg(cx, *(argv - 2), 0);
return JS_FALSE;
}
if (argv[0].isPrimitive()) {
/*
* Make sure that this is an object or null, as required by the generic
* functions.
*/
if (!js_ValueToObjectOrNull(cx, argv[0], &tmp))
return JS_FALSE;
argv[0].setObjectOrNull(tmp);
}
/*
* Copy all actual (argc) arguments down over our |this| parameter,
* argv[-1], which is almost always the class constructor object, e.g.
* Array. Then call the corresponding prototype native method with our
* first argument passed as |this|.
*/
memmove(argv - 1, argv, argc * sizeof(jsval));
/*
* Follow Function.prototype.apply and .call by using the global object as
* the 'this' param if no args.
*/
if (!ComputeThisFromArgv(cx, argv))
return JS_FALSE;
js_GetTopStackFrame(cx)->setThisValue(argv[-1]);
JS_ASSERT(cx->fp()->argv == argv);
/* Clear the last parameter in case too few arguments were passed. */
argv[--argc].setUndefined();
return fs->call(cx, &argv[-1].toObject(), argc, Jsvalify(argv), Jsvalify(rval));
}
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs) JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
{ {
@ -4275,14 +4235,11 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
flags &= ~JSFUN_GENERIC_NATIVE; flags &= ~JSFUN_GENERIC_NATIVE;
fun = JS_DefineFunction(cx, ctor, fs->name, fun = JS_DefineFunction(cx, ctor, fs->name,
(flags & JSFUN_FAST_NATIVE) Jsvalify(js_generic_native_method_dispatcher),
? (JSNative) js_generic_fast_native_method_dispatcher
: Jsvalify(js_generic_native_method_dispatcher),
fs->nargs + 1, fs->nargs + 1,
flags & ~JSFUN_TRCINFO); flags & ~JSFUN_TRCINFO);
if (!fun) if (!fun)
return JS_FALSE; return JS_FALSE;
fun->u.n.extra = (uint16)fs->extra;
/* /*
* As jsapi.h notes, fs must point to storage that lives as long * As jsapi.h notes, fs must point to storage that lives as long
@ -4293,12 +4250,9 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
return JS_FALSE; return JS_FALSE;
} }
JS_ASSERT(!(flags & JSFUN_FAST_NATIVE) ||
(uint16)(fs->extra >> 16) <= fs->nargs);
fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs, flags); fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs, flags);
if (!fun) if (!fun)
return JS_FALSE; return JS_FALSE;
fun->u.n.extra = (uint16)fs->extra;
} }
return JS_TRUE; return JS_TRUE;
} }
@ -4771,7 +4725,7 @@ JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc, jsval
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, fun, JSValueArray(argv, argc)); assertSameCompartment(cx, obj, fun, JSValueArray(argv, argc));
ok = InternalCall(cx, obj, ObjectValue(*fun), argc, Valueify(argv), Valueify(rval)); ok = ExternalInvoke(cx, obj, ObjectValue(*fun), argc, Valueify(argv), Valueify(rval));
LAST_FRAME_CHECKS(cx, ok); LAST_FRAME_CHECKS(cx, ok);
return ok; return ok;
} }
@ -4787,7 +4741,7 @@ JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc,
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
JSBool ok = atom && JSBool ok = atom &&
js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, tvr.addr()) && js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, tvr.addr()) &&
InternalCall(cx, obj, tvr.value(), argc, Valueify(argv), Valueify(rval)); ExternalInvoke(cx, obj, tvr.value(), argc, Valueify(argv), Valueify(rval));
LAST_FRAME_CHECKS(cx, ok); LAST_FRAME_CHECKS(cx, ok);
return ok; return ok;
} }
@ -4800,7 +4754,7 @@ JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc, jsval
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, fval, JSValueArray(argv, argc)); assertSameCompartment(cx, obj, fval, JSValueArray(argv, argc));
ok = InternalCall(cx, obj, Valueify(fval), argc, Valueify(argv), Valueify(rval)); ok = ExternalInvoke(cx, obj, Valueify(fval), argc, Valueify(argv), Valueify(rval));
LAST_FRAME_CHECKS(cx, ok); LAST_FRAME_CHECKS(cx, ok);
return ok; return ok;
} }
@ -4893,12 +4847,6 @@ JS_IsRunning(JSContext *cx)
return fp != NULL; return fp != NULL;
} }
JS_PUBLIC_API(JSBool)
JS_IsConstructing(JSContext *cx)
{
return cx->isConstructing();
}
JS_PUBLIC_API(JSStackFrame *) JS_PUBLIC_API(JSStackFrame *)
JS_SaveFrameChain(JSContext *cx) JS_SaveFrameChain(JSContext *cx)
{ {

Просмотреть файл

@ -484,6 +484,8 @@ extern JS_PUBLIC_DATA(jsid) JSID_EMPTY;
if getters/setters use a shortid */ if getters/setters use a shortid */
/* Function flags, set in JSFunctionSpec and passed to JS_NewFunction etc. */ /* Function flags, set in JSFunctionSpec and passed to JS_NewFunction etc. */
#define JSFUN_CONSTRUCTOR 0x02 /* native that can be called as a ctor
without creating a this object */
#define JSFUN_LAMBDA 0x08 /* expressed, not declared, function */ #define JSFUN_LAMBDA 0x08 /* expressed, not declared, function */
#define JSFUN_HEAVYWEIGHT 0x80 /* activation requires a Call object */ #define JSFUN_HEAVYWEIGHT 0x80 /* activation requires a Call object */
@ -497,9 +499,7 @@ extern JS_PUBLIC_DATA(jsid) JSID_EMPTY;
#define JSFUN_THISP_BOOLEAN 0x0400 /* |this| may be a primitive boolean */ #define JSFUN_THISP_BOOLEAN 0x0400 /* |this| may be a primitive boolean */
#define JSFUN_THISP_PRIMITIVE 0x0700 /* |this| may be any primitive value */ #define JSFUN_THISP_PRIMITIVE 0x0700 /* |this| may be any primitive value */
#define JSFUN_FAST_NATIVE 0x0800 /* JSFastNative needs no JSStackFrame */ #define JSFUN_FLAGS_MASK 0x07fa /* overlay JSFUN_* attributes --
#define JSFUN_FLAGS_MASK 0x0ff8 /* overlay JSFUN_* attributes --
bits 12-15 are used internally to bits 12-15 are used internally to
flag interpreted functions */ flag interpreted functions */
@ -1078,9 +1078,11 @@ JS_InitCTypesClass(JSContext *cx, JSObject *global);
* WARNING: These are not (yet) mandatory macros, but new code outside of the * WARNING: These are not (yet) mandatory macros, but new code outside of the
* engine should use them. In the Mozilla 2.0 milestone their definitions may * engine should use them. In the Mozilla 2.0 milestone their definitions may
* change incompatibly. * change incompatibly.
*
* N.B. constructors must not use JS_THIS, as no 'this' object has been created.
*/ */
#define JS_CALLEE(cx,vp) ((vp)[0]) #define JS_CALLEE(cx,vp) ((vp)[0])
#define JS_ARGV_CALLEE(argv) ((argv)[-2])
#define JS_THIS(cx,vp) JS_ComputeThis(cx, vp) #define JS_THIS(cx,vp) JS_ComputeThis(cx, vp)
#define JS_THIS_OBJECT(cx,vp) (JSVAL_TO_OBJECT(JS_THIS(cx,vp))) #define JS_THIS_OBJECT(cx,vp) (JSVAL_TO_OBJECT(JS_THIS(cx,vp)))
#define JS_ARGV(cx,vp) ((vp) + 2) #define JS_ARGV(cx,vp) ((vp) + 2)
@ -1665,7 +1667,6 @@ struct JSClass {
#define JSCLASS_NEW_ENUMERATE (1<<1) /* has JSNewEnumerateOp hook */ #define JSCLASS_NEW_ENUMERATE (1<<1) /* has JSNewEnumerateOp hook */
#define JSCLASS_NEW_RESOLVE (1<<2) /* has JSNewResolveOp hook */ #define JSCLASS_NEW_RESOLVE (1<<2) /* has JSNewResolveOp hook */
#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) /* private is (nsISupports *) */ #define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) /* private is (nsISupports *) */
/* (1<<4) was JSCLASS_SHARE_ALL_PROPERTIES, now obsolete. See bug 527805. */
#define JSCLASS_NEW_RESOLVE_GETS_START (1<<5) /* JSNewResolveOp gets starting #define JSCLASS_NEW_RESOLVE_GETS_START (1<<5) /* JSNewResolveOp gets starting
object in prototype chain object in prototype chain
passed in via *objp in/out passed in via *objp in/out
@ -1798,38 +1799,23 @@ struct JSFunctionSpec {
JSNative call; JSNative call;
uint16 nargs; uint16 nargs;
uint16 flags; uint16 flags;
/*
* extra & 0xFFFF: Number of extra argument slots for local GC roots.
* If fast native, must be zero.
* extra >> 16: Reserved for future use (must be 0).
*/
uint32 extra;
}; };
/* /*
* Terminating sentinel initializer to put at the end of a JSFunctionSpec array * Terminating sentinel initializer to put at the end of a JSFunctionSpec array
* that's passed to JS_DefineFunctions or JS_InitClass. * that's passed to JS_DefineFunctions or JS_InitClass.
*/ */
#define JS_FS_END JS_FS(NULL,NULL,0,0,0) #define JS_FS_END JS_FS(NULL,NULL,0,0)
/* /*
* Initializer macro for a JSFunctionSpec array element. This is the original * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name
* kind of native function specifier initializer. Use JS_FN ("fast native", see * pays homage to the old JSNative/JSFastNative split) simply adds the flag
* JSFastNative in jspubtd.h) for all functions that do not need a stack frame * JSFUN_STUB_GSOPS.
* when activated.
*/ */
#define JS_FS(name,call,nargs,flags,extra) \ #define JS_FS(name,call,nargs,flags) \
{name, call, nargs, flags, extra} {name, call, nargs, flags}
#define JS_FN(name,call,nargs,flags) \
/* {name, call, nargs, (flags) | JSFUN_STUB_GSOPS}
* "Fast native" initializer macro for a JSFunctionSpec array element. Use this
* in preference to JS_FS if the native in question does not need its own stack
* frame when activated.
*/
#define JS_FN(name,fastcall,nargs,flags) \
JS_FS(name, (JSNative)(fastcall), nargs, \
(flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS, 0)
extern JS_PUBLIC_API(JSObject *) extern JS_PUBLIC_API(JSObject *)
JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
@ -2586,9 +2572,6 @@ JS_TriggerAllOperationCallbacks(JSRuntime *rt);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_IsRunning(JSContext *cx); JS_IsRunning(JSContext *cx);
extern JS_PUBLIC_API(JSBool)
JS_IsConstructing(JSContext *cx);
/* /*
* Saving and restoring frame chains. * Saving and restoring frame chains.
* *
@ -3064,6 +3047,87 @@ JS_GetFunctionCallback(JSContext *cx);
/************************************************************************/ /************************************************************************/
/*
* JS_IsConstructing must be called from within a native given the
* native's original cx and vp arguments. If JS_IsConstructing is true,
* JS_THIS must not be used; the constructor should construct and return a
* new object. Otherwise, the native is called as an ordinary function and
* JS_THIS may be used.
*/
static JS_ALWAYS_INLINE JSBool
JS_IsConstructing(JSContext *cx, const jsval *vp)
{
jsval_layout l;
#ifdef DEBUG
JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
if (JS_ObjectIsFunction(cx, callee)) {
JSFunction *fun = JS_ValueToFunction(cx, JS_CALLEE(cx, vp));
JS_ASSERT((JS_GetFunctionFlags(fun) & JSFUN_CONSTRUCTOR) != 0);
} else {
JS_ASSERT(JS_GET_CLASS(cx, callee)->construct != NULL);
}
#endif
l.asBits = JSVAL_BITS(vp[1]);
return JSVAL_IS_MAGIC_IMPL(l);
}
/*
* In the case of a constructor called from JS_ConstructObject and
* JS_InitClass where the class has the JSCLASS_CONSTRUCT_PROTOTYPE flag set,
* the JS engine passes the constructor a non-standard 'this' object. In such
* cases, the following query provides the additional information of whether a
* special 'this' was supplied. E.g.:
*
* JSBool foo_native(JSContext *cx, uintN argc, jsval *vp) {
* JSObject *maybeThis;
* if (JS_IsConstructing_PossiblyWithGivenThisObject(cx, vp, &maybeThis)) {
* // native called as a constructor
* if (maybeThis)
* // native called as a constructor with maybeThis as 'this'
* } else {
* // native called as function, maybeThis is still uninitialized
* }
* }
*
* Note that embeddings do not need to use this query unless they use the
* aforementioned API/flags.
*/
static JS_ALWAYS_INLINE JSBool
JS_IsConstructing_PossiblyWithGivenThisObject(JSContext *cx, const jsval *vp,
JSObject **maybeThis)
{
jsval_layout l;
JSBool isCtor;
#ifdef DEBUG
JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
if (JS_ObjectIsFunction(cx, callee)) {
JSFunction *fun = JS_ValueToFunction(cx, JS_CALLEE(cx, vp));
JS_ASSERT((JS_GetFunctionFlags(fun) & JSFUN_CONSTRUCTOR) != 0);
} else {
JS_ASSERT(JS_GET_CLASS(cx, callee)->construct != NULL);
}
#endif
l.asBits = JSVAL_BITS(vp[1]);
isCtor = JSVAL_IS_MAGIC_IMPL(l);
if (isCtor)
*maybeThis = MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(l);
return isCtor;
}
/*
* If a constructor does not have any static knowledge about the type of
* object to create, it can request that the JS engine create a default new
* 'this' object, as is done for non-constructor natives when called with new.
*/
extern JS_PUBLIC_API(JSObject *)
JS_NewObjectForConstructor(JSContext *cx, const jsval *vp);
/************************************************************************/
#ifdef DEBUG #ifdef DEBUG
#define JS_GC_ZEAL 1 #define JS_GC_ZEAL 1
#endif #endif

Просмотреть файл

@ -1008,8 +1008,7 @@ Class js_ArrayClass = {
"Array", "Array",
Class::NON_NATIVE | Class::NON_NATIVE |
JSCLASS_HAS_RESERVED_SLOTS(JSObject::DENSE_ARRAY_CLASS_RESERVED_SLOTS) | JSCLASS_HAS_RESERVED_SLOTS(JSObject::DENSE_ARRAY_CLASS_RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Array) | JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
JSCLASS_FAST_CONSTRUCTOR,
PropertyStub, /* addProperty */ PropertyStub, /* addProperty */
PropertyStub, /* delProperty */ PropertyStub, /* delProperty */
PropertyStub, /* getProperty */ PropertyStub, /* getProperty */
@ -1045,8 +1044,7 @@ Class js_ArrayClass = {
Class js_SlowArrayClass = { Class js_SlowArrayClass = {
"Array", "Array",
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_Array) | JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
JSCLASS_FAST_CONSTRUCTOR,
slowarray_addProperty, slowarray_addProperty,
PropertyStub, /* delProperty */ PropertyStub, /* delProperty */
PropertyStub, /* getProperty */ PropertyStub, /* getProperty */
@ -2910,11 +2908,11 @@ array_every(JSContext *cx, uintN argc, Value *vp)
#endif #endif
static JSBool static JSBool
array_isArray(JSContext *cx, uintN argc, jsval *vp) array_isArray(JSContext *cx, uintN argc, Value *vp)
{ {
*vp = BOOLEAN_TO_JSVAL(argc > 0 && vp->setBoolean(argc > 0 &&
!JSVAL_IS_PRIMITIVE(vp[2]) && vp[2].isObject() &&
JSVAL_TO_OBJECT(vp[2])->wrappedObject(cx)->isArray()); vp[2].toObject().wrappedObject(cx)->isArray());
return JS_TRUE; return JS_TRUE;
} }
@ -3038,7 +3036,7 @@ JS_DEFINE_CALLINFO_3(extern, OBJECT, js_NewPreallocatedArray, CONTEXT, OBJECT, I
JSObject * JSObject *
js_InitArrayClass(JSContext *cx, JSObject *obj) js_InitArrayClass(JSContext *cx, JSObject *obj)
{ {
JSObject *proto = js_InitClass(cx, obj, NULL, &js_ArrayClass, (Native) js_Array, 1, JSObject *proto = js_InitClass(cx, obj, NULL, &js_ArrayClass, js_Array, 1,
NULL, array_methods, NULL, array_static_methods); NULL, array_methods, NULL, array_static_methods);
if (!proto) if (!proto)
return NULL; return NULL;

Просмотреть файл

@ -60,7 +60,8 @@ using namespace js;
Class js_BooleanClass = { Class js_BooleanClass = {
"Boolean", "Boolean",
JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean), JSCLASS_HAS_RESERVED_SLOTS(1) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean),
PropertyStub, /* addProperty */ PropertyStub, /* addProperty */
PropertyStub, /* delProperty */ PropertyStub, /* delProperty */
PropertyStub, /* getProperty */ PropertyStub, /* getProperty */
@ -126,18 +127,20 @@ static JSFunctionSpec boolean_methods[] = {
}; };
static JSBool static JSBool
Boolean(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) Boolean(JSContext *cx, uintN argc, Value *vp)
{ {
Value bval; Value *argv = vp + 2;
bool b = argc != 0 ? js_ValueToBoolean(argv[0]) : false;
if (argc != 0) if (IsConstructing(vp)) {
bval.setBoolean(!!js_ValueToBoolean(argv[0])); JSObject *obj = NewBuiltinClassInstance(cx, &js_BooleanClass);
else if (!obj)
bval.setBoolean(false); return false;
if (!JS_IsConstructing(cx)) obj->setPrimitiveThis(BooleanValue(b));
*rval = bval; vp->setObject(*obj);
else } else {
obj->setPrimitiveThis(bval); vp->setBoolean(b);
}
return true; return true;
} }

Просмотреть файл

@ -43,6 +43,7 @@
#ifdef JS_TRACER #ifdef JS_TRACER
#include "nanojit/nanojit.h" #include "nanojit/nanojit.h"
#include "jsvalue.h"
#ifdef THIS #ifdef THIS
#undef THIS #undef THIS
@ -61,7 +62,7 @@ enum {
#define JSTN_ERRTYPE(jstn) ((jstn)->flags & JSTN_ERRTYPE_MASK) #define JSTN_ERRTYPE(jstn) ((jstn)->flags & JSTN_ERRTYPE_MASK)
/* /*
* Type describing a type specialization of a JSFastNative. * Type describing a type specialization of a js::Native.
* *
* |prefix| and |argtypes| declare what arguments should be passed to the * |prefix| and |argtypes| declare what arguments should be passed to the
* native function. |prefix| can contain the following characters: * native function. |prefix| can contain the following characters:
@ -103,7 +104,7 @@ struct JSSpecializedNative {
* terminated by the lack of having the JSTN_MORE flag set. * terminated by the lack of having the JSTN_MORE flag set.
*/ */
struct JSNativeTraceInfo { struct JSNativeTraceInfo {
JSFastNative native; js::Native native;
JSSpecializedNative *specializations; JSSpecializedNative *specializations;
}; };
@ -506,7 +507,7 @@ struct ClosureVarInfo;
JSSpecializedNative name##_sns[] = { \ JSSpecializedNative name##_sns[] = { \
{ _JS_TN_INIT_HELPER_n tn0 } \ { _JS_TN_INIT_HELPER_n tn0 } \
}; \ }; \
JSNativeTraceInfo name##_trcinfo = { (JSFastNative)name, name##_sns }; JSNativeTraceInfo name##_trcinfo = { JS_VALUEIFY_NATIVE(name), name##_sns };
#define JS_DEFINE_TRCINFO_2(name, tn0, tn1) \ #define JS_DEFINE_TRCINFO_2(name, tn0, tn1) \
_JS_DEFINE_CALLINFO_n tn0 \ _JS_DEFINE_CALLINFO_n tn0 \
@ -515,7 +516,7 @@ struct ClosureVarInfo;
{ _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \ { _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \
{ _JS_TN_INIT_HELPER_n tn1 } \ { _JS_TN_INIT_HELPER_n tn1 } \
}; \ }; \
JSNativeTraceInfo name##_trcinfo = { (JSFastNative)name, name##_sns }; JSNativeTraceInfo name##_trcinfo = { JS_VALUEIFY_NATIVE(name), name##_sns };
#define JS_DEFINE_TRCINFO_3(name, tn0, tn1, tn2) \ #define JS_DEFINE_TRCINFO_3(name, tn0, tn1, tn2) \
_JS_DEFINE_CALLINFO_n tn0 \ _JS_DEFINE_CALLINFO_n tn0 \
@ -526,7 +527,7 @@ struct ClosureVarInfo;
{ _JS_TN_INIT_HELPER_n tn1 | JSTN_MORE }, \ { _JS_TN_INIT_HELPER_n tn1 | JSTN_MORE }, \
{ _JS_TN_INIT_HELPER_n tn2 } \ { _JS_TN_INIT_HELPER_n tn2 } \
}; \ }; \
JSNativeTraceInfo name##_trcinfo = { (JSFastNative)name, name##_sns }; JSNativeTraceInfo name##_trcinfo = { JS_VALUEIFY_NATIVE(name), name##_sns };
#define JS_DEFINE_TRCINFO_4(name, tn0, tn1, tn2, tn3) \ #define JS_DEFINE_TRCINFO_4(name, tn0, tn1, tn2, tn3) \
_JS_DEFINE_CALLINFO_n tn0 \ _JS_DEFINE_CALLINFO_n tn0 \
@ -539,7 +540,7 @@ struct ClosureVarInfo;
{ _JS_TN_INIT_HELPER_n tn2 | JSTN_MORE }, \ { _JS_TN_INIT_HELPER_n tn2 | JSTN_MORE }, \
{ _JS_TN_INIT_HELPER_n tn3 } \ { _JS_TN_INIT_HELPER_n tn3 } \
}; \ }; \
JSNativeTraceInfo name##_trcinfo = { (JSFastNative)name, name##_sns }; JSNativeTraceInfo name##_trcinfo = { JS_VALUEIFY_NATIVE(name), name##_sns };
#define _JS_DEFINE_CALLINFO_n(n, args) JS_DEFINE_CALLINFO_##n args #define _JS_DEFINE_CALLINFO_n(n, args) JS_DEFINE_CALLINFO_##n args
@ -611,7 +612,7 @@ JS_DECLARE_CALLINFO(js_NumberToString)
/* Defined in jsobj.cpp. */ /* Defined in jsobj.cpp. */
JS_DECLARE_CALLINFO(js_Object_tn) JS_DECLARE_CALLINFO(js_Object_tn)
JS_DECLARE_CALLINFO(js_NewInstance) JS_DECLARE_CALLINFO(js_NewInstanceFromTrace)
JS_DECLARE_CALLINFO(js_NonEmptyObject) JS_DECLARE_CALLINFO(js_NonEmptyObject)
/* Defined in jsregexp.cpp. */ /* Defined in jsregexp.cpp. */

Просмотреть файл

@ -341,37 +341,6 @@ FrameGuard::~FrameGuard()
cx->stack().popFrame(cx); cx->stack().popFrame(cx);
} }
JS_REQUIRES_STACK void
StackSpace::getSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *&seg, JSStackFrame *&fp)
{
Value *start = firstUnused();
JS_ASSERT(size_t(end - start) >= VALUES_PER_STACK_SEGMENT + VALUES_PER_STACK_FRAME);
seg = new(start) StackSegment;
fp = reinterpret_cast<JSStackFrame *>(seg + 1);
}
JS_REQUIRES_STACK void
StackSpace::pushSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *seg, JSFrameRegs &regs)
{
JS_ASSERT(!regs.fp->hasScript() && FUN_SLOW_NATIVE(regs.fp->getFunction()));
regs.fp->down = cx->maybefp();
seg->setPreviousInMemory(currentSegment);
currentSegment = seg;
cx->pushSegmentAndFrame(seg, regs);
seg->setInitialVarObj(NULL);
}
JS_REQUIRES_STACK void
StackSpace::popSynthesizedSlowNativeFrame(JSContext *cx)
{
JS_ASSERT(isCurrentAndActive(cx));
JS_ASSERT(cx->hasActiveSegment());
JS_ASSERT(currentSegment->getInitialFrame() == cx->fp());
JS_ASSERT(!cx->fp()->hasScript() && FUN_SLOW_NATIVE(cx->fp()->getFunction()));
cx->popSegmentAndFrame();
currentSegment = currentSegment->getPreviousInMemory();
}
JS_REQUIRES_STACK bool JS_REQUIRES_STACK bool
StackSpace::pushDummyFrame(JSContext *cx, FrameGuard &fg, JSFrameRegs &regs, JSObject *scopeChain) StackSpace::pushDummyFrame(JSContext *cx, FrameGuard &fg, JSFrameRegs &regs, JSObject *scopeChain)
{ {
@ -1947,12 +1916,10 @@ js_GetScriptedCaller(JSContext *cx, JSStackFrame *fp)
{ {
if (!fp) if (!fp)
fp = js_GetTopStackFrame(cx); fp = js_GetTopStackFrame(cx);
while (fp) { while (fp && fp->isDummyFrame())
if (fp->hasScript())
return fp;
fp = fp->down; fp = fp->down;
} JS_ASSERT_IF(fp, fp->hasScript());
return NULL; return fp;
} }
jsbytecode* jsbytecode*
@ -2195,20 +2162,6 @@ JSContext::checkMallocGCPressure(void *p)
} }
} }
bool
JSContext::isConstructing()
{
#ifdef JS_TRACER
if (JS_ON_TRACE(this)) {
JS_ASSERT(bailExit);
return *bailExit->pc == JSOP_NEW;
}
#endif
JSStackFrame *fp = js_GetTopStackFrame(this);
return fp && (fp->flags & JSFRAME_CONSTRUCTING);
}
/* /*
* Release pool's arenas if the stackPool has existed for longer than the * Release pool's arenas if the stackPool has existed for longer than the
* limit specified by gcEmptyArenaPoolLifespan. * limit specified by gcEmptyArenaPoolLifespan.

Просмотреть файл

@ -809,19 +809,6 @@ class StackSpace
JS_REQUIRES_STACK JS_REQUIRES_STACK
inline void popInlineFrame(JSContext *cx, JSStackFrame *up, JSStackFrame *down); inline void popInlineFrame(JSContext *cx, JSStackFrame *up, JSStackFrame *down);
/*
* For the special case of the slow native stack frame pushed and popped by
* tracing deep bail logic.
*/
JS_REQUIRES_STACK
void getSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *&seg, JSStackFrame *&fp);
JS_REQUIRES_STACK
void pushSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *seg, JSFrameRegs &regs);
JS_REQUIRES_STACK
void popSynthesizedSlowNativeFrame(JSContext *cx);
/* /*
* For pushing a bookkeeping frame. * For pushing a bookkeeping frame.
*/ */
@ -2361,8 +2348,6 @@ struct JSContext
this->free(p); this->free(p);
} }
bool isConstructing();
void purge(); void purge();
js::StackSpace &stack() const { js::StackSpace &stack() const {

Просмотреть файл

@ -604,27 +604,43 @@ assertSameCompartment(JSContext *cx, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
#undef START_ASSERT_SAME_COMPARTMENT #undef START_ASSERT_SAME_COMPARTMENT
inline JSBool JS_ALWAYS_INLINE bool
CallJSNative(JSContext *cx, js::Native native, JSObject *thisobj, uintN argc, js::Value *argv, js::Value *rval) CallJSNative(JSContext *cx, js::Native native, uintN argc, js::Value *vp)
{
assertSameCompartment(cx, thisobj, ValueArray(argv, argc));
JSBool ok = native(cx, thisobj, argc, argv, rval);
if (ok)
assertSameCompartment(cx, *rval);
return ok;
}
inline JSBool
CallJSFastNative(JSContext *cx, js::FastNative native, uintN argc, js::Value *vp)
{ {
#ifdef DEBUG
JSBool alreadyThrowing = cx->throwing;
#endif
assertSameCompartment(cx, ValueArray(vp, argc + 2)); assertSameCompartment(cx, ValueArray(vp, argc + 2));
JSBool ok = native(cx, argc, vp); JSBool ok = native(cx, argc, vp);
if (ok) if (ok) {
assertSameCompartment(cx, vp[0]); assertSameCompartment(cx, vp[0]);
JS_ASSERT_IF(!alreadyThrowing, !cx->throwing);
}
return ok; return ok;
} }
inline JSBool JS_ALWAYS_INLINE bool
CallJSNativeConstructor(JSContext *cx, js::Native native, uintN argc, js::Value *vp)
{
#ifdef DEBUG
JSObject *callee = &vp[0].toObject();
#endif
JS_ASSERT(vp[1].isMagic());
if (!CallJSNative(cx, native, argc, vp))
return false;
JS_ASSERT(!vp->isPrimitive());
/*
* Even though its technically legal, if a native constructor returns the
* callee, there is a 99.9999% chance it is a bug. If any valid code
* actually wants the constructor to return the callee, this can be removed.
*/
JS_ASSERT(callee != &vp[0].toObject());
return true;
}
JS_ALWAYS_INLINE bool
CallJSPropertyOp(JSContext *cx, js::PropertyOp op, JSObject *obj, jsid id, js::Value *vp) CallJSPropertyOp(JSContext *cx, js::PropertyOp op, JSObject *obj, jsid id, js::Value *vp)
{ {
assertSameCompartment(cx, obj, id, *vp); assertSameCompartment(cx, obj, id, *vp);
@ -634,7 +650,7 @@ CallJSPropertyOp(JSContext *cx, js::PropertyOp op, JSObject *obj, jsid id, js::V
return ok; return ok;
} }
inline JSBool JS_ALWAYS_INLINE bool
CallJSPropertyOpSetter(JSContext *cx, js::PropertyOp op, JSObject *obj, jsid id, js::Value *vp) CallJSPropertyOpSetter(JSContext *cx, js::PropertyOp op, JSObject *obj, jsid id, js::Value *vp)
{ {
assertSameCompartment(cx, obj, id, *vp); assertSameCompartment(cx, obj, id, *vp);

Просмотреть файл

@ -497,8 +497,7 @@ msFromTime(jsdouble t)
Class js_DateClass = { Class js_DateClass = {
js_Date_str, js_Date_str,
JSCLASS_HAS_RESERVED_SLOTS(JSObject::DATE_CLASS_RESERVED_SLOTS) | JSCLASS_HAS_RESERVED_SLOTS(JSObject::DATE_CLASS_RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Date) | JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
JSCLASS_FAST_CONSTRUCTOR,
PropertyStub, /* addProperty */ PropertyStub, /* addProperty */
PropertyStub, /* delProperty */ PropertyStub, /* delProperty */
PropertyStub, /* getProperty */ PropertyStub, /* getProperty */
@ -2479,25 +2478,27 @@ JSBool
js_Date(JSContext *cx, uintN argc, Value *vp) js_Date(JSContext *cx, uintN argc, Value *vp)
{ {
/* Date called as function. */ /* Date called as function. */
if (!vp[1].isMagic(JS_FAST_CONSTRUCTOR)) if (!IsConstructing(vp))
return date_format(cx, NowAsMillis(), FORMATSPEC_FULL, vp); return date_format(cx, NowAsMillis(), FORMATSPEC_FULL, vp);
Value *argv = vp + 2;
/* Date called as constructor. */ /* Date called as constructor. */
jsdouble d; jsdouble d;
if (argc == 0) { if (argc == 0) {
d = NowAsMillis(); d = NowAsMillis();
} else if (argc == 1) { } else if (argc == 1) {
if (!vp[2].isString()) { if (!argv[0].isString()) {
/* the argument is a millisecond number */ /* the argument is a millisecond number */
if (!ValueToNumber(cx, vp[2], &d)) if (!ValueToNumber(cx, argv[0], &d))
return JS_FALSE; return false;
d = TIMECLIP(d); d = TIMECLIP(d);
} else { } else {
/* the argument is a string; parse it. */ /* the argument is a string; parse it. */
JSString *str = js_ValueToString(cx, vp[2]); JSString *str = js_ValueToString(cx, argv[0]);
if (!str) if (!str)
return JS_FALSE; return false;
vp[2].setString(str); argv[0].setString(str);
if (!date_parseString(str, &d, cx)) if (!date_parseString(str, &d, cx))
d = js_NaN; d = js_NaN;
@ -2506,8 +2507,8 @@ js_Date(JSContext *cx, uintN argc, Value *vp)
} }
} else { } else {
jsdouble msec_time; jsdouble msec_time;
if (!date_msecFromArgs(cx, argc, vp + 2, &msec_time)) if (!date_msecFromArgs(cx, argc, argv, &msec_time))
return JS_FALSE; return false;
if (JSDOUBLE_IS_FINITE(msec_time)) { if (JSDOUBLE_IS_FINITE(msec_time)) {
msec_time = UTC(msec_time, cx); msec_time = UTC(msec_time, cx);
@ -2518,10 +2519,10 @@ js_Date(JSContext *cx, uintN argc, Value *vp)
JSObject *obj = js_NewDateObjectMsec(cx, d); JSObject *obj = js_NewDateObjectMsec(cx, d);
if (!obj) if (!obj)
return JS_FALSE; return false;
vp->setObject(*obj); vp->setObject(*obj);
return JS_TRUE; return true;
} }
JSObject * JSObject *
@ -2529,7 +2530,7 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
{ {
/* set static LocalTZA */ /* set static LocalTZA */
LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond); LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
JSObject *proto = js_InitClass(cx, obj, NULL, &js_DateClass, (Native) js_Date, MAXARGS, JSObject *proto = js_InitClass(cx, obj, NULL, &js_DateClass, js_Date, MAXARGS,
NULL, date_methods, NULL, date_static_methods); NULL, date_methods, NULL, date_static_methods);
if (!proto) if (!proto)
return NULL; return NULL;

Просмотреть файл

@ -93,6 +93,7 @@ JS_GetDebugMode(JSContext *cx)
return cx->compartment->debugMode; return cx->compartment->debugMode;
} }
#ifdef JS_METHODJIT
static bool static bool
IsScriptLive(JSContext *cx, JSScript *script) IsScriptLive(JSContext *cx, JSScript *script)
{ {
@ -102,6 +103,7 @@ IsScriptLive(JSContext *cx, JSScript *script)
} }
return false; return false;
} }
#endif
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_SetDebugMode(JSContext *cx, JSBool debug) js_SetDebugMode(JSContext *cx, JSBool debug)
@ -137,7 +139,7 @@ JS_SetDebugMode(JSContext *cx, JSBool debug)
{ {
#ifdef DEBUG #ifdef DEBUG
for (AllFramesIter i(cx); !i.done(); ++i) for (AllFramesIter i(cx); !i.done(); ++i)
JS_ASSERT(JS_IsNativeFrame(cx, i.fp())); JS_ASSERT(!JS_IsScriptFrame(cx, i.fp()));
#endif #endif
return js_SetDebugMode(cx, debug); return js_SetDebugMode(cx, debug);
@ -698,9 +700,9 @@ js_watch_set(JSContext *cx, JSObject *obj, jsid id, Value *vp)
*/ */
JSBool ok = !wp->setter || JSBool ok = !wp->setter ||
(shape->hasSetterValue() (shape->hasSetterValue()
? InternalCall(cx, obj, ? ExternalInvoke(cx, obj,
ObjectValue(*CastAsObject(wp->setter)), ObjectValue(*CastAsObject(wp->setter)),
1, vp, vp) 1, vp, vp)
: CallJSPropertyOpSetter(cx, wp->setter, obj, userid, vp)); : CallJSPropertyOpSetter(cx, wp->setter, obj, userid, vp));
DBG_LOCK(rt); DBG_LOCK(rt);
@ -712,18 +714,18 @@ js_watch_set(JSContext *cx, JSObject *obj, jsid id, Value *vp)
} }
JSBool JSBool
js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, Value *argv, js_watch_set_wrapper(JSContext *cx, uintN argc, Value *vp)
Value *rval)
{ {
JSObject *funobj; JSObject *obj = ComputeThisFromVp(cx, vp);
JSFunction *wrapper; if (!obj)
jsid userid; return false;
funobj = &argv[-2].toObject(); JSObject &funobj = JS_CALLEE(cx, vp).toObject();
wrapper = GET_FUNCTION_PRIVATE(cx, funobj); JSFunction *wrapper = funobj.getFunctionPrivate();
userid = ATOM_TO_JSID(wrapper->atom); jsid userid = ATOM_TO_JSID(wrapper->atom);
*rval = argv[0];
return js_watch_set(cx, obj, userid, rval); JS_SET_RVAL(cx, vp, argc ? JS_ARGV(cx, vp)[0] : UndefinedValue());
return js_watch_set(cx, obj, userid, vp);
} }
static bool static bool
@ -735,7 +737,7 @@ IsWatchedProperty(JSContext *cx, const Shape &shape)
return false; return false;
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj); JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
return FUN_NATIVE(fun) == js_watch_set_wrapper; return fun->maybeNative() == js_watch_set_wrapper;
} }
return shape.setterOp() == js_watch_set; return shape.setterOp() == js_watch_set;
} }
@ -1058,13 +1060,7 @@ JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
JS_PUBLIC_API(JSNative) JS_PUBLIC_API(JSNative)
JS_GetFunctionNative(JSContext *cx, JSFunction *fun) JS_GetFunctionNative(JSContext *cx, JSFunction *fun)
{ {
return Jsvalify(FUN_NATIVE(fun)); return Jsvalify(fun->maybeNative());
}
JS_PUBLIC_API(JSFastNative)
JS_GetFunctionFastNative(JSContext *cx, JSFunction *fun)
{
return Jsvalify(FUN_FAST_NATIVE(fun));
} }
JS_PUBLIC_API(JSPrincipals *) JS_PUBLIC_API(JSPrincipals *)
@ -1103,8 +1099,8 @@ JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp)
return js_GetScriptedCaller(cx, fp); return js_GetScriptedCaller(cx, fp);
} }
JS_PUBLIC_API(JSPrincipals *) JSPrincipals *
JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp) js_StackFramePrincipals(JSContext *cx, JSStackFrame *fp)
{ {
JSSecurityCallbacks *callbacks; JSSecurityCallbacks *callbacks;
@ -1134,24 +1130,18 @@ js_EvalFramePrincipals(JSContext *cx, JSObject *callee, JSStackFrame *caller)
principals = NULL; principals = NULL;
if (!caller) if (!caller)
return principals; return principals;
callerPrincipals = JS_StackFramePrincipals(cx, caller); callerPrincipals = js_StackFramePrincipals(cx, caller);
return (callerPrincipals && principals && return (callerPrincipals && principals &&
callerPrincipals->subsume(callerPrincipals, principals)) callerPrincipals->subsume(callerPrincipals, principals))
? principals ? principals
: callerPrincipals; : callerPrincipals;
} }
JS_PUBLIC_API(JSPrincipals *)
JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller)
{
return js_EvalFramePrincipals(cx, fp->callee(), caller);
}
JS_PUBLIC_API(void *) JS_PUBLIC_API(void *)
JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp) JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp)
{ {
if (fp->hasAnnotation() && fp->hasScript()) { if (fp->hasAnnotation() && fp->hasScript()) {
JSPrincipals *principals = JS_StackFramePrincipals(cx, fp); JSPrincipals *principals = js_StackFramePrincipals(cx, fp);
if (principals && principals->globalPrivilegesEnabled(cx, principals)) { if (principals && principals->globalPrivilegesEnabled(cx, principals)) {
/* /*
@ -1176,16 +1166,16 @@ JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp)
{ {
JSPrincipals *principals; JSPrincipals *principals;
principals = JS_StackFramePrincipals(cx, fp); principals = js_StackFramePrincipals(cx, fp);
if (!principals) if (!principals)
return NULL; return NULL;
return principals->getPrincipalArray(cx, principals); return principals->getPrincipalArray(cx, principals);
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp) JS_IsScriptFrame(JSContext *cx, JSStackFrame *fp)
{ {
return !fp->hasScript(); return !fp->isDummyFrame();
} }
/* this is deprecated, use JS_GetFrameScopeChain instead */ /* this is deprecated, use JS_GetFrameScopeChain instead */
@ -1356,7 +1346,7 @@ JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
* we use a static level that will cause us not to attempt to optimize * we use a static level that will cause us not to attempt to optimize
* variable references made by this frame. * variable references made by this frame.
*/ */
JSScript *script = Compiler::compileScript(cx, scobj, fp, JS_StackFramePrincipals(cx, fp), JSScript *script = Compiler::compileScript(cx, scobj, fp, js_StackFramePrincipals(cx, fp),
TCF_COMPILE_N_GO, chars, length, NULL, TCF_COMPILE_N_GO, chars, length, NULL,
filename, lineno, NULL, filename, lineno, NULL,
UpvarCookie::UPVAR_LEVEL_LIMIT); UpvarCookie::UPVAR_LEVEL_LIMIT);
@ -1876,50 +1866,50 @@ JS_DisconnectShark()
} }
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_StartShark(JSContext *cx, JSObject *obj, js_StartShark(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *rval)
{ {
if (!JS_StartChudRemote()) { if (!JS_StartChudRemote()) {
JS_ReportError(cx, "Error starting CHUD."); JS_ReportError(cx, "Error starting CHUD.");
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_StopShark(JSContext *cx, JSObject *obj, js_StopShark(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *rval)
{ {
if (!JS_StopChudRemote()) { if (!JS_StopChudRemote()) {
JS_ReportError(cx, "Error stopping CHUD."); JS_ReportError(cx, "Error stopping CHUD.");
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_ConnectShark(JSContext *cx, JSObject *obj, js_ConnectShark(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *rval)
{ {
if (!JS_ConnectShark()) { if (!JS_ConnectShark()) {
JS_ReportError(cx, "Error connecting to Shark."); JS_ReportError(cx, "Error connecting to Shark.");
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_DisconnectShark(JSContext *cx, JSObject *obj, js_DisconnectShark(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *rval)
{ {
if (!JS_DisconnectShark()) { if (!JS_DisconnectShark()) {
JS_ReportError(cx, "Error disconnecting from Shark."); JS_ReportError(cx, "Error disconnecting from Shark.");
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -1930,29 +1920,29 @@ js_DisconnectShark(JSContext *cx, JSObject *obj,
#include <valgrind/callgrind.h> #include <valgrind/callgrind.h>
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_StartCallgrind(JSContext *cx, JSObject *obj, js_StartCallgrind(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *rval)
{ {
CALLGRIND_START_INSTRUMENTATION; CALLGRIND_START_INSTRUMENTATION;
CALLGRIND_ZERO_STATS; CALLGRIND_ZERO_STATS;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_StopCallgrind(JSContext *cx, JSObject *obj, js_StopCallgrind(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *rval)
{ {
CALLGRIND_STOP_INSTRUMENTATION; CALLGRIND_STOP_INSTRUMENTATION;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_DumpCallgrind(JSContext *cx, JSObject *obj, js_DumpCallgrind(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *rval)
{ {
JSString *str; JSString *str;
char *cstr; char *cstr;
jsval *argv = JS_ARGV(cx, vp);
if (argc > 0 && JSVAL_IS_STRING(argv[0])) { if (argc > 0 && JSVAL_IS_STRING(argv[0])) {
str = JSVAL_TO_STRING(argv[0]); str = JSVAL_TO_STRING(argv[0]);
cstr = js_DeflateString(cx, str->chars(), str->length()); cstr = js_DeflateString(cx, str->chars(), str->length());
@ -1964,6 +1954,7 @@ js_DumpCallgrind(JSContext *cx, JSObject *obj,
} }
CALLGRIND_DUMP_STATS; CALLGRIND_DUMP_STATS;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }

Просмотреть файл

@ -142,8 +142,7 @@ extern JSBool
js_watch_set(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); js_watch_set(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool extern JSBool
js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, js::Value *argv, js_watch_set_wrapper(JSContext *cx, uintN argc, js::Value *vp);
js::Value *rval);
extern js::PropertyOp extern js::PropertyOp
js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, js::PropertyOp setter); js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, js::PropertyOp setter);
@ -189,9 +188,6 @@ JS_GetFunctionScript(JSContext *cx, JSFunction *fun);
extern JS_PUBLIC_API(JSNative) extern JS_PUBLIC_API(JSNative)
JS_GetFunctionNative(JSContext *cx, JSFunction *fun); JS_GetFunctionNative(JSContext *cx, JSFunction *fun);
extern JS_PUBLIC_API(JSFastNative)
JS_GetFunctionFastNative(JSContext *cx, JSFunction *fun);
extern JS_PUBLIC_API(JSPrincipals *) extern JS_PUBLIC_API(JSPrincipals *)
JS_GetScriptPrincipals(JSContext *cx, JSScript *script); JS_GetScriptPrincipals(JSContext *cx, JSScript *script);
@ -221,22 +217,8 @@ JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp);
* Return a weak reference to fp's principals. A null return does not denote * Return a weak reference to fp's principals. A null return does not denote
* an error, it means there are no principals. * an error, it means there are no principals.
*/ */
extern JS_PUBLIC_API(JSPrincipals *) extern JSPrincipals *
JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp); js_StackFramePrincipals(JSContext *cx, JSStackFrame *fp);
/*
* This API is like JS_StackFramePrincipals(cx, caller), except that if
* cx->runtime->findObjectPrincipals is non-null, it returns the weaker of
* the caller's principals and the object principals of fp's callee function
* object (fp->argv[-2]), which is eval, Function, or a similar eval-like
* method. The caller parameter should be JS_GetScriptedCaller(cx, fp).
*
* All eval-like methods must use JS_EvalFramePrincipals to acquire a weak
* reference to the correct principals for the eval call to be secure, given
* an embedding that calls JS_SetObjectPrincipalsFinder (see jsapi.h).
*/
extern JS_PUBLIC_API(JSPrincipals *)
JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller);
JSPrincipals * JSPrincipals *
js_EvalFramePrincipals(JSContext *cx, JSObject *callee, JSStackFrame *caller); js_EvalFramePrincipals(JSContext *cx, JSObject *callee, JSStackFrame *caller);
@ -251,7 +233,7 @@ extern JS_PUBLIC_API(void *)
JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp); JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp); JS_IsScriptFrame(JSContext *cx, JSStackFrame *fp);
/* this is deprecated, use JS_GetFrameScopeChain instead */ /* this is deprecated, use JS_GetFrameScopeChain instead */
extern JS_PUBLIC_API(JSObject *) extern JS_PUBLIC_API(JSObject *)
@ -535,36 +517,29 @@ extern JS_PUBLIC_API(JSBool)
JS_DisconnectShark(); JS_DisconnectShark();
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_StopShark(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_StopShark(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_StartShark(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_StartShark(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_ConnectShark(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_ConnectShark(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_DisconnectShark(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_DisconnectShark(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
#endif /* MOZ_SHARK */ #endif /* MOZ_SHARK */
#ifdef MOZ_CALLGRIND #ifdef MOZ_CALLGRIND
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_StopCallgrind(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_StopCallgrind(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_StartCallgrind(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_StartCallgrind(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_DumpCallgrind(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_DumpCallgrind(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
#endif /* MOZ_CALLGRIND */ #endif /* MOZ_CALLGRIND */

Просмотреть файл

@ -69,7 +69,7 @@ using namespace js;
/* Forward declarations for js_ErrorClass's initializer. */ /* Forward declarations for js_ErrorClass's initializer. */
static JSBool static JSBool
Exception(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval); Exception(JSContext *cx, uintN argc, Value *vp);
static void static void
exn_trace(JSTracer *trc, JSObject *obj); exn_trace(JSTracer *trc, JSObject *obj);
@ -696,31 +696,27 @@ StringToFilename(JSContext *cx, JSString *str)
} }
static JSBool static JSBool
Exception(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) Exception(JSContext *cx, uintN argc, Value *vp)
{ {
JSString *message, *filename; JSString *message, *filename;
JSStackFrame *fp; JSStackFrame *fp;
if (!JS_IsConstructing(cx)) { /*
/* * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when
* ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when * called as functions, without operator new. But as we do not give
* called as functions, without operator new. But as we do not give * each constructor a distinct JSClass, whose .name member is used by
* each constructor a distinct JSClass, whose .name member is used by * NewNativeClassInstance to find the class prototype, we must get the
* NewNativeClassInstance to find the class prototype, we must get the * class prototype ourselves.
* class prototype ourselves. */
*/ JSObject &callee = vp[0].toObject();
if (!argv[-2].toObject().getProperty(cx, Value protov;
ATOM_TO_JSID(cx->runtime->atomState if (!callee.getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom), &protov))
.classPrototypeAtom), return JS_FALSE;
rval)) {
return JS_FALSE; JSObject *errProto = &protov.toObject();
} JSObject *obj = NewNativeClassInstance(cx, &js_ErrorClass, errProto, errProto->getParent());
JSObject *errProto = &rval->toObject(); if (!obj)
obj = NewNativeClassInstance(cx, &js_ErrorClass, errProto, errProto->getParent()); return JS_FALSE;
if (!obj)
return JS_FALSE;
rval->setObject(*obj);
}
/* /*
* If it's a new object of class Exception, then null out the private * If it's a new object of class Exception, then null out the private
@ -730,6 +726,7 @@ Exception(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
obj->setPrivate(NULL); obj->setPrivate(NULL);
/* Set the 'message' property. */ /* Set the 'message' property. */
Value *argv = vp + 2;
if (argc != 0) { if (argc != 0) {
message = js_ValueToString(cx, argv[0]); message = js_ValueToString(cx, argv[0]);
if (!message) if (!message)
@ -768,8 +765,13 @@ Exception(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
lineno = (fp && fp->pc(cx)) ? js_FramePCToLineNumber(cx, fp) : 0; lineno = (fp && fp->pc(cx)) ? js_FramePCToLineNumber(cx, fp) : 0;
} }
return (obj->getClass() != &js_ErrorClass) || if (obj->getClass() == &js_ErrorClass &&
InitExnPrivate(cx, obj, message, filename, lineno, NULL); !InitExnPrivate(cx, obj, message, filename, lineno, NULL)) {
return JS_FALSE;
}
vp->setObject(*obj);
return JS_TRUE;
} }
/* /*
@ -780,7 +782,7 @@ Exception(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
* number information along with this message. * number information along with this message.
*/ */
static JSBool static JSBool
exn_toString(JSContext *cx, uintN argc, jsval *vp) exn_toString(JSContext *cx, uintN argc, Value *vp)
{ {
JSObject *obj; JSObject *obj;
jsval v; jsval v;
@ -788,11 +790,11 @@ exn_toString(JSContext *cx, uintN argc, jsval *vp)
jschar *chars, *cp; jschar *chars, *cp;
size_t name_length, message_length, length; size_t name_length, message_length, length;
obj = JS_THIS_OBJECT(cx, vp); obj = ComputeThisFromVp(cx, vp);
if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), Valueify(&v))) if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), Valueify(&v)))
return JS_FALSE; return JS_FALSE;
name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString; name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString;
*vp = STRING_TO_JSVAL(name); vp->setString(name);
if (!JS_GetProperty(cx, obj, js_message_str, &v)) if (!JS_GetProperty(cx, obj, js_message_str, &v))
return JS_FALSE; return JS_FALSE;
@ -825,7 +827,7 @@ exn_toString(JSContext *cx, uintN argc, jsval *vp)
result = name; result = name;
} }
*vp = STRING_TO_JSVAL(result); vp->setString(result);
return JS_TRUE; return JS_TRUE;
} }
@ -834,7 +836,7 @@ exn_toString(JSContext *cx, uintN argc, jsval *vp)
* Return a string that may eval to something similar to the original object. * Return a string that may eval to something similar to the original object.
*/ */
static JSBool static JSBool
exn_toSource(JSContext *cx, uintN argc, jsval *vp) exn_toSource(JSContext *cx, uintN argc, Value *vp)
{ {
JSObject *obj; JSObject *obj;
JSString *name, *message, *filename, *lineno_as_str, *result; JSString *name, *message, *filename, *lineno_as_str, *result;
@ -842,13 +844,13 @@ exn_toSource(JSContext *cx, uintN argc, jsval *vp)
size_t lineno_length, name_length, message_length, filename_length, length; size_t lineno_length, name_length, message_length, filename_length, length;
jschar *chars, *cp; jschar *chars, *cp;
obj = JS_THIS_OBJECT(cx, vp); obj = ComputeThisFromVp(cx, vp);
if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), Valueify(vp))) if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), vp))
return false; return false;
name = js_ValueToString(cx, Valueify(*vp)); name = js_ValueToString(cx, *vp);
if (!name) if (!name)
return false; return false;
*vp = STRING_TO_JSVAL(name); vp->setString(name);
{ {
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(localroots), Valueify(localroots)); AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(localroots), Valueify(localroots));
@ -948,7 +950,7 @@ exn_toSource(JSContext *cx, uintN argc, jsval *vp)
cx->free(chars); cx->free(chars);
return false; return false;
} }
*vp = STRING_TO_JSVAL(result); vp->setString(result);
return true; return true;
} }
} }
@ -1030,7 +1032,7 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
/* Make a constructor function for the current name. */ /* Make a constructor function for the current name. */
JSProtoKey protoKey = GetExceptionProtoKey(i); JSProtoKey protoKey = GetExceptionProtoKey(i);
JSAtom *atom = cx->runtime->atomState.classAtoms[protoKey]; JSAtom *atom = cx->runtime->atomState.classAtoms[protoKey];
JSFunction *fun = js_DefineFunction(cx, obj, atom, Exception, 3, 0); JSFunction *fun = js_DefineFunction(cx, obj, atom, Exception, 3, JSFUN_CONSTRUCTOR);
if (!fun) if (!fun)
return NULL; return NULL;
roots[2] = OBJECT_TO_JSVAL(FUN_OBJECT(fun)); roots[2] = OBJECT_TO_JSVAL(FUN_OBJECT(fun));

Просмотреть файл

@ -2162,8 +2162,6 @@ JS_PUBLIC_DATA(Class) js_FunctionClass = {
JS_CLASS_TRACE(fun_trace) JS_CLASS_TRACE(fun_trace)
}; };
namespace js {
JSString * JSString *
fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent) fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent)
{ {
@ -2183,8 +2181,6 @@ fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent)
return JS_DecompileFunction(cx, fun, indent); return JS_DecompileFunction(cx, fun, indent);
} }
} /* namespace js */
static JSBool static JSBool
fun_toString(JSContext *cx, uintN argc, Value *vp) fun_toString(JSContext *cx, uintN argc, Value *vp)
{ {
@ -2393,11 +2389,6 @@ js_fun_apply(JSContext *cx, uintN argc, Value *vp)
} }
namespace { namespace {
Native
FastNativeToNative(FastNative fn)
{
return reinterpret_cast<Native>(fn);
}
JSBool JSBool
CallOrConstructBoundFunction(JSContext *cx, uintN argc, Value *vp); CallOrConstructBoundFunction(JSContext *cx, uintN argc, Value *vp);
@ -2406,7 +2397,7 @@ CallOrConstructBoundFunction(JSContext *cx, uintN argc, Value *vp);
bool bool
JSFunction::isBound() const JSFunction::isBound() const
{ {
return isFastNative() && u.n.native == FastNativeToNative(CallOrConstructBoundFunction); return isNative() && u.n.native == CallOrConstructBoundFunction;
} }
inline bool inline bool
@ -2480,7 +2471,7 @@ CallOrConstructBoundFunction(JSContext *cx, uintN argc, Value *vp)
LeaveTrace(cx); LeaveTrace(cx);
bool constructing = vp[1].isMagic(JS_FAST_CONSTRUCTOR); bool constructing = IsConstructing(vp);
/* 15.3.4.5.1 step 1, 15.3.4.5.2 step 3. */ /* 15.3.4.5.1 step 1, 15.3.4.5.2 step 3. */
uintN argslen; uintN argslen;
@ -2574,8 +2565,8 @@ fun_bind(JSContext *cx, uintN argc, Value *vp)
/* NB: Bound functions abuse |parent| to store their target. */ /* NB: Bound functions abuse |parent| to store their target. */
JSObject *funobj = JSObject *funobj =
js_NewFunction(cx, NULL, FastNativeToNative(CallOrConstructBoundFunction), length, js_NewFunction(cx, NULL, CallOrConstructBoundFunction, length,
JSFUN_FAST_NATIVE | JSFUN_FAST_NATIVE_CTOR, target, name); JSFUN_CONSTRUCTOR, target, name);
if (!funobj) if (!funobj)
return false; return false;
@ -2606,36 +2597,15 @@ static JSFunctionSpec function_methods[] = {
}; };
static JSBool static JSBool
Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) Function(JSContext *cx, uintN argc, Value *vp)
{ {
JSFunction *fun; JSObject *obj = NewFunction(cx, NULL);
JSObject *parent; if (!obj)
JSStackFrame *fp, *caller; return JS_FALSE;
uintN i, n, lineno;
JSAtom *atom;
const char *filename;
JSBool ok;
JSString *str, *arg;
TokenStream ts(cx);
JSPrincipals *principals;
jschar *collected_args, *cp;
void *mark;
size_t arg_length, args_length, old_args_length;
TokenKind tt;
if (!JS_IsConstructing(cx)) { /* N.B. overwriting callee with return value */
obj = NewFunction(cx, NULL); JSObject *parent = vp[0].toObject().getParent();
if (!obj) vp[0].setObject(*obj);
return JS_FALSE;
rval->setObject(*obj);
} else {
/*
* The constructor is called before the private slot is initialized so
* we must use getPrivate, not GET_FUNCTION_PRIVATE here.
*/
if (obj->getPrivate())
return JS_TRUE;
}
/* /*
* NB: (new Function) is not lexically closed by its caller, it's just an * NB: (new Function) is not lexically closed by its caller, it's just an
@ -2647,11 +2617,8 @@ Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
* its running context's globalObject, which might be different from the * its running context's globalObject, which might be different from the
* top-level reachable from scopeChain (in HTML frames, e.g.). * top-level reachable from scopeChain (in HTML frames, e.g.).
*/ */
parent = argv[-2].toObject().getParent(); JSFunction *fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA | JSFUN_INTERPRETED,
parent, cx->runtime->atomState.anonymousAtom);
fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA | JSFUN_INTERPRETED,
parent, cx->runtime->atomState.anonymousAtom);
if (!fun) if (!fun)
return JS_FALSE; return JS_FALSE;
@ -2662,12 +2629,13 @@ Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
* are built for Function.prototype.call or .apply activations that invoke * are built for Function.prototype.call or .apply activations that invoke
* Function indirectly from a script. * Function indirectly from a script.
*/ */
fp = js_GetTopStackFrame(cx); JSStackFrame *caller = js_GetScriptedCaller(cx, NULL);
JS_ASSERT(!fp->hasScript() && fp->hasFunction() && uintN lineno;
fp->getFunction()->u.n.native == Function); const char *filename;
caller = js_GetScriptedCaller(cx, fp); JSPrincipals *principals;
if (caller) { if (caller) {
principals = JS_EvalFramePrincipals(cx, fp, caller); JSObject *callee = &JS_CALLEE(cx, vp).toObject();
principals = js_EvalFramePrincipals(cx, callee, caller);
filename = js_ComputeFilename(cx, caller, principals, &lineno); filename = js_ComputeFilename(cx, caller, principals, &lineno);
} else { } else {
filename = NULL; filename = NULL;
@ -2691,7 +2659,8 @@ Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
return JS_FALSE; return JS_FALSE;
} }
n = argc ? argc - 1 : 0; Value *argv = vp + 2;
uintN n = argc ? argc - 1 : 0;
if (n > 0) { if (n > 0) {
enum { OK, BAD, BAD_FORMAL } state; enum { OK, BAD, BAD_FORMAL } state;
@ -2706,10 +2675,10 @@ Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
* code. See ECMA 15.3.2.1. * code. See ECMA 15.3.2.1.
*/ */
state = BAD_FORMAL; state = BAD_FORMAL;
args_length = 0; size_t args_length = 0;
for (i = 0; i < n; i++) { for (uintN i = 0; i < n; i++) {
/* Collect the lengths for all the function-argument arguments. */ /* Collect the lengths for all the function-argument arguments. */
arg = js_ValueToString(cx, argv[i]); JSString *arg = js_ValueToString(cx, argv[i]);
if (!arg) if (!arg)
return JS_FALSE; return JS_FALSE;
argv[i].setString(arg); argv[i].setString(arg);
@ -2718,7 +2687,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
* Check for overflow. The < test works because the maximum * Check for overflow. The < test works because the maximum
* JSString length fits in 2 fewer bits than size_t has. * JSString length fits in 2 fewer bits than size_t has.
*/ */
old_args_length = args_length; size_t old_args_length = args_length;
args_length = old_args_length + arg->length(); args_length = old_args_length + arg->length();
if (args_length < old_args_length) { if (args_length < old_args_length) {
js_ReportAllocationOverflow(cx); js_ReportAllocationOverflow(cx);
@ -2727,7 +2696,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
} }
/* Add 1 for each joining comma and check for overflow (two ways). */ /* Add 1 for each joining comma and check for overflow (two ways). */
old_args_length = args_length; size_t old_args_length = args_length;
args_length = old_args_length + n - 1; args_length = old_args_length + n - 1;
if (args_length < old_args_length || if (args_length < old_args_length ||
args_length >= ~(size_t)0 / sizeof(jschar)) { args_length >= ~(size_t)0 / sizeof(jschar)) {
@ -2740,21 +2709,22 @@ Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
* for a terminating 0. Mark cx->tempPool for later release, to free * for a terminating 0. Mark cx->tempPool for later release, to free
* collected_args and its tokenstream in one swoop. * collected_args and its tokenstream in one swoop.
*/ */
mark = JS_ARENA_MARK(&cx->tempPool); void *mark = JS_ARENA_MARK(&cx->tempPool);
jschar *cp;
JS_ARENA_ALLOCATE_CAST(cp, jschar *, &cx->tempPool, JS_ARENA_ALLOCATE_CAST(cp, jschar *, &cx->tempPool,
(args_length+1) * sizeof(jschar)); (args_length+1) * sizeof(jschar));
if (!cp) { if (!cp) {
js_ReportOutOfScriptQuota(cx); js_ReportOutOfScriptQuota(cx);
return JS_FALSE; return JS_FALSE;
} }
collected_args = cp; jschar *collected_args = cp;
/* /*
* Concatenate the arguments into the new string, separated by commas. * Concatenate the arguments into the new string, separated by commas.
*/ */
for (i = 0; i < n; i++) { for (uintN i = 0; i < n; i++) {
arg = argv[i].toString(); JSString *arg = argv[i].toString();
arg_length = arg->length(); size_t arg_length = arg->length();
(void) js_strncpy(cp, arg->chars(), arg_length); (void) js_strncpy(cp, arg->chars(), arg_length);
cp += arg_length; cp += arg_length;
@ -2763,13 +2733,14 @@ Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
} }
/* Initialize a tokenstream that reads from the given string. */ /* Initialize a tokenstream that reads from the given string. */
TokenStream ts(cx);
if (!ts.init(collected_args, args_length, NULL, filename, lineno)) { if (!ts.init(collected_args, args_length, NULL, filename, lineno)) {
JS_ARENA_RELEASE(&cx->tempPool, mark); JS_ARENA_RELEASE(&cx->tempPool, mark);
return JS_FALSE; return JS_FALSE;
} }
/* The argument string may be empty or contain no tokens. */ /* The argument string may be empty or contain no tokens. */
tt = ts.getToken(); TokenKind tt = ts.getToken();
if (tt != TOK_EOF) { if (tt != TOK_EOF) {
for (;;) { for (;;) {
/* /*
@ -2784,18 +2755,18 @@ Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
* stream; we're assured at this point that it's a valid * stream; we're assured at this point that it's a valid
* identifier. * identifier.
*/ */
atom = ts.currentToken().t_atom; JSAtom *atom = ts.currentToken().t_atom;
/* Check for a duplicate parameter name. */ /* Check for a duplicate parameter name. */
if (fun->lookupLocal(cx, atom, NULL) != JSLOCAL_NONE) { if (fun->lookupLocal(cx, atom, NULL) != JSLOCAL_NONE) {
const char *name; const char *name;
name = js_AtomToPrintableString(cx, atom); name = js_AtomToPrintableString(cx, atom);
ok = name && ReportCompileErrorNumber(cx, &ts, NULL, if (!name && ReportCompileErrorNumber(cx, &ts, NULL,
JSREPORT_WARNING | JSREPORT_STRICT, JSREPORT_WARNING | JSREPORT_STRICT,
JSMSG_DUPLICATE_FORMAL, name); JSMSG_DUPLICATE_FORMAL, name)) {
if (!ok)
goto after_args; goto after_args;
}
} }
if (!fun->addLocal(cx, atom, JSLOCAL_ARG)) if (!fun->addLocal(cx, atom, JSLOCAL_ARG))
goto after_args; goto after_args;
@ -2829,6 +2800,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
return JS_FALSE; return JS_FALSE;
} }
JSString *str;
if (argc) { if (argc) {
str = js_ValueToString(cx, argv[argc-1]); str = js_ValueToString(cx, argv[argc-1]);
if (!str) if (!str)
@ -2872,7 +2844,7 @@ js_InitFunctionClass(JSContext *cx, JSObject *obj)
/* ES5 13.2.3: Construct the unique [[ThrowTypeError]] function object. */ /* ES5 13.2.3: Construct the unique [[ThrowTypeError]] function object. */
JSObject *throwTypeError = JSObject *throwTypeError =
js_NewFunction(cx, NULL, reinterpret_cast<Native>(ThrowTypeError), 0, js_NewFunction(cx, NULL, reinterpret_cast<Native>(ThrowTypeError), 0,
JSFUN_FAST_NATIVE, obj, NULL); 0, obj, NULL);
if (!throwTypeError) if (!throwTypeError)
return NULL; return NULL;
@ -2902,8 +2874,7 @@ js_NewFunction(JSContext *cx, JSObject *funobj, Native native, uintN nargs,
/* Initialize all function members. */ /* Initialize all function members. */
fun->nargs = uint16(nargs); fun->nargs = uint16(nargs);
fun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_KINDMASK | fun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_KINDMASK | JSFUN_TRCINFO);
JSFUN_TRCINFO | JSFUN_FAST_NATIVE_CTOR);
if ((flags & JSFUN_KINDMASK) >= JSFUN_INTERPRETED) { if ((flags & JSFUN_KINDMASK) >= JSFUN_INTERPRETED) {
JS_ASSERT(!native); JS_ASSERT(!native);
JS_ASSERT(nargs == 0); JS_ASSERT(nargs == 0);
@ -2914,8 +2885,6 @@ js_NewFunction(JSContext *cx, JSObject *funobj, Native native, uintN nargs,
fun->u.i.script = NULL; fun->u.i.script = NULL;
fun->u.i.names = cx->runtime->emptyCallShape; fun->u.i.names = cx->runtime->emptyCallShape;
} else { } else {
fun->u.n.extra = 0;
fun->u.n.spare = 0;
fun->u.n.clasp = NULL; fun->u.n.clasp = NULL;
if (flags & JSFUN_TRCINFO) { if (flags & JSFUN_TRCINFO) {
#ifdef JS_TRACER #ifdef JS_TRACER
@ -3049,7 +3018,8 @@ js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, Native native,
gsop = NULL; gsop = NULL;
} }
fun = js_NewFunction(cx, NULL, native, nargs, fun = js_NewFunction(cx, NULL, native, nargs,
attrs & (JSFUN_FLAGS_MASK | JSFUN_TRCINFO), obj, atom); attrs & (JSFUN_FLAGS_MASK | JSFUN_TRCINFO),
obj, atom);
if (!fun) if (!fun)
return NULL; return NULL;
if (!obj->defineProperty(cx, ATOM_TO_JSID(atom), ObjectValue(*fun), if (!obj->defineProperty(cx, ATOM_TO_JSID(atom), ObjectValue(*fun),

Просмотреть файл

@ -86,17 +86,6 @@
appear to call itself via its own name appear to call itself via its own name
or arguments.callee */ or arguments.callee */
#define JSFUN_FAST_NATIVE_CTOR 0x0002 /* JSFastNative directly invokable
* during construction. */
/*
* Extra JSCLASS flag indicating the native passed to JS_InitClass is
* a fast native constructor. This is internal for now as the 'this' value passed
* to such a constructor is a magic value, and there is no way to query this
* in the API. See bug 581263.
*/
#define JSCLASS_FAST_CONSTRUCTOR (1<<4)
#define JSFUN_EXPR_CLOSURE 0x1000 /* expression closure: function(x) x*x */ #define JSFUN_EXPR_CLOSURE 0x1000 /* expression closure: function(x) x*x */
#define JSFUN_TRCINFO 0x2000 /* when set, u.n.trcinfo is non-null, #define JSFUN_TRCINFO 0x2000 /* when set, u.n.trcinfo is non-null,
JSFunctionSpec::call points to a JSFunctionSpec::call points to a
@ -113,15 +102,7 @@
#define FUN_INTERPRETED(fun) (FUN_KIND(fun) >= JSFUN_INTERPRETED) #define FUN_INTERPRETED(fun) (FUN_KIND(fun) >= JSFUN_INTERPRETED)
#define FUN_FLAT_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_FLAT_CLOSURE) #define FUN_FLAT_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_FLAT_CLOSURE)
#define FUN_NULL_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_NULL_CLOSURE) #define FUN_NULL_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_NULL_CLOSURE)
#define FUN_SLOW_NATIVE(fun) (!FUN_INTERPRETED(fun) && !((fun)->flags & JSFUN_FAST_NATIVE))
#define FUN_SCRIPT(fun) (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL) #define FUN_SCRIPT(fun) (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL)
#define FUN_NATIVE(fun) (FUN_SLOW_NATIVE(fun) ? (fun)->u.n.native : NULL)
#define FUN_FAST_NATIVE(fun) (((fun)->flags & JSFUN_FAST_NATIVE) \
? (js::FastNative) (fun)->u.n.native \
: NULL)
#define FUN_MINARGS(fun) (((fun)->flags & JSFUN_FAST_NATIVE) \
? 0 \
: (fun)->nargs)
#define FUN_CLASP(fun) (JS_ASSERT(!FUN_INTERPRETED(fun)), \ #define FUN_CLASP(fun) (JS_ASSERT(!FUN_INTERPRETED(fun)), \
fun->u.n.clasp) fun->u.n.clasp)
#define FUN_TRCINFO(fun) (JS_ASSERT(!FUN_INTERPRETED(fun)), \ #define FUN_TRCINFO(fun) (JS_ASSERT(!FUN_INTERPRETED(fun)), \
@ -158,8 +139,6 @@ struct JSFunction : public JSObject
uint16 flags; /* flags, see JSFUN_* below and in jsapi.h */ uint16 flags; /* flags, see JSFUN_* below and in jsapi.h */
union U { union U {
struct { struct {
uint16 extra; /* number of arg slots for local GC roots */
uint16 spare; /* reserved for future use */
js::Native native; /* native method pointer or null */ js::Native native; /* native method pointer or null */
js::Class *clasp; /* class of objects constructed js::Class *clasp; /* class of objects constructed
by this function */ by this function */
@ -187,10 +166,10 @@ struct JSFunction : public JSObject
bool optimizedClosure() const { return FUN_KIND(this) > JSFUN_INTERPRETED; } bool optimizedClosure() const { return FUN_KIND(this) > JSFUN_INTERPRETED; }
bool needsWrapper() const { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; } bool needsWrapper() const { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
bool isInterpreted() const { return FUN_INTERPRETED(this); } bool isInterpreted() const { return FUN_INTERPRETED(this); }
bool isFastNative() const { return !!(flags & JSFUN_FAST_NATIVE); } bool isNative() const { return !FUN_INTERPRETED(this); }
bool isFastConstructor() const { return !!(flags & JSFUN_FAST_NATIVE_CTOR); } bool isConstructor() const { return flags & JSFUN_CONSTRUCTOR; }
bool isHeavyweight() const { return JSFUN_HEAVYWEIGHT_TEST(flags); } bool isHeavyweight() const { return JSFUN_HEAVYWEIGHT_TEST(flags); }
unsigned minArgs() const { return FUN_MINARGS(this); } unsigned minArgs() const { return isInterpreted() ? nargs : 0; }
inline bool inStrictMode() const; inline bool inStrictMode() const;
@ -309,6 +288,10 @@ struct JSFunction : public JSObject
fslots[METHOD_ATOM_SLOT].setString(ATOM_TO_STRING(atom)); fslots[METHOD_ATOM_SLOT].setString(ATOM_TO_STRING(atom));
} }
js::Native maybeNative() const {
return isInterpreted() ? NULL : u.n.native;
}
/* Number of extra fixed function object slots besides JSSLOT_PRIVATE. */ /* Number of extra fixed function object slots besides JSSLOT_PRIVATE. */
static const uint32 CLASS_RESERVED_SLOTS = JSObject::FUN_CLASS_RESERVED_SLOTS; static const uint32 CLASS_RESERVED_SLOTS = JSObject::FUN_CLASS_RESERVED_SLOTS;
static const uint32 FIRST_FREE_SLOT = JSSLOT_PRIVATE + CLASS_RESERVED_SLOTS + 1; static const uint32 FIRST_FREE_SLOT = JSSLOT_PRIVATE + CLASS_RESERVED_SLOTS + 1;
@ -324,8 +307,8 @@ JS_STATIC_ASSERT(sizeof(JSFunction) % JS_GCTHING_ALIGN == 0);
#ifdef JS_TRACER #ifdef JS_TRACER
/* MSVC demands the intermediate (void *) cast here. */ /* MSVC demands the intermediate (void *) cast here. */
# define JS_TN(name,fastcall,nargs,flags,trcinfo) \ # define JS_TN(name,fastcall,nargs,flags,trcinfo) \
JS_FN(name, JS_DATA_TO_FUNC_PTR(JSNative, trcinfo), nargs, \ JS_FN(name, JS_DATA_TO_FUNC_PTR(Native, trcinfo), nargs, \
(flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRCINFO) (flags) | JSFUN_STUB_GSOPS | JSFUN_TRCINFO)
#else #else
# define JS_TN(name,fastcall,nargs,flags,trcinfo) \ # define JS_TN(name,fastcall,nargs,flags,trcinfo) \
JS_FN(name, fastcall, nargs, flags) JS_FN(name, fastcall, nargs, flags)
@ -395,6 +378,15 @@ JSObject::isFunction() const
return getClass() == &js_FunctionClass; return getClass() == &js_FunctionClass;
} }
inline JSFunction *
JSObject::getFunctionPrivate() const
{
JS_ASSERT(isFunction());
return reinterpret_cast<JSFunction *>(getPrivate());
}
namespace js {
/* /*
* NB: jsapi.h and jsobj.h must be included before any call to this macro. * NB: jsapi.h and jsobj.h must be included before any call to this macro.
*/ */
@ -413,6 +405,16 @@ IsFunctionObject(const js::Value &v, JSObject **funobj)
return v.isObject() && (*funobj = &v.toObject())->isFunction(); return v.isObject() && (*funobj = &v.toObject())->isFunction();
} }
static JS_ALWAYS_INLINE bool
IsFunctionObject(const js::Value &v, JSFunction **fun)
{
JSObject *funobj;
bool b = IsFunctionObject(v, &funobj);
if (b)
*fun = funobj->getFunctionPrivate();
return b;
}
/* /*
* Macro to access the private slot of the function object after the slot is * Macro to access the private slot of the function object after the slot is
* initialized. * initialized.
@ -421,12 +423,6 @@ IsFunctionObject(const js::Value &v, JSObject **funobj)
(JS_ASSERT((funobj)->isFunction()), \ (JS_ASSERT((funobj)->isFunction()), \
(JSFunction *) (funobj)->getPrivate()) (JSFunction *) (funobj)->getPrivate())
extern JSFunction *
js_NewFunction(JSContext *cx, JSObject *funobj, js::Native native, uintN nargs,
uintN flags, JSObject *parent, JSAtom *atom);
namespace js {
/* /*
* Return true if this is a compiler-created internal function accessed by * Return true if this is a compiler-created internal function accessed by
* its own object. Such a function object must not be accessible to script * its own object. Such a function object must not be accessible to script
@ -440,10 +436,48 @@ IsInternalFunctionObject(JSObject *funobj)
return funobj == fun && (fun->flags & JSFUN_LAMBDA) && !funobj->getParent(); return funobj == fun && (fun->flags & JSFUN_LAMBDA) && !funobj->getParent();
} }
/* Valueified JS_IsConstructing. */
static JS_ALWAYS_INLINE bool
IsConstructing(const Value *vp)
{
#ifdef DEBUG
JSObject *callee = &JS_CALLEE(cx, vp).toObject();
if (callee->isFunction()) {
JSFunction *fun = callee->getFunctionPrivate();
JS_ASSERT((fun->flags & JSFUN_CONSTRUCTOR) != 0);
} else {
JS_ASSERT(callee->getClass()->construct != NULL);
}
#endif
return vp[1].isMagic();
}
static JS_ALWAYS_INLINE bool
IsConstructing_PossiblyWithGivenThisObject(const Value *vp, JSObject **ctorThis)
{
#ifdef DEBUG
JSObject *callee = &JS_CALLEE(cx, vp).toObject();
if (callee->isFunction()) {
JSFunction *fun = callee->getFunctionPrivate();
JS_ASSERT((fun->flags & JSFUN_CONSTRUCTOR) != 0);
} else {
JS_ASSERT(callee->getClass()->construct != NULL);
}
#endif
bool isCtor = vp[1].isMagic();
if (isCtor)
*ctorThis = vp[1].getMagicObjectOrNullPayload();
return isCtor;
}
} /* namespace js */
extern JSString * extern JSString *
fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent); fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent);
} /* namespace js */ extern JSFunction *
js_NewFunction(JSContext *cx, JSObject *funobj, js::Native native, uintN nargs,
uintN flags, JSObject *parent, JSAtom *atom);
extern JSObject * extern JSObject *
js_InitFunctionClass(JSContext *cx, JSObject *obj); js_InitFunctionClass(JSContext *cx, JSObject *obj);

Просмотреть файл

@ -468,57 +468,69 @@ RunScript(JSContext *cx, JSScript *script, JSFunction *fun, JSObject *scopeChain
return Interpret(cx, cx->fp()); return Interpret(cx, cx->fp());
} }
static JS_REQUIRES_STACK bool /*
CallJSNative(JSContext *cx, CallOp callOp, JSObject *thisp, uintN argc, Value *argv, Value *rval) * Find a function reference and its 'this' value implicit first parameter
{ * under argc arguments on cx's stack, and call the function. Push missing
Value *vp = argv - 2; * required arguments, allocate declared local variables, and pop everything
if (CallJSFastNative(cx, callOp, argc, vp)) { * when done. Then push the return value.
*rval = JS_RVAL(cx, vp); */
return true; JS_REQUIRES_STACK bool
} Invoke(JSContext *cx, const CallArgs &argsRef, uintN flags)
return false;
}
template <typename T>
static JS_REQUIRES_STACK bool
InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
const CallArgs &argsRef, uintN flags)
{ {
CallArgs args = argsRef; CallArgs args = argsRef;
JS_ASSERT(args.argc() <= JS_ARGS_LENGTH_MAX);
if (native && fun && fun->isFastNative()) { if (args.callee().isPrimitive()) {
#ifdef DEBUG_NOT_THROWING js_ReportIsNotFunction(cx, &args.callee(), flags & JSINVOKE_FUNFLAGS);
JSBool alreadyThrowing = cx->throwing; return false;
#endif
JSBool ok = CallJSFastNative(cx, (FastNative) native, args.argc(), args.base());
JS_RUNTIME_METER(cx->runtime, nativeCalls);
#ifdef DEBUG_NOT_THROWING
if (ok && !alreadyThrowing)
ASSERT_NOT_THROWING(cx);
#endif
return ok;
} }
JSObject *callee = &args.callee().toObject();
Class *clasp = callee->getClass();
/* Invoke non-functions. */
if (JS_UNLIKELY(clasp != &js_FunctionClass)) {
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(clasp == &js_NoSuchMethodClass))
return NoSuchMethod(cx, args.argc(), args.base(), 0);
#endif
JS_ASSERT_IF(flags & JSINVOKE_CONSTRUCT, !clasp->construct);
if (!clasp->call) {
js_ReportIsNotFunction(cx, &args.callee(), flags);
return false;
}
return CallJSNative(cx, clasp->call, args.argc(), args.base());
}
/* Invoke native functions. */
JSFunction *fun = callee->getFunctionPrivate();
JS_ASSERT_IF(flags & JSINVOKE_CONSTRUCT, !fun->isConstructor());
if (fun->isNative()) {
JS_ASSERT(args.thisv().isObjectOrNull() || PrimitiveThisTest(fun, args.thisv()));
return CallJSNative(cx, fun->u.n.native, args.argc(), args.base());
}
JS_ASSERT(fun->isInterpreted());
JSScript *script = fun->u.i.script;
/* Handle the empty-script special case. */
if (JS_UNLIKELY(script->isEmpty())) {
if (flags & JSINVOKE_CONSTRUCT) {
JS_ASSERT(args.thisv().isObject());
args.rval() = args.thisv();
} else {
args.rval().setUndefined();
}
return true;
}
JS_ASSERT_IF(flags & JSINVOKE_CONSTRUCT, args.thisv().isObject());
/* Calculate slot usage. */ /* Calculate slot usage. */
uintN nmissing; uintN minargs = fun->nargs;
uintN nvars; uintN nmissing = minargs > args.argc() ? minargs - args.argc() : 0;
if (fun) { uintN nvars = fun->u.i.nvars;
if (fun->isInterpreted()) { uintN nfixed = script->nslots;
uintN minargs = fun->nargs;
nmissing = minargs > args.argc() ? minargs - args.argc() : 0;
nvars = fun->u.i.nvars;
} else if (fun->isFastNative()) {
nvars = nmissing = 0;
} else {
uintN minargs = fun->nargs;
nmissing = (minargs > args.argc() ? minargs - args.argc() : 0) + fun->u.n.extra;
nvars = 0;
}
} else {
nvars = nmissing = 0;
}
uintN nfixed = script ? script->nslots : 0;
/* /*
* Get a pointer to new frame/slots. This memory is not "claimed", so the * Get a pointer to new frame/slots. This memory is not "claimed", so the
@ -543,7 +555,7 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
fp->setNumActualArgs(args.argc()); fp->setNumActualArgs(args.argc());
fp->argv = args.argv(); fp->argv = args.argv();
fp->setAnnotation(NULL); fp->setAnnotation(NULL);
fp->setScopeChain(NULL); fp->setScopeChain(callee->getParent());
fp->setBlockChain(NULL); fp->setBlockChain(NULL);
fp->flags = flags; fp->flags = flags;
JS_ASSERT(!fp->hasIMacroPC()); JS_ASSERT(!fp->hasIMacroPC());
@ -555,33 +567,15 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
/* Initialize regs. */ /* Initialize regs. */
JSFrameRegs &regs = frame.getRegs(); JSFrameRegs &regs = frame.getRegs();
if (script) { regs.pc = script->code;
regs.pc = script->code; regs.sp = fp->slots() + script->nfixed;
regs.sp = fp->slots() + script->nfixed;
} else {
regs.pc = NULL;
regs.sp = fp->slots();
}
/* Officially push |fp|. |frame|'s destructor pops. */ /* Officially push fp. frame's destructor pops. */
cx->stack().pushInvokeFrame(cx, args, frame); cx->stack().pushInvokeFrame(cx, args, frame);
/* Now that the frame has been pushed, fix up the scope chain. */ /* Now that the frame has been pushed, fix up the scope chain. */
JSObject *parent = args.callee().toObject().getParent(); if (fun->isHeavyweight() && !js_GetCallObject(cx, fp))
if (native) { return false;
/* Slow natives and call ops expect the caller's scopeChain as their scopeChain. */
if (JSStackFrame *down = fp->down)
fp->setScopeChain(down->maybeScopeChain());
/* Ensure that we have a scope chain. */
if (!fp->hasScopeChain())
fp->setScopeChain(parent);
} else {
/* Use parent scope so js_GetCallObject can find the right "Call". */
fp->setScopeChain(parent);
if (fun->isHeavyweight() && !js_GetCallObject(cx, fp))
return false;
}
/* /*
* Compute |this|. Currently, this must happen after the frame is pushed * Compute |this|. Currently, this must happen after the frame is pushed
@ -608,181 +602,34 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
} }
JS_ASSERT_IF(!args.thisv().isPrimitive(), IsSaneThisObject(args.thisv().toObject())); JS_ASSERT_IF(!args.thisv().isPrimitive(), IsSaneThisObject(args.thisv().toObject()));
/* Call the hook if present after we fully initialized the frame. */
JSInterpreterHook hook = cx->debugHooks->callHook; JSInterpreterHook hook = cx->debugHooks->callHook;
void *hookData = NULL; void *hookData = NULL;
if (hook) if (JS_UNLIKELY(hook != NULL))
hookData = hook(cx, fp, JS_TRUE, 0, cx->debugHooks->callHookData); hookData = hook(cx, fp, JS_TRUE, 0, cx->debugHooks->callHookData);
Probes::enterJSFun(cx, fun);
/* Call the function, either a native method or an interpreted script. */
JSBool ok; JSBool ok;
if (native) { {
#ifdef DEBUG_NOT_THROWING
JSBool alreadyThrowing = cx->throwing;
#endif
/* Primitive |this| should not be passed to slow natives. */
JSObject *thisp = fun ? fp->getThisObject(cx) : fp->getThisValue().toObjectOrNull();
ok = CallJSNative(cx, native, thisp, fp->numActualArgs(), fp->argv,
fp->addressReturnValue());
JS_ASSERT(cx->fp() == fp);
JS_RUNTIME_METER(cx->runtime, nativeCalls);
#ifdef DEBUG_NOT_THROWING
if (ok && !alreadyThrowing)
ASSERT_NOT_THROWING(cx);
#endif
} else {
JS_ASSERT(script);
AutoPreserveEnumerators preserve(cx); AutoPreserveEnumerators preserve(cx);
Probes::enterJSFun(cx, fun);
ok = RunScript(cx, script, fun, fp->getScopeChain()); ok = RunScript(cx, script, fun, fp->getScopeChain());
Probes::exitJSFun(cx, fun);
} }
Probes::exitJSFun(cx, fun); if (JS_UNLIKELY(hookData != NULL)) {
if (hookData) {
hook = cx->debugHooks->callHook; hook = cx->debugHooks->callHook;
if (hook) if (hook)
hook(cx, fp, JS_FALSE, &ok, hookData); hook(cx, fp, JS_FALSE, &ok, hookData);
} }
fp->putActivationObjects(cx); fp->putActivationObjects(cx);
args.rval() = fp->getReturnValue(); args.rval() = fp->getReturnValue();
return ok; return ok;
} }
static JSBool bool
DoConstruct(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) ExternalInvoke(JSContext *cx, const Value &thisv, const Value &fval,
{ uintN argc, Value *argv, Value *rval)
Class *clasp = argv[-2].toObject().getClass();
if (!clasp->construct) {
js_ReportIsNotFunction(cx, &argv[-2], JSV2F_CONSTRUCT);
return JS_FALSE;
}
return clasp->construct(cx, obj, argc, argv, rval);
}
static JSBool
DoSlowCall(JSContext *cx, uintN argc, Value *vp)
{
JSStackFrame *fp = cx->fp();
JSObject *obj = fp->getThisObject(cx);
if (!obj)
return false;
JS_ASSERT(ObjectValue(*obj) == fp->getThisValue());
JSObject *callee = &JS_CALLEE(cx, vp).toObject();
Class *clasp = callee->getClass();
JS_ASSERT(!(clasp->flags & Class::CALL_IS_FAST));
if (!clasp->call) {
js_ReportIsNotFunction(cx, &vp[0], 0);
return JS_FALSE;
}
AutoValueRooter rval(cx);
JSBool ok = clasp->call(cx, obj, argc, JS_ARGV(cx, vp), rval.addr());
if (ok)
JS_SET_RVAL(cx, vp, rval.value());
return ok;
}
/*
* Find a function reference and its 'this' value implicit first parameter
* under argc arguments on cx's stack, and call the function. Push missing
* required arguments, allocate declared local variables, and pop everything
* when done. Then push the return value.
*/
JS_REQUIRES_STACK bool
Invoke(JSContext *cx, const CallArgs &args, uintN flags)
{
JS_ASSERT(args.argc() <= JS_ARGS_LENGTH_MAX);
if (args.callee().isPrimitive()) {
js_ReportIsNotFunction(cx, &args.callee(), flags & JSINVOKE_FUNFLAGS);
return false;
}
JSObject *funobj = &args.callee().toObject();
Class *clasp = funobj->getClass();
if (clasp == &js_FunctionClass) {
/* Get private data and set derived locals from it. */
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
Native native;
JSScript *script;
if (FUN_INTERPRETED(fun)) {
native = NULL;
script = fun->u.i.script;
JS_ASSERT(script);
if (script->isEmpty()) {
if (flags & JSINVOKE_CONSTRUCT) {
JS_ASSERT(args.thisv().isObject());
args.rval() = args.thisv();
} else {
args.rval().setUndefined();
}
return true;
}
} else {
native = fun->u.n.native;
script = NULL;
}
if (!args.thisv().isObjectOrNull()) {
JS_ASSERT(!(flags & JSINVOKE_CONSTRUCT));
if (PrimitiveThisTest(fun, args.thisv()))
return InvokeCommon(cx, fun, script, native, args, flags);
}
if (flags & JSINVOKE_CONSTRUCT) {
JS_ASSERT(args.thisv().isObject());
} else {
/*
* We must call js_ComputeThis in case we are not called from the
* interpreter, where a prior bytecode has computed an appropriate
* |this| already.
*
* But we need to compute |this| eagerly only for so-called "slow"
* (i.e., not fast) native functions. Fast natives must use either
* JS_THIS or JS_THIS_OBJECT, and scripted functions will go through
* the appropriate this-computing bytecode, e.g., JSOP_THIS.
*/
if (native && (!fun || !(fun->flags & JSFUN_FAST_NATIVE))) {
if (!args.computeThis(cx))
return false;
}
}
return InvokeCommon(cx, fun, script, native, args, flags);
}
#if JS_HAS_NO_SUCH_METHOD
if (clasp == &js_NoSuchMethodClass)
return NoSuchMethod(cx, args.argc(), args.base(), flags);
#endif
/* Try a call or construct native object op. */
if (flags & JSINVOKE_CONSTRUCT) {
if (!args.thisv().isObjectOrNull()) {
if (!js_PrimitiveToObject(cx, &args.thisv()))
return false;
}
return InvokeCommon(cx, NULL, NULL, DoConstruct, args, flags);
}
CallOp callOp = (clasp->flags & Class::CALL_IS_FAST) ? (CallOp) clasp->call : DoSlowCall;
return InvokeCommon(cx, NULL, NULL, callOp, args, flags);
}
extern JS_REQUIRES_STACK JS_FRIEND_API(bool)
InvokeFriendAPI(JSContext *cx, const InvokeArgsGuard &args, uintN flags)
{
return Invoke(cx, args, flags);
}
JSBool
InternalInvoke(JSContext *cx, const Value &thisv, const Value &fval, uintN flags,
uintN argc, Value *argv, Value *rval)
{ {
LeaveTrace(cx); LeaveTrace(cx);
@ -794,7 +641,7 @@ InternalInvoke(JSContext *cx, const Value &thisv, const Value &fval, uintN flags
args.thisv() = thisv; args.thisv() = thisv;
memcpy(args.argv(), argv, argc * sizeof(Value)); memcpy(args.argv(), argv, argc * sizeof(Value));
if (!Invoke(cx, args, flags)) if (!Invoke(cx, args, 0))
return JS_FALSE; return JS_FALSE;
*rval = args.rval(); *rval = args.rval();
@ -803,18 +650,18 @@ InternalInvoke(JSContext *cx, const Value &thisv, const Value &fval, uintN flags
} }
bool bool
InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval, ExternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval,
JSAccessMode mode, uintN argc, Value *argv, Value *rval) JSAccessMode mode, uintN argc, Value *argv, Value *rval)
{ {
LeaveTrace(cx); LeaveTrace(cx);
/* /*
* InternalInvoke could result in another try to get or set the same id * ExternalInvoke could result in another try to get or set the same id
* again, see bug 355497. * again, see bug 355497.
*/ */
JS_CHECK_RECURSION(cx, return JS_FALSE); JS_CHECK_RECURSION(cx, return JS_FALSE);
return InternalCall(cx, obj, fval, argc, argv, rval); return ExternalInvoke(cx, obj, fval, argc, argv, rval);
} }
bool bool
@ -1185,66 +1032,82 @@ InvokeConstructor(JSContext *cx, const CallArgs &argsRef)
JS_ASSERT(!js_FunctionClass.construct); JS_ASSERT(!js_FunctionClass.construct);
CallArgs args = argsRef; CallArgs args = argsRef;
JSObject *obj2; JSObject *callee;
if (args.callee().isPrimitive() || !(obj2 = &args.callee().toObject())->getParent()) { if (args.callee().isPrimitive() || !(callee = &args.callee().toObject())->getParent()) {
/* Use js_ValueToFunction to report an error. */ js_ReportIsNotFunction(cx, &args.callee(), JSV2F_CONSTRUCT);
JS_ALWAYS_TRUE(!js_ValueToFunction(cx, &args.callee(), JSV2F_CONSTRUCT));
return false; return false;
} }
Class *clasp = &js_ObjectClass; /* Handle the fast-constructors cases before falling into the general case . */
Class *clasp = callee->getClass();
/* if (clasp == &js_FunctionClass) {
* Call fast constructors without making the object first. JSFunction *fun = callee->getFunctionPrivate();
* The native will be able to make the right new object faster. if (fun->isConstructor()) {
*/ args.thisv().setMagicWithObjectOrNullPayload(NULL);
if (obj2->isFunction()) { return CallJSNativeConstructor(cx, fun->u.n.native, args.argc(), args.base());
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj2);
if (fun->isFastConstructor()) {
args.thisv().setMagic(JS_FAST_CONSTRUCTOR);
FastNative fn = (FastNative)fun->u.n.native;
if (!fn(cx, args.argc(), args.base()))
return JS_FALSE;
JS_ASSERT(!args.rval().isPrimitive());
return JS_TRUE;
} }
} else if (clasp->construct) {
/* Get the class, for natives that aren't fast constructors. */ args.thisv().setMagicWithObjectOrNullPayload(NULL);
if (!fun->isInterpreted() && fun->u.n.clasp) return CallJSNativeConstructor(cx, clasp->construct, args.argc(), args.base());
clasp = fun->u.n.clasp;
} }
Value protov; /* Construct 'this'. */
if (!obj2->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom), &protov)) JSObject *obj = js_NewInstance(cx, callee);
return false;
JSObject *proto = protov.isObjectOrNull() ? protov.toObjectOrNull() : NULL;
JSObject *parent = obj2->getParent();
JSObject* obj = NewObject<WithProto::Class>(cx, clasp, proto, parent);
if (!obj) if (!obj)
return JS_FALSE; return false;
/* Now we have an object with a constructor method; call it. */
args.thisv().setObject(*obj); args.thisv().setObject(*obj);
if (!Invoke(cx, args, JSINVOKE_CONSTRUCT)) if (!Invoke(cx, args, JSINVOKE_CONSTRUCT))
return JS_FALSE; return false;
/* Check the return value and if it's primitive, force it to be obj. */ /* Check the return value and if it's primitive, force it to be obj. */
if (args.rval().isPrimitive()) { if (args.rval().isPrimitive()) {
if (obj2->getClass() != &js_FunctionClass) { if (callee->getClass() != &js_FunctionClass) {
/* native [[Construct]] returning primitive is error */ /* native [[Construct]] returning primitive is error */
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_NEW_RESULT, JSMSG_BAD_NEW_RESULT,
js_ValueToPrintableString(cx, args.rval())); js_ValueToPrintableString(cx, args.rval()));
return JS_FALSE; return false;
} }
args.rval().setObject(*obj); args.rval().setObject(*obj);
} }
JS_RUNTIME_METER(cx->runtime, constructs); JS_RUNTIME_METER(cx->runtime, constructs);
return JS_TRUE; return true;
}
bool
InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval,
uintN argc, Value *argv, Value *rval)
{
LeaveTrace(cx);
InvokeArgsGuard args;
if (!cx->stack().pushInvokeArgs(cx, argc, args))
return JS_FALSE;
args.callee() = fval;
/* Initialize args.thisv on all paths below. */
memcpy(args.argv(), argv, argc * sizeof(Value));
/* Handle the fast-constructor cases before calling the general case. */
JSObject &callee = fval.toObject();
Class *clasp = callee.getClass();
JSFunction *fun;
bool ok;
if (clasp == &js_FunctionClass && (fun = callee.getFunctionPrivate())->isConstructor()) {
args.thisv().setMagicWithObjectOrNullPayload(thisobj);
ok = CallJSNativeConstructor(cx, fun->u.n.native, args.argc(), args.base());
} else if (clasp->construct) {
args.thisv().setMagicWithObjectOrNullPayload(thisobj);
ok = CallJSNativeConstructor(cx, clasp->construct, args.argc(), args.base());
} else {
args.thisv().setObjectOrNull(thisobj);
ok = Invoke(cx, args, JSINVOKE_CONSTRUCT);
}
*rval = args.rval();
return ok;
} }
bool bool
@ -1673,7 +1536,6 @@ namespace reprmeter {
OBJECT_PLAIN, OBJECT_PLAIN,
FUNCTION_INTERPRETED, FUNCTION_INTERPRETED,
FUNCTION_FASTNATIVE, FUNCTION_FASTNATIVE,
FUNCTION_SLOWNATIVE,
ARRAY_SLOW, ARRAY_SLOW,
ARRAY_DENSE ARRAY_DENSE
}; };
@ -1701,9 +1563,7 @@ namespace reprmeter {
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj); JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
if (FUN_INTERPRETED(fun)) if (FUN_INTERPRETED(fun))
return FUNCTION_INTERPRETED; return FUNCTION_INTERPRETED;
if (fun->flags & JSFUN_FAST_NATIVE) return FUNCTION_FASTNATIVE;
return FUNCTION_FASTNATIVE;
return FUNCTION_SLOWNATIVE;
} }
// This must come before the general array test, because that // This must come before the general array test, because that
// one subsumes this one. // one subsumes this one.
@ -1718,7 +1578,7 @@ namespace reprmeter {
static const char *reprName[] = { "invalid", "int", "double", "bool", "special", static const char *reprName[] = { "invalid", "int", "double", "bool", "special",
"string", "null", "object", "string", "null", "object",
"fun:interp", "fun:fast", "fun:slow", "fun:interp", "fun:native"
"array:slow", "array:dense" }; "array:slow", "array:dense" };
// Logically, a tuple of (JSOp, repr_1, ..., repr_n) where repr_i is // Logically, a tuple of (JSOp, repr_1, ..., repr_n) where repr_i is
@ -1878,20 +1738,6 @@ CanIncDecWithoutOverflow(int32_t i)
return (i > JSVAL_INT_MIN) && (i < JSVAL_INT_MAX); return (i > JSVAL_INT_MIN) && (i < JSVAL_INT_MAX);
} }
/*
* Conditional assert to detect failure to clear a pending exception that is
* suppressed (or unintentional suppression of a wanted exception).
*/
#if defined DEBUG_brendan || defined DEBUG_mrbkap || defined DEBUG_shaver
# define DEBUG_NOT_THROWING 1
#endif
#ifdef DEBUG_NOT_THROWING
# define ASSERT_NOT_THROWING(cx) JS_ASSERT(!(cx)->throwing)
#else
# define ASSERT_NOT_THROWING(cx) /* nothing */
#endif
/* /*
* Define JS_OPMETER to instrument bytecode succession, generating a .dot file * Define JS_OPMETER to instrument bytecode succession, generating a .dot file
* on shutdown that shows the graph of significant predecessor/successor pairs * on shutdown that shows the graph of significant predecessor/successor pairs
@ -2452,15 +2298,8 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount)
* To support generator_throw and to catch ignored exceptions, * To support generator_throw and to catch ignored exceptions,
* fail if cx->throwing is set. * fail if cx->throwing is set.
*/ */
if (cx->throwing) { if (cx->throwing)
#ifdef DEBUG_NOT_THROWING
if (cx->exception != JSVAL_ARETURN) {
printf("JS INTERPRETER CALLED WITH PENDING EXCEPTION %lx\n",
(unsigned long) cx->exception);
}
#endif
goto error; goto error;
}
} }
#endif #endif
@ -2665,7 +2504,6 @@ END_CASE(JSOP_POPN)
BEGIN_CASE(JSOP_SETRVAL) BEGIN_CASE(JSOP_SETRVAL)
BEGIN_CASE(JSOP_POPV) BEGIN_CASE(JSOP_POPV)
ASSERT_NOT_THROWING(cx);
POP_RETURN_VALUE(); POP_RETURN_VALUE();
END_CASE(JSOP_POPV) END_CASE(JSOP_POPV)
@ -2702,7 +2540,6 @@ BEGIN_CASE(JSOP_STOP)
* When the inlined frame exits with an exception or an error, ok will be * When the inlined frame exits with an exception or an error, ok will be
* false after the inline_return label. * false after the inline_return label.
*/ */
ASSERT_NOT_THROWING(cx);
CHECK_BRANCH(); CHECK_BRANCH();
#ifdef JS_TRACER #ifdef JS_TRACER
@ -4767,19 +4604,16 @@ BEGIN_CASE(JSOP_APPLY)
DO_OP(); DO_OP();
} }
if (fun->flags & JSFUN_FAST_NATIVE) { JS_ASSERT(vp[1].isObjectOrNull() || PrimitiveThisTest(fun, vp[1]));
Probes::enterJSFun(cx, fun);
JS_ASSERT(fun->u.n.extra == 0); Probes::enterJSFun(cx, fun);
JS_ASSERT(vp[1].isObjectOrNull() || PrimitiveThisTest(fun, vp[1])); JSBool ok = fun->u.n.native(cx, argc, vp);
JSBool ok = ((FastNative) fun->u.n.native)(cx, argc, vp); Probes::exitJSFun(cx, fun);
Probes::exitJSFun(cx, fun); regs.sp = vp + 1;
regs.sp = vp + 1; if (!ok)
if (!ok) goto error;
goto error; TRACE_0(NativeCallComplete);
TRACE_0(NativeCallComplete); goto end_call;
goto end_call;
}
} }
bool ok; bool ok;
@ -5753,14 +5587,12 @@ BEGIN_CASE(JSOP_LAMBDA)
if (IsFunctionObject(cref, &callee)) { if (IsFunctionObject(cref, &callee)) {
JSFunction *calleeFun = GET_FUNCTION_PRIVATE(cx, callee); JSFunction *calleeFun = GET_FUNCTION_PRIVATE(cx, callee);
FastNative fastNative = FUN_FAST_NATIVE(calleeFun); if (Native native = calleeFun->maybeNative()) {
if (iargc == 1 && native == array_sort) {
if (fastNative) {
if (iargc == 1 && fastNative == array_sort) {
JS_FUNCTION_METER(cx, joinedsort); JS_FUNCTION_METER(cx, joinedsort);
break; break;
} }
if (iargc == 2 && fastNative == str_replace) { if (iargc == 2 && native == str_replace) {
JS_FUNCTION_METER(cx, joinedreplace); JS_FUNCTION_METER(cx, joinedreplace);
break; break;
} }
@ -6726,7 +6558,7 @@ END_CASE(JSOP_LEAVEBLOCK)
#if JS_HAS_GENERATORS #if JS_HAS_GENERATORS
BEGIN_CASE(JSOP_GENERATOR) BEGIN_CASE(JSOP_GENERATOR)
{ {
ASSERT_NOT_THROWING(cx); JS_ASSERT(!cx->throwing);
regs.pc += JSOP_GENERATOR_LENGTH; regs.pc += JSOP_GENERATOR_LENGTH;
JSObject *obj = js_NewGenerator(cx); JSObject *obj = js_NewGenerator(cx);
if (!obj) if (!obj)
@ -6740,7 +6572,7 @@ BEGIN_CASE(JSOP_GENERATOR)
} }
BEGIN_CASE(JSOP_YIELD) BEGIN_CASE(JSOP_YIELD)
ASSERT_NOT_THROWING(cx); JS_ASSERT(!cx->throwing);
if (cx->generatorFor(fp)->state == JSGEN_CLOSING) { if (cx->generatorFor(fp)->state == JSGEN_CLOSING) {
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD, js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD,
JSDVG_SEARCH_STACK, fp->argv[-2], NULL); JSDVG_SEARCH_STACK, fp->argv[-2], NULL);

Просмотреть файл

@ -685,38 +685,52 @@ Invoke(JSContext *cx, const CallArgs &args, uintN flags);
#define JSINVOKE_FUNFLAGS JSINVOKE_CONSTRUCT #define JSINVOKE_FUNFLAGS JSINVOKE_CONSTRUCT
/* /*
* "Internal" calls may come from C or C++ code using a JSContext on which no * "External" calls may come from C or C++ code using a JSContext on which no
* JS is running (!cx->fp), so they may need to push a dummy JSStackFrame. * JS is running (!cx->fp), so they may need to push a dummy JSStackFrame.
*/ */
extern JSBool
InternalInvoke(JSContext *cx, const Value &thisv, const Value &fval, uintN flags, extern bool
ExternalInvoke(JSContext *cx, const Value &thisv, const Value &fval,
uintN argc, Value *argv, Value *rval); uintN argc, Value *argv, Value *rval);
static JS_ALWAYS_INLINE bool static JS_ALWAYS_INLINE bool
InternalCall(JSContext *cx, JSObject *obj, const Value &fval, ExternalInvoke(JSContext *cx, JSObject *obj, const Value &fval,
uintN argc, Value *argv, Value *rval) uintN argc, Value *argv, Value *rval)
{ {
return InternalInvoke(cx, ObjectOrNullValue(obj), fval, 0, argc, argv, rval); return ExternalInvoke(cx, ObjectOrNullValue(obj), fval, argc, argv, rval);
}
static JS_ALWAYS_INLINE bool
InternalConstruct(JSContext *cx, JSObject *obj, const Value &fval,
uintN argc, Value *argv, Value *rval)
{
return InternalInvoke(cx, ObjectOrNullValue(obj), fval, JSINVOKE_CONSTRUCT, argc, argv, rval);
} }
extern bool extern bool
InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval, ExternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval,
JSAccessMode mode, uintN argc, Value *argv, Value *rval); JSAccessMode mode, uintN argc, Value *argv, Value *rval);
extern JS_FORCES_STACK bool /*
Execute(JSContext *cx, JSObject *chain, JSScript *script, * These two functions invoke a function called from a constructor context
JSStackFrame *down, uintN flags, Value *result); * (e.g. 'new'). InvokeConstructor handles the general case where a new object
* needs to be created for/by the constructor. ConstructWithGivenThis directly
* calls the constructor with the given 'this', hence the caller must
* understand the semantics of the constructor call.
*/
extern JS_REQUIRES_STACK bool extern JS_REQUIRES_STACK bool
InvokeConstructor(JSContext *cx, const CallArgs &args); InvokeConstructor(JSContext *cx, const CallArgs &args);
extern JS_REQUIRES_STACK bool
InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval,
uintN argc, Value *argv, Value *rval);
/*
* Executes a script with the given scope chain in the context of the given
* frame.
*/
extern JS_FORCES_STACK bool
Execute(JSContext *cx, JSObject *chain, JSScript *script,
JSStackFrame *down, uintN flags, Value *result);
/*
* Execute the caller-initialized frame for a user-defined script or function
* pointed to by cx->fp until completion or error.
*/
extern JS_REQUIRES_STACK bool extern JS_REQUIRES_STACK bool
Interpret(JSContext *cx, JSStackFrame *stopFp, uintN inlineCallCount = 0); Interpret(JSContext *cx, JSStackFrame *stopFp, uintN inlineCallCount = 0);

Просмотреть файл

@ -87,7 +87,8 @@ static JSObject *iterator_iterator(JSContext *cx, JSObject *obj, JSBool keysonly
Class js_IteratorClass = { Class js_IteratorClass = {
"Iterator", "Iterator",
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) | JSCLASS_MARK_IS_TRACE, JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) |
JSCLASS_MARK_IS_TRACE,
PropertyStub, /* addProperty */ PropertyStub, /* addProperty */
PropertyStub, /* delProperty */ PropertyStub, /* delProperty */
PropertyStub, /* getProperty */ PropertyStub, /* getProperty */
@ -407,7 +408,7 @@ GetCustomIterator(JSContext *cx, JSObject *obj, uintN flags, Value *vp)
/* Otherwise call it and return that object. */ /* Otherwise call it and return that object. */
LeaveTrace(cx); LeaveTrace(cx);
Value arg = BooleanValue((flags & JSITER_FOREACH) == 0); Value arg = BooleanValue((flags & JSITER_FOREACH) == 0);
if (!InternalCall(cx, obj, *vp, 1, &arg, vp)) if (!ExternalInvoke(cx, obj, *vp, 1, &arg, vp))
return false; return false;
if (vp->isPrimitive()) { if (vp->isPrimitive()) {
/* /*
@ -729,15 +730,13 @@ iterator_iterator(JSContext *cx, JSObject *obj, JSBool keysonly)
} }
static JSBool static JSBool
Iterator(JSContext *cx, JSObject *iterobj, uintN argc, Value *argv, Value *rval) Iterator(JSContext *cx, uintN argc, Value *vp)
{ {
JSBool keyonly; Value *argv = JS_ARGV(cx, vp);
uintN flags; bool keyonly = argc >= 2 ? js_ValueToBoolean(argv[1]) : false;
uintN flags = JSITER_OWNONLY | (keyonly ? 0 : (JSITER_FOREACH | JSITER_KEYVALUE));
keyonly = js_ValueToBoolean(argv[1]); *vp = argc >= 1 ? argv[0] : UndefinedValue();
flags = JSITER_OWNONLY | (keyonly ? 0 : (JSITER_FOREACH | JSITER_KEYVALUE)); return js_ValueToIterator(cx, flags, vp);
*rval = argv[0];
return js_ValueToIterator(cx, flags, rval);
} }
JSBool JSBool
@ -967,7 +966,7 @@ js_IteratorMore(JSContext *cx, JSObject *iterobj, Value *rval)
jsid id = ATOM_TO_JSID(cx->runtime->atomState.nextAtom); jsid id = ATOM_TO_JSID(cx->runtime->atomState.nextAtom);
if (!js_GetMethod(cx, iterobj, id, JSGET_METHOD_BARRIER, rval)) if (!js_GetMethod(cx, iterobj, id, JSGET_METHOD_BARRIER, rval))
return false; return false;
if (!InternalCall(cx, iterobj, *rval, 0, NULL, rval)) { if (!ExternalInvoke(cx, iterobj, *rval, 0, NULL, rval)) {
/* Check for StopIteration. */ /* Check for StopIteration. */
if (!cx->throwing || !js_ValueIsStopIteration(cx->exception)) if (!cx->throwing || !js_ValueIsStopIteration(cx->exception))
return false; return false;

Просмотреть файл

@ -531,18 +531,27 @@ Class js_NumberClass = {
}; };
static JSBool static JSBool
Number(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) Number(JSContext *cx, uintN argc, Value *vp)
{ {
if (argc != 0) { /* Sample JS_CALLEE before clobbering. */
if (!ValueToNumber(cx, &argv[0])) bool isConstructing = IsConstructing(vp);
return JS_FALSE;
if (argc > 0) {
if (!ValueToNumber(cx, &vp[2]))
return false;
vp[0] = vp[2];
} else { } else {
argv[0].setInt32(0); vp[0].setInt32(0);
} }
if (!JS_IsConstructing(cx))
*rval = argv[0]; if (!isConstructing)
else return true;
obj->setPrimitiveThis(argv[0]);
JSObject *obj = NewBuiltinClassInstance(cx, &js_NumberClass);
if (!obj)
return false;
obj->setPrimitiveThis(vp[0]);
vp->setObject(*obj);
return true; return true;
} }

Просмотреть файл

@ -107,8 +107,7 @@ JS_FRIEND_DATA(const JSObjectMap) JSObjectMap::sharedNonNative(JSObjectMap::SHAP
Class js_ObjectClass = { Class js_ObjectClass = {
js_Object_str, js_Object_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) | JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
JSCLASS_FAST_CONSTRUCTOR,
PropertyStub, /* addProperty */ PropertyStub, /* addProperty */
PropertyStub, /* delProperty */ PropertyStub, /* delProperty */
PropertyStub, /* getProperty */ PropertyStub, /* getProperty */
@ -1091,7 +1090,7 @@ obj_eval(JSContext *cx, uintN argc, Value *vp)
staticLevel = 0; staticLevel = 0;
if (!js_CheckPrincipalsAccess(cx, obj, if (!js_CheckPrincipalsAccess(cx, obj,
JS_StackFramePrincipals(cx, caller), js_StackFramePrincipals(cx, caller),
cx->runtime->atomState.evalAtom)) { cx->runtime->atomState.evalAtom)) {
return JS_FALSE; return JS_FALSE;
} }
@ -1290,7 +1289,7 @@ obj_watch_handler(JSContext *cx, JSObject *obj, jsid id, jsval old,
* the currently executing script. * the currently executing script.
*/ */
watcher = callbacks->findObjectPrincipals(cx, callable); watcher = callbacks->findObjectPrincipals(cx, callable);
subject = JS_StackFramePrincipals(cx, caller); subject = js_StackFramePrincipals(cx, caller);
if (watcher && subject && !watcher->subsume(watcher, subject)) { if (watcher && subject && !watcher->subsume(watcher, subject)) {
/* Silently don't call the watch handler. */ /* Silently don't call the watch handler. */
@ -1311,7 +1310,7 @@ obj_watch_handler(JSContext *cx, JSObject *obj, jsid id, jsval old,
argv[0] = IdToValue(id); argv[0] = IdToValue(id);
argv[1] = Valueify(old); argv[1] = Valueify(old);
argv[2] = Valueify(*nvp); argv[2] = Valueify(*nvp);
ok = InternalCall(cx, obj, ObjectOrNullValue(callable), 3, argv, Valueify(nvp)); ok = ExternalInvoke(cx, obj, ObjectOrNullValue(callable), 3, argv, Valueify(nvp));
js_StopResolving(cx, &key, JSRESFLAG_WATCH, entry, generation); js_StopResolving(cx, &key, JSRESFLAG_WATCH, entry, generation);
return ok; return ok;
} }
@ -2584,6 +2583,27 @@ js_Object(JSContext *cx, uintN argc, Value *vp)
return JS_TRUE; return JS_TRUE;
} }
JSObject*
js_NewInstance(JSContext *cx, JSObject *callee)
{
Class *clasp = callee->getClass();
Class *newclasp = &js_ObjectClass;
if (clasp == &js_FunctionClass) {
JSFunction *fun = callee->getFunctionPrivate();
if (fun->isNative() && fun->u.n.clasp)
newclasp = fun->u.n.clasp;
}
Value protov;
if (!callee->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom), &protov))
return NULL;
JSObject *proto = protov.isObjectOrNull() ? protov.toObjectOrNull() : NULL;
JSObject *parent = callee->getParent();
return NewObject<WithProto::Class>(cx, newclasp, proto, parent);
}
#ifdef JS_TRACER #ifdef JS_TRACER
JSObject* JSObject*
@ -2625,7 +2645,7 @@ JS_DEFINE_CALLINFO_2(extern, CONSTRUCTOR_RETRY, js_NonEmptyObject, CONTEXT, CALL
nanojit::ACCSET_STORE_ANY) nanojit::ACCSET_STORE_ANY)
JSObject* FASTCALL JSObject* FASTCALL
js_NewInstance(JSContext *cx, Class *clasp, JSObject *ctor) js_NewInstanceFromTrace(JSContext *cx, Class *clasp, JSObject *ctor)
{ {
JS_ASSERT(JS_ON_TRACE(cx)); JS_ASSERT(JS_ON_TRACE(cx));
JS_ASSERT(ctor->isFunction()); JS_ASSERT(ctor->isFunction());
@ -2676,7 +2696,7 @@ js_NewInstance(JSContext *cx, Class *clasp, JSObject *ctor)
return NewNonFunction<WithProto::Given>(cx, clasp, proto, parent); return NewNonFunction<WithProto::Given>(cx, clasp, proto, parent);
} }
JS_DEFINE_CALLINFO_3(extern, CONSTRUCTOR_RETRY, js_NewInstance, CONTEXT, CLASS, OBJECT, 0, JS_DEFINE_CALLINFO_3(extern, CONSTRUCTOR_RETRY, js_NewInstanceFromTrace, CONTEXT, CLASS, OBJECT, 0,
nanojit::ACCSET_STORE_ANY) nanojit::ACCSET_STORE_ANY)
#else /* !JS_TRACER */ #else /* !JS_TRACER */
@ -3244,15 +3264,14 @@ Class js_BlockClass = {
JSObject * JSObject *
js_InitObjectClass(JSContext *cx, JSObject *obj) js_InitObjectClass(JSContext *cx, JSObject *obj)
{ {
JSObject *proto = js_InitClass(cx, obj, NULL, &js_ObjectClass, (Native) js_Object, 1, JSObject *proto = js_InitClass(cx, obj, NULL, &js_ObjectClass, js_Object, 1,
object_props, object_methods, NULL, object_static_methods); object_props, object_methods, NULL, object_static_methods);
if (!proto) if (!proto)
return NULL; return NULL;
/* ECMA (15.1.2.1) says 'eval' is a property of the global object. */ /* ECMA (15.1.2.1) says 'eval' is a property of the global object. */
if (!js_DefineFunction(cx, obj, cx->runtime->atomState.evalAtom, if (!js_DefineFunction(cx, obj, cx->runtime->atomState.evalAtom, obj_eval, 1,
(Native)obj_eval, 1, JSFUN_STUB_GSOPS)) {
JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS)) {
return NULL; return NULL;
} }
@ -3390,11 +3409,7 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
ctor = proto; ctor = proto;
} else { } else {
uint16 flags = 0; fun = js_NewFunction(cx, NULL, constructor, nargs, JSFUN_CONSTRUCTOR, obj, atom);
if (clasp->flags & JSCLASS_FAST_CONSTRUCTOR)
flags |= JSFUN_FAST_NATIVE | JSFUN_FAST_NATIVE_CTOR;
fun = js_NewFunction(cx, NULL, constructor, nargs, flags, obj, atom);
if (!fun) if (!fun)
goto bad; goto bad;
@ -3418,8 +3433,10 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
ctor = FUN_OBJECT(fun); ctor = FUN_OBJECT(fun);
if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) { if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) {
Value rval; Value rval;
if (!InternalConstruct(cx, proto, ObjectOrNullValue(ctor), 0, NULL, &rval)) if (!InvokeConstructorWithGivenThis(cx, proto, ObjectOrNullValue(ctor),
0, NULL, &rval)) {
goto bad; goto bad;
}
if (rval.isObject() && &rval.toObject() != proto) if (rval.isObject() && &rval.toObject() != proto)
proto = &rval.toObject(); proto = &rval.toObject();
} }
@ -3835,7 +3852,7 @@ js_ConstructObject(JSContext *cx, Class *clasp, JSObject *proto, JSObject *paren
return NULL; return NULL;
Value rval; Value rval;
if (!InternalConstruct(cx, obj, cval, argc, argv, &rval)) if (!InvokeConstructorWithGivenThis(cx, obj, cval, argc, argv, &rval))
return NULL; return NULL;
if (rval.isPrimitive()) if (rval.isPrimitive())
@ -5299,9 +5316,8 @@ DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
JSObject *funobj; JSObject *funobj;
if (IsFunctionObject(fval, &funobj)) { if (IsFunctionObject(fval, &funobj)) {
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj); JSFunction *fun = funobj->getFunctionPrivate();
if (fun->maybeNative() == js_str_toString) {
if (FUN_FAST_NATIVE(fun) == js_str_toString) {
JS_UNLOCK_OBJ(cx, lockedobj); JS_UNLOCK_OBJ(cx, lockedobj);
*vp = obj->getPrimitiveThis(); *vp = obj->getPrimitiveThis();
return JS_TRUE; return JS_TRUE;
@ -5703,7 +5719,7 @@ js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
if (fval.isPrimitive()) if (fval.isPrimitive())
return JS_TRUE; return JS_TRUE;
return InternalCall(cx, obj, fval, argc, argv, rval); return ExternalInvoke(cx, obj, fval, argc, argv, rval);
} }
#if JS_HAS_XDR #if JS_HAS_XDR

Просмотреть файл

@ -1354,6 +1354,9 @@ extern JSObject *
js_ConstructObject(JSContext *cx, js::Class *clasp, JSObject *proto, js_ConstructObject(JSContext *cx, js::Class *clasp, JSObject *proto,
JSObject *parent, uintN argc, js::Value *argv); JSObject *parent, uintN argc, js::Value *argv);
extern JSObject *
js_NewInstance(JSContext *cx, JSObject *callee);
extern jsid extern jsid
js_CheckForStringIndex(jsid id); js_CheckForStringIndex(jsid id);

Просмотреть файл

@ -453,13 +453,6 @@ JSObject::setDateUTCTime(const js::Value &time)
fslots[JSSLOT_DATE_UTC_TIME] = time; fslots[JSSLOT_DATE_UTC_TIME] = time;
} }
inline JSFunction *
JSObject::getFunctionPrivate() const
{
JS_ASSERT(isFunction());
return reinterpret_cast<JSFunction *>(getPrivate());
}
inline js::Value * inline js::Value *
JSObject::getFlatClosureUpvars() const JSObject::getFlatClosureUpvars() const
{ {

Просмотреть файл

@ -96,6 +96,7 @@ Probes::FunctionLineNumber(JSContext *cx, const JSFunction *fun)
* This is used by the function-args and function-rval probes, which also * This is used by the function-args and function-rval probes, which also
* provide raw (unmasked) jsvals should type info be useful from D scripts. * provide raw (unmasked) jsvals should type info be useful from D scripts.
*/ */
#if 0
static void * static void *
jsprobes_jsvaltovoid(JSContext *cx, const js::Value &argval) jsprobes_jsvaltovoid(JSContext *cx, const js::Value &argval)
{ {
@ -120,6 +121,7 @@ jsprobes_jsvaltovoid(JSContext *cx, const js::Value &argval)
return argval.asGCThing(); return argval.asGCThing();
} }
#endif
const char * const char *
Probes::FunctionName(JSContext *cx, const JSFunction *fun) Probes::FunctionName(JSContext *cx, const JSFunction *fun)

Просмотреть файл

@ -125,7 +125,7 @@ JSProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id,
return true; return true;
} }
if (desc.attrs & JSPROP_GETTER) { if (desc.attrs & JSPROP_GETTER) {
return InternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.getter), return ExternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.getter),
JSACC_READ, 0, 0, vp); JSACC_READ, 0, 0, vp);
} }
if (desc.attrs & JSPROP_SHORTID) if (desc.attrs & JSPROP_SHORTID)
@ -144,7 +144,7 @@ JSProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id,
if (desc.obj) { if (desc.obj) {
if (desc.setter) { if (desc.setter) {
if (desc.attrs & JSPROP_SETTER) { if (desc.attrs & JSPROP_SETTER) {
return InternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.setter), return ExternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.setter),
JSACC_READ, 0, 0, vp); JSACC_READ, 0, 0, vp);
} }
if (desc.attrs & JSPROP_SHORTID) if (desc.attrs & JSPROP_SHORTID)
@ -161,7 +161,7 @@ JSProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id,
if (desc.obj) { if (desc.obj) {
if (desc.setter) { if (desc.setter) {
if (desc.attrs & JSPROP_SETTER) { if (desc.attrs & JSPROP_SETTER) {
return InternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.setter), return ExternalGetOrSet(cx, proxy, id, CastAsObjectJsval(desc.setter),
JSACC_READ, 0, 0, vp); JSACC_READ, 0, 0, vp);
} }
if (desc.attrs & JSPROP_SHORTID) if (desc.attrs & JSPROP_SHORTID)
@ -249,7 +249,7 @@ JSProxyHandler::call(JSContext *cx, JSObject *proxy, uintN argc, Value *vp)
{ {
JS_ASSERT(OperationInProgress(cx, proxy)); JS_ASSERT(OperationInProgress(cx, proxy));
AutoValueRooter rval(cx); AutoValueRooter rval(cx);
JSBool ok = InternalInvoke(cx, vp[1], GetCall(proxy), 0, argc, JS_ARGV(cx, vp), JSBool ok = ExternalInvoke(cx, vp[1], GetCall(proxy), argc, JS_ARGV(cx, vp),
rval.addr()); rval.addr());
if (ok) if (ok)
JS_SET_RVAL(cx, vp, rval.value()); JS_SET_RVAL(cx, vp, rval.value());
@ -277,7 +277,7 @@ JSProxyHandler::construct(JSContext *cx, JSObject *proxy,
*/ */
JS_ASSERT(fval.isObject()); JS_ASSERT(fval.isObject());
JSObject *thisobj = fval.toObject().getGlobal(); JSObject *thisobj = fval.toObject().getGlobal();
return InternalCall(cx, thisobj, fval, argc, argv, rval); return ExternalInvoke(cx, thisobj, fval, argc, argv, rval);
} }
void void
@ -329,7 +329,7 @@ Trap(JSContext *cx, JSObject *handler, Value fval, uintN argc, Value* argv, Valu
{ {
JS_CHECK_RECURSION(cx, return false); JS_CHECK_RECURSION(cx, return false);
return InternalCall(cx, handler, fval, argc, argv, rval); return ExternalInvoke(cx, handler, fval, argc, argv, rval);
} }
static bool static bool
@ -948,11 +948,14 @@ proxy_Call(JSContext *cx, uintN argc, Value *vp)
} }
JSBool JSBool
proxy_Construct(JSContext *cx, JSObject * /*obj*/, uintN argc, Value *argv, Value *rval) proxy_Construct(JSContext *cx, uintN argc, Value *vp)
{ {
JSObject *proxy = &argv[-2].toObject(); JSObject *proxy = &JS_CALLEE(cx, vp).toObject();
JS_ASSERT(proxy->isProxy()); JS_ASSERT(proxy->isProxy());
return JSProxy::construct(cx, proxy, argc, argv, rval); Value rval;
bool ok = JSProxy::construct(cx, proxy, argc, JS_ARGV(cx, vp), &rval);
*vp = rval;
return ok;
} }
static JSType static JSType
@ -965,7 +968,7 @@ proxy_TypeOf_fun(JSContext *cx, JSObject *obj)
JS_FRIEND_API(Class) FunctionProxyClass = { JS_FRIEND_API(Class) FunctionProxyClass = {
"Proxy", "Proxy",
Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(4) | Class::CALL_IS_FAST, Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(4),
PropertyStub, /* addProperty */ PropertyStub, /* addProperty */
PropertyStub, /* delProperty */ PropertyStub, /* delProperty */
PropertyStub, /* getProperty */ PropertyStub, /* getProperty */
@ -976,7 +979,7 @@ JS_FRIEND_API(Class) FunctionProxyClass = {
NULL, /* finalize */ NULL, /* finalize */
NULL, /* reserved0 */ NULL, /* reserved0 */
NULL, /* checkAccess */ NULL, /* checkAccess */
CastCallOpAsNative(proxy_Call), proxy_Call,
proxy_Construct, proxy_Construct,
NULL, /* xdrObject */ NULL, /* xdrObject */
proxy_HasInstance, proxy_HasInstance,
@ -1153,18 +1156,29 @@ static const uint32 JSSLOT_CALLABLE_CALL = JSSLOT_PRIVATE;
static const uint32 JSSLOT_CALLABLE_CONSTRUCT = JSSLOT_PRIVATE + 1; static const uint32 JSSLOT_CALLABLE_CONSTRUCT = JSSLOT_PRIVATE + 1;
static JSBool static JSBool
callable_Call(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) callable_Call(JSContext *cx, uintN argc, Value *vp)
{ {
JSObject *callable = &argv[-2].toObject(); JSObject *thisobj = ComputeThisFromVp(cx, vp);
if (!thisobj)
return false;
JSObject *callable = &JS_CALLEE(cx, vp).toObject();
JS_ASSERT(callable->getClass() == &CallableObjectClass); JS_ASSERT(callable->getClass() == &CallableObjectClass);
const Value &fval = callable->fslots[JSSLOT_CALLABLE_CALL]; const Value &fval = callable->fslots[JSSLOT_CALLABLE_CALL];
return InternalCall(cx, obj, fval, argc, argv, rval); Value rval;
bool ok = ExternalInvoke(cx, thisobj, fval, argc, JS_ARGV(cx, vp), &rval);
*vp = rval;
return ok;
} }
static JSBool static JSBool
callable_Construct(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) callable_Construct(JSContext *cx, uintN argc, Value *vp)
{ {
JSObject *callable = &argv[-2].toObject(); JSObject *thisobj = js_NewInstance(cx, &JS_CALLEE(cx, vp).toObject());
if (!thisobj)
return false;
JSObject *callable = &vp[0].toObject();
JS_ASSERT(callable->getClass() == &CallableObjectClass); JS_ASSERT(callable->getClass() == &CallableObjectClass);
Value fval = callable->fslots[JSSLOT_CALLABLE_CONSTRUCT]; Value fval = callable->fslots[JSSLOT_CALLABLE_CONSTRUCT];
if (fval.isUndefined()) { if (fval.isUndefined()) {
@ -1173,12 +1187,13 @@ callable_Construct(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value
JS_ASSERT(fval.isObject()); JS_ASSERT(fval.isObject());
/* callable is the constructor, so get callable.prototype is the proto of the new object. */ /* callable is the constructor, so get callable.prototype is the proto of the new object. */
if (!callable->getProperty(cx, ATOM_TO_JSID(ATOM(classPrototype)), rval)) Value protov;
if (!callable->getProperty(cx, ATOM_TO_JSID(ATOM(classPrototype)), &protov))
return false; return false;
JSObject *proto; JSObject *proto;
if (rval->isObject()) { if (protov.isObject()) {
proto = &rval->toObject(); proto = &protov.toObject();
} else { } else {
if (!js_GetClassPrototype(cx, NULL, JSProto_Object, &proto)) if (!js_GetClassPrototype(cx, NULL, JSProto_Object, &proto))
return false; return false;
@ -1188,19 +1203,23 @@ callable_Construct(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value
if (!newobj) if (!newobj)
return false; return false;
rval->setObject(*newobj);
/* If the call returns an object, return that, otherwise the original newobj. */ /* If the call returns an object, return that, otherwise the original newobj. */
if (!InternalCall(cx, newobj, callable->fslots[JSSLOT_CALLABLE_CALL], Value rval;
argc, argv, rval)) { if (!ExternalInvoke(cx, newobj, callable->fslots[JSSLOT_CALLABLE_CALL],
argc, vp + 2, &rval)) {
return false; return false;
} }
if (rval->isPrimitive()) if (rval.isPrimitive())
rval->setObject(*newobj); vp->setObject(*newobj);
else
*vp = rval;
return true; return true;
} }
return InternalCall(cx, obj, fval, argc, argv, rval);
Value rval;
bool ok = ExternalInvoke(cx, thisobj, fval, argc, vp + 2, &rval);
*vp = rval;
return ok;
} }
Class CallableObjectClass = { Class CallableObjectClass = {

Просмотреть файл

@ -328,14 +328,6 @@ typedef JSBool
typedef JSBool typedef JSBool
(* JSAttributesOp)(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); (* JSAttributesOp)(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
/*
* The type of ops->call. Same argument types as JSFastNative, but a different
* contract. A JSCallOp expects a dummy stack frame with the caller's
* scopeChain.
*/
typedef JSBool
(* JSCallOp)(JSContext *cx, uintN argc, jsval *vp);
/* /*
* A generic type for functions mapping an object to another object, or null * A generic type for functions mapping an object to another object, or null
* if an error or exception was thrown on cx. * if an error or exception was thrown on cx.

Просмотреть файл

@ -396,15 +396,14 @@ typedef void
typedef JSBool typedef JSBool
(* JSEqualityOp)(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp); (* JSEqualityOp)(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
/* Typedef for native functions called by the JS VM. */ /*
* Typedef for native functions called by the JS VM.
*
* See jsapi.h, the JS_CALLEE, JS_THIS, etc. macros.
*/
typedef JSBool typedef JSBool
(* JSNative)(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, (* JSNative)(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
/* See jsapi.h, the JS_CALLEE, JS_THIS, etc. macros. */
typedef JSBool
(* JSFastNative)(JSContext *cx, uintN argc, jsval *vp);
/* Callbacks and their arguments. */ /* Callbacks and their arguments. */

Просмотреть файл

@ -576,9 +576,9 @@ static JSBool
regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, Value *argv, JSBool test, Value *rval); regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, Value *argv, JSBool test, Value *rval);
static JSBool static JSBool
regexp_call(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) regexp_call(JSContext *cx, uintN argc, Value *vp)
{ {
return regexp_exec_sub(cx, argv[-2].toObjectOrNull(), argc, argv, JS_FALSE, rval); return regexp_exec_sub(cx, &JS_CALLEE(cx, vp).toObject(), argc, JS_ARGV(cx, vp), false, vp);
} }
#if JS_HAS_XDR #if JS_HAS_XDR
@ -960,32 +960,26 @@ static JSFunctionSpec regexp_methods[] = {
}; };
static JSBool static JSBool
regexp_construct(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) regexp_construct(JSContext *cx, uintN argc, Value *vp)
{ {
if (!JS_IsConstructing(cx)) { /*
/* * If first arg is regexp and no flags are given, just return the arg.
* If first arg is regexp and no flags are given, just return the arg. * (regexp_compile_sub detects the regexp + flags case and throws a
* (regexp_compile_sub detects the regexp + flags case and throws a * TypeError.) See 10.15.3.1.
* TypeError.) See 10.15.3.1. */
*/ Value *argv = vp + 2;
if ((argc < 2 || argv[1].isUndefined()) && !argv[0].isPrimitive() && if ((argc < 2 || argv[1].isUndefined()) && argv[0].isObject() &&
argv[0].toObject().getClass() == &js_RegExpClass) { argv[0].toObject().getClass() == &js_RegExpClass) {
*rval = argv[0]; *vp = argv[0];
return true; return true;
}
/* Otherwise, replace obj with a new RegExp object. */
obj = NewBuiltinClassInstance(cx, &js_RegExpClass);
if (!obj)
return false;
/*
* regexp_compile_sub does not use rval to root its temporaries so we
* can use it to root obj.
*/
*rval = ObjectValue(*obj);
} }
return regexp_compile_sub(cx, obj, argc, argv, rval);
/* Otherwise, replace obj with a new RegExp object. */
JSObject *obj = NewBuiltinClassInstance(cx, &js_RegExpClass);
if (!obj)
return false;
return regexp_compile_sub(cx, obj, argc, argv, vp);
} }
JSObject * JSObject *

Просмотреть файл

@ -215,7 +215,7 @@ Shape::get(JSContext* cx, JSObject* obj, JSObject *pobj, js::Value* vp) const
if (hasGetterValue()) { if (hasGetterValue()) {
JS_ASSERT(!isMethod()); JS_ASSERT(!isMethod());
js::Value fval = getterValue(); js::Value fval = getterValue();
return js::InternalGetOrSet(cx, obj, id, fval, JSACC_READ, 0, 0, vp); return js::ExternalGetOrSet(cx, obj, id, fval, JSACC_READ, 0, 0, vp);
} }
if (isMethod()) { if (isMethod()) {
@ -239,7 +239,7 @@ Shape::set(JSContext* cx, JSObject* obj, js::Value* vp) const
if (attrs & JSPROP_SETTER) { if (attrs & JSPROP_SETTER) {
js::Value fval = setterValue(); js::Value fval = setterValue();
return js::InternalGetOrSet(cx, obj, id, fval, JSACC_WRITE, 1, vp, vp); return js::ExternalGetOrSet(cx, obj, id, fval, JSACC_WRITE, 1, vp, vp);
} }
if (attrs & JSPROP_GETTER) if (attrs & JSPROP_GETTER)

Просмотреть файл

@ -832,8 +832,7 @@ str_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
Class js_StringClass = { Class js_StringClass = {
js_String_str, js_String_str,
JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_NEW_RESOLVE |
JSCLASS_HAS_CACHED_PROTO(JSProto_String) | JSCLASS_HAS_CACHED_PROTO(JSProto_String),
JSCLASS_FAST_CONSTRUCTOR,
PropertyStub, /* addProperty */ PropertyStub, /* addProperty */
PropertyStub, /* delProperty */ PropertyStub, /* delProperty */
str_getProperty, str_getProperty,
@ -3264,27 +3263,27 @@ const char JSString::deflatedUnitStringTable[] = {
JSBool JSBool
js_String(JSContext *cx, uintN argc, Value *vp) js_String(JSContext *cx, uintN argc, Value *vp)
{ {
JSString *str; Value *argv = vp + 2;
JSString *str;
if (argc > 0) { if (argc > 0) {
str = js_ValueToString(cx, vp[2]); str = js_ValueToString(cx, argv[0]);
if (!str) if (!str)
return JS_FALSE; return false;
vp[2].setString(str);
} else { } else {
str = cx->runtime->emptyString; str = cx->runtime->emptyString;
} }
if (vp[1].isMagic(JS_FAST_CONSTRUCTOR)) { if (IsConstructing(vp)) {
JSObject *obj = NewBuiltinClassInstance(cx, &js_StringClass); JSObject *obj = NewBuiltinClassInstance(cx, &js_StringClass);
if (!obj) if (!obj)
return JS_FALSE; return false;
obj->setPrimitiveThis(StringValue(str)); obj->setPrimitiveThis(StringValue(str));
vp->setObject(*obj); vp->setObject(*obj);
} else { } else {
vp->setString(str); vp->setString(str);
} }
return JS_TRUE; return true;
} }
#ifdef JS_TRACER #ifdef JS_TRACER
@ -3373,7 +3372,7 @@ js_InitStringClass(JSContext *cx, JSObject *obj)
if (!JS_DefineFunctions(cx, obj, string_functions)) if (!JS_DefineFunctions(cx, obj, string_functions))
return NULL; return NULL;
proto = js_InitClass(cx, obj, NULL, &js_StringClass, (Native) js_String, 1, proto = js_InitClass(cx, obj, NULL, &js_StringClass, js_String, 1,
NULL, string_methods, NULL, string_methods,
NULL, string_static_methods); NULL, string_static_methods);
if (!proto) if (!proto)

Просмотреть файл

@ -466,6 +466,8 @@ InitJITStatsClass(JSContext *cx, JSObject *glob)
#define INS_ATOM(atom) INS_CONSTSTR(ATOM_TO_STRING(atom)) #define INS_ATOM(atom) INS_CONSTSTR(ATOM_TO_STRING(atom))
#define INS_NULL() INS_CONSTPTR(NULL) #define INS_NULL() INS_CONSTPTR(NULL)
#define INS_UNDEFINED() INS_CONST(0) #define INS_UNDEFINED() INS_CONST(0)
#define INS_MAGIC_WHY(why) INS_CONSTWORD((size_t)why)
#define INS_MAGIC_NULL() INS_NULL()
static const size_t sPayloadOffset = offsetof(jsval_layout, s.payload); static const size_t sPayloadOffset = offsetof(jsval_layout, s.payload);
#if JS_BITS_PER_WORD == 32 #if JS_BITS_PER_WORD == 32
@ -4283,7 +4285,6 @@ TraceRecorder::snapshot(ExitType exitType)
exit->imacpc = fp->maybeIMacroPC(); exit->imacpc = fp->maybeIMacroPC();
exit->sp_adj = (stackSlots * sizeof(double)) - tree->nativeStackBase; exit->sp_adj = (stackSlots * sizeof(double)) - tree->nativeStackBase;
exit->rp_adj = exit->calldepth * sizeof(FrameInfo*); exit->rp_adj = exit->calldepth * sizeof(FrameInfo*);
exit->nativeCalleeWord = 0;
exit->lookupFlags = js_InferFlags(cx, 0); exit->lookupFlags = js_InferFlags(cx, 0);
memcpy(exit->fullTypeMap(), typemap, typemap_size); memcpy(exit->fullTypeMap(), typemap, typemap_size);
@ -5729,46 +5730,6 @@ SynthesizeFrame(JSContext* cx, const FrameInfo& fi, JSObject* callee)
newscript->nfixed + SPECIAL_FRAME_SLOTS; newscript->nfixed + SPECIAL_FRAME_SLOTS;
} }
JS_REQUIRES_STACK static void
SynthesizeSlowNativeFrame(TracerState& state, JSContext *cx, VMSideExit *exit)
{
/*
* StackSpace::getInlineFrame calls js_ReportOutOfScriptQuota if there is
* no space (which will try to deep bail, which is bad), however we already
* check on entry to ExecuteTree that there is enough space.
*/
StackSegment *seg;
JSStackFrame *fp;
cx->stack().getSynthesizedSlowNativeFrame(cx, seg, fp);
#ifdef DEBUG
JSObject *callee = &state.nativeVp[0].toObject();
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, callee);
JS_ASSERT(!fun->isInterpreted() && !fun->isFastNative());
JS_ASSERT(fun->u.n.extra == 0);
#endif
fp->setCallObj(NULL);
fp->setArgsObj(NULL);
fp->setScript(NULL);
fp->setThisValue(state.nativeVp[1]);
fp->setNumActualArgs(state.nativeVpLen - 2);
fp->argv = state.nativeVp + 2;
fp->setFunction(GET_FUNCTION_PRIVATE(cx, fp->callee()));
fp->clearReturnValue();
fp->setAnnotation(NULL);
fp->setScopeChain(cx->fp()->getScopeChain());
fp->setBlockChain(NULL);
fp->flags = exit->constructing() ? JSFRAME_CONSTRUCTING : 0;
JS_ASSERT(!fp->hasIMacroPC());
state.bailedSlowNativeRegs.fp = fp;
state.bailedSlowNativeRegs.pc = NULL;
state.bailedSlowNativeRegs.sp = fp->slots();
cx->stack().pushSynthesizedSlowNativeFrame(cx, seg, state.bailedSlowNativeRegs);
}
static JS_REQUIRES_STACK bool static JS_REQUIRES_STACK bool
RecordTree(JSContext* cx, TreeFragment* first, jsbytecode* outer, RecordTree(JSContext* cx, TreeFragment* first, jsbytecode* outer,
uint32 outerArgc, SlotList* globalSlots) uint32 outerArgc, SlotList* globalSlots)
@ -6770,15 +6731,7 @@ LeaveTree(TraceMonitor *tm, TracerState& state, VMSideExit* lr)
* A _FAIL native already called LeaveTree. We already reconstructed * A _FAIL native already called LeaveTree. We already reconstructed
* the interpreter stack, in pre-call state, with pc pointing to the * the interpreter stack, in pre-call state, with pc pointing to the
* CALL/APPLY op, for correctness. Then we continued in native code. * CALL/APPLY op, for correctness. Then we continued in native code.
*
* First, if we just returned from a slow native, pop its stack frame.
*/ */
if (!cx->fp()->hasScript()) {
JS_ASSERT(cx->regs == &state.bailedSlowNativeRegs);
cx->stack().popSynthesizedSlowNativeFrame(cx);
}
JS_ASSERT(cx->fp()->hasScript());
if (!(bs & (BUILTIN_ERROR | BUILTIN_NO_FIXUP_NEEDED))) { if (!(bs & (BUILTIN_ERROR | BUILTIN_NO_FIXUP_NEEDED))) {
/* /*
* The builtin or native deep-bailed but finished successfully * The builtin or native deep-bailed but finished successfully
@ -7000,9 +6953,6 @@ LeaveTree(TraceMonitor *tm, TracerState& state, VMSideExit* lr)
stack, NULL); stack, NULL);
JS_ASSERT(unsigned(slots) == innermost->numStackSlots); JS_ASSERT(unsigned(slots) == innermost->numStackSlots);
if (innermost->nativeCalleeWord)
SynthesizeSlowNativeFrame(state, cx, innermost);
/* Write back interned globals. */ /* Write back interned globals. */
JS_ASSERT(state.eos == state.stackBase + MAX_NATIVE_STACK_SLOTS); JS_ASSERT(state.eos == state.stackBase + MAX_NATIVE_STACK_SLOTS);
JSObject* globalObj = outermostTree->globalObj; JSObject* globalObj = outermostTree->globalObj;
@ -9793,7 +9743,7 @@ TraceRecorder::unbox_non_double_object(LIns* v_ins, JSValueType type, VMSideExit
unboxed_ins = INS_UNDEFINED(); unboxed_ins = INS_UNDEFINED();
} else if (type == JSVAL_TYPE_NULL) { } else if (type == JSVAL_TYPE_NULL) {
unboxed_ins = INS_NULL(); unboxed_ins = INS_NULL();
} else if (type >= JSVAL_LOWER_INCL_TYPE_OF_GCTHING_SET) { } else if (type >= JSVAL_LOWER_INCL_TYPE_OF_PTR_PAYLOAD_SET) {
unboxed_ins = unpack_ptr(v_ins); unboxed_ins = unpack_ptr(v_ins);
} else { } else {
JS_ASSERT(type == JSVAL_TYPE_INT32 || type == JSVAL_TYPE_BOOLEAN || type == JSVAL_TYPE_MAGIC); JS_ASSERT(type == JSVAL_TYPE_INT32 || type == JSVAL_TYPE_BOOLEAN || type == JSVAL_TYPE_MAGIC);
@ -9889,7 +9839,7 @@ TraceRecorder::box_value_for_native_call(const Value &v, LIns *v_ins)
uint64 shiftedTag = ((uint64)tag) << JSVAL_TAG_SHIFT; uint64 shiftedTag = ((uint64)tag) << JSVAL_TAG_SHIFT;
LIns *shiftedTag_ins = INS_CONSTQWORD(shiftedTag); LIns *shiftedTag_ins = INS_CONSTQWORD(shiftedTag);
if (v.isGCThing()) if (v.hasPtrPayload())
return lir->ins2(LIR_orq, v_ins, shiftedTag_ins); return lir->ins2(LIR_orq, v_ins, shiftedTag_ins);
return lir->ins2(LIR_orq, lir->ins1(LIR_ui2uq, v_ins), shiftedTag_ins); return lir->ins2(LIR_orq, lir->ins1(LIR_ui2uq, v_ins), shiftedTag_ins);
} }
@ -11010,22 +10960,13 @@ TraceRecorder::emitNativePropertyOp(const Shape* shape, LIns* obj_ins,
JS_REQUIRES_STACK RecordingStatus JS_REQUIRES_STACK RecordingStatus
TraceRecorder::emitNativeCall(JSSpecializedNative* sn, uintN argc, LIns* args[], bool rooted) TraceRecorder::emitNativeCall(JSSpecializedNative* sn, uintN argc, LIns* args[], bool rooted)
{ {
bool constructing = !!(sn->flags & JSTN_CONSTRUCTOR);
if (JSTN_ERRTYPE(sn) == FAIL_STATUS) { if (JSTN_ERRTYPE(sn) == FAIL_STATUS) {
// This needs to capture the pre-call state of the stack. So do not set // This needs to capture the pre-call state of the stack. So do not set
// pendingSpecializedNative before taking this snapshot. // pendingSpecializedNative before taking this snapshot.
JS_ASSERT(!pendingSpecializedNative); JS_ASSERT(!pendingSpecializedNative);
// Take snapshot for DeepBail and store it in cx->bailExit. // Take snapshot for DeepBail and store it in cx->bailExit.
// If we are calling a slow native, add information to the side exit enterDeepBailCall();
// for SynthesizeSlowNativeFrame.
VMSideExit* exit = enterDeepBailCall();
JSObject* funobj = &stackval(0 - (2 + argc)).toObject();
if (FUN_SLOW_NATIVE(GET_FUNCTION_PRIVATE(cx, funobj))) {
exit->setNativeCallee(funobj, constructing);
tree->gcthings.addUnique(ObjectValue(*funobj));
}
} }
LIns* res_ins = lir->insCall(sn->builtin, args); LIns* res_ins = lir->insCall(sn->builtin, args);
@ -11184,7 +11125,7 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
Value* vp = &stackval(0 - (2 + argc)); Value* vp = &stackval(0 - (2 + argc));
JSObject* funobj = &vp[0].toObject(); JSObject* funobj = &vp[0].toObject();
JSFunction* fun = GET_FUNCTION_PRIVATE(cx, funobj); JSFunction* fun = GET_FUNCTION_PRIVATE(cx, funobj);
FastNative native = (FastNative)fun->u.n.native; Native native = fun->u.n.native;
switch (argc) { switch (argc) {
case 1: case 1:
@ -11199,13 +11140,13 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
} }
if (vp[1].isString()) { if (vp[1].isString()) {
JSString *str = vp[1].toString(); JSString *str = vp[1].toString();
if (native == (FastNative)js_str_charAt) { if (native == js_str_charAt) {
LIns* str_ins = get(&vp[1]); LIns* str_ins = get(&vp[1]);
LIns* idx_ins = get(&vp[2]); LIns* idx_ins = get(&vp[2]);
set(&vp[0], getCharAt(str, str_ins, idx_ins, mode)); set(&vp[0], getCharAt(str, str_ins, idx_ins, mode));
pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK; pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK;
return RECORD_CONTINUE; return RECORD_CONTINUE;
} else if (native == (FastNative)js_str_charCodeAt) { } else if (native == js_str_charCodeAt) {
jsdouble i = vp[2].toNumber(); jsdouble i = vp[2].toNumber();
if (i < 0 || i >= str->length()) if (i < 0 || i >= str->length())
RETURN_STOP("charCodeAt out of bounds"); RETURN_STOP("charCodeAt out of bounds");
@ -11242,7 +11183,7 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
if (fun->flags & JSFUN_TRCINFO) { if (fun->flags & JSFUN_TRCINFO) {
JSNativeTraceInfo *trcinfo = FUN_TRCINFO(fun); JSNativeTraceInfo *trcinfo = FUN_TRCINFO(fun);
JS_ASSERT(trcinfo && (JSFastNative)fun->u.n.native == trcinfo->native); JS_ASSERT(trcinfo && fun->u.n.native == trcinfo->native);
/* Try to call a type specialized version of the native. */ /* Try to call a type specialized version of the native. */
if (trcinfo->specializations) { if (trcinfo->specializations) {
@ -11255,13 +11196,8 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
if (native == js_fun_apply || native == js_fun_call) if (native == js_fun_apply || native == js_fun_call)
RETURN_STOP("trying to call native apply or call"); RETURN_STOP("trying to call native apply or call");
if (fun->u.n.extra > 0)
RETURN_STOP("trying to trace slow native with fun->u.n.extra > 0");
// Allocate the vp vector and emit code to root it. // Allocate the vp vector and emit code to root it.
uintN vplen = 2 + JS_MAX(argc, unsigned(FUN_MINARGS(fun))); uintN vplen = 2 + argc;
if (!(fun->flags & JSFUN_FAST_NATIVE))
vplen++; // slow native return value slot
LIns* invokevp_ins = lir->insAlloc(vplen * sizeof(Value)); LIns* invokevp_ins = lir->insAlloc(vplen * sizeof(Value));
// vp[0] is the callee. // vp[0] is the callee.
@ -11285,9 +11221,9 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
if (!clasp->isNative()) if (!clasp->isNative())
RETURN_STOP("new with non-native ops"); RETURN_STOP("new with non-native ops");
if (fun->isFastConstructor()) { if (fun->isConstructor()) {
vp[1].setMagic(JS_FAST_CONSTRUCTOR); vp[1].setMagicWithObjectOrNullPayload(NULL);
newobj_ins = INS_CONST(JS_FAST_CONSTRUCTOR); newobj_ins = INS_MAGIC_NULL();
/* Treat this as a regular call, the constructor will behave correctly. */ /* Treat this as a regular call, the constructor will behave correctly. */
mode = JSOP_CALL; mode = JSOP_CALL;
@ -11295,7 +11231,7 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
args[0] = INS_CONSTOBJ(funobj); args[0] = INS_CONSTOBJ(funobj);
args[1] = INS_CONSTPTR(clasp); args[1] = INS_CONSTPTR(clasp);
args[2] = cx_ins; args[2] = cx_ins;
newobj_ins = lir->insCall(&js_NewInstance_ci, args); newobj_ins = lir->insCall(&js_NewInstanceFromTrace_ci, args);
guard(false, lir->insEqP_0(newobj_ins), OOM_EXIT); guard(false, lir->insEqP_0(newobj_ins), OOM_EXIT);
/* /*
@ -11312,31 +11248,6 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
this_ins = newobj_ins; this_ins = newobj_ins;
} else { } else {
this_ins = get(&vp[1]); this_ins = get(&vp[1]);
/*
* For fast natives, 'null' or primitives are fine as as 'this' value.
* For slow natives we have to ensure the object is substituted for the
* appropriate global object or boxed object value. JSOP_NEW allocates its
* own object so it's guaranteed to have a valid 'this' value.
*/
if (!(fun->flags & JSFUN_FAST_NATIVE)) {
if (vp[1].isNull()) {
JSObject* thisObj = ComputeThisFromVp(cx, vp);
if (!thisObj)
RETURN_ERROR("error in js_ComputeGlobalThis");
this_ins = INS_CONSTOBJ(thisObj);
} else if (!vp[1].isObject()) {
RETURN_STOP("slow native(primitive, args)");
} else {
if (vp[1].toObject().hasClass(&js_WithClass))
RETURN_STOP("can't trace slow native invocation on With object");
guardNotClass(this_ins, &js_WithClass, snapshot(MISMATCH_EXIT), LOAD_CONST);
this_ins = lir->insChoose(lir->insEqP_0(stobj_get_parent(this_ins)),
INS_CONSTOBJ(globalObj),
this_ins, avmplus::AvmCore::use_cmov());
}
}
} }
set(&vp[1], this_ins); set(&vp[1], this_ins);
box_value_into(vp[1], this_ins, invokevp_ins, 1 * sizeof(Value), ACCSET_OTHER); box_value_into(vp[1], this_ins, invokevp_ins, 1 * sizeof(Value), ACCSET_OTHER);
@ -11360,26 +11271,13 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
} }
// Set up arguments for the JSNative or JSFastNative. // Set up arguments for the JSNative or JSFastNative.
uint32 typesig; if (mode == JSOP_NEW)
if (fun->flags & JSFUN_FAST_NATIVE) { RETURN_STOP("untraceable fast native constructor");
if (mode == JSOP_NEW && !(fun->flags & JSFUN_FAST_NATIVE_CTOR)) native_rval_ins = invokevp_ins;
RETURN_STOP("untraceable fast native constructor"); args[0] = invokevp_ins;
native_rval_ins = invokevp_ins; args[1] = lir->insImmI(argc);
args[0] = invokevp_ins; args[2] = cx_ins;
args[1] = lir->insImmI(argc); uint32 typesig = CallInfo::typeSig3(ARGTYPE_I, ARGTYPE_P, ARGTYPE_I, ARGTYPE_P);
args[2] = cx_ins;
typesig = CallInfo::typeSig3(ARGTYPE_I, ARGTYPE_P, ARGTYPE_I, ARGTYPE_P);
} else {
int32_t offset = (vplen - 1) * sizeof(Value);
native_rval_ins = lir->ins2(LIR_addp, invokevp_ins, INS_CONSTWORD(offset));
args[0] = native_rval_ins;
args[1] = lir->ins2(LIR_addp, invokevp_ins, INS_CONSTWORD(2 * sizeof(Value)));
args[2] = lir->insImmI(argc);
args[3] = this_ins;
args[4] = cx_ins;
typesig = CallInfo::typeSig5(ARGTYPE_I,
ARGTYPE_P, ARGTYPE_P, ARGTYPE_I, ARGTYPE_P, ARGTYPE_P);
}
// Generate CallInfo and a JSSpecializedNative structure on the fly. // Generate CallInfo and a JSSpecializedNative structure on the fly.
// Do not use JSTN_UNBOX_AFTER for mode JSOP_NEW because // Do not use JSTN_UNBOX_AFTER for mode JSOP_NEW because
@ -11461,14 +11359,14 @@ TraceRecorder::functionCall(uintN argc, JSOp mode)
if (FUN_INTERPRETED(fun)) { if (FUN_INTERPRETED(fun)) {
if (mode == JSOP_NEW) { if (mode == JSOP_NEW) {
LIns* args[] = { get(&fval), INS_CONSTPTR(&js_ObjectClass), cx_ins }; LIns* args[] = { get(&fval), INS_CONSTPTR(&js_ObjectClass), cx_ins };
LIns* tv_ins = lir->insCall(&js_NewInstance_ci, args); LIns* tv_ins = lir->insCall(&js_NewInstanceFromTrace_ci, args);
guard(false, lir->insEqP_0(tv_ins), OOM_EXIT); guard(false, lir->insEqP_0(tv_ins), OOM_EXIT);
set(&tval, tv_ins); set(&tval, tv_ins);
} }
return interpretedFunctionCall(fval, fun, argc, mode == JSOP_NEW); return interpretedFunctionCall(fval, fun, argc, mode == JSOP_NEW);
} }
FastNative native = FUN_FAST_NATIVE(fun); Native native = fun->maybeNative();
Value* argv = &tval + 1; Value* argv = &tval + 1;
if (native == js_Array) if (native == js_Array)
return newArray(&fval.toObject(), argc, argv, &fval); return newArray(&fval.toObject(), argc, argv, &fval);
@ -13319,8 +13217,8 @@ TraceRecorder::record_JSOP_APPLY()
if (FUN_INTERPRETED(fun)) if (FUN_INTERPRETED(fun))
return record_JSOP_CALL(); return record_JSOP_CALL();
bool apply = (FastNative)fun->u.n.native == js_fun_apply; bool apply = fun->u.n.native == js_fun_apply;
if (!apply && (FastNative)fun->u.n.native != js_fun_call) if (!apply && fun->u.n.native != js_fun_call)
return record_JSOP_CALL(); return record_JSOP_CALL();
/* /*
@ -14348,8 +14246,8 @@ TraceRecorder::record_JSOP_ENDITER()
JS_REQUIRES_STACK void JS_REQUIRES_STACK void
TraceRecorder::storeMagic(JSWhyMagic why, nanojit::LIns *addr_ins, ptrdiff_t offset, AccSet accSet) TraceRecorder::storeMagic(JSWhyMagic why, nanojit::LIns *addr_ins, ptrdiff_t offset, AccSet accSet)
{ {
lir->insStore(INS_CONSTU(why), addr_ins, offset + sPayloadOffset, accSet); lir->insStore(INS_MAGIC_WHY(why), addr_ins, offset + sPayloadOffset, accSet);
lir->insStore(INS_CONSTU(JSVAL_TAG_MAGIC), addr_ins, offset + sTagOffset, accSet); lir->insStore(INS_MAGIC_WHY(JSVAL_TAG_MAGIC), addr_ins, offset + sTagOffset, accSet);
} }
#elif JS_BITS_PER_WORD == 64 #elif JS_BITS_PER_WORD == 64
JS_REQUIRES_STACK void JS_REQUIRES_STACK void
@ -14956,11 +14854,11 @@ TraceRecorder::record_JSOP_LAMBDA()
JSObject *callee; JSObject *callee;
if (IsFunctionObject(cref, &callee)) { if (IsFunctionObject(cref, &callee)) {
JSFunction *calleeFun = GET_FUNCTION_PRIVATE(cx, callee); JSFunction *calleeFun = callee->getFunctionPrivate();
FastNative fastNative = FUN_FAST_NATIVE(calleeFun); Native native = calleeFun->maybeNative();
if ((iargc == 1 && fastNative == array_sort) || if ((iargc == 1 && native == array_sort) ||
(iargc == 2 && fastNative == str_replace)) { (iargc == 2 && native == str_replace)) {
stack(0, INS_CONSTOBJ(FUN_OBJECT(fun))); stack(0, INS_CONSTOBJ(FUN_OBJECT(fun)));
return ARECORD_CONTINUE; return ARECORD_CONTINUE;
} }
@ -15862,7 +15760,7 @@ TraceRecorder::record_JSOP_NEWARRAY()
JS_REQUIRES_STACK AbortableRecordingStatus JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_HOLE() TraceRecorder::record_JSOP_HOLE()
{ {
stack(0, INS_CONST(JS_ARRAY_HOLE)); stack(0, INS_MAGIC_WHY(JS_ARRAY_HOLE));
return ARECORD_CONTINUE; return ARECORD_CONTINUE;
} }

Просмотреть файл

@ -414,24 +414,6 @@ struct VMSideExit : public nanojit::SideExit
uintN lookupFlags; uintN lookupFlags;
unsigned hitcount; unsigned hitcount;
/*
* Ordinarily 0. If a slow native function is atop the stack, the 1 bit is
* set if constructing and the other bits are a pointer to the funobj.
*/
uintptr_t nativeCalleeWord;
JSObject * nativeCallee() {
return (JSObject *) (nativeCalleeWord & ~1);
}
bool constructing() {
return bool(nativeCalleeWord & 1);
}
void setNativeCallee(JSObject *callee, bool constructing) {
nativeCalleeWord = uintptr_t(callee) | (constructing ? 1 : 0);
}
inline JSValueType* stackTypeMap() { inline JSValueType* stackTypeMap() {
return (JSValueType*)(this + 1); return (JSValueType*)(this + 1);
} }

Просмотреть файл

@ -102,29 +102,19 @@ ArrayBuffer::class_finalize(JSContext *cx, JSObject *obj)
* new ArrayBuffer(byteLength) * new ArrayBuffer(byteLength)
*/ */
JSBool JSBool
ArrayBuffer::class_constructor(JSContext *cx, JSObject *obj, ArrayBuffer::class_constructor(JSContext *cx, uintN argc, Value *vp)
uintN argc, Value *argv, Value *rval)
{ {
if (!JS_IsConstructing(cx)) { return create(cx, argc, JS_ARGV(cx, vp), vp);
obj = NewBuiltinClassInstance(cx, &ArrayBuffer::jsclass);
if (!obj)
return false;
rval->setObject(*obj);
}
return create(cx, obj, argc, argv, rval);
} }
bool bool
ArrayBuffer::create(JSContext *cx, JSObject *obj, ArrayBuffer::create(JSContext *cx, uintN argc, Value *argv, Value *rval)
uintN argc, Value *argv, Value *rval)
{ {
if (!obj) { /* N.B. there may not be an argv[-2]/argv[-1]. */
obj = NewBuiltinClassInstance(cx, &ArrayBuffer::jsclass);
if (!obj) JSObject *obj = NewBuiltinClassInstance(cx, &ArrayBuffer::jsclass);
return false; if (!obj)
rval->setObject(*obj); return false;
}
int32_t nbytes = 0; int32_t nbytes = 0;
if (argc > 0) { if (argc > 0) {
@ -155,6 +145,7 @@ ArrayBuffer::create(JSContext *cx, JSObject *obj,
} }
obj->setPrivate(abuf); obj->setPrivate(abuf);
rval->setObject(*obj);
return true; return true;
} }
@ -713,32 +704,20 @@ class TypedArrayTemplate
* new [Type]Array(ArrayBuffer, [optional] byteOffset, [optional] length) * new [Type]Array(ArrayBuffer, [optional] byteOffset, [optional] length)
*/ */
static JSBool static JSBool
class_constructor(JSContext *cx, JSObject *obj, class_constructor(JSContext *cx, uintN argc, Value *vp)
uintN argc, Value *argv, Value *rval)
{ {
// /* N.B. this is a constructor for slowClass, not fastClass! */
// Note: this is a constructor for slowClass, not fastClass! return create(cx, argc, JS_ARGV(cx, vp), vp);
//
if (!JS_IsConstructing(cx)) {
obj = NewBuiltinClassInstance(cx, slowClass());
if (!obj)
return false;
rval->setObject(*obj);
}
return create(cx, obj, argc, argv, rval);
} }
static bool static JSBool
create(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) create(JSContext *cx, uintN argc, Value *argv, Value *rval)
{ {
if (!obj) { /* N.B. there may not be an argv[-2]/argv[-1]. */
obj = NewBuiltinClassInstance(cx, slowClass());
if (!obj) JSObject *obj = NewBuiltinClassInstance(cx, slowClass());
return false; if (!obj)
rval->setObject(*obj); return false;
}
ThisTypeArray *tarray = 0; ThisTypeArray *tarray = 0;
@ -807,6 +786,7 @@ class TypedArrayTemplate
} }
makeFastWithPrivate(cx, obj, tarray); makeFastWithPrivate(cx, obj, tarray);
rval->setObject(*obj);
return true; return true;
} }
@ -1341,12 +1321,11 @@ class TypedArrayTemplate
bool bool
createBufferWithByteLength(JSContext *cx, int32 bytes) createBufferWithByteLength(JSContext *cx, int32 bytes)
{ {
Value argv = Int32Value(bytes); Value arg = Int32Value(bytes), rval;
AutoValueRooter tvr(cx); if (!ArrayBuffer::create(cx, 1, &arg, &rval))
if (!ArrayBuffer::create(cx, NULL, 1, &argv, tvr.addr()))
return false; return false;
JSObject *obj = &tvr.value().toObject(); JSObject *obj = &rval.toObject();
bufferJS = obj; bufferJS = obj;
buffer = ArrayBuffer::fromJSObject(obj); buffer = ArrayBuffer::fromJSObject(obj);
@ -1636,15 +1615,10 @@ js_IsTypedArray(JSObject *obj)
JS_FRIEND_API(JSObject *) JS_FRIEND_API(JSObject *)
js_CreateArrayBuffer(JSContext *cx, jsuint nbytes) js_CreateArrayBuffer(JSContext *cx, jsuint nbytes)
{ {
Value vals[2]; Value arg = NumberValue(nbytes), rval;
vals[0].setNumber(nbytes); if (!ArrayBuffer::create(cx, 1, &arg, &rval))
vals[1].setUndefined();
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(vals), vals);
if (!ArrayBuffer::create(cx, NULL, 1, &vals[0], &vals[1]))
return NULL; return NULL;
return &rval.toObject();
return &vals[1].toObject();
} }
static inline JSBool static inline JSBool
@ -1652,31 +1626,31 @@ TypedArrayConstruct(JSContext *cx, jsint atype, uintN argc, Value *argv, Value *
{ {
switch (atype) { switch (atype) {
case TypedArray::TYPE_INT8: case TypedArray::TYPE_INT8:
return !!Int8Array::create(cx, NULL, argc, argv, rv); return Int8Array::create(cx, argc, argv, rv);
case TypedArray::TYPE_UINT8: case TypedArray::TYPE_UINT8:
return !!Uint8Array::create(cx, NULL, argc, argv, rv); return Uint8Array::create(cx, argc, argv, rv);
case TypedArray::TYPE_INT16: case TypedArray::TYPE_INT16:
return !!Int16Array::create(cx, NULL, argc, argv, rv); return Int16Array::create(cx, argc, argv, rv);
case TypedArray::TYPE_UINT16: case TypedArray::TYPE_UINT16:
return !!Uint16Array::create(cx, NULL, argc, argv, rv); return Uint16Array::create(cx, argc, argv, rv);
case TypedArray::TYPE_INT32: case TypedArray::TYPE_INT32:
return !!Int32Array::create(cx, NULL, argc, argv, rv); return Int32Array::create(cx, argc, argv, rv);
case TypedArray::TYPE_UINT32: case TypedArray::TYPE_UINT32:
return !!Uint32Array::create(cx, NULL, argc, argv, rv); return Uint32Array::create(cx, argc, argv, rv);
case TypedArray::TYPE_FLOAT32: case TypedArray::TYPE_FLOAT32:
return !!Float32Array::create(cx, NULL, argc, argv, rv); return Float32Array::create(cx, argc, argv, rv);
case TypedArray::TYPE_FLOAT64: case TypedArray::TYPE_FLOAT64:
return !!Float64Array::create(cx, NULL, argc, argv, rv); return Float64Array::create(cx, argc, argv, rv);
case TypedArray::TYPE_UINT8_CLAMPED: case TypedArray::TYPE_UINT8_CLAMPED:
return !!Uint8ClampedArray::create(cx, NULL, argc, argv, rv); return Uint8ClampedArray::create(cx, argc, argv, rv);
default: default:
JS_NOT_REACHED("shouldn't have gotten here"); JS_NOT_REACHED("shouldn't have gotten here");

Просмотреть файл

@ -62,11 +62,9 @@ struct JS_FRIEND_API(ArrayBuffer) {
static JSBool prop_getByteLength(JSContext *cx, JSObject *obj, jsid id, Value *vp); static JSBool prop_getByteLength(JSContext *cx, JSObject *obj, jsid id, Value *vp);
static void class_finalize(JSContext *cx, JSObject *obj); static void class_finalize(JSContext *cx, JSObject *obj);
static JSBool class_constructor(JSContext *cx, JSObject *obj, uintN argc, Value *argv, static JSBool class_constructor(JSContext *cx, uintN argc, Value *vp);
Value *rval);
static bool create(JSContext *cx, JSObject *obj, uintN argc, static bool create(JSContext *cx, uintN argc, Value *argv, Value *rval);
Value *argv, Value *rval);
static ArrayBuffer *fromJSObject(JSObject *obj); static ArrayBuffer *fromJSObject(JSObject *obj);

Просмотреть файл

@ -222,7 +222,7 @@ typedef uint64 JSValueShiftedTag;
#define JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET JSVAL_TYPE_NULL #define JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET JSVAL_TYPE_NULL
#define JSVAL_UPPER_EXCL_TYPE_OF_PRIMITIVE_SET JSVAL_TYPE_OBJECT #define JSVAL_UPPER_EXCL_TYPE_OF_PRIMITIVE_SET JSVAL_TYPE_OBJECT
#define JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET JSVAL_TYPE_INT32 #define JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET JSVAL_TYPE_INT32
#define JSVAL_LOWER_INCL_TYPE_OF_GCTHING_SET JSVAL_TYPE_STRING #define JSVAL_LOWER_INCL_TYPE_OF_PTR_PAYLOAD_SET JSVAL_TYPE_MAGIC
#define JSVAL_UPPER_INCL_TYPE_OF_VALUE_SET JSVAL_TYPE_OBJECT #define JSVAL_UPPER_INCL_TYPE_OF_VALUE_SET JSVAL_TYPE_OBJECT
#define JSVAL_UPPER_INCL_TYPE_OF_BOXABLE_SET JSVAL_TYPE_FUNOBJ #define JSVAL_UPPER_INCL_TYPE_OF_BOXABLE_SET JSVAL_TYPE_FUNOBJ
@ -245,6 +245,7 @@ typedef uint64 JSValueShiftedTag;
#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL #define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL
#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT #define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT
#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED #define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED
#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_PTR_PAYLOAD_SET JSVAL_SHIFTED_TAG_MAGIC
#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET JSVAL_SHIFTED_TAG_STRING #define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET JSVAL_SHIFTED_TAG_STRING
#endif /* JS_BITS_PER_WORD */ #endif /* JS_BITS_PER_WORD */
@ -258,7 +259,6 @@ typedef enum JSWhyMagic
* enumerated like a native object. */ * enumerated like a native object. */
JS_NO_ITER_VALUE, /* there is not a pending iterator value */ JS_NO_ITER_VALUE, /* there is not a pending iterator value */
JS_GENERATOR_CLOSING, /* exception value thrown when closing a generator */ JS_GENERATOR_CLOSING, /* exception value thrown when closing a generator */
JS_FAST_CONSTRUCTOR, /* 'this' value for fast natives invoked with 'new' */
JS_NO_CONSTANT, /* compiler sentinel value */ JS_NO_CONSTANT, /* compiler sentinel value */
JS_THIS_POISON, /* used in debug builds to catch tracing errors */ JS_THIS_POISON, /* used in debug builds to catch tracing errors */
JS_SERIALIZE_NO_NODE, /* an empty subnode in the AST serializer */ JS_SERIALIZE_NO_NODE, /* an empty subnode in the AST serializer */
@ -433,6 +433,19 @@ BOOLEAN_TO_JSVAL_IMPL(JSBool b)
return l; return l;
} }
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_MAGIC_IMPL(jsval_layout l)
{
return l.s.tag == JSVAL_TAG_MAGIC;
}
static JS_ALWAYS_INLINE JSObject *
MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(jsval_layout l)
{
JS_ASSERT(JSVAL_IS_MAGIC_IMPL(l));
return l.s.payload.obj;
}
static JS_ALWAYS_INLINE JSBool static JS_ALWAYS_INLINE JSBool
JSVAL_IS_OBJECT_IMPL(jsval_layout l) JSVAL_IS_OBJECT_IMPL(jsval_layout l)
{ {
@ -462,6 +475,7 @@ static JS_ALWAYS_INLINE jsval_layout
OBJECT_TO_JSVAL_IMPL(JSObject *obj) OBJECT_TO_JSVAL_IMPL(JSObject *obj)
{ {
jsval_layout l; jsval_layout l;
JS_ASSERT(obj);
l.s.tag = JSVAL_TAG_OBJECT; l.s.tag = JSVAL_TAG_OBJECT;
l.s.payload.obj = obj; l.s.payload.obj = obj;
return l; return l;
@ -609,6 +623,21 @@ BOOLEAN_TO_JSVAL_IMPL(JSBool b)
return l; return l;
} }
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_MAGIC_IMPL(jsval_layout l)
{
return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_MAGIC;
}
static JS_ALWAYS_INLINE JSObject *
MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(jsval_layout l)
{
JS_ASSERT(JSVAL_IS_MAGIC_IMPL(l));
uint64 ptrBits = l.asBits & JSVAL_PAYLOAD_MASK;
JS_ASSERT((ptrBits >> JSVAL_TAG_SHIFT) == 0);
return (JSObject *)ptrBits;
}
static JS_ALWAYS_INLINE JSBool static JS_ALWAYS_INLINE JSBool
JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l) JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
{ {
@ -641,6 +670,7 @@ static JS_ALWAYS_INLINE jsval_layout
OBJECT_TO_JSVAL_IMPL(JSObject *obj) OBJECT_TO_JSVAL_IMPL(JSObject *obj)
{ {
jsval_layout l; jsval_layout l;
JS_ASSERT(obj);
uint64 objBits = (uint64)obj; uint64 objBits = (uint64)obj;
JS_ASSERT((objBits >> JSVAL_TAG_SHIFT) == 0); JS_ASSERT((objBits >> JSVAL_TAG_SHIFT) == 0);
l.asBits = objBits | JSVAL_SHIFTED_TAG_OBJECT; l.asBits = objBits | JSVAL_SHIFTED_TAG_OBJECT;

Просмотреть файл

@ -135,12 +135,6 @@ JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b)
return (l.s.tag == JSVAL_TAG_BOOLEAN) && (l.s.payload.boo == b); return (l.s.tag == JSVAL_TAG_BOOLEAN) && (l.s.payload.boo == b);
} }
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_MAGIC_IMPL(jsval_layout l)
{
return l.s.tag == JSVAL_TAG_MAGIC;
}
static JS_ALWAYS_INLINE jsval_layout static JS_ALWAYS_INLINE jsval_layout
MAGIC_TO_JSVAL_IMPL(JSWhyMagic why) MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
{ {
@ -150,6 +144,15 @@ MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
return l; return l;
} }
static JS_ALWAYS_INLINE jsval_layout
MAGIC_TO_JSVAL_IMPL(JSObject *obj)
{
jsval_layout l;
l.s.tag = JSVAL_TAG_MAGIC;
l.s.payload.obj = obj;
return l;
}
static JS_ALWAYS_INLINE JSBool static JS_ALWAYS_INLINE JSBool
JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs) JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs)
{ {
@ -225,12 +228,6 @@ JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b)
return l.asBits == (((uint64)(uint32)b) | JSVAL_SHIFTED_TAG_BOOLEAN); return l.asBits == (((uint64)(uint32)b) | JSVAL_SHIFTED_TAG_BOOLEAN);
} }
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_MAGIC_IMPL(jsval_layout l)
{
return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_MAGIC;
}
static JS_ALWAYS_INLINE jsval_layout static JS_ALWAYS_INLINE jsval_layout
MAGIC_TO_JSVAL_IMPL(JSWhyMagic why) MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
{ {
@ -239,6 +236,14 @@ MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
return l; return l;
} }
static JS_ALWAYS_INLINE jsval_layout
MAGIC_TO_JSVAL_IMPL(JSObject *obj)
{
jsval_layout l;
l.asBits = ((uint64)obj) | JSVAL_SHIFTED_TAG_MAGIC;
return l;
}
static JS_ALWAYS_INLINE JSBool static JS_ALWAYS_INLINE JSBool
JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs) JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs)
{ {
@ -291,7 +296,7 @@ BOX_NON_DOUBLE_JSVAL(JSValueType type, uint64 *slot)
/* N.B. for 32-bit payloads, the high 32 bits of the slot are trash. */ /* N.B. for 32-bit payloads, the high 32 bits of the slot are trash. */
jsval_layout l; jsval_layout l;
JS_ASSERT(type > JSVAL_TYPE_DOUBLE && type <= JSVAL_UPPER_INCL_TYPE_OF_BOXABLE_SET); JS_ASSERT(type > JSVAL_TYPE_DOUBLE && type <= JSVAL_UPPER_INCL_TYPE_OF_BOXABLE_SET);
uint32 isI32 = (uint32)(type < JSVAL_LOWER_INCL_TYPE_OF_GCTHING_SET); uint32 isI32 = (uint32)(type < JSVAL_LOWER_INCL_TYPE_OF_PTR_PAYLOAD_SET);
uint32 shift = isI32 * 32; uint32 shift = isI32 * 32;
uint64 mask = ((uint64)-1) >> shift; uint64 mask = ((uint64)-1) >> shift;
uint64 payload = *slot & mask; uint64 payload = *slot & mask;
@ -322,49 +327,69 @@ class Value
/*** Mutatators ***/ /*** Mutatators ***/
JS_ALWAYS_INLINE
void setNull() { void setNull() {
data.asBits = JSVAL_BITS(JSVAL_NULL); data.asBits = JSVAL_BITS(JSVAL_NULL);
} }
JS_ALWAYS_INLINE
void setUndefined() { void setUndefined() {
data.asBits = JSVAL_BITS(JSVAL_VOID); data.asBits = JSVAL_BITS(JSVAL_VOID);
} }
JS_ALWAYS_INLINE
void setInt32(int32 i) { void setInt32(int32 i) {
data = INT32_TO_JSVAL_IMPL(i); data = INT32_TO_JSVAL_IMPL(i);
} }
JS_ALWAYS_INLINE
int32 &getInt32Ref() { int32 &getInt32Ref() {
JS_ASSERT(isInt32()); JS_ASSERT(isInt32());
return data.s.payload.i32; return data.s.payload.i32;
} }
JS_ALWAYS_INLINE
void setDouble(double d) { void setDouble(double d) {
data = DOUBLE_TO_JSVAL_IMPL(d); data = DOUBLE_TO_JSVAL_IMPL(d);
} }
JS_ALWAYS_INLINE
double &getDoubleRef() { double &getDoubleRef() {
JS_ASSERT(isDouble()); JS_ASSERT(isDouble());
return data.asDouble; return data.asDouble;
} }
JS_ALWAYS_INLINE
void setString(JSString *str) { void setString(JSString *str) {
data = STRING_TO_JSVAL_IMPL(str); data = STRING_TO_JSVAL_IMPL(str);
} }
JS_ALWAYS_INLINE
void setObject(JSObject &obj) { void setObject(JSObject &obj) {
JS_ASSERT(&obj != NULL); JS_ASSERT(&obj != NULL);
data = OBJECT_TO_JSVAL_IMPL(&obj); data = OBJECT_TO_JSVAL_IMPL(&obj);
} }
JS_ALWAYS_INLINE
void setBoolean(bool b) { void setBoolean(bool b) {
data = BOOLEAN_TO_JSVAL_IMPL(b); data = BOOLEAN_TO_JSVAL_IMPL(b);
} }
JS_ALWAYS_INLINE
void setMagic(JSWhyMagic why) { void setMagic(JSWhyMagic why) {
data = MAGIC_TO_JSVAL_IMPL(why); data = MAGIC_TO_JSVAL_IMPL(why);
} }
JS_ALWAYS_INLINE
void setMagicWithObjectOrNullPayload(JSObject *obj) {
data = MAGIC_TO_JSVAL_IMPL(obj);
}
JS_ALWAYS_INLINE
JSObject *getMagicObjectOrNullPayload() const {
return MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(data);
}
JS_ALWAYS_INLINE JS_ALWAYS_INLINE
void setNumber(uint32 ui) { void setNumber(uint32 ui) {
if (ui > JSVAL_INT_MAX) if (ui > JSVAL_INT_MAX)
@ -398,6 +423,7 @@ class Value
setUndefined(); setUndefined();
} }
JS_ALWAYS_INLINE
void swap(Value &rhs) { void swap(Value &rhs) {
uint64 tmp = rhs.data.asBits; uint64 tmp = rhs.data.asBits;
rhs.data.asBits = data.asBits; rhs.data.asBits = data.asBits;
@ -406,85 +432,112 @@ class Value
/*** Value type queries ***/ /*** Value type queries ***/
JS_ALWAYS_INLINE
bool isUndefined() const { bool isUndefined() const {
return JSVAL_IS_UNDEFINED_IMPL(data); return JSVAL_IS_UNDEFINED_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isNull() const { bool isNull() const {
return JSVAL_IS_NULL_IMPL(data); return JSVAL_IS_NULL_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isNullOrUndefined() const { bool isNullOrUndefined() const {
return isNull() || isUndefined(); return isNull() || isUndefined();
} }
JS_ALWAYS_INLINE
bool isInt32() const { bool isInt32() const {
return JSVAL_IS_INT32_IMPL(data); return JSVAL_IS_INT32_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isInt32(int32 i32) const { bool isInt32(int32 i32) const {
return JSVAL_IS_SPECIFIC_INT32_IMPL(data, i32); return JSVAL_IS_SPECIFIC_INT32_IMPL(data, i32);
} }
JS_ALWAYS_INLINE
bool isDouble() const { bool isDouble() const {
return JSVAL_IS_DOUBLE_IMPL(data); return JSVAL_IS_DOUBLE_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isNumber() const { bool isNumber() const {
return JSVAL_IS_NUMBER_IMPL(data); return JSVAL_IS_NUMBER_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isString() const { bool isString() const {
return JSVAL_IS_STRING_IMPL(data); return JSVAL_IS_STRING_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isObject() const { bool isObject() const {
return JSVAL_IS_OBJECT_IMPL(data); return JSVAL_IS_OBJECT_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isPrimitive() const { bool isPrimitive() const {
return JSVAL_IS_PRIMITIVE_IMPL(data); return JSVAL_IS_PRIMITIVE_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isObjectOrNull() const { bool isObjectOrNull() const {
return JSVAL_IS_OBJECT_OR_NULL_IMPL(data); return JSVAL_IS_OBJECT_OR_NULL_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isGCThing() const { bool isGCThing() const {
return JSVAL_IS_GCTHING_IMPL(data); return JSVAL_IS_GCTHING_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isBoolean() const { bool isBoolean() const {
return JSVAL_IS_BOOLEAN_IMPL(data); return JSVAL_IS_BOOLEAN_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isTrue() const { bool isTrue() const {
return JSVAL_IS_SPECIFIC_BOOLEAN(data, true); return JSVAL_IS_SPECIFIC_BOOLEAN(data, true);
} }
JS_ALWAYS_INLINE
bool isFalse() const { bool isFalse() const {
return JSVAL_IS_SPECIFIC_BOOLEAN(data, false); return JSVAL_IS_SPECIFIC_BOOLEAN(data, false);
} }
JS_ALWAYS_INLINE
bool isMagic() const { bool isMagic() const {
return JSVAL_IS_MAGIC_IMPL(data); return JSVAL_IS_MAGIC_IMPL(data);
} }
JS_ALWAYS_INLINE
bool isMagic(JSWhyMagic why) const { bool isMagic(JSWhyMagic why) const {
JS_ASSERT_IF(isMagic(), data.s.payload.why == why); JS_ASSERT_IF(isMagic(), data.s.payload.why == why);
return JSVAL_IS_MAGIC_IMPL(data); return JSVAL_IS_MAGIC_IMPL(data);
} }
#if JS_BITS_PER_WORD == 64
JS_ALWAYS_INLINE
bool hasPtrPayload() const {
return data.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_PTR_PAYLOAD_SET;
}
#endif
JS_ALWAYS_INLINE
bool isMarkable() const { bool isMarkable() const {
return JSVAL_IS_TRACEABLE_IMPL(data); return JSVAL_IS_TRACEABLE_IMPL(data);
} }
JS_ALWAYS_INLINE
int32 gcKind() const { int32 gcKind() const {
JS_ASSERT(isMarkable()); JS_ASSERT(isMarkable());
return JSVAL_TRACE_KIND_IMPL(data); return JSVAL_TRACE_KIND_IMPL(data);
} }
#ifdef DEBUG #ifdef DEBUG
JS_ALWAYS_INLINE
JSWhyMagic whyMagic() const { JSWhyMagic whyMagic() const {
JS_ASSERT(isMagic()); JS_ASSERT(isMagic());
return data.s.payload.why; return data.s.payload.why;
@ -493,65 +546,78 @@ class Value
/*** Comparison ***/ /*** Comparison ***/
JS_ALWAYS_INLINE
bool operator==(const Value &rhs) const { bool operator==(const Value &rhs) const {
return data.asBits == rhs.data.asBits; return data.asBits == rhs.data.asBits;
} }
JS_ALWAYS_INLINE
bool operator!=(const Value &rhs) const { bool operator!=(const Value &rhs) const {
return data.asBits != rhs.data.asBits; return data.asBits != rhs.data.asBits;
} }
JS_ALWAYS_INLINE
friend bool SameType(const Value &lhs, const Value &rhs) { friend bool SameType(const Value &lhs, const Value &rhs) {
return JSVAL_SAME_TYPE_IMPL(lhs.data, rhs.data); return JSVAL_SAME_TYPE_IMPL(lhs.data, rhs.data);
} }
/*** Extract the value's typed payload ***/ /*** Extract the value's typed payload ***/
JS_ALWAYS_INLINE
int32 toInt32() const { int32 toInt32() const {
JS_ASSERT(isInt32()); JS_ASSERT(isInt32());
return JSVAL_TO_INT32_IMPL(data); return JSVAL_TO_INT32_IMPL(data);
} }
JS_ALWAYS_INLINE
double toDouble() const { double toDouble() const {
JS_ASSERT(isDouble()); JS_ASSERT(isDouble());
return data.asDouble; return data.asDouble;
} }
JS_ALWAYS_INLINE
double toNumber() const { double toNumber() const {
JS_ASSERT(isNumber()); JS_ASSERT(isNumber());
return isDouble() ? toDouble() : double(toInt32()); return isDouble() ? toDouble() : double(toInt32());
} }
JS_ALWAYS_INLINE
JSString *toString() const { JSString *toString() const {
JS_ASSERT(isString()); JS_ASSERT(isString());
return JSVAL_TO_STRING_IMPL(data); return JSVAL_TO_STRING_IMPL(data);
} }
JS_ALWAYS_INLINE
JSObject &toObject() const { JSObject &toObject() const {
JS_ASSERT(isObject()); JS_ASSERT(isObject());
return *JSVAL_TO_OBJECT_IMPL(data); return *JSVAL_TO_OBJECT_IMPL(data);
} }
JS_ALWAYS_INLINE
JSObject *toObjectOrNull() const { JSObject *toObjectOrNull() const {
JS_ASSERT(isObjectOrNull()); JS_ASSERT(isObjectOrNull());
return JSVAL_TO_OBJECT_IMPL(data); return JSVAL_TO_OBJECT_IMPL(data);
} }
JS_ALWAYS_INLINE
void *asGCThing() const { void *asGCThing() const {
JS_ASSERT(isGCThing()); JS_ASSERT(isGCThing());
return JSVAL_TO_GCTHING_IMPL(data); return JSVAL_TO_GCTHING_IMPL(data);
} }
JS_ALWAYS_INLINE
bool toBoolean() const { bool toBoolean() const {
JS_ASSERT(isBoolean()); JS_ASSERT(isBoolean());
return JSVAL_TO_BOOLEAN_IMPL(data); return JSVAL_TO_BOOLEAN_IMPL(data);
} }
JS_ALWAYS_INLINE
uint32 payloadAsRawUint32() const { uint32 payloadAsRawUint32() const {
JS_ASSERT(!isDouble()); JS_ASSERT(!isDouble());
return data.s.payload.u32; return data.s.payload.u32;
} }
JS_ALWAYS_INLINE
uint64 asRawBits() const { uint64 asRawBits() const {
return data.asBits; return data.asBits;
} }
@ -562,18 +628,22 @@ class Value
* these operations to be implemented more efficiently, since doubles * these operations to be implemented more efficiently, since doubles
* generally already require special handling by the caller. * generally already require special handling by the caller.
*/ */
JS_ALWAYS_INLINE
JSValueType extractNonDoubleType() const { JSValueType extractNonDoubleType() const {
return JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(data); return JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(data);
} }
JS_ALWAYS_INLINE
JSValueTag extractNonDoubleTag() const { JSValueTag extractNonDoubleTag() const {
return JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(data); return JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(data);
} }
JS_ALWAYS_INLINE
void unboxNonDoubleTo(uint64 *out) const { void unboxNonDoubleTo(uint64 *out) const {
UNBOX_NON_DOUBLE_JSVAL(data, out); UNBOX_NON_DOUBLE_JSVAL(data, out);
} }
JS_ALWAYS_INLINE
void boxNonDoubleFrom(JSValueType type, uint64 *out) { void boxNonDoubleFrom(JSValueType type, uint64 *out) {
data = BOX_NON_DOUBLE_JSVAL(type, out); data = BOX_NON_DOUBLE_JSVAL(type, out);
} }
@ -583,11 +653,13 @@ class Value
* JSVAL_TYPE_NONFUNOBJ. Since these two operations just return the type of * JSVAL_TYPE_NONFUNOBJ. Since these two operations just return the type of
* a value, the caller must handle JSVAL_TYPE_OBJECT separately. * a value, the caller must handle JSVAL_TYPE_OBJECT separately.
*/ */
JS_ALWAYS_INLINE
JSValueType extractNonDoubleObjectTraceType() const { JSValueType extractNonDoubleObjectTraceType() const {
JS_ASSERT(!isObject()); JS_ASSERT(!isObject());
return JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(data); return JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(data);
} }
JS_ALWAYS_INLINE
JSValueTag extractNonDoubleObjectTraceTag() const { JSValueTag extractNonDoubleObjectTraceTag() const {
JS_ASSERT(!isObject()); JS_ASSERT(!isObject());
return JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(data); return JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(data);
@ -602,24 +674,29 @@ class Value
* Privates values are given a type type which ensures they are not marked. * Privates values are given a type type which ensures they are not marked.
*/ */
JS_ALWAYS_INLINE
void setPrivate(void *ptr) { void setPrivate(void *ptr) {
data = PRIVATE_PTR_TO_JSVAL_IMPL(ptr); data = PRIVATE_PTR_TO_JSVAL_IMPL(ptr);
} }
JS_ALWAYS_INLINE
void *toPrivate() const { void *toPrivate() const {
JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(data)); JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(data));
return JSVAL_TO_PRIVATE_PTR_IMPL(data); return JSVAL_TO_PRIVATE_PTR_IMPL(data);
} }
JS_ALWAYS_INLINE
void setPrivateUint32(uint32 ui) { void setPrivateUint32(uint32 ui) {
data = PRIVATE_UINT32_TO_JSVAL_IMPL(ui); data = PRIVATE_UINT32_TO_JSVAL_IMPL(ui);
} }
JS_ALWAYS_INLINE
uint32 toPrivateUint32() const { uint32 toPrivateUint32() const {
JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(data)); JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(data));
return JSVAL_TO_PRIVATE_UINT32_IMPL(data); return JSVAL_TO_PRIVATE_UINT32_IMPL(data);
} }
JS_ALWAYS_INLINE
uint32 &getPrivateUint32Ref() { uint32 &getPrivateUint32Ref() {
JS_ASSERT(isDouble()); JS_ASSERT(isDouble());
return data.s.payload.u32; return data.s.payload.u32;
@ -764,9 +841,7 @@ static inline const Value & Valueify(const jsval &v) { return (const Value &)v
struct Class; struct Class;
typedef JSBool typedef JSBool
(* Native)(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval); (* Native)(JSContext *cx, uintN argc, Value *vp);
typedef JSBool
(* FastNative)(JSContext *cx, uintN argc, Value *vp);
typedef JSBool typedef JSBool
(* PropertyOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp); (* PropertyOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp);
typedef JSBool typedef JSBool
@ -791,8 +866,6 @@ typedef JSBool
static inline Native Valueify(JSNative f) { return (Native)f; } static inline Native Valueify(JSNative f) { return (Native)f; }
static inline JSNative Jsvalify(Native f) { return (JSNative)f; } static inline JSNative Jsvalify(Native f) { return (JSNative)f; }
static inline FastNative Valueify(JSFastNative f) { return (FastNative)f; }
static inline JSFastNative Jsvalify(FastNative f) { return (JSFastNative)f; }
static inline PropertyOp Valueify(JSPropertyOp f) { return (PropertyOp)f; } static inline PropertyOp Valueify(JSPropertyOp f) { return (PropertyOp)f; }
static inline JSPropertyOp Jsvalify(PropertyOp f) { return (JSPropertyOp)f; } static inline JSPropertyOp Jsvalify(PropertyOp f) { return (JSPropertyOp)f; }
static inline ConvertOp Valueify(JSConvertOp f) { return (ConvertOp)f; } static inline ConvertOp Valueify(JSConvertOp f) { return (ConvertOp)f; }
@ -809,8 +882,6 @@ static inline DefinePropOp Valueify(JSDefinePropOp f) { return (DefinePr
static inline JSDefinePropOp Jsvalify(DefinePropOp f) { return (JSDefinePropOp)f; } static inline JSDefinePropOp Jsvalify(DefinePropOp f) { return (JSDefinePropOp)f; }
static inline PropertyIdOp Valueify(JSPropertyIdOp f); /* Same type as JSPropertyOp */ static inline PropertyIdOp Valueify(JSPropertyIdOp f); /* Same type as JSPropertyOp */
static inline JSPropertyIdOp Jsvalify(PropertyIdOp f); /* Same type as PropertyOp */ static inline JSPropertyIdOp Jsvalify(PropertyIdOp f); /* Same type as PropertyOp */
static inline CallOp Valueify(JSCallOp f); /* Same type as JSFastNative */
static inline JSCallOp Jsvalify(CallOp f); /* Same type as FastNative */
static const PropertyOp PropertyStub = (PropertyOp)JS_PropertyStub; static const PropertyOp PropertyStub = (PropertyOp)JS_PropertyStub;
static const JSEnumerateOp EnumerateStub = JS_EnumerateStub; static const JSEnumerateOp EnumerateStub = JS_EnumerateStub;
@ -885,9 +956,6 @@ struct Class {
uint8 pad[sizeof(JSClass) - sizeof(ClassSizeMeasurement) - uint8 pad[sizeof(JSClass) - sizeof(ClassSizeMeasurement) -
sizeof(ClassExtension) - sizeof(ObjectOps)]; sizeof(ClassExtension) - sizeof(ObjectOps)];
/* Flag indicating that Class::call is a fast native. */
static const uint32 CALL_IS_FAST = JSCLASS_INTERNAL_FLAG1;
/* Class is not native and its map is not a scope. */ /* Class is not native and its map is not a scope. */
static const uint32 NON_NATIVE = JSCLASS_INTERNAL_FLAG2; static const uint32 NON_NATIVE = JSCLASS_INTERNAL_FLAG2;
@ -896,13 +964,6 @@ struct Class {
} }
}; };
/* Helper to initialize Class::call when Class::CALL_IS_FAST. */
inline Native
CastCallOpAsNative(CallOp op)
{
return reinterpret_cast<Native>(op);
}
JS_STATIC_ASSERT(offsetof(JSClass, name) == offsetof(Class, name)); JS_STATIC_ASSERT(offsetof(JSClass, name) == offsetof(Class, name));
JS_STATIC_ASSERT(offsetof(JSClass, flags) == offsetof(Class, flags)); JS_STATIC_ASSERT(offsetof(JSClass, flags) == offsetof(Class, flags));
JS_STATIC_ASSERT(offsetof(JSClass, addProperty) == offsetof(Class, addProperty)); JS_STATIC_ASSERT(offsetof(JSClass, addProperty) == offsetof(Class, addProperty));
@ -945,6 +1006,38 @@ static JS_ALWAYS_INLINE PropertyDescriptor * Valueify(JSPropertyDescriptor *p)
/******************************************************************************/ /******************************************************************************/
/*
* Any cast-via-function-call, inlined or not, will cause initialization to
* happen at startup, rather than statically, so just cast in release builds.
*/
#ifdef DEBUG
static inline JSNative JsvalifyNative(Native n) { return (JSNative)n; }
static inline JSNative JsvalifyNative(JSNative n) { return n; }
static inline Native ValueifyNative(JSNative n) { return (Native)n; }
static inline Native ValueifyNative(Native n) { return n; }
# define JS_VALUEIFY_NATIVE(n) js::ValueifyNative(n)
# define JS_JSVALIFY_NATIVE(n) js::JsvalifyNative(n)
#else
# define JS_VALUEIFY_NATIVE(n) ((js::Native)n)
# define JS_JSVALIFY_NATIVE(n) ((JSNative)n)
#endif
/*
* JSFunctionSpec uses JSAPI jsval in function signatures whereas the engine
* uses js::Value. To avoid widespread (JSNative) casting, have JS_FN perfom a
* type-safe cast.
*/
#undef JS_FN
#define JS_FN(name,call,nargs,flags) \
{name, JS_JSVALIFY_NATIVE(call), nargs, (flags) | JSFUN_STUB_GSOPS}
/******************************************************************************/
/* /*
* In some cases (quickstubs) we want to take a value in whatever manner is * In some cases (quickstubs) we want to take a value in whatever manner is
* appropriate for the architecture and normalize to a const js::Value &. On * appropriate for the architecture and normalize to a const js::Value &. On

Просмотреть файл

@ -197,10 +197,9 @@ IsDeclared(const JSObject *obj)
} }
static JSBool static JSBool
xml_isXMLName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, xml_isXMLName(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
*rval = BOOLEAN_TO_JSVAL(js_IsXMLName(cx, argv[0])); *vp = BOOLEAN_TO_JSVAL(js_IsXMLName(cx, argc ? vp[2] : JSVAL_VOID));
return JS_TRUE; return JS_TRUE;
} }
@ -287,14 +286,14 @@ static JSPropertySpec namespace_props[] = {
}; };
static JSBool static JSBool
namespace_toString(JSContext *cx, uintN argc, jsval *vp) namespace_toString(JSContext *cx, uintN argc, Value *vp)
{ {
JSObject *obj; JSObject *obj;
obj = JS_THIS_OBJECT(cx, vp); obj = ComputeThisFromVp(cx, vp);
if (!JS_InstanceOf(cx, obj, Jsvalify(&js_NamespaceClass), vp + 2)) if (!JS_InstanceOf(cx, obj, Jsvalify(&js_NamespaceClass), Jsvalify(vp + 2)))
return JS_FALSE; return JS_FALSE;
*vp = obj->getNameURI(); *vp = Valueify(obj->getNameURI());
return JS_TRUE; return JS_TRUE;
} }
@ -440,7 +439,7 @@ static JSPropertySpec qname_props[] = {
}; };
static JSBool static JSBool
qname_toString(JSContext *cx, uintN argc, jsval *vp) qname_toString(JSContext *cx, uintN argc, Value *vp)
{ {
JSObject *obj; JSObject *obj;
Class *clasp; Class *clasp;
@ -448,13 +447,13 @@ qname_toString(JSContext *cx, uintN argc, jsval *vp)
size_t length; size_t length;
jschar *chars; jschar *chars;
obj = JS_THIS_OBJECT(cx, vp); obj = ComputeThisFromVp(cx, vp);
if (!obj) if (!obj)
return JS_FALSE; return JS_FALSE;
clasp = obj->getClass(); clasp = obj->getClass();
if (clasp != &js_AttributeNameClass && if (clasp != &js_AttributeNameClass &&
clasp != &js_AnyNameClass && clasp != &js_AnyNameClass &&
!JS_InstanceOf(cx, obj, Jsvalify(&js_QNameClass), vp + 2)) { !JS_InstanceOf(cx, obj, Jsvalify(&js_QNameClass), Jsvalify(vp + 2))) {
return JS_FALSE; return JS_FALSE;
} }
@ -490,7 +489,7 @@ qname_toString(JSContext *cx, uintN argc, jsval *vp)
} }
} }
*vp = STRING_TO_JSVAL(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }
@ -635,8 +634,8 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv,
obj = NewBuiltinClassInstance(cx, &js_NamespaceClass); obj = NewBuiltinClassInstance(cx, &js_NamespaceClass);
if (!obj) if (!obj)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(obj);
} }
*rval = OBJECT_TO_JSVAL(obj);
METER(xml_stats.xmlnamespace); METER(xml_stats.xmlnamespace);
empty = cx->runtime->emptyString; empty = cx->runtime->emptyString;
@ -689,16 +688,15 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv,
obj->setNamePrefix(STRING_TO_JSVAL(prefix)); obj->setNamePrefix(STRING_TO_JSVAL(prefix));
} }
} }
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Namespace(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) Namespace(JSContext *cx, uintN argc, Value *vp)
{ {
return NamespaceHelper(cx, JSObject *thisobj = NULL;
cx->isConstructing() ? obj : NULL, (void)IsConstructing_PossiblyWithGivenThisObject(vp, &thisobj);
argc, Jsvalify(argv), Jsvalify(rval)); return NamespaceHelper(cx, thisobj, argc, Jsvalify(vp + 2), Jsvalify(vp));
} }
/* /*
@ -742,8 +740,8 @@ QNameHelper(JSContext *cx, JSObject *obj, Class *clasp, intN argc,
obj = NewBuiltinClassInstance(cx, clasp); obj = NewBuiltinClassInstance(cx, clasp);
if (!obj) if (!obj)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(obj);
} }
*rval = OBJECT_TO_JSVAL(obj);
METER(xml_stats.qname); METER(xml_stats.qname);
if (isQName) { if (isQName) {
@ -829,18 +827,19 @@ out:
} }
static JSBool static JSBool
QName(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) QName(JSContext *cx, uintN argc, Value *vp)
{ {
return QNameHelper(cx, cx->isConstructing() ? obj : NULL, JSObject *thisobj = NULL;
&js_QNameClass, argc, Jsvalify(argv), Jsvalify(rval)); (void)IsConstructing_PossiblyWithGivenThisObject(vp, &thisobj);
return QNameHelper(cx, thisobj, &js_QNameClass, argc, Jsvalify(vp + 2), Jsvalify(vp));
} }
static JSBool static JSBool
AttributeName(JSContext *cx, JSObject *obj, uintN argc, Value *argv, AttributeName(JSContext *cx, uintN argc, Value *vp)
Value *rval)
{ {
return QNameHelper(cx, cx->isConstructing() ? obj : NULL, JSObject *thisobj = NULL;
&js_AttributeNameClass, argc, Jsvalify(argv), Jsvalify(rval)); (void)IsConstructing_PossiblyWithGivenThisObject(vp, &thisobj);
return QNameHelper(cx, thisobj, &js_AttributeNameClass, argc, Jsvalify(vp + 2), Jsvalify(vp));
} }
/* /*
@ -5071,7 +5070,8 @@ out:
JS_FRIEND_DATA(Class) js_XMLClass = { JS_FRIEND_DATA(Class) js_XMLClass = {
js_XML_str, js_XML_str,
JSCLASS_HAS_PRIVATE | JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_XML), JSCLASS_HAS_PRIVATE | JSCLASS_MARK_IS_TRACE |
JSCLASS_HAS_CACHED_PROTO(JSProto_XML),
PropertyStub, /* addProperty */ PropertyStub, /* addProperty */
PropertyStub, /* delProperty */ PropertyStub, /* delProperty */
PropertyStub, /* getProperty */ PropertyStub, /* getProperty */
@ -6819,52 +6819,51 @@ static JSFunctionSpec xml_static_methods[] = {
}; };
static JSBool static JSBool
XML(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) XML(JSContext *cx, uintN argc, Value *vp)
{ {
jsval v;
JSXML *xml, *copy; JSXML *xml, *copy;
JSObject *xobj, *vobj; JSObject *xobj, *vobj;
Class *clasp; Class *clasp;
v = argv[0]; jsval v = argc ? Jsvalify(vp[2]) : JSVAL_VOID;
if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v))
v = STRING_TO_JSVAL(cx->runtime->emptyString); v = STRING_TO_JSVAL(cx->runtime->emptyString);
xobj = ToXML(cx, v); xobj = ToXML(cx, v);
if (!xobj) if (!xobj)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(xobj);
xml = (JSXML *) xobj->getPrivate(); xml = (JSXML *) xobj->getPrivate();
if (cx->isConstructing() && !JSVAL_IS_PRIMITIVE(v)) { if (IsConstructing(vp) && !JSVAL_IS_PRIMITIVE(v)) {
vobj = JSVAL_TO_OBJECT(v); vobj = JSVAL_TO_OBJECT(v);
clasp = vobj->getClass(); clasp = vobj->getClass();
if (clasp == &js_XMLClass || if (clasp == &js_XMLClass ||
(clasp->flags & JSCLASS_DOCUMENT_OBSERVER)) { (clasp->flags & JSCLASS_DOCUMENT_OBSERVER)) {
/* No need to lock obj, it's newly constructed and thread local. */ copy = DeepCopy(cx, xml, NULL, 0);
copy = DeepCopy(cx, xml, obj, 0);
if (!copy) if (!copy)
return JS_FALSE; return JS_FALSE;
JS_ASSERT(copy->object == obj); vp->setObject(*copy->object);
*rval = OBJECT_TO_JSVAL(obj);
return JS_TRUE; return JS_TRUE;
} }
} }
vp->setObject(*xobj);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
XMLList(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) XMLList(JSContext *cx, uintN argc, jsval *vp)
{ {
jsval v;
JSObject *vobj, *listobj; JSObject *vobj, *listobj;
JSXML *xml, *list; JSXML *xml, *list;
v = argv[0]; jsval v = argc ? vp[2] : JSVAL_VOID;
if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v))
v = STRING_TO_JSVAL(cx->runtime->emptyString); v = STRING_TO_JSVAL(cx->runtime->emptyString);
if (cx->isConstructing() && !JSVAL_IS_PRIMITIVE(v)) { if (IsConstructing(Valueify(vp)) && !JSVAL_IS_PRIMITIVE(v)) {
vobj = JSVAL_TO_OBJECT(v); vobj = JSVAL_TO_OBJECT(v);
if (vobj->isXML()) { if (vobj->isXML()) {
xml = (JSXML *) vobj->getPrivate(); xml = (JSXML *) vobj->getPrivate();
@ -6872,7 +6871,7 @@ XMLList(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
if (!listobj) if (!listobj)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(listobj); *vp = OBJECT_TO_JSVAL(listobj);
list = (JSXML *) listobj->getPrivate(); list = (JSXML *) listobj->getPrivate();
if (!Append(cx, list, xml)) if (!Append(cx, list, xml))
@ -6887,7 +6886,7 @@ XMLList(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!listobj) if (!listobj)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(listobj); *vp = OBJECT_TO_JSVAL(listobj);
return JS_TRUE; return JS_TRUE;
} }
@ -7079,7 +7078,7 @@ js_InitXMLClass(JSContext *cx, JSObject *obj)
return NULL; return NULL;
/* Define the XML class constructor and prototype. */ /* Define the XML class constructor and prototype. */
proto = js_InitClass(cx, obj, NULL, &js_XMLClass, Valueify(XML), 1, proto = js_InitClass(cx, obj, NULL, &js_XMLClass, XML, 1,
NULL, xml_methods, NULL, xml_methods,
xml_static_props, xml_static_methods); xml_static_props, xml_static_methods);
if (!proto) if (!proto)
@ -7118,7 +7117,7 @@ js_InitXMLClass(JSContext *cx, JSObject *obj)
return NULL; return NULL;
/* Define the XMLList function and give it the same prototype as XML. */ /* Define the XMLList function and give it the same prototype as XML. */
fun = JS_DefineFunction(cx, obj, js_XMLList_str, XMLList, 1, 0); fun = JS_DefineFunction(cx, obj, js_XMLList_str, XMLList, 1, JSFUN_CONSTRUCTOR);
if (!fun) if (!fun)
return NULL; return NULL;
if (!js_SetClassPrototype(cx, FUN_OBJECT(fun), proto, if (!js_SetClassPrototype(cx, FUN_OBJECT(fun), proto,
@ -7219,14 +7218,13 @@ js_GetFunctionNamespace(JSContext *cx, Value *vp)
JSBool JSBool
js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp) js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp)
{ {
JSStackFrame *fp;
JSObject *ns, *obj, *tmp; JSObject *ns, *obj, *tmp;
jsval v; jsval v;
fp = js_GetTopStackFrame(cx); JSObject *scopeChain = JS_GetScopeChain(cx);
obj = NULL; obj = NULL;
for (tmp = fp->getScopeChain(); tmp; tmp = tmp->getParent()) { for (tmp = scopeChain; tmp; tmp = tmp->getParent()) {
Class *clasp = tmp->getClass(); Class *clasp = tmp->getClass();
if (clasp == &js_BlockClass || clasp == &js_WithClass) if (clasp == &js_BlockClass || clasp == &js_WithClass)
continue; continue;
@ -7337,10 +7335,9 @@ js_ValueToXMLString(JSContext *cx, const Value &v)
} }
static JSBool static JSBool
anyname_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, anyname_toString(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
*rval = ATOM_TO_JSVAL(cx->runtime->atomState.starAtom); *vp = ATOM_TO_JSVAL(cx->runtime->atomState.starAtom);
return JS_TRUE; return JS_TRUE;
} }

Просмотреть файл

@ -397,15 +397,14 @@ stubs::SlowCall(VMFrame &f, uint32 argc)
return ret; return ret;
} }
if (fun->isFastNative()) { if (fun->isNative()) {
#ifdef JS_MONOIC #ifdef JS_MONOIC
#ifdef JS_CPU_X86 #ifdef JS_CPU_X86
ic::CallFastNative(cx, f.fp()->getScript(), mic, fun, false); ic::CallNative(cx, f.fp()->getScript(), mic, fun, false);
#endif #endif
#endif #endif
FastNative fn = (FastNative)fun->u.n.native; if (!fun->u.n.native(cx, argc, vp))
if (!fn(cx, argc, vp))
THROWV(NULL); THROWV(NULL);
return NULL; return NULL;
} }
@ -452,17 +451,16 @@ stubs::SlowNew(VMFrame &f, uint32 argc)
return ret; return ret;
} }
if (fun->isFastConstructor()) { if (fun->isConstructor()) {
#ifdef JS_MONOIC #ifdef JS_MONOIC
#ifdef JS_CPU_X86 #ifdef JS_CPU_X86
ic::CallFastNative(cx, f.fp()->getScript(), mic, fun, true); ic::CallNative(cx, f.fp()->getScript(), mic, fun, true);
#endif #endif
#endif #endif
vp[1].setMagic(JS_FAST_CONSTRUCTOR); vp[1].setMagicWithObjectOrNullPayload(NULL);
FastNative fn = (FastNative)fun->u.n.native; if (!fun->u.n.native(cx, argc, vp))
if (!fn(cx, argc, vp))
THROWV(NULL); THROWV(NULL);
JS_ASSERT(!vp->isPrimitive()); JS_ASSERT(!vp->isPrimitive());

Просмотреть файл

@ -229,7 +229,7 @@ ic::NativeCallCompiler::finish(JSScript *script, uint8 *start, uint8 *fallthroug
} }
void void
ic::CallFastNative(JSContext *cx, JSScript *script, MICInfo &mic, JSFunction *fun, bool isNew) ic::CallNative(JSContext *cx, JSScript *script, MICInfo &mic, JSFunction *fun, bool isNew)
{ {
if (mic.u.generated) { if (mic.u.generated) {
/* Already generated a MIC at this site, don't make another one. */ /* Already generated a MIC at this site, don't make another one. */
@ -237,11 +237,11 @@ ic::CallFastNative(JSContext *cx, JSScript *script, MICInfo &mic, JSFunction *fu
} }
mic.u.generated = true; mic.u.generated = true;
JS_ASSERT(fun->isFastNative()); JS_ASSERT(fun->isNative());
if (isNew) if (isNew)
JS_ASSERT(fun->isFastConstructor()); JS_ASSERT(fun->isConstructor());
FastNative fn = (FastNative)fun->u.n.native; Native native = fun->u.n.native;
typedef JSC::MacroAssembler::ImmPtr ImmPtr; typedef JSC::MacroAssembler::ImmPtr ImmPtr;
typedef JSC::MacroAssembler::Imm32 Imm32; typedef JSC::MacroAssembler::Imm32 Imm32;
@ -281,8 +281,10 @@ ic::CallFastNative(JSContext *cx, JSScript *script, MICInfo &mic, JSFunction *fu
ncc.masm.storePtr(temp, Address(JSC::X86Registers::esp, 0x8)); ncc.masm.storePtr(temp, Address(JSC::X86Registers::esp, 0x8));
if (isNew) { if (isNew) {
/* Mark vp[1] as magic. */ /* Mark 'this' as magic. */
ncc.masm.storeValue(MagicValue(JS_FAST_CONSTRUCTOR), Address(temp, sizeof(Value))); Value magicCtorThis;
magicCtorThis.setMagicWithObjectOrNullPayload(NULL);
ncc.masm.storeValue(magicCtorThis, Address(temp, sizeof(Value)));
} }
/* Push argc */ /* Push argc */
@ -293,7 +295,7 @@ ic::CallFastNative(JSContext *cx, JSScript *script, MICInfo &mic, JSFunction *fu
ncc.masm.storePtr(temp, Address(JSC::X86Registers::esp, 0)); ncc.masm.storePtr(temp, Address(JSC::X86Registers::esp, 0));
/* Do the call. */ /* Do the call. */
ncc.masm.call(JS_FUNC_TO_DATA_PTR(void *, fn)); ncc.masm.call(JS_FUNC_TO_DATA_PTR(void *, native));
/* Restore stack. */ /* Restore stack. */
ncc.masm.add32(Imm32(stackAdjustment), JSC::X86Registers::esp); ncc.masm.add32(Imm32(stackAdjustment), JSC::X86Registers::esp);

Просмотреть файл

@ -158,7 +158,7 @@ class NativeCallCompiler
void finish(JSScript *script, uint8 *start, uint8 *fallthrough); void finish(JSScript *script, uint8 *start, uint8 *fallthrough);
}; };
void CallFastNative(JSContext *cx, JSScript *script, MICInfo &mic, JSFunction *fun, bool isNew); void CallNative(JSContext *cx, JSScript *script, MICInfo &mic, JSFunction *fun, bool isNew);
#endif /* JS_CPU_X86 */ #endif /* JS_CPU_X86 */

Просмотреть файл

@ -1609,13 +1609,13 @@ stubs::LambdaJoinableForCall(VMFrame &f, JSFunction *fun)
JSObject *callee; JSObject *callee;
if (IsFunctionObject(cref, &callee)) { if (IsFunctionObject(cref, &callee)) {
JSFunction *calleeFun = GET_FUNCTION_PRIVATE(cx, callee); JSFunction *calleeFun = callee->getFunctionPrivate();
FastNative fastNative = FUN_FAST_NATIVE(calleeFun); Native native = calleeFun->maybeNative();
if (fastNative) { if (native) {
if (iargc == 1 && fastNative == array_sort) if (iargc == 1 && native == array_sort)
return obj; return obj;
if (iargc == 2 && fastNative == str_replace) if (iargc == 2 && native == str_replace)
return obj; return obj;
} }
} }

Просмотреть файл

@ -50,10 +50,14 @@ static PerfMeasurement* GetPMFromThis(JSContext* cx, jsval* vp);
// Constructor and destructor // Constructor and destructor
static JSBool static JSBool
pm_construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) pm_construct(JSContext* cx, uintN argc, jsval* vp)
{ {
uint32 mask; uint32 mask;
if (!JS_ConvertArguments(cx, argc, argv, "u", &mask)) if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "u", &mask))
return JS_FALSE;
JSObject *obj = JS_NewObjectForConstructor(cx, vp);
if (!obj)
return JS_FALSE; return JS_FALSE;
if (!JS_SealObject(cx, obj, JS_FALSE)) if (!JS_SealObject(cx, obj, JS_FALSE))
@ -66,6 +70,7 @@ pm_construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
} }
JS_SetPrivate(cx, obj, p); JS_SetPrivate(cx, obj, p);
*vp = OBJECT_TO_JSVAL(obj);
return JS_TRUE; return JS_TRUE;
} }

Просмотреть файл

@ -864,17 +864,18 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
} }
static JSBool static JSBool
Version(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Version(JSContext *cx, uintN argc, jsval *vp)
{ {
jsval *argv = JS_ARGV(cx, vp);
if (argc > 0 && JSVAL_IS_INT(argv[0])) if (argc > 0 && JSVAL_IS_INT(argv[0]))
*rval = INT_TO_JSVAL(JS_SetVersion(cx, (JSVersion) JSVAL_TO_INT(argv[0]))); *vp = INT_TO_JSVAL(JS_SetVersion(cx, (JSVersion) JSVAL_TO_INT(argv[0])));
else else
*rval = INT_TO_JSVAL(JS_GetVersion(cx)); *vp = INT_TO_JSVAL(JS_GetVersion(cx));
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Options(JSContext *cx, uintN argc, jsval *vp)
{ {
uint32 optset, flag; uint32 optset, flag;
JSString *str; JSString *str;
@ -883,6 +884,7 @@ Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JSBool found; JSBool found;
optset = 0; optset = 0;
jsval *argv = JS_ARGV(cx, vp);
for (uintN i = 0; i < argc; i++) { for (uintN i = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]); str = JS_ValueToString(cx, argv[i]);
if (!str) if (!str)
@ -920,12 +922,12 @@ Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
free(names); free(names);
return JS_FALSE; return JS_FALSE;
} }
*rval = STRING_TO_JSVAL(str); *vp = STRING_TO_JSVAL(str);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Load(JSContext *cx, uintN argc, jsval *vp)
{ {
uintN i; uintN i;
JSString *str; JSString *str;
@ -934,6 +936,11 @@ Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JSBool ok; JSBool ok;
uint32 oldopts; uint32 oldopts;
JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
if (!thisobj)
return JS_FALSE;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]); str = JS_ValueToString(cx, argv[i]);
if (!str) if (!str)
@ -943,13 +950,13 @@ Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
errno = 0; errno = 0;
oldopts = JS_GetOptions(cx); oldopts = JS_GetOptions(cx);
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL); JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
script = JS_CompileFile(cx, obj, filename); script = JS_CompileFile(cx, thisobj, filename);
JS_SetOptions(cx, oldopts); JS_SetOptions(cx, oldopts);
if (!script) { if (!script) {
ok = JS_FALSE; ok = JS_FALSE;
} else { } else {
ok = !compileOnly ok = !compileOnly
? JS_ExecuteScript(cx, obj, script, NULL) ? JS_ExecuteScript(cx, thisobj, script, NULL)
: JS_TRUE; : JS_TRUE;
JS_DestroyScript(cx, script); JS_DestroyScript(cx, script);
} }
@ -1102,12 +1109,12 @@ Print(JSContext *cx, uintN argc, jsval *vp)
} }
static JSBool static JSBool
Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); Help(JSContext *cx, uintN argc, jsval *vp);
static JSBool static JSBool
Quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Quit(JSContext *cx, uintN argc, jsval *vp)
{ {
JS_ConvertArguments(cx, argc, argv,"/ i", &gExitCode); JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/ i", &gExitCode);
gQuitting = JS_TRUE; gQuitting = JS_TRUE;
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
@ -1472,8 +1479,9 @@ ValueToScript(JSContext *cx, jsval v)
} }
static JSBool static JSBool
SetDebug(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) SetDebug(JSContext *cx, uintN argc, jsval *vp)
{ {
jsval *argv = JS_ARGV(cx, vp);
if (argc == 0 || !JSVAL_IS_BOOLEAN(argv[0])) { if (argc == 0 || !JSVAL_IS_BOOLEAN(argv[0])) {
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
JSSMSG_NOT_ENOUGH_ARGS, "setDebug"); JSSMSG_NOT_ENOUGH_ARGS, "setDebug");
@ -1481,7 +1489,7 @@ SetDebug(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
} }
js_SetDebugMode(cx, JSVAL_TO_BOOLEAN(argv[0])); js_SetDebugMode(cx, JSVAL_TO_BOOLEAN(argv[0]));
*rval = JSVAL_VOID; JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -1534,12 +1542,13 @@ TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
} }
static JSBool static JSBool
Trap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Trap(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
JSScript *script; JSScript *script;
int32 i; int32 i;
jsval *argv = JS_ARGV(cx, vp);
if (argc == 0) { if (argc == 0) {
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_TRAP_USAGE); JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_TRAP_USAGE);
return JS_FALSE; return JS_FALSE;
@ -1551,18 +1560,20 @@ Trap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
argv[argc] = STRING_TO_JSVAL(str); argv[argc] = STRING_TO_JSVAL(str);
if (!GetTrapArgs(cx, argc, argv, &script, &i)) if (!GetTrapArgs(cx, argc, argv, &script, &i))
return JS_FALSE; return JS_FALSE;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_SetTrap(cx, script, script->code + i, TrapHandler, STRING_TO_JSVAL(str)); return JS_SetTrap(cx, script, script->code + i, TrapHandler, STRING_TO_JSVAL(str));
} }
static JSBool static JSBool
Untrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Untrap(JSContext *cx, uintN argc, jsval *vp)
{ {
JSScript *script; JSScript *script;
int32 i; int32 i;
if (!GetTrapArgs(cx, argc, argv, &script, &i)) if (!GetTrapArgs(cx, argc, JS_ARGV(cx, vp), &script, &i))
return JS_FALSE; return JS_FALSE;
JS_ClearTrap(cx, script, script->code + i, NULL, NULL); JS_ClearTrap(cx, script, script->code + i, NULL, NULL);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -1574,7 +1585,7 @@ DebuggerAndThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *
} }
static JSBool static JSBool
SetDebuggerHandler(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) SetDebuggerHandler(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
if (argc == 0) { if (argc == 0) {
@ -1583,17 +1594,17 @@ SetDebuggerHandler(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
return JS_FALSE; return JS_FALSE;
} }
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
JS_SetDebuggerHandler(cx->runtime, DebuggerAndThrowHandler, str); JS_SetDebuggerHandler(cx->runtime, DebuggerAndThrowHandler, str);
*rval = JSVAL_VOID; JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
SetThrowHook(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) SetThrowHook(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
if (argc == 0) { if (argc == 0) {
@ -1602,17 +1613,17 @@ SetThrowHook(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
return JS_FALSE; return JS_FALSE;
} }
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
JS_SetThrowHook(cx->runtime, DebuggerAndThrowHandler, str); JS_SetThrowHook(cx->runtime, DebuggerAndThrowHandler, str);
*rval = JSVAL_VOID; JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
LineToPC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) LineToPC(JSContext *cx, uintN argc, jsval *vp)
{ {
JSScript *script; JSScript *script;
int32 i; int32 i;
@ -1624,29 +1635,29 @@ LineToPC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
return JS_FALSE; return JS_FALSE;
} }
script = JS_GetScriptedCaller(cx, NULL)->getScript(); script = JS_GetScriptedCaller(cx, NULL)->getScript();
if (!GetTrapArgs(cx, argc, argv, &script, &i)) if (!GetTrapArgs(cx, argc, JS_ARGV(cx, vp), &script, &i))
return JS_FALSE; return JS_FALSE;
lineno = (i == 0) ? script->lineno : (uintN)i; lineno = (i == 0) ? script->lineno : (uintN)i;
pc = JS_LineNumberToPC(cx, script, lineno); pc = JS_LineNumberToPC(cx, script, lineno);
if (!pc) if (!pc)
return JS_FALSE; return JS_FALSE;
*rval = INT_TO_JSVAL(pc - script->code); *vp = INT_TO_JSVAL(pc - script->code);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
PCToLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) PCToLine(JSContext *cx, uintN argc, jsval *vp)
{ {
JSScript *script; JSScript *script;
int32 i; int32 i;
uintN lineno; uintN lineno;
if (!GetTrapArgs(cx, argc, argv, &script, &i)) if (!GetTrapArgs(cx, argc, JS_ARGV(cx, vp), &script, &i))
return JS_FALSE; return JS_FALSE;
lineno = JS_PCToLineNumber(cx, script, script->code + i); lineno = JS_PCToLineNumber(cx, script, script->code + i);
if (!lineno) if (!lineno)
return JS_FALSE; return JS_FALSE;
*rval = INT_TO_JSVAL(lineno); *vp = INT_TO_JSVAL(lineno);
return JS_TRUE; return JS_TRUE;
} }
@ -1806,11 +1817,12 @@ SrcNotes(JSContext *cx, JSScript *script)
} }
static JSBool static JSBool
Notes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Notes(JSContext *cx, uintN argc, jsval *vp)
{ {
uintN i; uintN i;
JSScript *script; JSScript *script;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
script = ValueToScript(cx, argv[i]); script = ValueToScript(cx, argv[i]);
if (!script) if (!script)
@ -1818,6 +1830,7 @@ Notes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
SrcNotes(cx, script); SrcNotes(cx, script);
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -1927,10 +1940,11 @@ DisassembleValue(JSContext *cx, jsval v, bool lines, bool recursive)
} }
static JSBool static JSBool
Disassemble(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Disassemble(JSContext *cx, uintN argc, jsval *vp)
{ {
bool lines = false, recursive = false; bool lines = false, recursive = false;
jsval *argv = JS_ARGV(cx, vp);
while (argc > 0 && JSVAL_IS_STRING(argv[0])) { while (argc > 0 && JSVAL_IS_STRING(argv[0])) {
const char *bytes = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); const char *bytes = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
lines = !strcmp(bytes, "-l"); lines = !strcmp(bytes, "-l");
@ -1944,11 +1958,12 @@ Disassemble(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!DisassembleValue(cx, argv[i], lines, recursive)) if (!DisassembleValue(cx, argv[i], lines, recursive))
return false; return false;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true; return true;
} }
static JSBool static JSBool
DisassFile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) DisassFile(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
const char *filename; const char *filename;
@ -1959,15 +1974,18 @@ DisassFile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!argc) if (!argc)
return JS_TRUE; return JS_TRUE;
str = JS_ValueToString(cx, argv[0]); JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
if (!thisobj)
return JS_FALSE;
str = JS_ValueToString(cx, vp[2]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
argv[0] = STRING_TO_JSVAL(str);
filename = JS_GetStringBytes(str); filename = JS_GetStringBytes(str);
oldopts = JS_GetOptions(cx); oldopts = JS_GetOptions(cx);
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL); JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
script = JS_CompileFile(cx, obj, filename); script = JS_CompileFile(cx, thisobj, filename);
JS_SetOptions(cx, oldopts); JS_SetOptions(cx, oldopts);
if (!script) if (!script)
return JS_FALSE; return JS_FALSE;
@ -1975,20 +1993,19 @@ DisassFile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (script->isEmpty()) if (script->isEmpty())
return JS_TRUE; return JS_TRUE;
obj = JS_NewScriptObject(cx, script); JSObject *obj = JS_NewScriptObject(cx, script);
if (!obj) if (!obj)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(obj); /* I like to root it, root it. */ *vp = OBJECT_TO_JSVAL(obj); /* I like to root it, root it. */
ok = Disassemble(cx, obj, 1, rval, rval); /* gross, but works! */ ok = Disassemble(cx, 1, vp); /* gross, but works! */
*rval = JSVAL_VOID; JS_SET_RVAL(cx, vp, JSVAL_VOID);
return ok; return ok;
} }
static JSBool static JSBool
DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, DisassWithSrc(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
#define LINE_BUF_LEN 512 #define LINE_BUF_LEN 512
uintN i, len, line1, line2, bupline; uintN i, len, line1, line2, bupline;
@ -2000,6 +2017,7 @@ DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
static char sep[] = ";-------------------------"; static char sep[] = ";-------------------------";
ok = JS_TRUE; ok = JS_TRUE;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; ok && i < argc; i++) { for (i = 0; ok && i < argc; i++) {
script = ValueToScript(cx, argv[i]); script = ValueToScript(cx, argv[i]);
if (!script) if (!script)
@ -2073,20 +2091,22 @@ DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
bail: bail:
fclose(file); fclose(file);
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return ok; return ok;
#undef LINE_BUF_LEN #undef LINE_BUF_LEN
} }
static JSBool static JSBool
Tracing(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Tracing(JSContext *cx, uintN argc, jsval *vp)
{ {
FILE *file; FILE *file;
if (argc == 0) { if (argc == 0) {
*rval = BOOLEAN_TO_JSVAL(cx->tracefp != 0); *vp = BOOLEAN_TO_JSVAL(cx->tracefp != 0);
return JS_TRUE; return JS_TRUE;
} }
jsval *argv = JS_ARGV(cx, vp);
switch (JS_TypeOfValue(cx, argv[0])) { switch (JS_TypeOfValue(cx, argv[0])) {
case JSTYPE_NUMBER: case JSTYPE_NUMBER:
case JSTYPE_BOOLEAN: { case JSTYPE_BOOLEAN: {
@ -2112,6 +2132,7 @@ Tracing(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
fclose((FILE *)cx->tracefp); fclose((FILE *)cx->tracefp);
cx->tracefp = file; cx->tracefp = file;
cx->tracePrevPc = NULL; cx->tracePrevPc = NULL;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
bad_argument: bad_argument:
@ -2134,7 +2155,7 @@ DumpScope(JSContext *cx, JSObject *obj, FILE *fp)
} }
static JSBool static JSBool
DumpStats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) DumpStats(JSContext *cx, uintN argc, jsval *vp)
{ {
uintN i; uintN i;
JSString *str; JSString *str;
@ -2144,6 +2165,7 @@ DumpStats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JSProperty *prop; JSProperty *prop;
Value value; Value value;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]); str = JS_ValueToString(cx, argv[i]);
if (!str) if (!str)
@ -2161,6 +2183,7 @@ DumpStats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
} else { } else {
if (!JS_ValueToId(cx, STRING_TO_JSVAL(str), &id)) if (!JS_ValueToId(cx, STRING_TO_JSVAL(str), &id))
return JS_FALSE; return JS_FALSE;
JSObject *obj;
if (!js_FindProperty(cx, id, &obj, &obj2, &prop)) if (!js_FindProperty(cx, id, &obj, &obj2, &prop))
return JS_FALSE; return JS_FALSE;
if (prop) { if (prop) {
@ -2178,6 +2201,7 @@ DumpStats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
DumpScope(cx, obj, stdout); DumpScope(cx, obj, stdout);
} }
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -2279,14 +2303,15 @@ DumpHeap(JSContext *cx, uintN argc, jsval *vp)
} }
JSBool JSBool
DumpObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) DumpObject(JSContext *cx, uintN argc, jsval *vp)
{ {
JSObject *arg0 = NULL; JSObject *arg0 = NULL;
if (!JS_ConvertArguments(cx, argc, argv, "o", &arg0)) if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "o", &arg0))
return JS_FALSE; return JS_FALSE;
js_DumpObject(arg0); js_DumpObject(arg0);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -2371,7 +2396,7 @@ ZZ_formatter(JSContext *cx, const char *format, JSBool fromJS, jsval **vpp,
} }
static JSBool static JSBool
ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ConvertArgs(JSContext *cx, uintN argc, jsval *vp)
{ {
JSBool b = JS_FALSE; JSBool b = JS_FALSE;
jschar c = 0; jschar c = 0;
@ -2388,7 +2413,7 @@ ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!JS_AddArgumentFormatter(cx, "ZZ", ZZ_formatter)) if (!JS_AddArgumentFormatter(cx, "ZZ", ZZ_formatter))
return JS_FALSE; return JS_FALSE;
ok = JS_ConvertArguments(cx, argc, argv, "b/ciujdIsSWofvZZ*", ok = JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "b/ciujdIsSWofvZZ*",
&b, &c, &i, &u, &j, &d, &I, &s, &str, &w, &obj2, &b, &c, &i, &u, &j, &d, &I, &s, &str, &w, &obj2,
&fun, &v, &re, &im); &fun, &v, &re, &im);
JS_RemoveArgumentFormatter(cx, "ZZ"); JS_RemoveArgumentFormatter(cx, "ZZ");
@ -2414,6 +2439,7 @@ ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
obj2string.getBytes(), obj2string.getBytes(),
fun ? func : "", fun ? func : "",
valueString.getBytes(), re, im); valueString.getBytes(), re, im);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
@ -2431,11 +2457,13 @@ BuildDate(JSContext *cx, uintN argc, jsval *vp)
} }
static JSBool static JSBool
Clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Clear(JSContext *cx, uintN argc, jsval *vp)
{ {
if (argc != 0 && !JS_ValueToObject(cx, argv[0], &obj)) JSObject *obj;
if (argc != 0 && !JS_ValueToObject(cx, JS_ARGV(cx, vp)[0], &obj))
return JS_FALSE; return JS_FALSE;
JS_ClearScope(cx, obj); JS_ClearScope(cx, obj);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -2456,10 +2484,14 @@ Intern(JSContext *cx, uintN argc, jsval *vp)
} }
static JSBool static JSBool
Clone(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Clone(JSContext *cx, uintN argc, jsval *vp)
{ {
JSObject *funobj, *parent, *clone; JSObject *funobj, *parent, *clone;
if (!argc)
return JS_FALSE;
jsval *argv = JS_ARGV(cx, vp);
if (VALUE_IS_FUNCTION(cx, argv[0])) { if (VALUE_IS_FUNCTION(cx, argv[0])) {
funobj = JSVAL_TO_OBJECT(argv[0]); funobj = JSVAL_TO_OBJECT(argv[0]);
} else { } else {
@ -2477,18 +2509,19 @@ Clone(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
clone = JS_CloneFunctionObject(cx, funobj, parent); clone = JS_CloneFunctionObject(cx, funobj, parent);
if (!clone) if (!clone)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(clone); *vp = OBJECT_TO_JSVAL(clone);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Seal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Seal(JSContext *cx, uintN argc, jsval *vp)
{ {
JSObject *target; JSObject *target;
JSBool deep = JS_FALSE; JSBool deep = JS_FALSE;
if (!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep)) if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "o/b", &target, &deep))
return JS_FALSE; return JS_FALSE;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
if (!target) if (!target)
return JS_TRUE; return JS_TRUE;
return JS_SealObject(cx, target, deep); return JS_SealObject(cx, target, deep);
@ -2570,10 +2603,9 @@ ToInt32(JSContext *cx, uintN argc, jsval *vp)
} }
static JSBool static JSBool
StringsAreUTF8(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, StringsAreUTF8(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
*rval = JS_CStringsAreUTF8() ? JSVAL_TRUE : JSVAL_FALSE; *vp = JS_CStringsAreUTF8() ? JSVAL_TRUE : JSVAL_FALSE;
return JS_TRUE; return JS_TRUE;
} }
@ -2597,14 +2629,14 @@ static const char* bigUTF8 = "...\xFB\xBF\xBF\xBF\xBF...";
static const jschar badSurrogate[] = { 'A', 'B', 'C', 0xDEEE, 'D', 'E', 0 }; static const jschar badSurrogate[] = { 'A', 'B', 'C', 0xDEEE, 'D', 'E', 0 };
static JSBool static JSBool
TestUTF8(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) TestUTF8(JSContext *cx, uintN argc, jsval *vp)
{ {
int32 mode = 1; int32 mode = 1;
jschar chars[20]; jschar chars[20];
size_t charsLength = 5; size_t charsLength = 5;
char bytes[20]; char bytes[20];
size_t bytesLength = 20; size_t bytesLength = 20;
if (argc && !JS_ValueToInt32(cx, *argv, &mode)) if (argc && !JS_ValueToInt32(cx, *JS_ARGV(cx, vp), &mode))
return JS_FALSE; return JS_FALSE;
/* The following throw errors if compiled with UTF-8. */ /* The following throw errors if compiled with UTF-8. */
@ -2629,11 +2661,12 @@ TestUTF8(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JS_ReportError(cx, "invalid mode parameter"); JS_ReportError(cx, "invalid mode parameter");
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return !JS_IsExceptionPending (cx); return !JS_IsExceptionPending (cx);
} }
static JSBool static JSBool
ThrowError(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ThrowError(JSContext *cx, uintN argc, jsval *vp)
{ {
JS_ReportError(cx, "This is an error"); JS_ReportError(cx, "This is an error");
return JS_FALSE; return JS_FALSE;
@ -3117,12 +3150,11 @@ NewSandbox(JSContext *cx, bool lazy, bool split)
} }
static JSBool static JSBool
EvalInContext(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, EvalInContext(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSString *str; JSString *str;
JSObject *sobj = NULL; JSObject *sobj = NULL;
if (!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sobj)) if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S / o", &str, &sobj))
return false; return false;
const jschar *src = JS_GetStringChars(str); const jschar *src = JS_GetStringChars(str);
@ -3146,7 +3178,7 @@ EvalInContext(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return false; return false;
} }
*rval = OBJECT_TO_JSVAL(sobj); *vp = OBJECT_TO_JSVAL(sobj);
if (srclen == 0) if (srclen == 0)
return true; return true;
@ -3169,11 +3201,11 @@ EvalInContext(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
if (!JS_EvaluateUCScript(cx, sobj, src, srclen, if (!JS_EvaluateUCScript(cx, sobj, src, srclen,
fp->getScript()->filename, fp->getScript()->filename,
JS_PCToLineNumber(cx, fp->getScript(), fp->pc(cx)), JS_PCToLineNumber(cx, fp->getScript(), fp->pc(cx)),
rval)) { vp)) {
return false; return false;
} }
} }
return cx->compartment->wrap(cx, Valueify(rval)); return cx->compartment->wrap(cx, Valueify(vp));
} }
static JSBool static JSBool
@ -3918,7 +3950,7 @@ Parse(JSContext *cx, uintN argc, jsval *vp)
} }
static JSBool static JSBool
Snarf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Snarf(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
const char *filename; const char *filename;
@ -3929,7 +3961,10 @@ Snarf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
char *buf; char *buf;
FILE *file; FILE *file;
str = JS_ValueToString(cx, argv[0]); if (!argc)
return JS_FALSE;
str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
filename = JS_GetStringBytes(str); filename = JS_GetStringBytes(str);
@ -3986,19 +4021,23 @@ Snarf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JS_free(cx, buf); JS_free(cx, buf);
return JS_FALSE; return JS_FALSE;
} }
*rval = STRING_TO_JSVAL(str); *vp = STRING_TO_JSVAL(str);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Snarl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Snarl(JSContext *cx, uintN argc, jsval *vp)
{ {
if (argc < 1) { if (argc < 1) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED, JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED,
"compile", "0", "s"); "compile", "0", "s");
} }
jsval arg0 = argv[0]; JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
if (!thisobj)
return JS_FALSE;
jsval arg0 = JS_ARGV(cx, vp)[0];
if (!JSVAL_IS_STRING(arg0)) { if (!JSVAL_IS_STRING(arg0)) {
const char *typeName = JS_GetTypeName(cx, JS_TypeOfValue(cx, arg0)); const char *typeName = JS_GetTypeName(cx, JS_TypeOfValue(cx, arg0));
JS_ReportError(cx, "expected string to compile, got %s", typeName); JS_ReportError(cx, "expected string to compile, got %s", typeName);
@ -4011,9 +4050,10 @@ Snarl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!script) if (!script)
return JS_FALSE; return JS_FALSE;
JS_ExecuteScript(cx, obj, script, NULL); JS_ExecuteScript(cx, thisobj, script, NULL);
JS_DestroyScript(cx, script); JS_DestroyScript(cx, script);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -4040,15 +4080,15 @@ Wrap(JSContext *cx, uintN argc, jsval *vp)
/* We use a mix of JS_FS and JS_FN to test both kinds of natives. */ /* We use a mix of JS_FS and JS_FN to test both kinds of natives. */
static JSFunctionSpec shell_functions[] = { static JSFunctionSpec shell_functions[] = {
JS_FS("version", Version, 0,0,0), JS_FN("version", Version, 0,0),
JS_FS("options", Options, 0,0,0), JS_FN("options", Options, 0,0),
JS_FS("load", Load, 1,0,0), JS_FN("load", Load, 1,0),
JS_FN("readline", ReadLine, 0,0), JS_FN("readline", ReadLine, 0,0),
JS_FN("print", Print, 0,0), JS_FN("print", Print, 0,0),
JS_FN("putstr", PutStr, 0,0), JS_FN("putstr", PutStr, 0,0),
JS_FN("dateNow", Now, 0,0), JS_FN("dateNow", Now, 0,0),
JS_FS("help", Help, 0,0,0), JS_FN("help", Help, 0,0),
JS_FS("quit", Quit, 0,0,0), JS_FN("quit", Quit, 0,0),
JS_FN("assertEq", AssertEq, 2,0), JS_FN("assertEq", AssertEq, 2,0),
JS_FN("assertJit", AssertJit, 0,0), JS_FN("assertJit", AssertJit, 0,0),
JS_FN("gc", ::GC, 0,0), JS_FN("gc", ::GC, 0,0),
@ -4060,72 +4100,72 @@ static JSFunctionSpec shell_functions[] = {
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
JS_FN("gczeal", GCZeal, 1,0), JS_FN("gczeal", GCZeal, 1,0),
#endif #endif
JS_FS("setDebug", SetDebug, 1,0,0), JS_FN("setDebug", SetDebug, 1,0),
JS_FS("setDebuggerHandler", SetDebuggerHandler, 1,0,0), JS_FN("setDebuggerHandler", SetDebuggerHandler, 1,0),
JS_FS("setThrowHook", SetThrowHook, 1,0,0), JS_FN("setThrowHook", SetThrowHook, 1,0),
JS_FS("trap", Trap, 3,0,0), JS_FN("trap", Trap, 3,0),
JS_FS("untrap", Untrap, 2,0,0), JS_FN("untrap", Untrap, 2,0),
JS_FS("line2pc", LineToPC, 0,0,0), JS_FN("line2pc", LineToPC, 0,0),
JS_FS("pc2line", PCToLine, 0,0,0), JS_FN("pc2line", PCToLine, 0,0),
JS_FN("stackQuota", StackQuota, 0,0), JS_FN("stackQuota", StackQuota, 0,0),
JS_FS("stringsAreUTF8", StringsAreUTF8, 0,0,0), JS_FN("stringsAreUTF8", StringsAreUTF8, 0,0),
JS_FS("testUTF8", TestUTF8, 1,0,0), JS_FN("testUTF8", TestUTF8, 1,0),
JS_FS("throwError", ThrowError, 0,0,0), JS_FN("throwError", ThrowError, 0,0),
#ifdef DEBUG #ifdef DEBUG
JS_FS("dis", Disassemble, 1,0,0), JS_FN("dis", Disassemble, 1,0),
JS_FS("disfile", DisassFile, 1,0,0), JS_FN("disfile", DisassFile, 1,0),
JS_FS("dissrc", DisassWithSrc, 1,0,0), JS_FN("dissrc", DisassWithSrc, 1,0),
JS_FN("dumpHeap", DumpHeap, 0,0), JS_FN("dumpHeap", DumpHeap, 0,0),
JS_FS("dumpObject", DumpObject, 1,0,0), JS_FN("dumpObject", DumpObject, 1,0),
JS_FS("notes", Notes, 1,0,0), JS_FN("notes", Notes, 1,0),
JS_FS("tracing", Tracing, 0,0,0), JS_FN("tracing", Tracing, 0,0),
JS_FS("stats", DumpStats, 1,0,0), JS_FN("stats", DumpStats, 1,0),
#endif #endif
#ifdef TEST_CVTARGS #ifdef TEST_CVTARGS
JS_FS("cvtargs", ConvertArgs, 0,0,12), JS_FN("cvtargs", ConvertArgs, 0,0),
#endif #endif
JS_FN("build", BuildDate, 0,0), JS_FN("build", BuildDate, 0,0),
JS_FS("clear", Clear, 0,0,0), JS_FN("clear", Clear, 0,0),
JS_FN("intern", Intern, 1,0), JS_FN("intern", Intern, 1,0),
JS_FS("clone", Clone, 1,0,0), JS_FN("clone", Clone, 1,0),
JS_FS("seal", Seal, 1,0,1), JS_FN("seal", Seal, 1,0),
JS_FN("getpda", GetPDA, 1,0), JS_FN("getpda", GetPDA, 1,0),
JS_FN("getslx", GetSLX, 1,0), JS_FN("getslx", GetSLX, 1,0),
JS_FN("toint32", ToInt32, 1,0), JS_FN("toint32", ToInt32, 1,0),
JS_FS("evalcx", EvalInContext, 1,0,0), JS_FN("evalcx", EvalInContext, 1,0),
JS_FN("evalInFrame", EvalInFrame, 2,0), JS_FN("evalInFrame", EvalInFrame, 2,0),
JS_FN("shapeOf", ShapeOf, 1,0), JS_FN("shapeOf", ShapeOf, 1,0),
#ifdef MOZ_SHARK #ifdef MOZ_SHARK
JS_FS("startShark", js_StartShark, 0,0,0), JS_FN("startShark", js_StartShark, 0,0),
JS_FS("stopShark", js_StopShark, 0,0,0), JS_FN("stopShark", js_StopShark, 0,0),
JS_FS("connectShark", js_ConnectShark, 0,0,0), JS_FN("connectShark", js_ConnectShark, 0,0),
JS_FS("disconnectShark",js_DisconnectShark, 0,0,0), JS_FN("disconnectShark",js_DisconnectShark, 0,0),
#endif #endif
#ifdef MOZ_CALLGRIND #ifdef MOZ_CALLGRIND
JS_FS("startCallgrind", js_StartCallgrind, 0,0,0), JS_FN("startCallgrind", js_StartCallgrind, 0,0),
JS_FS("stopCallgrind", js_StopCallgrind, 0,0,0), JS_FN("stopCallgrind", js_StopCallgrind, 0,0),
JS_FS("dumpCallgrind", js_DumpCallgrind, 1,0,0), JS_FN("dumpCallgrind", js_DumpCallgrind, 1,0),
#endif #endif
#ifdef MOZ_VTUNE #ifdef MOZ_VTUNE
JS_FS("startVtune", js_StartVtune, 1,0,0), JS_FN("startVtune", js_StartVtune, 1,0),
JS_FS("stopVtune", js_StopVtune, 0,0,0), JS_FN("stopVtune", js_StopVtune, 0,0),
JS_FS("pauseVtune", js_PauseVtune, 0,0,0), JS_FN("pauseVtune", js_PauseVtune, 0,0),
JS_FS("resumeVtune", js_ResumeVtune, 0,0,0), JS_FN("resumeVtune", js_ResumeVtune, 0,0),
#endif #endif
#ifdef MOZ_TRACEVIS #ifdef MOZ_TRACEVIS
JS_FS("startTraceVis", StartTraceVisNative, 1,0,0), JS_FN("startTraceVis", StartTraceVisNative, 1,0),
JS_FS("stopTraceVis", StopTraceVisNative, 0,0,0), JS_FN("stopTraceVis", StopTraceVisNative, 0,0),
#endif #endif
#ifdef DEBUG_ARRAYS #ifdef DEBUG_ARRAYS
JS_FS("arrayInfo", js_ArrayInfo, 1,0,0), JS_FN("arrayInfo", js_ArrayInfo, 1,0),
#endif #endif
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
JS_FN("sleep", Sleep_fn, 1,0), JS_FN("sleep", Sleep_fn, 1,0),
JS_FN("scatter", Scatter, 1,0), JS_FN("scatter", Scatter, 1,0),
#endif #endif
JS_FS("snarf", Snarf, 0,0,0), JS_FN("snarf", Snarf, 0,0),
JS_FS("snarl", Snarl, 0,0,0), JS_FN("snarl", Snarl, 0,0),
JS_FS("read", Snarf, 0,0,0), JS_FN("read", Snarf, 0,0),
JS_FN("compile", Compile, 1,0), JS_FN("compile", Compile, 1,0),
JS_FN("parse", Parse, 1,0), JS_FN("parse", Parse, 1,0),
JS_FN("timeout", Timeout, 1,0), JS_FN("timeout", Timeout, 1,0),
@ -4278,7 +4318,7 @@ CheckHelpMessages()
#endif #endif
static JSBool static JSBool
Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Help(JSContext *cx, uintN argc, jsval *vp)
{ {
uintN i, j; uintN i, j;
int did_header, did_something; int did_header, did_something;
@ -4294,6 +4334,7 @@ Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
fprintf(gOutFile, "%s\n", shell_help_messages[i]); fprintf(gOutFile, "%s\n", shell_help_messages[i]);
} else { } else {
did_header = 0; did_header = 0;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
did_something = 0; did_something = 0;
type = JS_TypeOfValue(cx, argv[i]); type = JS_TypeOfValue(cx, argv[i]);
@ -4328,6 +4369,7 @@ Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
} }
} }
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -4432,19 +4474,20 @@ static JSPropertySpec its_props[] = {
}; };
static JSBool static JSBool
its_bindMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, its_bindMethod(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
char *name; char *name;
JSObject *method; JSObject *method;
if (!JS_ConvertArguments(cx, argc, argv, "so", &name, &method)) JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "so", &name, &method))
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(method); *vp = OBJECT_TO_JSVAL(method);
if (JS_TypeOfValue(cx, *rval) != JSTYPE_FUNCTION) { if (JS_TypeOfValue(cx, *vp) != JSTYPE_FUNCTION) {
JSString *valstr = JS_ValueToString(cx, *rval); JSString *valstr = JS_ValueToString(cx, *vp);
if (valstr) { if (valstr) {
JS_ReportError(cx, "can't bind method %s to non-callable object %s", JS_ReportError(cx, "can't bind method %s to non-callable object %s",
name, JS_GetStringBytes(valstr)); name, JS_GetStringBytes(valstr));
@ -4452,15 +4495,15 @@ its_bindMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return JS_FALSE; return JS_FALSE;
} }
if (!JS_DefineProperty(cx, obj, name, *rval, NULL, NULL, JSPROP_ENUMERATE)) if (!JS_DefineProperty(cx, thisobj, name, *vp, NULL, NULL, JSPROP_ENUMERATE))
return JS_FALSE; return JS_FALSE;
return JS_SetParent(cx, method, obj); return JS_SetParent(cx, method, thisobj);
} }
static JSFunctionSpec its_methods[] = { static JSFunctionSpec its_methods[] = {
{"bindMethod", its_bindMethod, 2,0,0}, {"bindMethod", its_bindMethod, 2,0},
{NULL,NULL,0,0,0} {NULL,NULL,0,0}
}; };
#ifdef JSD_LOWLEVEL_SOURCE #ifdef JSD_LOWLEVEL_SOURCE
@ -4753,7 +4796,7 @@ my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
#if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX) #if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
static JSBool static JSBool
Exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Exec(JSContext *cx, uintN argc, jsval *vp)
{ {
JSFunction *fun; JSFunction *fun;
const char *name, **nargv; const char *name, **nargv;
@ -4762,7 +4805,9 @@ Exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
pid_t pid; pid_t pid;
int status; int status;
fun = JS_ValueToFunction(cx, argv[-2]); JS_SET_RVAL(cx, vp, JSVAL_VOID);
fun = JS_ValueToFunction(cx, vp[0]);
if (!fun) if (!fun)
return JS_FALSE; return JS_FALSE;
if (!fun->atom) if (!fun->atom)
@ -4773,6 +4818,7 @@ Exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!nargv) if (!nargv)
return JS_FALSE; return JS_FALSE;
nargv[0] = name; nargv[0] = name;
jsval *argv = JS_ARGV(cx, vp);
for (i = 1; i < nargc; i++) { for (i = 1; i < nargc; i++) {
str = JS_ValueToString(cx, argv[i-1]); str = JS_ValueToString(cx, argv[i-1]);
if (!str) { if (!str) {

Просмотреть файл

@ -624,8 +624,7 @@ class Worker : public WorkerParent
// is collected. Therefore it's safe to stash a pointer (a weak // is collected. Therefore it's safe to stash a pointer (a weak
// reference) to the C++ Worker object in the reserved slot. // reference) to the C++ Worker object in the reserved slot.
post = JS_GetFunctionObject(JS_DefineFunction(context, global, "postMessage", post = JS_GetFunctionObject(JS_DefineFunction(context, global, "postMessage",
(JSNative) jsPostMessageToParent, 1, (JSNative) jsPostMessageToParent, 1, 0));
JSFUN_FAST_NATIVE));
if (!post || !JS_SetReservedSlot(context, post, 0, PRIVATE_TO_JSVAL(this))) if (!post || !JS_SetReservedSlot(context, post, 0, PRIVATE_TO_JSVAL(this)))
goto bad; goto bad;
@ -685,9 +684,9 @@ class Worker : public WorkerParent
return true; return true;
} }
static JSBool jsPostMessageToParent(JSContext *cx, int argc, jsval *vp); static JSBool jsPostMessageToParent(JSContext *cx, uintN argc, jsval *vp);
static JSBool jsPostMessageToChild(JSContext *cx, int argc, jsval *vp); static JSBool jsPostMessageToChild(JSContext *cx, uintN argc, jsval *vp);
static JSBool jsTerminate(JSContext *cx, int argc, jsval *vp); static JSBool jsTerminate(JSContext *cx, uintN argc, jsval *vp);
bool checkTermination() { bool checkTermination() {
AutoLock hold(lock); AutoLock hold(lock);
@ -807,20 +806,20 @@ class Worker : public WorkerParent
return true; return true;
} }
static JSBool jsConstruct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { static JSBool jsConstruct(JSContext *cx, uintN argc, jsval *vp) {
WorkerParent *parent; WorkerParent *parent;
if (!getWorkerParentFromConstructor(cx, JSVAL_TO_OBJECT(argv[-2]), &parent)) if (!getWorkerParentFromConstructor(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), &parent))
return false; return false;
JSString *scriptName = JS_ValueToString(cx, argv[0]);
JSString *scriptName = JS_ValueToString(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID);
if (!scriptName) if (!scriptName)
return false; return false;
argv[0] = STRING_TO_JSVAL(scriptName);
obj = JS_NewObject(cx, &jsWorkerClass, NULL, NULL); JSObject *obj = JS_NewObject(cx, &jsWorkerClass, NULL, NULL);
if (!obj || !create(cx, parent, scriptName, obj)) if (!obj || !create(cx, parent, scriptName, obj))
return false; return false;
*rval = OBJECT_TO_JSVAL(obj); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
return true; return true;
} }
@ -1126,7 +1125,7 @@ Worker::processOneEvent()
} }
JSBool JSBool
Worker::jsPostMessageToParent(JSContext *cx, int argc, jsval *vp) Worker::jsPostMessageToParent(JSContext *cx, uintN argc, jsval *vp)
{ {
jsval workerval; jsval workerval;
if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0, &workerval)) if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0, &workerval))
@ -1150,11 +1149,12 @@ Worker::jsPostMessageToParent(JSContext *cx, int argc, jsval *vp)
delete event; delete event;
JS_ReportOutOfMemory(cx); JS_ReportOutOfMemory(cx);
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true; return true;
} }
JSBool JSBool
Worker::jsPostMessageToChild(JSContext *cx, int argc, jsval *vp) Worker::jsPostMessageToChild(JSContext *cx, uintN argc, jsval *vp)
{ {
JSObject *workerobj = JS_THIS_OBJECT(cx, vp); JSObject *workerobj = JS_THIS_OBJECT(cx, vp);
if (!workerobj) if (!workerobj)
@ -1177,12 +1177,15 @@ Worker::jsPostMessageToChild(JSContext *cx, int argc, jsval *vp)
JS_ReportOutOfMemory(cx); JS_ReportOutOfMemory(cx);
return false; return false;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true; return true;
} }
JSBool JSBool
Worker::jsTerminate(JSContext *cx, int argc, jsval *vp) Worker::jsTerminate(JSContext *cx, uintN argc, jsval *vp)
{ {
JS_SET_RVAL(cx, vp, JSVAL_VOID);
JSObject *workerobj = JS_THIS_OBJECT(cx, vp); JSObject *workerobj = JS_THIS_OBJECT(cx, vp);
if (!workerobj) if (!workerobj)
return false; return false;

Просмотреть файл

@ -5164,7 +5164,7 @@ function testSlowNativeBail() {
for (var i = 0; i < a.length; i++) for (var i = 0; i < a.length; i++)
new RegExp(a[i]); new RegExp(a[i]);
} catch (exc) { } catch (exc) {
assertEq(""+exc.stack.match(/^RegExp/), "RegExp"); assertEq(""+exc, "SyntaxError: invalid quantifier");
} }
} }
test(testSlowNativeBail); test(testSlowNativeBail);

Просмотреть файл

@ -4,7 +4,7 @@ function testSlowNativeBail() {
for (var i = 0; i < a.length; i++) for (var i = 0; i < a.length; i++)
new RegExp(a[i]); new RegExp(a[i]);
} catch (exc) { } catch (exc) {
assertEq(""+exc.stack.match(/^RegExp/), "RegExp"); assertEq(""+exc, "SyntaxError: invalid quantifier");
} }
} }
testSlowNativeBail(); testSlowNativeBail();

Просмотреть файл

@ -188,13 +188,13 @@ mozJSLoaderErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
} }
static JSBool static JSBool
Dump(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Dump(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
if (!argc) if (!argc)
return JS_TRUE; return JS_TRUE;
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
@ -204,23 +204,23 @@ Dump(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
} }
static JSBool static JSBool
Debug(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Debug(JSContext *cx, uintN argc, jsval *vp)
{ {
#ifdef DEBUG #ifdef DEBUG
return Dump(cx, obj, argc, argv, rval); return Dump(cx, argc, vp);
#else #else
return JS_TRUE; return JS_TRUE;
#endif #endif
} }
static JSBool static JSBool
Atob(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Atob(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
if (!argc) if (!argc)
return JS_TRUE; return JS_TRUE;
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
@ -245,18 +245,18 @@ Atob(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*rval = STRING_TO_JSVAL(str); JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Btoa(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Btoa(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
if (!argc) if (!argc)
return JS_TRUE; return JS_TRUE;
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
@ -273,37 +273,37 @@ Btoa(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*rval = STRING_TO_JSVAL(str); JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
return JS_TRUE; return JS_TRUE;
} }
static JSFunctionSpec gGlobalFun[] = { static JSFunctionSpec gGlobalFun[] = {
{"dump", Dump, 1,0,0}, {"dump", Dump, 1,0},
{"debug", Debug, 1,0,0}, {"debug", Debug, 1,0},
{"atob", Atob, 1,0,0}, {"atob", Atob, 1,0},
{"btoa", Btoa, 1,0,0}, {"btoa", Btoa, 1,0},
#ifdef MOZ_SHARK #ifdef MOZ_SHARK
{"startShark", js_StartShark, 0,0,0}, {"startShark", js_StartShark, 0,0},
{"stopShark", js_StopShark, 0,0,0}, {"stopShark", js_StopShark, 0,0},
{"connectShark", js_ConnectShark, 0,0,0}, {"connectShark", js_ConnectShark, 0,0},
{"disconnectShark", js_DisconnectShark,0,0,0}, {"disconnectShark", js_DisconnectShark,0,0},
#endif #endif
#ifdef MOZ_CALLGRIND #ifdef MOZ_CALLGRIND
{"startCallgrind", js_StartCallgrind, 0,0,0}, {"startCallgrind", js_StartCallgrind, 0,0},
{"stopCallgrind", js_StopCallgrind, 0,0,0}, {"stopCallgrind", js_StopCallgrind, 0,0},
{"dumpCallgrind", js_DumpCallgrind, 1,0,0}, {"dumpCallgrind", js_DumpCallgrind, 1,0},
#endif #endif
#ifdef MOZ_VTUNE #ifdef MOZ_VTUNE
{"startVtune", js_StartVtune, 1,0,0}, {"startVtune", js_StartVtune, 1,0},
{"stopVtune", js_StopVtune, 0,0,0}, {"stopVtune", js_StopVtune, 0,0},
{"pauseVtune", js_PauseVtune, 0,0,0}, {"pauseVtune", js_PauseVtune, 0,0},
{"resumeVtune", js_ResumeVtune, 0,0,0}, {"resumeVtune", js_ResumeVtune, 0,0},
#endif #endif
#ifdef MOZ_TRACEVIS #ifdef MOZ_TRACEVIS
{"initEthogram", js_InitEthogram, 0,0,0}, {"initEthogram", js_InitEthogram, 0,0},
{"shutdownEthogram", js_ShutdownEthogram, 0,0,0}, {"shutdownEthogram", js_ShutdownEthogram, 0,0},
#endif #endif
{nsnull,nsnull,0,0,0} {nsnull,nsnull,0,0}
}; };
class JSCLContextHelper class JSCLContextHelper

Просмотреть файл

@ -288,7 +288,7 @@ my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
// Don't report an exception from inner JS frames as the callers may intend // Don't report an exception from inner JS frames as the callers may intend
// to handle it. // to handle it.
while ((fp = JS_FrameIterator(cx, &fp))) { while ((fp = JS_FrameIterator(cx, &fp))) {
if (!JS_IsNativeFrame(cx, fp)) { if (JS_IsScriptFrame(cx, fp)) {
return; return;
} }
} }
@ -371,7 +371,7 @@ my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
} }
static JSBool static JSBool
ReadLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ReadLine(JSContext *cx, uintN argc, jsval *vp)
{ {
// While 4096 might be quite arbitrary, this is something to be fixed in // While 4096 might be quite arbitrary, this is something to be fixed in
// bug 105707. It is also the same limit as in ProcessFile. // bug 105707. It is also the same limit as in ProcessFile.
@ -380,10 +380,9 @@ ReadLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
/* If a prompt was specified, construct the string */ /* If a prompt was specified, construct the string */
if (argc > 0) { if (argc > 0) {
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
argv[0] = STRING_TO_JSVAL(str);
} else { } else {
str = JSVAL_TO_STRING(JS_GetEmptyStringValue(cx)); str = JSVAL_TO_STRING(JS_GetEmptyStringValue(cx));
} }
@ -396,7 +395,7 @@ ReadLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
unsigned int buflen = strlen(buf); unsigned int buflen = strlen(buf);
if (buflen == 0) { if (buflen == 0) {
if (feof(gInFile)) { if (feof(gInFile)) {
*rval = JSVAL_NULL; JS_SET_RVAL(cx, vp, JSVAL_NULL);
return JS_TRUE; return JS_TRUE;
} }
} else if (buf[buflen - 1] == '\n') { } else if (buf[buflen - 1] == '\n') {
@ -408,16 +407,17 @@ ReadLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*rval = STRING_TO_JSVAL(str); JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Print(JSContext *cx, uintN argc, jsval *vp)
{ {
uintN i, n; uintN i, n;
JSString *str; JSString *str;
jsval *argv = JS_ARGV(cx, vp);
for (i = n = 0; i < argc; i++) { for (i = n = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]); str = JS_ValueToString(cx, argv[i]);
if (!str) if (!str)
@ -428,17 +428,20 @@ Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
n++; n++;
if (n) if (n)
fputc('\n', gOutFile); fputc('\n', gOutFile);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Dump(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Dump(JSContext *cx, uintN argc, jsval *vp)
{ {
JS_SET_RVAL(cx, vp, JSVAL_VOID);
JSString *str; JSString *str;
if (!argc) if (!argc)
return JS_TRUE; return JS_TRUE;
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
@ -448,7 +451,7 @@ Dump(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
} }
static JSBool static JSBool
Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Load(JSContext *cx, uintN argc, jsval *vp)
{ {
uintN i; uintN i;
JSString *str; JSString *str;
@ -458,6 +461,11 @@ Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
jsval result; jsval result;
FILE *file; FILE *file;
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]); str = JS_ValueToString(cx, argv[i]);
if (!str) if (!str)
@ -482,31 +490,33 @@ Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!ok) if (!ok)
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Version(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Version(JSContext *cx, uintN argc, jsval *vp)
{ {
if (argc > 0 && JSVAL_IS_INT(argv[0])) if (argc > 0 && JSVAL_IS_INT(JS_ARGV(cx, vp)[0]))
*rval = INT_TO_JSVAL(JS_SetVersion(cx, JSVersion(JSVAL_TO_INT(argv[0])))); JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_SetVersion(cx, JSVersion(JSVAL_TO_INT(JS_ARGV(cx, vp)[0])))));
else else
*rval = INT_TO_JSVAL(JS_GetVersion(cx)); JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_GetVersion(cx)));
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
BuildDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) BuildDate(JSContext *cx, uintN argc, jsval *vp)
{ {
fprintf(gOutFile, "built on %s at %s\n", __DATE__, __TIME__); fprintf(gOutFile, "built on %s at %s\n", __DATE__, __TIME__);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Quit(JSContext *cx, uintN argc, jsval *vp)
{ {
gExitCode = 0; gExitCode = 0;
JS_ConvertArguments(cx, argc, argv,"/ i", &gExitCode); JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp),"/ i", &gExitCode);
gQuitting = JS_TRUE; gQuitting = JS_TRUE;
// exit(0); // exit(0);
@ -514,23 +524,24 @@ Quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
} }
static JSBool static JSBool
DumpXPC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) DumpXPC(JSContext *cx, uintN argc, jsval *vp)
{ {
int32 depth = 2; int32 depth = 2;
if (argc > 0) { if (argc > 0) {
if (!JS_ValueToInt32(cx, argv[0], &depth)) if (!JS_ValueToInt32(cx, JS_ARGV(cx, vp)[0], &depth))
return JS_FALSE; return JS_FALSE;
} }
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID()); nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
if(xpc) if(xpc)
xpc->DebugDump((int16)depth); xpc->DebugDump((int16)depth);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
GC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) GC(JSContext *cx, uintN argc, jsval *vp)
{ {
JSRuntime *rt; JSRuntime *rt;
uint32 preBytes; uint32 preBytes;
@ -549,18 +560,20 @@ GC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
#ifdef JS_GCMETER #ifdef JS_GCMETER
js_DumpGCStats(rt, stdout); js_DumpGCStats(rt, stdout);
#endif #endif
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
static JSBool static JSBool
GCZeal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) GCZeal(JSContext *cx, uintN argc, jsval *vp)
{ {
uint32 zeal; uint32 zeal;
if (!JS_ValueToECMAUint32(cx, argv[0], &zeal)) if (!JS_ValueToECMAUint32(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID, &zeal))
return JS_FALSE; return JS_FALSE;
JS_SetGCZeal(cx, (PRUint8)zeal); JS_SetGCZeal(cx, (PRUint8)zeal);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
@ -568,7 +581,7 @@ GCZeal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
#ifdef DEBUG #ifdef DEBUG
static JSBool static JSBool
DumpHeap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) DumpHeap(JSContext *cx, uintN argc, jsval *vp)
{ {
char *fileName = NULL; char *fileName = NULL;
void* startThing = NULL; void* startThing = NULL;
@ -576,12 +589,14 @@ DumpHeap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
void *thingToFind = NULL; void *thingToFind = NULL;
size_t maxDepth = (size_t)-1; size_t maxDepth = (size_t)-1;
void *thingToIgnore = NULL; void *thingToIgnore = NULL;
jsval *vp;
FILE *dumpFile; FILE *dumpFile;
JSBool ok; JSBool ok;
vp = &argv[0]; jsval *argv = JS_ARGV(cx, vp);
if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) { JS_SET_RVAL(cx, vp, JSVAL_VOID);
vp = argv + 0;
if (argc > 0 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
JSString *str; JSString *str;
str = JS_ValueToString(cx, *vp); str = JS_ValueToString(cx, *vp);
@ -591,23 +606,23 @@ DumpHeap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
fileName = JS_GetStringBytes(str); fileName = JS_GetStringBytes(str);
} }
vp = &argv[1]; vp = argv + 1;
if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) { if (argc > 1 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
if (!JSVAL_IS_TRACEABLE(*vp)) if (!JSVAL_IS_TRACEABLE(*vp))
goto not_traceable_arg; goto not_traceable_arg;
startThing = JSVAL_TO_TRACEABLE(*vp); startThing = JSVAL_TO_TRACEABLE(*vp);
startTraceKind = JSVAL_TRACE_KIND(*vp); startTraceKind = JSVAL_TRACE_KIND(*vp);
} }
vp = &argv[2]; vp = argv + 2;
if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) { if (argc > 2 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
if (!JSVAL_IS_TRACEABLE(*vp)) if (!JSVAL_IS_TRACEABLE(*vp))
goto not_traceable_arg; goto not_traceable_arg;
thingToFind = JSVAL_TO_TRACEABLE(*vp); thingToFind = JSVAL_TO_TRACEABLE(*vp);
} }
vp = &argv[3]; vp = argv + 3;
if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) { if (argc > 3 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
uint32 depth; uint32 depth;
if (!JS_ValueToECMAUint32(cx, *vp, &depth)) if (!JS_ValueToECMAUint32(cx, *vp, &depth))
@ -615,8 +630,8 @@ DumpHeap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
maxDepth = depth; maxDepth = depth;
} }
vp = &argv[4]; vp = argv + 4;
if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) { if (argc > 4 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
if (!JSVAL_IS_TRACEABLE(*vp)) if (!JSVAL_IS_TRACEABLE(*vp))
goto not_traceable_arg; goto not_traceable_arg;
thingToIgnore = JSVAL_TO_TRACEABLE(*vp); thingToIgnore = JSVAL_TO_TRACEABLE(*vp);
@ -649,14 +664,15 @@ DumpHeap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
#endif /* DEBUG */ #endif /* DEBUG */
static JSBool static JSBool
Clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Clear(JSContext *cx, uintN argc, jsval *vp)
{ {
if (argc > 0 && !JSVAL_IS_PRIMITIVE(argv[0])) { if (argc > 0 && !JSVAL_IS_PRIMITIVE(JS_ARGV(cx, vp)[0])) {
JS_ClearScope(cx, JSVAL_TO_OBJECT(argv[0])); JS_ClearScope(cx, JSVAL_TO_OBJECT(JS_ARGV(cx, vp)[0]));
} else { } else {
JS_ReportError(cx, "'clear' requires an object"); JS_ReportError(cx, "'clear' requires an object");
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
@ -664,16 +680,15 @@ Clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
static JSBool static JSBool
SendCommand(JSContext* cx, SendCommand(JSContext* cx,
JSObject* obj,
uintN argc, uintN argc,
jsval* argv, jsval* vp)
jsval* rval)
{ {
if (argc == 0) { if (argc == 0) {
JS_ReportError(cx, "Function takes at least one argument!"); JS_ReportError(cx, "Function takes at least one argument!");
return JS_FALSE; return JS_FALSE;
} }
jsval *argv = JS_ARGV(cx, vp);
JSString* str = JS_ValueToString(cx, argv[0]); JSString* str = JS_ValueToString(cx, argv[0]);
if (!str) { if (!str) {
JS_ReportError(cx, "Could not convert argument 1 to string!"); JS_ReportError(cx, "Could not convert argument 1 to string!");
@ -690,19 +705,18 @@ SendCommand(JSContext* cx,
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
GetChildGlobalObject(JSContext* cx, GetChildGlobalObject(JSContext* cx,
JSObject*,
uintN, uintN,
jsval*, jsval* vp)
jsval* rval)
{ {
JSObject* global; JSObject* global;
if (XRE_GetChildGlobalObject(cx, &global)) { if (XRE_GetChildGlobalObject(cx, &global)) {
*rval = OBJECT_TO_JSVAL(global); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(global));
return JS_TRUE; return JS_TRUE;
} }
return JS_FALSE; return JS_FALSE;
@ -758,7 +772,7 @@ MapContextOptionNameToFlag(JSContext* cx, const char* name)
} }
static JSBool static JSBool
Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Options(JSContext *cx, uintN argc, jsval *vp)
{ {
uint32 optset, flag; uint32 optset, flag;
JSString *str; JSString *str;
@ -767,6 +781,7 @@ Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JSBool found; JSBool found;
optset = 0; optset = 0;
jsval *argv = JS_ARGV(cx, vp);
for (uintN i = 0; i < argc; i++) { for (uintN i = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]); str = JS_ValueToString(cx, argv[i]);
if (!str) if (!str)
@ -804,7 +819,7 @@ Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
free(names); free(names);
return JS_FALSE; return JS_FALSE;
} }
*rval = STRING_TO_JSVAL(str); JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
return JS_TRUE; return JS_TRUE;
} }
@ -827,40 +842,40 @@ Parent(JSContext *cx, uintN argc, jsval *vp)
} }
static JSFunctionSpec glob_functions[] = { static JSFunctionSpec glob_functions[] = {
{"print", Print, 0,0,0}, {"print", Print, 0,0},
{"readline", ReadLine, 1,0,0}, {"readline", ReadLine, 1,0},
{"load", Load, 1,0,0}, {"load", Load, 1,0},
{"quit", Quit, 0,0,0}, {"quit", Quit, 0,0},
{"version", Version, 1,0,0}, {"version", Version, 1,0},
{"build", BuildDate, 0,0,0}, {"build", BuildDate, 0,0},
{"dumpXPC", DumpXPC, 1,0,0}, {"dumpXPC", DumpXPC, 1,0},
{"dump", Dump, 1,0,0}, {"dump", Dump, 1,0},
{"gc", GC, 0,0,0}, {"gc", GC, 0,0},
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
{"gczeal", GCZeal, 1,0,0}, {"gczeal", GCZeal, 1,0},
#endif #endif
{"clear", Clear, 1,0,0}, {"clear", Clear, 1,0},
{"options", Options, 0,0,0}, {"options", Options, 0,0},
JS_FN("parent", Parent, 1,0), JS_FN("parent", Parent, 1,0),
#ifdef DEBUG #ifdef DEBUG
{"dumpHeap", DumpHeap, 5,0,0}, {"dumpHeap", DumpHeap, 5,0},
#endif #endif
#ifdef MOZ_IPC #ifdef MOZ_IPC
{"sendCommand", SendCommand, 1,0,0}, {"sendCommand", SendCommand, 1,0},
{"getChildGlobalObject", GetChildGlobalObject, 0,0,0}, {"getChildGlobalObject", GetChildGlobalObject, 0,0},
#endif #endif
#ifdef MOZ_SHARK #ifdef MOZ_SHARK
{"startShark", js_StartShark, 0,0,0}, {"startShark", js_StartShark, 0,0},
{"stopShark", js_StopShark, 0,0,0}, {"stopShark", js_StopShark, 0,0},
{"connectShark", js_ConnectShark, 0,0,0}, {"connectShark", js_ConnectShark, 0,0},
{"disconnectShark", js_DisconnectShark, 0,0,0}, {"disconnectShark", js_DisconnectShark, 0,0},
#endif #endif
#ifdef MOZ_CALLGRIND #ifdef MOZ_CALLGRIND
{"startCallgrind", js_StartCallgrind, 0,0,0}, {"startCallgrind", js_StartCallgrind, 0,0},
{"stopCallgrind", js_StopCallgrind, 0,0,0}, {"stopCallgrind", js_StopCallgrind, 0,0},
{"dumpCallgrind", js_DumpCallgrind, 1,0,0}, {"dumpCallgrind", js_DumpCallgrind, 1,0},
#endif #endif
{nsnull,nsnull,0,0,0} {nsnull,nsnull,0,0}
}; };
JSClass global_class = { JSClass global_class = {

Просмотреть файл

@ -375,16 +375,20 @@ RewrapForContent(JSContext *cx, JSObject *wrapperObj, jsval *vp);
// This function wrapper calls a function from untrusted content into chrome. // This function wrapper calls a function from untrusted content into chrome.
static JSBool static JSBool
XPC_COW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_COW_FunctionWrapper(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
jsval funToCall; jsval funToCall;
if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(argv[-2]), if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)),
XPCWrapper::eWrappedFunctionSlot, &funToCall)) { XPCWrapper::eWrappedFunctionSlot, &funToCall)) {
return JS_FALSE; return JS_FALSE;
} }
JSObject *scope = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(funToCall)); JSObject *scope = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(funToCall));
jsval *argv = JS_ARGV(cx, vp);
for (uintN i = 0; i < argc; ++i) { for (uintN i = 0; i < argc; ++i) {
if (!JSVAL_IS_PRIMITIVE(argv[i]) && if (!JSVAL_IS_PRIMITIVE(argv[i]) &&
!RewrapObject(cx, scope, JSVAL_TO_OBJECT(argv[i]), XPCNW_EXPLICIT, !RewrapObject(cx, scope, JSVAL_TO_OBJECT(argv[i]), XPCNW_EXPLICIT,
@ -393,9 +397,9 @@ XPC_COW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
} }
} }
if (!RewrapObject(cx, scope, obj, XPCNW_EXPLICIT, rval) || if (!RewrapObject(cx, scope, obj, XPCNW_EXPLICIT, vp) ||
!JS_CallFunctionValue(cx, JSVAL_TO_OBJECT(*rval), funToCall, argc, argv, !JS_CallFunctionValue(cx, JSVAL_TO_OBJECT(*vp), funToCall, argc,
rval)) { JS_ARGV(cx, vp), vp)) {
return JS_FALSE; return JS_FALSE;
} }
@ -404,9 +408,9 @@ XPC_COW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return JS_FALSE; return JS_FALSE;
} }
return JSVAL_IS_PRIMITIVE(*rval) || return JSVAL_IS_PRIMITIVE(*vp) ||
RewrapObject(cx, JS_GetGlobalForObject(cx, scope), RewrapObject(cx, JS_GetGlobalForObject(cx, scope),
JSVAL_TO_OBJECT(*rval), COW, rval); JSVAL_TO_OBJECT(*vp), COW, vp);
} }
static JSBool static JSBool

Просмотреть файл

@ -78,11 +78,10 @@ XPC_XOW_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
jsval *vp); jsval *vp);
static JSBool static JSBool
XPC_XOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); XPC_XOW_Call(JSContext *cx, uintN argc, jsval *vp);
static JSBool static JSBool
XPC_XOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_XOW_Construct(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static JSBool static JSBool
XPC_XOW_HasInstance(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp); XPC_XOW_HasInstance(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
@ -143,8 +142,7 @@ GetWrappedObject(JSContext *cx, JSObject *wrapper)
} }
static JSBool static JSBool
XPC_XOW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_XOW_FunctionWrapper(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
// This flag is set on objects that were created for UniversalXPConnect- // This flag is set on objects that were created for UniversalXPConnect-
// enabled code. // enabled code.
@ -495,8 +493,7 @@ WrapObject(JSContext *cx, JSObject *parent, jsval *vp, XPCWrappedNative* wn)
using namespace XPCCrossOriginWrapper; using namespace XPCCrossOriginWrapper;
static JSBool static JSBool
XPC_XOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_XOW_toString(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static JSBool static JSBool
IsValFrame(JSObject *obj, jsid id, XPCWrappedNative *wn) IsValFrame(JSObject *obj, jsid id, XPCWrappedNative *wn)
@ -532,9 +529,12 @@ static JSBool
WrapSameOriginProp(JSContext *cx, JSObject *outerObj, jsval *vp); WrapSameOriginProp(JSContext *cx, JSObject *outerObj, jsval *vp);
static JSBool static JSBool
XPC_XOW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_XOW_FunctionWrapper(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
JSObject *wrappedObj, *outerObj = obj; JSObject *wrappedObj, *outerObj = obj;
// Allow 'this' to be either an XOW, in which case we unwrap it. // Allow 'this' to be either an XOW, in which case we unwrap it.
@ -551,7 +551,7 @@ XPC_XOW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
wrappedObj = obj; wrappedObj = obj;
} }
JSObject *funObj = JSVAL_TO_OBJECT(argv[-2]); JSObject *funObj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
jsval funToCall; jsval funToCall;
if (!JS_GetReservedSlot(cx, funObj, eWrappedFunctionSlot, &funToCall)) { if (!JS_GetReservedSlot(cx, funObj, eWrappedFunctionSlot, &funToCall)) {
return JS_FALSE; return JS_FALSE;
@ -577,15 +577,15 @@ XPC_XOW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
NS_ASSERTION(native, "How'd we get here with a scripted function?"); NS_ASSERTION(native, "How'd we get here with a scripted function?");
#endif #endif
if (!JS_CallFunctionValue(cx, wrappedObj, funToCall, argc, argv, rval)) { if (!JS_CallFunctionValue(cx, wrappedObj, funToCall, argc, JS_ARGV(cx, vp), vp)) {
return JS_FALSE; return JS_FALSE;
} }
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
return WrapSameOriginProp(cx, outerObj, rval); return WrapSameOriginProp(cx, outerObj, vp);
} }
return RewrapIfNeeded(cx, obj, rval); return RewrapIfNeeded(cx, obj, vp);
} }
static JSBool static JSBool
@ -997,7 +997,8 @@ XPC_XOW_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
// Converting the prototype to something. // Converting the prototype to something.
if (type == JSTYPE_STRING || type == JSTYPE_VOID) { if (type == JSTYPE_STRING || type == JSTYPE_VOID) {
return XPC_XOW_toString(cx, obj, 0, nsnull, vp); jsval args[2] = { JSVAL_VOID, OBJECT_TO_JSVAL(obj) };
return XPC_XOW_toString(cx, 0, args);
} }
*vp = OBJECT_TO_JSVAL(obj); *vp = OBJECT_TO_JSVAL(obj);
@ -1080,8 +1081,13 @@ XPC_XOW_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
} }
static JSBool static JSBool
XPC_XOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) XPC_XOW_Call(JSContext *cx, uintN argc, jsval *vp)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj) {
return JS_FALSE;
}
JSObject *wrappedObj = GetWrappedObject(cx, obj); JSObject *wrappedObj = GetWrappedObject(cx, obj);
if (!wrappedObj) { if (!wrappedObj) {
// Nothing to call. // Nothing to call.
@ -1098,22 +1104,21 @@ XPC_XOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
return JS_FALSE; return JS_FALSE;
} }
JSObject *callee = JSVAL_TO_OBJECT(argv[-2]); JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
NS_ASSERTION(GetWrappedObject(cx, callee), "How'd we get here?"); NS_ASSERTION(GetWrappedObject(cx, callee), "How'd we get here?");
callee = GetWrappedObject(cx, callee); callee = GetWrappedObject(cx, callee);
if (!JS_CallFunctionValue(cx, obj, OBJECT_TO_JSVAL(callee), argc, argv, if (!JS_CallFunctionValue(cx, obj, OBJECT_TO_JSVAL(callee), argc,
rval)) { JS_ARGV(cx, vp), vp)) {
return JS_FALSE; return JS_FALSE;
} }
return RewrapIfNeeded(cx, callee, rval); return RewrapIfNeeded(cx, callee, vp);
} }
static JSBool static JSBool
XPC_XOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_XOW_Construct(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *realObj = GetWrapper(JSVAL_TO_OBJECT(argv[-2])); JSObject *realObj = GetWrapper(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
JSObject *wrappedObj = GetWrappedObject(cx, realObj); JSObject *wrappedObj = GetWrappedObject(cx, realObj);
if (!wrappedObj) { if (!wrappedObj) {
// Nothing to construct. // Nothing to construct.
@ -1129,12 +1134,13 @@ XPC_XOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return JS_FALSE; return JS_FALSE;
} }
if (!JS_CallFunctionValue(cx, obj, OBJECT_TO_JSVAL(wrappedObj), argc, argv, JSObject *obj = JS_New(cx, wrappedObj, argc, JS_ARGV(cx, vp));
rval)) { if (!obj) {
return JS_FALSE; return JS_FALSE;
} }
return RewrapIfNeeded(cx, wrappedObj, rval); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
return RewrapIfNeeded(cx, wrappedObj, vp);
} }
static JSBool static JSBool
@ -1275,9 +1281,12 @@ XPC_XOW_WrappedObject(JSContext *cx, JSObject *obj)
} }
static JSBool static JSBool
XPC_XOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_XOW_toString(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
obj = GetWrapper(obj); obj = GetWrapper(obj);
if (!obj) { if (!obj) {
return ThrowException(NS_ERROR_UNEXPECTED, cx); return ThrowException(NS_ERROR_UNEXPECTED, cx);
@ -1292,7 +1301,7 @@ XPC_XOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
if (!str) { if (!str) {
return JS_FALSE; return JS_FALSE;
} }
*rval = STRING_TO_JSVAL(str); JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
return JS_TRUE; return JS_TRUE;
} }
@ -1318,5 +1327,5 @@ XPC_XOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
XPCWrappedNative *wn = XPCWrappedNative *wn =
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, wrappedObj); XPCWrappedNative::GetWrappedNativeOfJSObject(cx, wrappedObj);
return NativeToString(cx, wn, argc, argv, rval, JS_FALSE); return NativeToString(cx, wn, argc, JS_ARGV(cx, vp), vp, JS_FALSE);
} }

Просмотреть файл

@ -73,12 +73,10 @@ XPC_NW_CheckAccess(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp); JSAccessMode mode, jsval *vp);
static JSBool static JSBool
XPC_NW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_NW_Call(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static JSBool static JSBool
XPC_NW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_NW_Construct(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static JSBool static JSBool
XPC_NW_HasInstance(JSContext *cx, JSObject *obj, const jsval *valp, JSBool *bp); XPC_NW_HasInstance(JSContext *cx, JSObject *obj, const jsval *valp, JSBool *bp);
@ -93,8 +91,7 @@ static JSObject *
XPC_NW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly); XPC_NW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly);
static JSBool static JSBool
XPC_NW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_NW_FunctionWrapper(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
using namespace XPCWrapper; using namespace XPCWrapper;
@ -286,8 +283,7 @@ RewrapValue(JSContext *cx, JSObject *obj, jsval v, jsval *rval)
using namespace XPCNativeWrapper; using namespace XPCNativeWrapper;
static JSBool static JSBool
XPC_NW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_NW_toString(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static inline static inline
JSBool JSBool
@ -432,10 +428,13 @@ XPC_NW_DelProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
} }
static JSBool static JSBool
XPC_NW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_NW_FunctionWrapper(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *funObj = JSVAL_TO_OBJECT(argv[-2]); JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
JSObject *funObj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
if (!::JS_ObjectIsFunction(cx, funObj)) { if (!::JS_ObjectIsFunction(cx, funObj)) {
obj = nsnull; obj = nsnull;
} }
@ -467,8 +466,8 @@ XPC_NW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval v; jsval v;
if (!::JS_CallFunctionValue(cx, wrappedNative->GetFlatJSObject(), if (!::JS_CallFunctionValue(cx, wrappedNative->GetFlatJSObject(),
OBJECT_TO_JSVAL(methodToCallObj), argc, argv, OBJECT_TO_JSVAL(methodToCallObj), argc,
&v)) { JS_ARGV(cx, vp), &v)) {
return JS_FALSE; return JS_FALSE;
} }
@ -477,7 +476,7 @@ XPC_NW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
// Make sure v doesn't get collected while we're re-wrapping it. // Make sure v doesn't get collected while we're re-wrapping it.
AUTO_MARK_JSVAL(ccx, v); AUTO_MARK_JSVAL(ccx, v);
return RewrapValue(cx, obj, v, rval); return RewrapValue(cx, obj, v, vp);
} }
static JSBool static JSBool
@ -685,27 +684,25 @@ XPC_NW_CheckAccess(JSContext *cx, JSObject *obj, jsid id,
} }
static JSBool static JSBool
XPC_NW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) XPC_NW_Call(JSContext *cx, uintN argc, jsval *vp)
{ {
#ifdef DEBUG #ifdef DEBUG
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
if (!XPCNativeWrapper::IsNativeWrapper(obj) && if (!XPCNativeWrapper::IsNativeWrapper(obj) &&
!JS_ObjectIsFunction(cx, obj)) { !JS_ObjectIsFunction(cx, obj)) {
NS_WARNING("Ignoring a call for a weird object"); NS_WARNING("Ignoring a call for a weird object");
} }
#endif #endif
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
XPC_NW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_NW_Construct(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
// The object given to us by the JS engine is actually a stub object (the JSObject *obj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
// "new" object). This isn't any help to us, so instead use the function
// object of the constructor that we're calling (which is the native
// wrapper).
obj = JSVAL_TO_OBJECT(argv[-2]);
if (!EnsureLegalActivity(cx, obj)) { if (!EnsureLegalActivity(cx, obj)) {
return JS_FALSE; return JS_FALSE;
} }
@ -723,7 +720,7 @@ XPC_NW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
} }
nsresult rv = wrappedNative->GetScriptableInfo()-> nsresult rv = wrappedNative->GetScriptableInfo()->
GetCallback()->Construct(wrappedNative, cx, obj, argc, argv, rval, GetCallback()->Construct(wrappedNative, cx, obj, argc, JS_ARGV(cx, vp), vp,
&retval); &retval);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return ThrowException(rv, cx); return ThrowException(rv, cx);
@ -733,11 +730,11 @@ XPC_NW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return JS_FALSE; return JS_FALSE;
} }
if (JSVAL_IS_PRIMITIVE(*rval)) { if (JSVAL_IS_PRIMITIVE(*vp)) {
return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx);
} }
return RewrapValue(cx, obj, *rval, rval); return RewrapValue(cx, obj, *vp, vp);
} }
static JSBool static JSBool
@ -747,21 +744,26 @@ XPC_NW_HasInstance(JSContext *cx, JSObject *obj, const jsval *valp, JSBool *bp)
} }
static JSBool static JSBool
XPCNativeWrapperCtor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPCNativeWrapperCtor(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSStackFrame *fp = nsnull;
JSBool constructing = JS_FALSE; JSBool constructing = JS_FALSE;
if (JS_FrameIterator(cx, &fp) && JS_IsConstructorFrame(cx, fp)) {
JSObject *givenThis;
if (JS_IsConstructing_PossiblyWithGivenThisObject(cx, vp, &givenThis)) {
constructing = JS_TRUE; constructing = JS_TRUE;
if (givenThis) {
// This is the XPCNativeWrapper prototype
JS_ASSERT(givenThis->getProto() != NULL);
JS_ASSERT(XPCNativeWrapper::IsNativeWrapper(givenThis));
JS_ASSERT(!XPCNativeWrapper::IsNativeWrapper(givenThis->getProto()));
JSObject *proto = obj->getProto(); if (!JS_SetPrivate(cx, givenThis, nsnull) ||
if (proto && !XPCNativeWrapper::IsNativeWrapper(proto)) { !JS_SetReservedSlot(cx, givenThis, 0, JSVAL_ZERO)) {
// Deal with our prototype object specially. return JS_FALSE;
}
JS_ASSERT(XPCNativeWrapper::IsNativeWrapper(obj)); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(givenThis));
return JS_SetPrivate(cx, obj, nsnull) && return JS_TRUE;
JS_SetReservedSlot(cx, obj, 0, JSVAL_ZERO);
} }
} }
@ -769,10 +771,7 @@ XPCNativeWrapperCtor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx); return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx);
} }
// |obj| almost always has the wrong proto and parent so we have to create jsval *argv = JS_ARGV(cx, vp);
// our own object anyway. Set |obj| to null so we don't use it by accident.
obj = nsnull;
jsval native = argv[0]; jsval native = argv[0];
if (JSVAL_IS_PRIMITIVE(native)) { if (JSVAL_IS_PRIMITIVE(native)) {
@ -780,7 +779,7 @@ XPCNativeWrapperCtor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx);
} }
*rval = native; JS_SET_RVAL(cx, vp, native);
return JS_TRUE; return JS_TRUE;
} }
@ -846,7 +845,7 @@ XPCNativeWrapperCtor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
} }
} }
if (!XPCNativeWrapper::CreateExplicitWrapper(cx, wrappedNative, rval)) { if (!XPCNativeWrapper::CreateExplicitWrapper(cx, wrappedNative, vp)) {
return JS_FALSE; return JS_FALSE;
} }
@ -854,7 +853,7 @@ XPCNativeWrapperCtor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return JS_TRUE; return JS_TRUE;
} }
return SystemOnlyWrapper::MakeSOW(cx, JSVAL_TO_OBJECT(*rval)); return SystemOnlyWrapper::MakeSOW(cx, JSVAL_TO_OBJECT(*vp));
} }
static void static void
@ -939,9 +938,12 @@ XPC_NW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly)
} }
static JSBool static JSBool
XPC_NW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_NW_toString(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
while (!XPCNativeWrapper::IsNativeWrapper(obj)) { while (!XPCNativeWrapper::IsNativeWrapper(obj)) {
obj = obj->getProto(); obj = obj->getProto();
if (!obj) { if (!obj) {
@ -966,11 +968,11 @@ XPC_NW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
(protoString.get()), (protoString.get()),
protoString.Length()); protoString.Length());
NS_ENSURE_TRUE(str, JS_FALSE); NS_ENSURE_TRUE(str, JS_FALSE);
*rval = STRING_TO_JSVAL(str); JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
return JS_TRUE; return JS_TRUE;
} }
return NativeToString(cx, wrappedNative, argc, argv, rval, JS_TRUE); return NativeToString(cx, wrappedNative, argc, JS_ARGV(cx, vp), vp, JS_TRUE);
} }
static JSBool static JSBool

Просмотреть файл

@ -74,16 +74,13 @@ XPC_SJOW_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
jsval *vp); jsval *vp);
static JSBool static JSBool
XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_SJOW_Call(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static JSBool static JSBool
XPC_SJOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_SJOW_Construct(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static JSBool static JSBool
XPC_SJOW_Create(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_SJOW_Create(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static JSBool static JSBool
XPC_SJOW_Equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp); XPC_SJOW_Equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
@ -245,8 +242,7 @@ FindSafeObject(JSObject *obj)
} }
static JSBool static JSBool
XPC_SJOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_SJOW_toString(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
namespace XPCSafeJSObjectWrapper { namespace XPCSafeJSObjectWrapper {
@ -300,7 +296,7 @@ WrapObject(JSContext *cx, JSObject *scope, jsval v, jsval *vp)
if (objToWrap->getClass() == &js_ScriptClass || if (objToWrap->getClass() == &js_ScriptClass ||
(JS_ObjectIsFunction(cx, objToWrap) && (JS_ObjectIsFunction(cx, objToWrap) &&
JS_GetFunctionFastNative(cx, JS_ValueToFunction(cx, v)) == JS_GetFunctionNative(cx, JS_ValueToFunction(cx, v)) ==
XPCWrapper::sEvalNative)) { XPCWrapper::sEvalNative)) {
return ThrowException(NS_ERROR_INVALID_ARG, cx); return ThrowException(NS_ERROR_INVALID_ARG, cx);
} }
@ -786,9 +782,12 @@ XPC_SJOW_CheckAccess(JSContext *cx, JSObject *obj, jsid id,
} }
static JSBool static JSBool
XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_SJOW_Call(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
JSObject *tmp = FindSafeObject(obj); JSObject *tmp = FindSafeObject(obj);
JSObject *unsafeObj, *callThisObj = nsnull; JSObject *unsafeObj, *callThisObj = nsnull;
@ -814,7 +813,7 @@ XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return JS_FALSE; return JS_FALSE;
} }
obj = FindSafeObject(JSVAL_TO_OBJECT(argv[-2])); obj = FindSafeObject(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
if (!obj) { if (!obj) {
return ThrowException(NS_ERROR_INVALID_ARG, cx); return ThrowException(NS_ERROR_INVALID_ARG, cx);
@ -830,7 +829,7 @@ XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
callThisObj = unsafeObj; callThisObj = unsafeObj;
} }
JSObject *safeObj = JSVAL_TO_OBJECT(argv[-2]); JSObject *safeObj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
JSObject *funToCall = GetUnsafeObject(cx, safeObj); JSObject *funToCall = GetUnsafeObject(cx, safeObj);
if (!funToCall) { if (!funToCall) {
@ -857,6 +856,7 @@ XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
SafeCallGuard guard(cx, FindObjectPrincipals(cx, safeObj, funToCall)); SafeCallGuard guard(cx, FindObjectPrincipals(cx, safeObj, funToCall));
JSObject *scope = JS_GetGlobalForObject(cx, funToCall); JSObject *scope = JS_GetGlobalForObject(cx, funToCall);
jsval *argv = JS_ARGV(cx, vp);
for (uintN i = 0; i < argc; ++i) { for (uintN i = 0; i < argc; ++i) {
// NB: Passing NONE for a hint here. // NB: Passing NONE for a hint here.
if (!JSVAL_IS_PRIMITIVE(argv[i]) && if (!JSVAL_IS_PRIMITIVE(argv[i]) &&
@ -872,34 +872,30 @@ XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
if (!js_CallFunctionValueWithFakeFrame(cx, JSVAL_TO_OBJECT(v), scopeChain, if (!js_CallFunctionValueWithFakeFrame(cx, JSVAL_TO_OBJECT(v), scopeChain,
OBJECT_TO_JSVAL(funToCall), OBJECT_TO_JSVAL(funToCall),
argc, argv, rval)) { argc, argv, vp)) {
return JS_FALSE; return JS_FALSE;
} }
} }
return WrapJSValue(cx, safeObj, *rval, rval); return WrapJSValue(cx, safeObj, *vp, vp);
} }
static JSBool static JSBool
XPC_SJOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_SJOW_Construct(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
if (argc < 1) { if (argc < 1) {
return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx); return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx);
} }
// We're not going to use obj because we have callers who aren't the JS JSObject *scope = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
// engine, but we can use it to figure out what scope we're creating this
// SJOW for.
JSObject *scope = JS_GetGlobalForObject(cx, obj);
jsval *argv = JS_ARGV(cx, vp);
if (JSVAL_IS_PRIMITIVE(argv[0])) { if (JSVAL_IS_PRIMITIVE(argv[0])) {
JSStackFrame *fp = nsnull; if (JS_IsConstructing(cx, vp)) {
if (JS_FrameIterator(cx, &fp) && JS_IsConstructorFrame(cx, fp)) {
return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx);
} }
*rval = argv[0]; JS_SET_RVAL(cx, vp, argv[0]);
return JS_TRUE; return JS_TRUE;
} }
@ -914,14 +910,13 @@ XPC_SJOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return JS_FALSE; return JS_FALSE;
} }
return WrapObject(cx, scope, OBJECT_TO_JSVAL(objToWrap), rval); return WrapObject(cx, scope, OBJECT_TO_JSVAL(objToWrap), vp);
} }
static JSBool static JSBool
XPC_SJOW_Create(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_SJOW_Create(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *callee = JSVAL_TO_OBJECT(argv[-2]); JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
NS_ASSERTION(GetUnsafeObject(cx, callee), "How'd we get here?"); NS_ASSERTION(GetUnsafeObject(cx, callee), "How'd we get here?");
JSObject *unsafeObj = GetUnsafeObject(cx, callee); JSObject *unsafeObj = GetUnsafeObject(cx, callee);
@ -942,7 +937,13 @@ XPC_SJOW_Create(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return JS_FALSE; return JS_FALSE;
} }
JSAutoCrossCompartmentCall accc;
if (!accc.enter(cx, unsafeObj)) {
return JS_FALSE;
}
JSObject *scope = JS_GetGlobalForObject(cx, unsafeObj); JSObject *scope = JS_GetGlobalForObject(cx, unsafeObj);
jsval *argv = JS_ARGV(cx, vp);
for (uintN i = 0; i < argc; ++i) { for (uintN i = 0; i < argc; ++i) {
// NB: Passing NONE for a hint here. // NB: Passing NONE for a hint here.
if (!JSVAL_IS_PRIMITIVE(argv[i]) && if (!JSVAL_IS_PRIMITIVE(argv[i]) &&
@ -951,19 +952,14 @@ XPC_SJOW_Create(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
} }
} }
jsval v; JSObject *obj = JS_New(cx, unsafeObj, argc, argv);
if (!RewrapObject(cx, scope, obj, NONE, &v)) { if (!obj)
return JS_FALSE; return JS_FALSE;
}
if (!js_CallFunctionValueWithFakeFrame(cx, JSVAL_TO_OBJECT(v), scopeChain, JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
OBJECT_TO_JSVAL(unsafeObj),
argc, argv, rval)) {
return JS_FALSE;
}
} }
return WrapJSValue(cx, callee, *rval, rval); return WrapJSValue(cx, callee, *vp, vp);
} }
static JSBool static JSBool
@ -1045,9 +1041,13 @@ XPC_SJOW_WrappedObject(JSContext *cx, JSObject *obj)
} }
static JSBool static JSBool
XPC_SJOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_SJOW_toString(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj) {
return JS_FALSE;
}
obj = FindSafeObject(obj); obj = FindSafeObject(obj);
if (!obj) { if (!obj) {
return ThrowException(NS_ERROR_INVALID_ARG, cx); return ThrowException(NS_ERROR_INVALID_ARG, cx);
@ -1065,8 +1065,7 @@ XPC_SJOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return JS_FALSE; return JS_FALSE;
} }
*rval = STRING_TO_JSVAL(str); JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
return JS_TRUE; return JS_TRUE;
} }
@ -1086,7 +1085,7 @@ XPC_SJOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
if (!str) { if (!str) {
return JS_FALSE; return JS_FALSE;
} }
*rval = STRING_TO_JSVAL(str); JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
} }
return JS_TRUE; return JS_TRUE;
} }

Просмотреть файл

@ -302,9 +302,12 @@ GetWrappedObject(JSContext *cx, JSObject *wrapper)
} }
static JSBool static JSBool
XPC_SOW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_SOW_FunctionWrapper(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
if (!AllowedToAct(cx, JSID_VOID)) { if (!AllowedToAct(cx, JSID_VOID)) {
return JS_FALSE; return JS_FALSE;
} }
@ -326,13 +329,13 @@ XPC_SOW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
wrappedObj = obj; wrappedObj = obj;
} }
JSObject *funObj = JSVAL_TO_OBJECT(argv[-2]); JSObject *funObj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
jsval funToCall; jsval funToCall;
if (!JS_GetReservedSlot(cx, funObj, eWrappedFunctionSlot, &funToCall)) { if (!JS_GetReservedSlot(cx, funObj, eWrappedFunctionSlot, &funToCall)) {
return JS_FALSE; return JS_FALSE;
} }
return JS_CallFunctionValue(cx, wrappedObj, funToCall, argc, argv, rval); return JS_CallFunctionValue(cx, wrappedObj, funToCall, argc, JS_ARGV(cx, vp), vp);
} }
JSBool JSBool

Просмотреть файл

@ -49,7 +49,7 @@ namespace XPCWrapper {
const PRUint32 sWrappedObjSlot = 1; const PRUint32 sWrappedObjSlot = 1;
const PRUint32 sFlagsSlot = 0; const PRUint32 sFlagsSlot = 0;
const PRUint32 sNumSlots = 2; const PRUint32 sNumSlots = 2;
JSFastNative sEvalNative = nsnull; JSNative sEvalNative = nsnull;
const PRUint32 FLAG_RESOLVING = 0x1; const PRUint32 FLAG_RESOLVING = 0x1;
const PRUint32 FLAG_SOW = 0x2; const PRUint32 FLAG_SOW = 0x2;
@ -342,8 +342,7 @@ FinishCreatingIterator(JSContext *cx, JSObject *iterObj, JSBool keysonly)
} }
// Initialize iterObj. // Initialize iterObj.
if (!JS_DefineFunction(cx, iterObj, "next", (JSNative)IteratorNext, 0, if (!JS_DefineFunction(cx, iterObj, "next", IteratorNext, 0, 0)) {
JSFUN_FAST_NATIVE)) {
return nsnull; return nsnull;
} }
@ -449,8 +448,7 @@ CreateSimpleIterator(JSContext *cx, JSObject *scope, JSBool keysonly,
return nsnull; return nsnull;
} }
if (!JS_DefineFunction(cx, iterObj, "next", (JSNative)IteratorNext, 0, if (!JS_DefineFunction(cx, iterObj, "next", IteratorNext, 0, 0)) {
JSFUN_FAST_NATIVE)) {
return nsnull; return nsnull;
} }

Просмотреть файл

@ -210,7 +210,7 @@ extern const PRUint32 sNumSlots;
* Cross origin wrappers and safe JSObject wrappers both need to know * Cross origin wrappers and safe JSObject wrappers both need to know
* which native is 'eval' for various purposes. * which native is 'eval' for various purposes.
*/ */
extern JSFastNative sEvalNative; extern JSNative sEvalNative;
enum FunctionObjectSlot { enum FunctionObjectSlot {
eWrappedFunctionSlot = 0, eWrappedFunctionSlot = 0,
@ -277,7 +277,7 @@ FindEval(XPCCallContext &ccx, JSObject *obj)
} }
sEvalNative = sEvalNative =
::JS_GetFunctionFastNative(ccx, ::JS_ValueToFunction(ccx, eval_val)); ::JS_GetFunctionNative(ccx, ::JS_ValueToFunction(ccx, eval_val));
if (!sEvalNative) { if (!sEvalNative) {
return DoThrowException(NS_ERROR_UNEXPECTED, ccx); return DoThrowException(NS_ERROR_UNEXPECTED, ccx);

Просмотреть файл

@ -2716,26 +2716,30 @@ nsXPCComponents_Utils::GetSandbox(nsIXPCComponents_utils_Sandbox **aSandbox)
} }
static JSBool static JSBool
MethodWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, MethodWrapper(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
if (!thisobj)
return JS_FALSE;
jsval *argv = JS_ARGV(cx, vp);
jsval v; jsval v;
if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(argv[-2]), 0, &v) || if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0, &v) ||
!JS_CallFunctionValue(cx, obj, v, argc, argv, rval)) { !JS_CallFunctionValue(cx, thisobj, v, argc, argv, vp)) {
return JS_FALSE; return JS_FALSE;
} }
if (JSVAL_IS_PRIMITIVE(*rval)) if (JSVAL_IS_PRIMITIVE(*vp))
return JS_TRUE; return JS_TRUE;
XPCWrappedNative *wn = XPCWrappedNative *wn =
XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(*rval)); XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(*vp));
if (!wn) { if (!wn) {
XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx); XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx);
return JS_FALSE; return JS_FALSE;
} }
return XPCNativeWrapper::CreateExplicitWrapper(cx, wn, rval); return XPCNativeWrapper::CreateExplicitWrapper(cx, wn, vp);
} }
/* void lookupMethod (); */ /* void lookupMethod (); */
@ -3013,13 +3017,13 @@ PrincipalHolder::GetPrincipal()
} }
static JSBool static JSBool
SandboxDump(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) SandboxDump(JSContext *cx, uintN argc, jsval *vp)
{ {
JSString *str; JSString *str;
if (!argc) if (!argc)
return JS_TRUE; return JS_TRUE;
str = JS_ValueToString(cx, argv[0]); str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
@ -3045,28 +3049,33 @@ SandboxDump(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
fputs(cstr, stderr); fputs(cstr, stderr);
NS_Free(cstr); NS_Free(cstr);
JS_SET_RVAL(cx, vp, JSVAL_TRUE);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
SandboxDebug(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) SandboxDebug(JSContext *cx, uintN argc, jsval *vp)
{ {
#ifdef DEBUG #ifdef DEBUG
return SandboxDump(cx, obj, argc, argv, rval); return SandboxDump(cx, argc, vp);
#else #else
return JS_TRUE; return JS_TRUE;
#endif #endif
} }
static JSBool static JSBool
SandboxImport(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, SandboxImport(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
if (!thisobj)
return JS_FALSE;
if (argc < 1) { if (argc < 1) {
XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx); XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
return JS_FALSE; return JS_FALSE;
} }
jsval *argv = JS_ARGV(cx, vp);
JSFunction *fun = JS_ValueToFunction(cx, argv[0]); JSFunction *fun = JS_ValueToFunction(cx, argv[0]);
if (!fun) { if (!fun) {
XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx); XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
@ -3092,7 +3101,9 @@ SandboxImport(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsid id; jsid id;
if (!JS_ValueToId(cx, STRING_TO_JSVAL(funname), &id)) if (!JS_ValueToId(cx, STRING_TO_JSVAL(funname), &id))
return JS_FALSE; return JS_FALSE;
return JS_SetPropertyById(cx, obj, id, &argv[0]);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_SetPropertyById(cx, thisobj, id, &argv[0]);
} }
static JSBool static JSBool
@ -3174,10 +3185,10 @@ static JSClass SandboxClass = {
}; };
static JSFunctionSpec SandboxFunctions[] = { static JSFunctionSpec SandboxFunctions[] = {
{"dump", SandboxDump, 1,0,0}, {"dump", SandboxDump, 1,0},
{"debug", SandboxDebug, 1,0,0}, {"debug", SandboxDebug, 1,0},
{"importFunction", SandboxImport, 1,0,0}, {"importFunction", SandboxImport, 1,0},
{nsnull,nsnull,0,0,0} {nsnull,nsnull,0,0}
}; };
#endif /* !XPCONNECT_STANDALONE */ #endif /* !XPCONNECT_STANDALONE */

Просмотреть файл

@ -68,9 +68,6 @@ static char* FormatJSFrame(JSContext* cx, JSStackFrame* fp,
char* buf, int num, char* buf, int num,
JSBool showArgs, JSBool showLocals, JSBool showThisProps) JSBool showArgs, JSBool showLocals, JSBool showThisProps)
{ {
if(JS_IsNativeFrame(cx, fp))
return JS_sprintf_append(buf, "%d [native frame]\n", num);
JSPropertyDescArray callProps = {0, nsnull}; JSPropertyDescArray callProps = {0, nsnull};
JSPropertyDescArray thisProps = {0, nsnull}; JSPropertyDescArray thisProps = {0, nsnull};
JSObject* thisObj = nsnull; JSObject* thisObj = nsnull;

Просмотреть файл

@ -1277,12 +1277,10 @@ extern JSBool
XPC_WN_Equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp); XPC_WN_Equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
extern JSBool extern JSBool
XPC_WN_CallMethod(JSContext *cx, JSObject *obj, XPC_WN_CallMethod(JSContext *cx, uintN argc, jsval *vp);
uintN argc, jsval *argv, jsval *vp);
extern JSBool extern JSBool
XPC_WN_GetterSetter(JSContext *cx, JSObject *obj, XPC_WN_GetterSetter(JSContext *cx, uintN argc, jsval *vp);
uintN argc, jsval *argv, jsval *vp);
extern JSBool extern JSBool
XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,

Просмотреть файл

@ -170,7 +170,7 @@ GeneratePropertyOp(JSContext *cx, JSObject *obj, jsval idval, uintN argc,
// XPConnect to use. Use them to stick the necessary info here. // XPConnect to use. Use them to stick the necessary info here.
JSFunction *fun = JSFunction *fun =
JS_NewFunction(cx, reinterpret_cast<JSNative>(PropertyOpForwarder), JS_NewFunction(cx, reinterpret_cast<JSNative>(PropertyOpForwarder),
argc, JSFUN_FAST_NATIVE, obj, name); argc, 0, obj, name);
if(!fun) if(!fun)
return JS_FALSE; return JS_FALSE;
@ -342,8 +342,8 @@ DefineGetterOrSetter(JSContext *cx, uintN argc, JSBool wantGetter, jsval *vp)
JSObject *obj = JS_THIS_OBJECT(cx, vp); JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj) if (!obj)
return JS_FALSE; return JS_FALSE;
JSFastNative forward = wantGetter ? Jsvalify(js_obj_defineGetter) JSNative forward = wantGetter ? Jsvalify(js_obj_defineGetter)
: Jsvalify(js_obj_defineSetter); : Jsvalify(js_obj_defineSetter);
jsval id = (argc >= 1) ? JS_ARGV(cx, vp)[0] : JSVAL_VOID; jsval id = (argc >= 1) ? JS_ARGV(cx, vp)[0] : JSVAL_VOID;
if(!JSVAL_IS_STRING(id)) if(!JSVAL_IS_STRING(id))
return forward(cx, argc, vp); return forward(cx, argc, vp);
@ -434,7 +434,7 @@ xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, uintN flags,
if(!JS_DefineFunction( if(!JS_DefineFunction(
cx, proto, fs->name, cx, proto, fs->name,
reinterpret_cast<JSNative>(fs->native), reinterpret_cast<JSNative>(fs->native),
fs->arity, flags | JSFUN_FAST_NATIVE)) fs->arity, flags))
return JS_FALSE; return JS_FALSE;
} }
} }
@ -446,8 +446,7 @@ xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, uintN flags,
{ {
if(!JS_DefineFunction( if(!JS_DefineFunction(
cx, proto, ts->name, ts->native, ts->arity, cx, proto, ts->name, ts->native, ts->arity,
flags | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | flags | JSFUN_STUB_GSOPS | JSFUN_TRCINFO))
JSFUN_TRCINFO))
return JS_FALSE; return JS_FALSE;
} }
} }
@ -543,7 +542,7 @@ GetMethodInfo(JSContext *cx,
{ {
JSObject *funobj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)); JSObject *funobj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
NS_ASSERTION(JS_ObjectIsFunction(cx, funobj), NS_ASSERTION(JS_ObjectIsFunction(cx, funobj),
"JSFastNative callee should be Function object"); "JSNative callee should be Function object");
JSString *str = JS_GetFunctionId((JSFunction *) JS_GetPrivate(cx, funobj)); JSString *str = JS_GetFunctionId((JSFunction *) JS_GetPrivate(cx, funobj));
jsid methodId = str ? INTERNED_STRING_TO_JSID(str) : JSID_VOID; jsid methodId = str ? INTERNED_STRING_TO_JSID(str) : JSID_VOID;

Просмотреть файл

@ -56,7 +56,7 @@ struct xpc_qsPropertySpec {
struct xpc_qsFunctionSpec { struct xpc_qsFunctionSpec {
const char *name; const char *name;
JSFastNative native; JSNative native;
uintN arity; uintN arity;
}; };

Просмотреть файл

@ -150,7 +150,7 @@ XPCJSStackFrame::CreateStack(JSContext* cx, JSStackFrame* fp,
if(!failed) if(!failed)
{ {
if (JS_IsNativeFrame(cx, fp)) if (!JS_IsScriptFrame(cx, fp))
self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS; self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS;
else else
self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT; self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT;

Просмотреть файл

@ -1116,7 +1116,7 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx,
JSStackFrame * fp = nsnull; JSStackFrame * fp = nsnull;
while((fp = JS_FrameIterator(cx, &fp))) while((fp = JS_FrameIterator(cx, &fp)))
{ {
if(!JS_IsNativeFrame(cx, fp)) if(JS_IsScriptFrame(cx, fp))
{ {
onlyNativeStackFrames = PR_FALSE; onlyNativeStackFrames = PR_FALSE;
break; break;

Просмотреть файл

@ -107,9 +107,12 @@ ToStringGuts(XPCCallContext& ccx)
/***************************************************************************/ /***************************************************************************/
static JSBool static JSBool
XPC_WN_Shared_ToString(JSContext *cx, JSObject *obj, XPC_WN_Shared_ToString(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *vp)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
if(IS_SLIM_WRAPPER(obj)) if(IS_SLIM_WRAPPER(obj))
{ {
XPCNativeScriptableInfo *si = XPCNativeScriptableInfo *si =
@ -142,13 +145,12 @@ XPC_WN_Shared_ToString(JSContext *cx, JSObject *obj,
XPCCallContext ccx(JS_CALLER, cx, obj); XPCCallContext ccx(JS_CALLER, cx, obj);
ccx.SetName(ccx.GetRuntime()->GetStringID(XPCJSRuntime::IDX_TO_STRING)); ccx.SetName(ccx.GetRuntime()->GetStringID(XPCJSRuntime::IDX_TO_STRING));
ccx.SetArgsAndResultPtr(argc, argv, vp); ccx.SetArgsAndResultPtr(argc, JS_ARGV(cx, vp), vp);
return ToStringGuts(ccx); return ToStringGuts(ccx);
} }
static JSBool static JSBool
XPC_WN_Shared_ToSource(JSContext *cx, JSObject *obj, XPC_WN_Shared_ToSource(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *vp)
{ {
static const char empty[] = "({})"; static const char empty[] = "({})";
JSString *str = JS_NewStringCopyN(cx, empty, sizeof(empty)-1); JSString *str = JS_NewStringCopyN(cx, empty, sizeof(empty)-1);
@ -200,15 +202,18 @@ GetDoubleWrappedJSObject(XPCCallContext& ccx, XPCWrappedNative* wrapper)
// double wrapped JSObjects. // double wrapped JSObjects.
static JSBool static JSBool
XPC_WN_DoubleWrappedGetter(JSContext *cx, JSObject *obj, XPC_WN_DoubleWrappedGetter(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *vp)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
MORPH_SLIM_WRAPPER(cx, obj); MORPH_SLIM_WRAPPER(cx, obj);
XPCCallContext ccx(JS_CALLER, cx, obj); XPCCallContext ccx(JS_CALLER, cx, obj);
XPCWrappedNative* wrapper = ccx.GetWrapper(); XPCWrappedNative* wrapper = ccx.GetWrapper();
THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
NS_ASSERTION(JS_TypeOfValue(cx, argv[-2]) == JSTYPE_FUNCTION, "bad function"); NS_ASSERTION(JS_TypeOfValue(cx, JS_CALLEE(cx, vp)) == JSTYPE_FUNCTION, "bad function");
JSObject* realObject = GetDoubleWrappedJSObject(ccx, wrapper); JSObject* realObject = GetDoubleWrappedJSObject(ccx, wrapper);
if(!realObject) if(!realObject)
@ -1061,15 +1066,13 @@ XPC_WN_Helper_CheckAccess(JSContext *cx, JSObject *obj, jsid id,
} }
static JSBool static JSBool
XPC_WN_Helper_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_WN_Helper_Call(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
// this is a hack to get the obj of the actual object not the object // N.B. we want obj to be the callee, not JS_THIS(cx, vp)
// that JS thinks is the 'this' (which it passes as 'obj'). JSObject *obj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
if(!(obj = JSVAL_TO_OBJECT(argv[-2])))
return JS_FALSE;
XPCCallContext ccx(JS_CALLER, cx, obj, nsnull, JSID_VOID, argc, argv, rval); XPCCallContext ccx(JS_CALLER, cx, obj, nsnull, JSID_VOID,
argc, JS_ARGV(cx, vp), vp);
if(!ccx.IsValid()) if(!ccx.IsValid())
return JS_FALSE; return JS_FALSE;
@ -1077,20 +1080,19 @@ XPC_WN_Helper_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
SLIM_LOG_WILL_MORPH(cx, obj); SLIM_LOG_WILL_MORPH(cx, obj);
PRE_HELPER_STUB_NO_SLIM PRE_HELPER_STUB_NO_SLIM
Call(wrapper, cx, obj, argc, argv, rval, &retval); Call(wrapper, cx, obj, argc, JS_ARGV(cx, vp), vp, &retval);
POST_HELPER_STUB POST_HELPER_STUB
} }
static JSBool static JSBool
XPC_WN_Helper_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, XPC_WN_Helper_Construct(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
// this is a hack to get the obj of the actual object not the object JSObject *obj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
// that JS thinks is the 'this' (which it passes as 'obj'). if(!obj)
if(!(obj = JSVAL_TO_OBJECT(argv[-2])))
return JS_FALSE; return JS_FALSE;
XPCCallContext ccx(JS_CALLER, cx, obj, nsnull, JSID_VOID, argc, argv, rval); XPCCallContext ccx(JS_CALLER, cx, obj, nsnull, JSID_VOID,
argc, JS_ARGV(cx, vp), vp);
if(!ccx.IsValid()) if(!ccx.IsValid())
return JS_FALSE; return JS_FALSE;
@ -1098,7 +1100,7 @@ XPC_WN_Helper_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
SLIM_LOG_WILL_MORPH(cx, obj); SLIM_LOG_WILL_MORPH(cx, obj);
PRE_HELPER_STUB_NO_SLIM PRE_HELPER_STUB_NO_SLIM
Construct(wrapper, cx, obj, argc, argv, rval, &retval); Construct(wrapper, cx, obj, argc, JS_ARGV(cx, vp), vp, &retval);
POST_HELPER_STUB POST_HELPER_STUB
} }
@ -1719,25 +1721,24 @@ XPCNativeScriptableShared::PopulateJSClass(JSBool isGlobal)
/***************************************************************************/ /***************************************************************************/
JSBool JSBool
XPC_WN_CallMethod(JSContext *cx, JSObject *obj, XPC_WN_CallMethod(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *vp)
{ {
NS_ASSERTION(JS_TypeOfValue(cx, argv[-2]) == JSTYPE_FUNCTION, "bad function"); NS_ASSERTION(JS_TypeOfValue(cx, JS_CALLEE(cx, vp)) == JSTYPE_FUNCTION, "bad function");
JSObject* funobj = JSVAL_TO_OBJECT(argv[-2]); JSObject* funobj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
JSObject* obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
#ifdef DEBUG_slimwrappers #ifdef DEBUG_slimwrappers
const char* funname = nsnull; JSFunction* fun = GET_FUNCTION_PRIVATE(cx, funobj);
if(JS_TypeOfValue(cx, argv[-2]) == JSTYPE_FUNCTION) const char* funname = JS_GetFunctionName(fun);
{
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
funname = JS_GetFunctionName(fun);
}
SLIM_LOG_WILL_MORPH_FOR_PROP(cx, obj, funname); SLIM_LOG_WILL_MORPH_FOR_PROP(cx, obj, funname);
#endif #endif
if(IS_SLIM_WRAPPER(obj) && !MorphSlimWrapper(cx, obj)) if(IS_SLIM_WRAPPER(obj) && !MorphSlimWrapper(cx, obj))
return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
XPCCallContext ccx(JS_CALLER, cx, obj, funobj, JSID_VOID, argc, argv, vp); XPCCallContext ccx(JS_CALLER, cx, obj, funobj, JSID_VOID, argc, JS_ARGV(cx, vp), vp);
XPCWrappedNative* wrapper = ccx.GetWrapper(); XPCWrappedNative* wrapper = ccx.GetWrapper();
THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
@ -1751,15 +1752,18 @@ XPC_WN_CallMethod(JSContext *cx, JSObject *obj,
} }
JSBool JSBool
XPC_WN_GetterSetter(JSContext *cx, JSObject *obj, XPC_WN_GetterSetter(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *vp)
{ {
NS_ASSERTION(JS_TypeOfValue(cx, argv[-2]) == JSTYPE_FUNCTION, "bad function"); NS_ASSERTION(JS_TypeOfValue(cx, JS_CALLEE(cx, vp)) == JSTYPE_FUNCTION, "bad function");
JSObject* funobj = JSVAL_TO_OBJECT(argv[-2]); JSObject* funobj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
JSObject* obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
#ifdef DEBUG_slimwrappers #ifdef DEBUG_slimwrappers
const char* funname = nsnull; const char* funname = nsnull;
if(JS_TypeOfValue(cx, argv[-2]) == JSTYPE_FUNCTION) if(JS_TypeOfValue(cx, JS_CALLEE(cx, vp)) == JSTYPE_FUNCTION)
{ {
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj); JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
funname = JS_GetFunctionName(fun); funname = JS_GetFunctionName(fun);
@ -1779,13 +1783,13 @@ XPC_WN_GetterSetter(JSContext *cx, JSObject *obj,
if(!XPCNativeMember::GetCallInfo(ccx, funobj, &iface, &member)) if(!XPCNativeMember::GetCallInfo(ccx, funobj, &iface, &member))
return Throw(NS_ERROR_XPC_CANT_GET_METHOD_INFO, cx); return Throw(NS_ERROR_XPC_CANT_GET_METHOD_INFO, cx);
ccx.SetArgsAndResultPtr(argc, argv, vp); ccx.SetArgsAndResultPtr(argc, JS_ARGV(cx, vp), vp);
if(argc && member->IsWritableAttribute()) if(argc && member->IsWritableAttribute())
{ {
ccx.SetCallInfo(iface, member, JS_TRUE); ccx.SetCallInfo(iface, member, JS_TRUE);
JSBool retval = XPCWrappedNative::SetAttribute(ccx); JSBool retval = XPCWrappedNative::SetAttribute(ccx);
if(retval && vp) if(retval)
*vp = argv[0]; *vp = JS_ARGV(cx, vp)[0];
return retval; return retval;
} }
// else... // else...

Просмотреть файл

@ -72,11 +72,12 @@ FILE *gOutFile = NULL;
FILE *gErrFile = NULL; FILE *gErrFile = NULL;
static JSBool static JSBool
Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Print(JSContext *cx, uintN argc, jsval *vp)
{ {
uintN i, n; uintN i, n;
JSString *str; JSString *str;
jsval *argv = JS_ARGV(cx, vp);
for (i = n = 0; i < argc; i++) { for (i = n = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]); str = JS_ValueToString(cx, argv[i]);
if (!str) if (!str)
@ -86,11 +87,12 @@ Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
n++; n++;
if (n) if (n)
fputc('\n', gOutFile); fputc('\n', gOutFile);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Load(JSContext *cx, uintN argc, jsval *vp)
{ {
uintN i; uintN i;
JSString *str; JSString *str;
@ -99,6 +101,11 @@ Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JSBool ok; JSBool ok;
jsval result; jsval result;
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]); str = JS_ValueToString(cx, argv[i]);
if (!str) if (!str)
@ -115,13 +122,14 @@ Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (!ok) if (!ok)
return JS_FALSE; return JS_FALSE;
} }
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE; return JS_TRUE;
} }
static JSFunctionSpec glob_functions[] = { static JSFunctionSpec glob_functions[] = {
{"print", Print, 0,0,0}, {"print", Print, 0,0},
{"load", Load, 1,0,0}, {"load", Load, 1,0},
{nsnull,nsnull,0,0,0} {nsnull,nsnull,0,0}
}; };
static JSClass global_class = { static JSClass global_class = {

Просмотреть файл

@ -171,12 +171,10 @@ static void
NPObjWrapper_Finalize(JSContext *cx, JSObject *obj); NPObjWrapper_Finalize(JSContext *cx, JSObject *obj);
static JSBool static JSBool
NPObjWrapper_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, NPObjWrapper_Call(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static JSBool static JSBool
NPObjWrapper_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, NPObjWrapper_Construct(JSContext *cx, uintN argc, jsval *vp);
jsval *rval);
static JSBool static JSBool
CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject *npobj, CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject *npobj,
@ -208,8 +206,7 @@ static void
NPObjectMember_Finalize(JSContext *cx, JSObject *obj); NPObjectMember_Finalize(JSContext *cx, JSObject *obj);
static JSBool static JSBool
NPObjectMember_Call(JSContext *cx, JSObject *obj, uintN argc, NPObjectMember_Call(JSContext *cx, uintN argc, jsval *vp);
jsval *argv, jsval *rval);
static uint32 static uint32
NPObjectMember_Mark(JSContext *cx, JSObject *obj, void *arg); NPObjectMember_Mark(JSContext *cx, JSObject *obj, void *arg);
@ -1548,10 +1545,13 @@ CallNPMethodInternal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
} }
static JSBool static JSBool
CallNPMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, CallNPMethod(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
return CallNPMethodInternal(cx, obj, argc, argv, rval, PR_FALSE); JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
return CallNPMethodInternal(cx, obj, argc, JS_ARGV(cx, vp), vp, PR_FALSE);
} }
struct NPObjectEnumerateState { struct NPObjectEnumerateState {
@ -1750,19 +1750,17 @@ NPObjWrapper_Finalize(JSContext *cx, JSObject *obj)
} }
static JSBool static JSBool
NPObjWrapper_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, NPObjWrapper_Call(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval, return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), argc,
PR_FALSE); JS_ARGV(cx, vp), vp, PR_FALSE);
} }
static JSBool static JSBool
NPObjWrapper_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, NPObjWrapper_Construct(JSContext *cx, uintN argc, jsval *vp)
jsval *rval)
{ {
return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval, return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), argc,
PR_TRUE); JS_ARGV(cx, vp), vp, PR_TRUE);
} }
class NPObjWrapperHashEntry : public PLDHashEntryHdr class NPObjWrapperHashEntry : public PLDHashEntryHdr
@ -2247,16 +2245,15 @@ NPObjectMember_Finalize(JSContext *cx, JSObject *obj)
} }
static JSBool static JSBool
NPObjectMember_Call(JSContext *cx, JSObject *obj, NPObjectMember_Call(JSContext *cx, uintN argc, jsval *vp)
uintN argc, jsval *argv, jsval *rval)
{ {
JSObject *memobj = JSVAL_TO_OBJECT(argv[-2]); JSObject *memobj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
NS_ENSURE_TRUE(memobj, JS_FALSE); NS_ENSURE_TRUE(memobj, JS_FALSE);
NPObjectMemberPrivate *memberPrivate = NPObjectMemberPrivate *memberPrivate =
(NPObjectMemberPrivate *)::JS_GetInstancePrivate(cx, memobj, (NPObjectMemberPrivate *)::JS_GetInstancePrivate(cx, memobj,
&sNPObjectMemberClass, &sNPObjectMemberClass,
argv); JS_ARGV(cx, vp));
if (!memberPrivate || !memberPrivate->npobjWrapper) if (!memberPrivate || !memberPrivate->npobjWrapper)
return JS_FALSE; return JS_FALSE;
@ -2284,6 +2281,7 @@ NPObjectMember_Call(JSContext *cx, JSObject *obj,
// Convert arguments // Convert arguments
PRUint32 i; PRUint32 i;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; i < argc; ++i) { for (i = 0; i < argc; ++i) {
if (!JSValToNPVariant(memberPrivate->npp, cx, argv[i], npargs + i)) { if (!JSValToNPVariant(memberPrivate->npp, cx, argv[i], npargs + i)) {
ThrowJSException(cx, "Error converting jsvals to NPVariants!"); ThrowJSException(cx, "Error converting jsvals to NPVariants!");
@ -2320,9 +2318,9 @@ NPObjectMember_Call(JSContext *cx, JSObject *obj,
return JS_FALSE; return JS_FALSE;
} }
*rval = NPVariantToJSVal(memberPrivate->npp, cx, &npv); JS_SET_RVAL(cx, vp, NPVariantToJSVal(memberPrivate->npp, cx, &npv));
// *rval now owns the value, release our reference. // *vp now owns the value, release our reference.
_releasevariantvalue(&npv); _releasevariantvalue(&npv);
return ReportExceptionIfPending(cx); return ReportExceptionIfPending(cx);

Просмотреть файл

@ -18,15 +18,13 @@ function run_test() {
_("Got trace:", trace); _("Got trace:", trace);
do_check_neq(trace, ""); do_check_neq(trace, "");
let errorPos = trace.indexOf('Error("3")@:0');
let bazPos = trace.indexOf("baz(2)@test_utils_stackTrace.js:4"); let bazPos = trace.indexOf("baz(2)@test_utils_stackTrace.js:4");
let barPos = trace.indexOf("bar(1)@test_utils_stackTrace.js:3"); let barPos = trace.indexOf("bar(1)@test_utils_stackTrace.js:3");
let fooPos = trace.indexOf("foo(0)@test_utils_stackTrace.js:2"); let fooPos = trace.indexOf("foo(0)@test_utils_stackTrace.js:2");
_("String positions:", errorPos, bazPos, barPos, fooPos); _("String positions:", bazPos, barPos, fooPos);
_("Make sure the desired messages show up"); _("Make sure the desired messages show up");
do_check_true(errorPos >= 0); do_check_true(bazPos >= 0);
do_check_true(bazPos > errorPos);
do_check_true(barPos > bazPos); do_check_true(barPos > bazPos);
do_check_true(fooPos > barPos); do_check_true(fooPos > barPos);
} }

Просмотреть файл

@ -249,8 +249,8 @@ StatementJSHelper::NewResolve(nsIXPConnectWrappedNative *aWrapper,
const char *name = ::JS_GetStringBytes(JSID_TO_STRING(aId)); const char *name = ::JS_GetStringBytes(JSID_TO_STRING(aId));
if (::strcmp(name, "step") == 0) { if (::strcmp(name, "step") == 0) {
*_retval = ::JS_DefineFunction(aCtx, aScopeObj, "step", (JSNative)stepFunc, *_retval = ::JS_DefineFunction(aCtx, aScopeObj, "step", stepFunc,
0, JSFUN_FAST_NATIVE) != nsnull; 0, 0) != nsnull;
*_objp = aScopeObj; *_objp = aScopeObj;
return NS_OK; return NS_OK;
} }