Lazy ComputeGlobalThis required now in fast native implementations (417893, r=mrbkap).

This commit is contained in:
brendan%mozilla.org 2008-02-18 00:12:34 +00:00
Родитель ea0374d976
Коммит 4011b63c4d
13 изменённых файлов: 215 добавлений и 170 удалений

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

@ -1706,6 +1706,14 @@ JS_GetGlobalForObject(JSContext *cx, JSObject *obj)
return obj;
}
JS_PUBLIC_API(jsval)
JS_ComputeThis(JSContext *cx, jsval *vp)
{
if (!js_ComputeThis(cx, JS_FALSE, vp + 2))
return JSVAL_NULL;
return vp[1];
}
JS_PUBLIC_API(void *)
JS_malloc(JSContext *cx, size_t nbytes)
{
@ -2764,7 +2772,7 @@ JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv)
JSFunction *fun;
CHECK_REQUEST(cx);
if (OBJ_GET_CLASS(cx, obj) == clasp)
if (obj && OBJ_GET_CLASS(cx, obj) == clasp)
return JS_TRUE;
if (argv) {
fun = js_ValueToFunction(cx, &argv[-2], 0);
@ -2772,7 +2780,9 @@ JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv)
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_INCOMPATIBLE_PROTO,
clasp->name, JS_GetFunctionName(fun),
OBJ_GET_CLASS(cx, obj)->name);
obj
? OBJ_GET_CLASS(cx, obj)->name
: js_null_str);
}
}
return JS_FALSE;

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

@ -1,4 +1,5 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=78:
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -656,6 +657,16 @@ JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
* without breaking source and binary compatibility (argv[-2] is well-known to
* be the callee jsval, and argv[-1] is as well known to be |this|).
*
* Note well: However, argv[-1] may be JSVAL_NULL where with slow natives it
* is the global object, so embeddings implementing fast natives *must* call
* JS_THIS or JS_THIS_OBJECT and test for failure indicated by a null return,
* which should propagate as a false return from native functions and hooks.
*
* To reduce boilerplace checks, JS_InstanceOf and JS_GetInstancePrivate now
* handle a null obj parameter by returning false (throwing a TypeError if
* given non-null argv), so most native functions that type-check their |this|
* parameter need not add null checking.
*
* NB: there is an anti-dependency between JS_CALLEE and JS_SET_RVAL: native
* methods that may inspect their callee must defer setting their return value
* until after any such possible inspection. Otherwise the return value will be
@ -667,12 +678,17 @@ JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
*/
#define JS_CALLEE(cx,vp) ((vp)[0])
#define JS_ARGV_CALLEE(argv) ((argv)[-2])
#define JS_THIS(cx,vp) ((vp)[1])
#define JS_THIS(cx,vp) (JSVAL_IS_NULL((vp)[1]) \
? JS_ComputeThis(cx, vp) \
: (vp)[1])
#define JS_THIS_OBJECT(cx,vp) ((JSObject *) JS_THIS(cx,vp))
#define JS_ARGV(cx,vp) ((vp) + 2)
#define JS_RVAL(cx,vp) (*(vp))
#define JS_SET_RVAL(cx,vp,v) (*(vp) = (v))
extern JS_PUBLIC_API(jsval)
JS_ComputeThis(JSContext *cx, jsval *vp);
extern JS_PUBLIC_API(void *)
JS_malloc(JSContext *cx, size_t nbytes);

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

@ -724,7 +724,7 @@ array_toSource(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2))
return JS_FALSE;
return array_join_sub(cx, obj, TO_SOURCE, NULL, vp);
@ -736,7 +736,7 @@ array_toString(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2))
return JS_FALSE;
return array_join_sub(cx, obj, TO_STRING, NULL, vp);
@ -747,7 +747,7 @@ array_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2))
return JS_FALSE;
@ -790,6 +790,7 @@ static JSBool
array_join(JSContext *cx, uintN argc, jsval *vp)
{
JSString *str;
JSObject *obj;
if (JSVAL_IS_VOID(vp[2])) {
str = NULL;
@ -799,7 +800,8 @@ array_join(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
vp[2] = STRING_TO_JSVAL(str);
}
return array_join_sub(cx, JS_THIS_OBJECT(cx, vp), TO_STRING, str, vp);
obj = JS_THIS_OBJECT(cx, vp);
return obj && array_join_sub(cx, obj, TO_STRING, str, vp);
}
static JSBool
@ -811,7 +813,7 @@ array_reverse(JSContext *cx, uintN argc, jsval *vp)
JSBool ok, hole, hole2;
obj = JS_THIS_OBJECT(cx, vp);
if (!js_GetLengthProperty(cx, obj, &len))
if (!obj || !js_GetLengthProperty(cx, obj, &len))
return JS_FALSE;
ok = JS_TRUE;
@ -1084,7 +1086,7 @@ array_sort(JSContext *cx, uintN argc, jsval *vp)
}
obj = JS_THIS_OBJECT(cx, vp);
if (!js_GetLengthProperty(cx, obj, &len))
if (!obj || !js_GetLengthProperty(cx, obj, &len))
return JS_FALSE;
if (len == 0) {
*vp = OBJECT_TO_JSVAL(obj);
@ -1341,7 +1343,9 @@ array_push(JSContext *cx, uintN argc, jsval *vp)
jsval v;
/* Insist on one argument and obj of the expected class. */
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
if (argc != 1 || OBJ_GET_CLASS(cx, obj) != &js_ArrayClass)
return slow_array_push(cx, obj, argc, vp);
@ -1376,7 +1380,7 @@ array_pop(JSContext *cx, uintN argc, jsval *vp)
JSBool hole;
obj = JS_THIS_OBJECT(cx, vp);
if (!js_GetLengthProperty(cx, obj, &index))
if (!obj || !js_GetLengthProperty(cx, obj, &index))
return JS_FALSE;
if (index == 0) {
*vp = JSVAL_VOID;
@ -1401,7 +1405,7 @@ array_shift(JSContext *cx, uintN argc, jsval *vp)
JSTempValueRooter tvr;
obj = JS_THIS_OBJECT(cx, vp);
if (!js_GetLengthProperty(cx, obj, &length))
if (!obj || !js_GetLengthProperty(cx, obj, &length))
return JS_FALSE;
if (length == 0) {
*vp = JSVAL_VOID;
@ -1443,7 +1447,7 @@ array_unshift(JSContext *cx, uintN argc, jsval *vp)
JSTempValueRooter tvr;
obj = JS_THIS_OBJECT(cx, vp);
if (!js_GetLengthProperty(cx, obj, &length))
if (!obj || !js_GetLengthProperty(cx, obj, &length))
return JS_FALSE;
if (argc > 0) {
/* Slide up the array to make room for argc at the bottom. */
@ -1495,7 +1499,7 @@ array_splice(JSContext *cx, uintN argc, jsval *vp)
return JS_TRUE;
argv = JS_ARGV(cx, vp);
obj = JS_THIS_OBJECT(cx, vp);
if (!js_GetLengthProperty(cx, obj, &length))
if (!obj || !js_GetLengthProperty(cx, obj, &length))
return JS_FALSE;
/* Convert the first argument into a starting index. */
@ -1707,7 +1711,7 @@ array_slice(JSContext *cx, uintN argc, jsval *vp)
*vp = OBJECT_TO_JSVAL(nobj);
obj = JS_THIS_OBJECT(cx, vp);
if (!js_GetLengthProperty(cx, obj, &length))
if (!obj || !js_GetLengthProperty(cx, obj, &length))
return JS_FALSE;
begin = 0;
end = length;
@ -1774,8 +1778,8 @@ array_indexOfHelper(JSContext *cx, JSBool isLast, uintN argc, jsval *vp)
jsint direction;
JSBool hole;
obj = JSVAL_TO_OBJECT(vp[1]);
if (!js_GetLengthProperty(cx, obj, &length))
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !js_GetLengthProperty(cx, obj, &length))
return JS_FALSE;
if (length == 0)
goto not_found;
@ -1867,8 +1871,8 @@ array_extra(JSContext *cx, ArrayExtraMode mode, uintN argc, jsval *vp)
jsint start, end, step, i;
void *mark;
obj = JSVAL_TO_OBJECT(vp[1]);
if (!js_GetLengthProperty(cx, obj, &length))
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !js_GetLengthProperty(cx, obj, &length))
return JS_FALSE;
/*

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

@ -980,7 +980,7 @@ GetLocalTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
jsdouble result;
jsdouble *cached;
if (!JS_GetReservedSlot(cx, obj, LOCAL_TIME_SLOT, &v))
if (!obj || !JS_GetReservedSlot(cx, obj, LOCAL_TIME_SLOT, &v))
return JS_FALSE;
result = *JSVAL_TO_DOUBLE(v);
@ -1015,7 +1015,7 @@ date_getTime(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
return GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result) &&
return GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result) &&
js_NewNumberValue(cx, result, vp);
}
@ -1024,7 +1024,7 @@ GetYear(JSContext *cx, JSBool fullyear, jsval *vp)
{
jsdouble result;
if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) {
@ -1055,7 +1055,7 @@ date_getUTCFullYear(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1069,7 +1069,7 @@ date_getMonth(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1083,7 +1083,7 @@ date_getUTCMonth(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1097,7 +1097,7 @@ date_getDate(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1111,7 +1111,7 @@ date_getUTCDate(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1125,7 +1125,7 @@ date_getDay(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1139,7 +1139,7 @@ date_getUTCDay(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1153,7 +1153,7 @@ date_getHours(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1167,7 +1167,7 @@ date_getUTCHours(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1181,7 +1181,7 @@ date_getMinutes(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetLocalTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1195,7 +1195,7 @@ date_getUTCMinutes(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1211,7 +1211,7 @@ date_getUTCSeconds(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1227,7 +1227,7 @@ date_getUTCMilliseconds(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &result))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result))
return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result))
@ -1242,7 +1242,7 @@ date_getTimezoneOffset(JSContext *cx, uintN argc, jsval *vp)
JSObject *obj;
jsdouble utctime, localtime, result;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!GetUTCTime(cx, obj, vp, &utctime))
return JS_FALSE;
if (!GetLocalTime(cx, obj, NULL, &localtime))
@ -1267,7 +1267,7 @@ date_setTime(JSContext *cx, uintN argc, jsval *vp)
result = TIMECLIP(result);
if (!SetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, result))
if (!SetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, result))
return JS_FALSE;
return js_NewNumberValue(cx, result, vp);
@ -1286,7 +1286,7 @@ date_makeTime(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
jsdouble msec_time;
jsdouble result;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!GetUTCTime(cx, obj, vp, &result))
return JS_FALSE;
@ -1425,7 +1425,7 @@ date_makeDate(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
jsdouble year, month, day;
jsdouble result;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!GetUTCTime(cx, obj, vp, &result))
return JS_FALSE;
@ -1534,7 +1534,7 @@ date_setYear(JSContext *cx, uintN argc, jsval *vp)
jsdouble day;
jsdouble result;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!GetUTCTime(cx, obj, vp, &result))
return JS_FALSE;
@ -1586,7 +1586,7 @@ date_toGMTString(JSContext *cx, uintN argc, jsval *vp)
JSString *str;
jsdouble utctime;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &utctime))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(utctime)) {
@ -1760,7 +1760,7 @@ date_toLocaleHelper(JSContext *cx, const char *format, jsval *vp)
PRMJTime split;
jsdouble utctime;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!GetUTCTime(cx, obj, vp, &utctime))
return JS_FALSE;
@ -1866,7 +1866,7 @@ date_toTimeString(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble utctime;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &utctime))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
return JS_FALSE;
return date_format(cx, utctime, FORMATSPEC_TIME, vp);
}
@ -1876,7 +1876,7 @@ date_toDateString(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble utctime;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &utctime))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
return JS_FALSE;
return date_format(cx, utctime, FORMATSPEC_DATE, vp);
}
@ -1892,7 +1892,7 @@ date_toSource(JSContext *cx, uintN argc, jsval *vp)
char buf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr, *bytes;
JSString *str;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &utctime))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
return JS_FALSE;
numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, utctime);
@ -1922,7 +1922,7 @@ date_toString(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble utctime;
if (!GetUTCTime(cx, JSVAL_TO_OBJECT(vp[1]), vp, &utctime))
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
return JS_FALSE;
return date_format(cx, utctime, FORMATSPEC_FULL, vp);
}

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

@ -819,8 +819,9 @@ exn_toString(JSContext *cx, uintN argc, jsval *vp)
jschar *chars, *cp;
size_t name_length, message_length, length;
obj = JSVAL_TO_OBJECT(vp[1]);
if (!OBJ_GET_PROPERTY(cx, obj,
obj = JS_THIS_OBJECT(cx, vp);
if (!obj ||
!OBJ_GET_PROPERTY(cx, obj,
ATOM_TO_JSID(cx->runtime->atomState.nameAtom),
&v)) {
return JS_FALSE;
@ -880,7 +881,8 @@ exn_toSource(JSContext *cx, uintN argc, jsval *vp)
jschar *chars, *cp;
obj = JS_THIS_OBJECT(cx, vp);
if (!OBJ_GET_PROPERTY(cx, obj,
if (!obj ||
!OBJ_GET_PROPERTY(cx, obj,
ATOM_TO_JSID(cx->runtime->atomState.nameAtom),
vp)) {
return JS_FALSE;

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

@ -1427,7 +1427,10 @@ fun_toStringHelper(JSContext *cx, uint32 indent, uintN argc, jsval *vp)
JSFunction *fun;
JSString *str;
fval = vp[1];
fval = JS_THIS(cx, vp);
if (JSVAL_IS_NULL(fval))
return JS_FALSE;
if (!VALUE_IS_FUNCTION(cx, fval)) {
/*
* If we don't have a function to start off with, try converting the
@ -1490,8 +1493,8 @@ fun_call(JSContext *cx, uintN argc, jsval *vp)
void *mark;
JSBool ok;
obj = JSVAL_TO_OBJECT(vp[1]);
if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &vp[1]))
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &vp[1]))
return JS_FALSE;
fval = vp[1];
@ -1556,8 +1559,8 @@ fun_apply(JSContext *cx, uintN argc, jsval *vp)
return fun_call(cx, argc, vp);
}
obj = JSVAL_TO_OBJECT(vp[1]);
if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &vp[1]))
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &vp[1]))
return JS_FALSE;
fval = vp[1];
@ -1660,7 +1663,7 @@ fun_applyConstructor(JSContext *cx, uintN argc, jsval *vp)
sp = invokevp;
*sp++ = vp[1];
*sp++ = JSVAL_NULL; /* This is filled automagically. */
*sp++ = JSVAL_NULL; /* this is filled automagically */
for (i = 0; i < length; i++) {
ok = JS_GetElement(cx, aobj, (jsint)i, sp);
if (!ok)

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

@ -284,7 +284,7 @@ iterator_next(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!JS_InstanceOf(cx, obj, &js_IteratorClass, vp + 2))
return JS_FALSE;
@ -302,8 +302,8 @@ iterator_next(JSContext *cx, uintN argc, jsval *vp)
static JSBool
iterator_self(JSContext *cx, uintN argc, jsval *vp)
{
*vp = vp[1];
return JS_TRUE;
*vp = JS_THIS(cx, vp);
return !JSVAL_IS_NULL(*vp);
}
#define JSPROP_ROPERM (JSPROP_READONLY | JSPROP_PERMANENT)
@ -954,7 +954,7 @@ generator_op(JSContext *cx, JSGeneratorOp op, jsval *vp)
JSGenerator *gen;
jsval arg;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!JS_InstanceOf(cx, obj, &js_GeneratorClass, vp + 2))
return JS_FALSE;

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

@ -632,9 +632,8 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp)
/* If outermost, we need parentheses to be an expression, not a block. */
outermost = (cx->sharpObjectMap.depth == 0);
obj = JSVAL_TO_OBJECT(vp[1]);
he = js_EnterSharpObject(cx, obj, &ida, &chars);
if (!he) {
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !(he = js_EnterSharpObject(cx, obj, &ida, &chars))) {
ok = JS_FALSE;
goto out;
}
@ -1008,12 +1007,16 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp)
static JSBool
obj_toString(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj;
jschar *chars;
size_t nchars;
const char *clazz, *prefix;
JSString *str;
clazz = OBJ_GET_CLASS(cx, JS_THIS_OBJECT(cx, vp))->name;
obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
clazz = OBJ_GET_CLASS(cx, obj)->name;
nchars = 9 + strlen(clazz); /* 9 for "[object ]" */
chars = (jschar *) JS_malloc(cx, (nchars + 1) * sizeof(jschar));
if (!chars)
@ -1040,9 +1043,14 @@ obj_toString(JSContext *cx, uintN argc, jsval *vp)
static JSBool
obj_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
{
jsval thisv;
JSString *str;
str = js_ValueToString(cx, vp[1]);
thisv = JS_THIS(cx, vp);
if (JSVAL_IS_NULL(thisv))
return JS_FALSE;
str = js_ValueToString(cx, thisv);
if (!str)
return JS_FALSE;
@ -1053,8 +1061,8 @@ obj_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
static JSBool
obj_valueOf(JSContext *cx, uintN argc, jsval *vp)
{
*vp = vp[1];
return JS_TRUE;
*vp = JS_THIS(cx, vp);
return !JSVAL_IS_NULL(*vp);
}
/*
@ -1407,8 +1415,8 @@ obj_watch(JSContext *cx, uintN argc, jsval *vp)
if (!JS_ValueToId(cx, userid, &propid))
return JS_FALSE;
obj = JSVAL_TO_OBJECT(vp[1]);
if (!OBJ_CHECK_ACCESS(cx, obj, propid, JSACC_WATCH, &value, &attrs))
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !OBJ_CHECK_ACCESS(cx, obj, propid, JSACC_WATCH, &value, &attrs))
return JS_FALSE;
if (attrs & JSPROP_READONLY)
return JS_TRUE;
@ -1419,8 +1427,13 @@ obj_watch(JSContext *cx, uintN argc, jsval *vp)
static JSBool
obj_unwatch(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj;
obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
*vp = JSVAL_VOID;
return JS_ClearWatchPoint(cx, JSVAL_TO_OBJECT(vp[1]), vp[2], NULL, NULL);
return JS_ClearWatchPoint(cx, obj, vp[2], NULL, NULL);
}
#endif /* JS_HAS_OBJ_WATCHPOINT */
@ -1436,8 +1449,9 @@ obj_hasOwnProperty(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj;
obj = JSVAL_TO_OBJECT(vp[1]);
return js_HasOwnPropertyHelper(cx, obj->map->ops->lookupProperty, vp);
obj = JS_THIS_OBJECT(cx, vp);
return obj &&
js_HasOwnPropertyHelper(cx, obj->map->ops->lookupProperty, vp);
}
JSBool
@ -1450,8 +1464,8 @@ js_HasOwnPropertyHelper(JSContext *cx, JSLookupPropOp lookup, jsval *vp)
if (!JS_ValueToId(cx, vp[2], &id))
return JS_FALSE;
obj = JSVAL_TO_OBJECT(vp[1]);
if (!lookup(cx, obj, id, &obj2, &prop))
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !lookup(cx, obj, id, &obj2, &prop))
return JS_FALSE;
if (!prop) {
*vp = JSVAL_FALSE;
@ -1506,7 +1520,7 @@ obj_isPrototypeOf(JSContext *cx, uintN argc, jsval *vp)
{
JSBool b;
if (!js_IsDelegate(cx, JSVAL_TO_OBJECT(vp[1]), vp[2], &b))
if (!js_IsDelegate(cx, JS_THIS_OBJECT(cx, vp), vp[2], &b))
return JS_FALSE;
*vp = BOOLEAN_TO_JSVAL(b);
return JS_TRUE;
@ -1526,7 +1540,7 @@ obj_propertyIsEnumerable(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
obj = JS_THIS_OBJECT(cx, vp);
if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
if (!obj || !OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
return JS_FALSE;
if (!prop) {
@ -1579,8 +1593,8 @@ obj_defineGetter(JSContext *cx, uintN argc, jsval *vp)
if (!JS_ValueToId(cx, vp[2], &id))
return JS_FALSE;
obj = JSVAL_TO_OBJECT(vp[1]);
if (!js_CheckRedeclaration(cx, obj, id, JSPROP_GETTER, NULL, NULL))
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !js_CheckRedeclaration(cx, obj, id, JSPROP_GETTER, NULL, NULL))
return JS_FALSE;
/*
* Getters and setters are just like watchpoints from an access
@ -1613,8 +1627,8 @@ obj_defineSetter(JSContext *cx, uintN argc, jsval *vp)
if (!JS_ValueToId(cx, vp[2], &id))
return JS_FALSE;
obj = JSVAL_TO_OBJECT(vp[1]);
if (!js_CheckRedeclaration(cx, obj, id, JSPROP_SETTER, NULL, NULL))
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !js_CheckRedeclaration(cx, obj, id, JSPROP_SETTER, NULL, NULL))
return JS_FALSE;
/*
* Getters and setters are just like watchpoints from an access
@ -1633,13 +1647,14 @@ static JSBool
obj_lookupGetter(JSContext *cx, uintN argc, jsval *vp)
{
jsid id;
JSObject *pobj;
JSObject *obj, *pobj;
JSProperty *prop;
JSScopeProperty *sprop;
if (!JS_ValueToId(cx, vp[2], &id))
return JS_FALSE;
if (!OBJ_LOOKUP_PROPERTY(cx, JSVAL_TO_OBJECT(vp[1]), id, &pobj, &prop))
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
return JS_FALSE;
*vp = JSVAL_VOID;
if (prop) {
@ -1657,13 +1672,14 @@ static JSBool
obj_lookupSetter(JSContext *cx, uintN argc, jsval *vp)
{
jsid id;
JSObject *pobj;
JSObject *obj, *pobj;
JSProperty *prop;
JSScopeProperty *sprop;
if (!JS_ValueToId(cx, vp[2], &id))
return JS_FALSE;
if (!OBJ_LOOKUP_PROPERTY(cx, JSVAL_TO_OBJECT(vp[1]), id, &pobj, &prop))
obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
return JS_FALSE;
*vp = JSVAL_VOID;
if (prop) {

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

@ -3969,7 +3969,10 @@ js_regexp_toString(JSContext *cx, JSObject *obj, jsval *vp)
static JSBool
regexp_toString(JSContext *cx, uintN argc, jsval *vp)
{
return js_regexp_toString(cx, JS_THIS_OBJECT(cx, vp), vp);
JSObject *obj;
obj = JS_THIS_OBJECT(cx, vp);
return obj && js_regexp_toString(cx, obj, vp);
}
static JSBool
@ -4094,7 +4097,10 @@ created:
static JSBool
regexp_compile(JSContext *cx, uintN argc, jsval *vp)
{
return regexp_compile_sub(cx, JS_THIS_OBJECT(cx, vp), argc, vp + 2, vp);
JSObject *obj;
obj = JS_THIS_OBJECT(cx, vp);
return obj && regexp_compile_sub(cx, obj, argc, vp + 2, vp);
}
static JSBool

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

@ -649,7 +649,7 @@ script_freeze(JSContext *cx, uintN argc, jsval *vp)
void *buf;
JSString *str;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, vp + 2))
return JS_FALSE;
script = (JSScript *) JS_GetPrivate(cx, obj);
@ -715,7 +715,7 @@ script_thaw(JSContext *cx, uintN argc, jsval *vp)
JSBool ok, hasMagic;
jsint execDepth;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, vp + 2))
return JS_FALSE;

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

@ -399,7 +399,10 @@ js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
static JSBool
str_escape(JSContext *cx, uintN argc, jsval *vp)
{
return js_str_escape(cx, JS_THIS_OBJECT(cx, vp), argc, vp + 2, vp);
JSObject *obj;
obj = JS_THIS_OBJECT(cx, vp);
return obj && js_str_escape(cx, obj, argc, vp + 2, vp);
}
/* See ECMA-262 Edition 3 B.2.2 */
@ -602,6 +605,31 @@ JSClass js_StringClass = {
JSCLASS_NO_OPTIONAL_MEMBERS
};
#define NORMALIZE_THIS(cx,vp,str) \
JS_BEGIN_MACRO \
if (JSVAL_IS_STRING(vp[1])) { \
str = JSVAL_TO_STRING(vp[1]); \
} else { \
str = NormalizeThis(cx, vp); \
if (!str) \
return JS_FALSE; \
} \
JS_END_MACRO
static JSString *
NormalizeThis(JSContext *cx, jsval *vp)
{
JSString *str;
if (JSVAL_IS_NULL(vp[1]) && JSVAL_IS_NULL(JS_THIS(cx, vp)))
return NULL;
str = js_ValueToString(cx, vp[1]);
if (!str)
return NULL;
vp[1] = STRING_TO_JSVAL(str);
return str;
}
#if JS_HAS_TOSOURCE
/*
@ -613,11 +641,7 @@ str_quote(JSContext *cx, uintN argc, jsval *vp)
{
JSString *str;
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
str = js_QuoteString(cx, str, '"');
if (!str)
return JS_FALSE;
@ -680,11 +704,7 @@ str_substring(JSContext *cx, uintN argc, jsval *vp)
jsdouble d;
jsdouble length, begin, end;
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
if (argc != 0) {
if (!js_ValueToNumber(cx, vp[2], &d))
return JS_FALSE;
@ -729,11 +749,7 @@ str_toLowerCase(JSContext *cx, uintN argc, jsval *vp)
size_t i, n;
jschar *s, *news;
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
JSSTRING_CHARS_AND_LENGTH(str, s, n);
news = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));
if (!news)
@ -760,10 +776,7 @@ str_toLocaleLowerCase(JSContext *cx, uintN argc, jsval *vp)
* ECMA has reserved that argument, presumably for defining the locale.
*/
if (cx->localeCallbacks && cx->localeCallbacks->localeToLowerCase) {
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
return cx->localeCallbacks->localeToLowerCase(cx, str, vp);
}
return str_toLowerCase(cx, 0, vp);
@ -776,11 +789,7 @@ str_toUpperCase(JSContext *cx, uintN argc, jsval *vp)
size_t i, n;
jschar *s, *news;
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
JSSTRING_CHARS_AND_LENGTH(str, s, n);
news = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));
if (!news)
@ -807,10 +816,7 @@ str_toLocaleUpperCase(JSContext *cx, uintN argc, jsval *vp)
* ECMA has reserved that argument, presumbaly for defining the locale.
*/
if (cx->localeCallbacks && cx->localeCallbacks->localeToUpperCase) {
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
return cx->localeCallbacks->localeToUpperCase(cx, str, vp);
}
return str_toUpperCase(cx, 0, vp);
@ -821,11 +827,7 @@ str_localeCompare(JSContext *cx, uintN argc, jsval *vp)
{
JSString *str, *thatStr;
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
if (argc == 0) {
*vp = JSVAL_ZERO;
} else {
@ -858,10 +860,9 @@ str_charAt(JSContext *cx, uintN argc, jsval *vp)
if ((size_t)i >= JSSTRING_LENGTH(str))
goto out_of_range;
} else {
str = js_ValueToString(cx, t);
str = NormalizeThis(cx, vp);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
if (argc == 0) {
d = 0.0;
@ -906,10 +907,9 @@ str_charCodeAt(JSContext *cx, uintN argc, jsval *vp)
if ((size_t)i >= JSSTRING_LENGTH(str))
goto out_of_range;
} else {
str = js_ValueToString(cx, t);
str = NormalizeThis(cx, vp);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
if (argc == 0) {
d = 0.0;
@ -979,10 +979,9 @@ str_indexOf(JSContext *cx, uintN argc, jsval *vp)
str = JSVAL_TO_STRING(t);
str2 = JSVAL_TO_STRING(v);
} else {
str = js_ValueToString(cx, t);
str = NormalizeThis(cx, vp);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
str2 = js_ValueToString(cx, v);
if (!str2)
@ -1047,10 +1046,7 @@ str_lastIndexOf(JSContext *cx, uintN argc, jsval *vp)
jsint i, j, textlen, patlen;
jsdouble d;
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
text = JSSTRING_CHARS(str);
textlen = (jsint) JSSTRING_LENGTH(str);
@ -1136,10 +1132,7 @@ match_or_replace(JSContext *cx,
JSBool ok, test;
jsint count;
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
data->str = str;
if (JSVAL_IS_REGEXP(cx, vp[2])) {
@ -1801,10 +1794,7 @@ str_split(JSContext *cx, uintN argc, jsval *vp)
jsint i, j;
uint32 len, limit;
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL);
if (!arrayobj)
@ -1900,11 +1890,7 @@ str_substr(JSContext *cx, uintN argc, jsval *vp)
jsdouble d;
jsdouble length, begin, end;
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
if (argc != 0) {
if (!js_ValueToNumber(cx, vp[2], &d))
return JS_FALSE;
@ -1952,10 +1938,7 @@ str_concat(JSContext *cx, uintN argc, jsval *vp)
jsval *argv;
uintN i;
str = js_ValueToString(cx, vp[1]);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
for (i = 0, argv = vp + 2; i < argc; i++) {
str2 = js_ValueToString(cx, argv[i]);
@ -2004,10 +1987,7 @@ str_slice(JSContext *cx, uintN argc, jsval *vp)
}
}
str = js_ValueToString(cx, t);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
NORMALIZE_THIS(cx, vp, str);
if (argc != 0) {
double begin, end, length;
@ -2059,22 +2039,12 @@ static JSBool
tagify(JSContext *cx, const char *begin, JSString *param, const char *end,
jsval *vp)
{
jsval v;
JSString *str;
jschar *tagbuf;
size_t beglen, endlen, parlen, taglen;
size_t i, j;
v = vp[1];
if (!JSVAL_IS_OBJECT(v)) {
JS_ASSERT(JSVAL_IS_STRING(v));
str = JSVAL_TO_STRING(v);
} else {
str = js_ValueToString(cx, v);
if (!str)
return JS_FALSE;
vp[1] = STRING_TO_JSVAL(str);
}
NORMALIZE_THIS(cx, vp, str);
if (!end)
end = begin;

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

@ -496,6 +496,8 @@ qname_toString(JSContext *cx, uintN argc, jsval *vp)
jschar *chars;
obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
clasp = OBJ_GET_CLASS(cx, obj);
if (clasp == &js_AttributeNameClass || clasp == &js_AnyNameClass) {
qn = (JSXMLQName *) JS_GetPrivate(cx, obj);
@ -6072,7 +6074,7 @@ xml_hasOwnProperty(JSContext *cx, uintN argc, jsval *vp)
jsval name;
JSBool found;
obj = JSVAL_TO_OBJECT(vp[1]);
obj = JS_THIS_OBJECT(cx, vp);
if (!JS_InstanceOf(cx, obj, &js_XMLClass, vp + 2))
return JS_FALSE;
@ -7151,9 +7153,13 @@ xml_toString_helper(JSContext *cx, JSXML *xml)
static JSBool
xml_toSource(JSContext *cx, uintN argc, jsval *vp)
{
jsval thisv;
JSString *str;
str = ToXMLString(cx, vp[1], TO_SOURCE_FLAG);
thisv = JS_THIS(cx, vp);
if (JSVAL_IS_NULL(thisv))
return JS_FALSE;
str = ToXMLString(cx, thisv, TO_SOURCE_FLAG);
if (!str)
return JS_FALSE;
*vp = STRING_TO_JSVAL(str);
@ -7177,9 +7183,13 @@ xml_toString(JSContext *cx, uintN argc, jsval *vp)
static JSBool
xml_toXMLString(JSContext *cx, uintN argc, jsval *vp)
{
jsval thisv;
JSString *str;
str = ToXMLString(cx, vp[1], 0);
thisv = JS_THIS(cx, vp);
if (JSVAL_IS_NULL(thisv))
return JS_FALSE;
str = ToXMLString(cx, thisv, 0);
if (!str)
return JS_FALSE;
*vp = STRING_TO_JSVAL(str);
@ -7190,8 +7200,8 @@ xml_toXMLString(JSContext *cx, uintN argc, jsval *vp)
static JSBool
xml_valueOf(JSContext *cx, uintN argc, jsval *vp)
{
*vp = vp[1];
return JS_TRUE;
*vp = JS_THIS(cx, vp);
return !JSVAL_IS_NULL(*vp);
}
static JSFunctionSpec xml_methods[] = {
@ -7280,12 +7290,14 @@ static JSBool
xml_settings(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *settings;
JSObject *obj;
settings = JS_NewObject(cx, NULL, NULL, NULL);
if (!settings)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(settings);
return CopyXMLSettings(cx, JS_THIS_OBJECT(cx, vp), settings);
obj = JS_THIS_OBJECT(cx, vp);
return obj && CopyXMLSettings(cx, obj, settings);
}
static JSBool
@ -7296,6 +7308,8 @@ xml_setSettings(JSContext *cx, uintN argc, jsval *vp)
JSBool ok;
obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
v = vp[2];
if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) {
cx->xmlSettingFlags = 0;

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

@ -69,8 +69,12 @@ IteratorFinalize(JSContext *cx, JSObject *obj)
JS_STATIC_DLL_CALLBACK(JSBool)
IteratorNext(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj = JSVAL_TO_OBJECT(vp[1]);
JSObject *obj;
jsval v;
obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
JS_GetReservedSlot(cx, obj, 0, &v);
JSIdArray *ida = reinterpret_cast<JSIdArray *>(JSVAL_TO_PRIVATE(v));