Esempio n. 1
0
static JSBool
FindConstructor(JSContext *cx, JSClass *clasp, jsval *vp)
{
    JSAtom *atom;
    JSObject *obj, *tmp;
    JSBool ok;

    PR_ASSERT(JS_IS_LOCKED(cx));

    /* XXX pre-atomize in JS_InitClass! */
    atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
    if (!atom)
	return JS_FALSE;

    if (cx->fp && (tmp = cx->fp->scopeChain)) {
	/* Find the topmost object in the scope chain. */
	do {
	    obj = tmp;
	    tmp = OBJ_GET_PARENT(obj);
	} while (tmp);
    } else {
	obj = cx->globalObject;
	if (!obj) {
	    *vp = JSVAL_VOID;
	    return JS_TRUE;
	}
    }

    ok = (js_GetProperty(cx, obj, (jsval)atom, vp) != NULL);
    js_DropAtom(cx, atom);
    return JS_TRUE;
}
Esempio n. 2
0
JSObject *
js_FindVariableScope(JSContext *cx, JSFunction **funp)
{
    JSStackFrame *fp;
    JSObject *obj, *parent, *withobj;
    JSClass *clasp;
    JSFunction *fun;

    PR_ASSERT(JS_IS_LOCKED(cx));

    fp = cx->fp;
    for (obj = fp->scopeChain, withobj = NULL; ; obj = parent) {
	parent = OBJ_GET_PARENT(obj);
	clasp = obj->map->clasp;
	if (!parent || clasp != &js_WithClass)
	    break;
	withobj = obj;
    }

    fun = (clasp == &js_FunctionClass) ? JS_GetPrivate(cx, obj) : NULL;
#if JS_HAS_CALL_OBJECT
    if (fun && fun->script) {
	for (; fp && fp->fun != fun; fp = fp->down)
	    ;
	if (fp) {
	    obj = js_GetCallObject(cx, fp, parent);
	    if (withobj)
		OBJ_SET_PARENT(withobj, obj);
	}
    }
#endif

    *funp = fun;
    return obj;
}
Esempio n. 3
0
static JSBool
IteratorNextImpl(JSContext *cx, JSObject *obj, jsval *rval)
{
    JSObject *iterable;
    jsval state;
    uintN flags;
    JSBool foreach, ok;
    jsid id;

    JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_IteratorClass);

    iterable = OBJ_GET_PARENT(cx, obj);
    JS_ASSERT(iterable);
    state = STOBJ_GET_SLOT(obj, JSSLOT_ITER_STATE);
    if (JSVAL_IS_NULL(state))
        goto stop;

    flags = JSVAL_TO_INT(STOBJ_GET_SLOT(obj, JSSLOT_ITER_FLAGS));
    JS_ASSERT(!(flags & JSITER_ENUMERATE));
    foreach = (flags & JSITER_FOREACH) != 0;
    ok =
#if JS_HAS_XML_SUPPORT
         (foreach && OBJECT_IS_XML(cx, iterable))
         ? ((JSXMLObjectOps *) iterable->map->ops)->
               enumerateValues(cx, iterable, JSENUMERATE_NEXT, &state,
                               &id, rval)
         :
#endif
           OBJ_ENUMERATE(cx, iterable, JSENUMERATE_NEXT, &state, &id);
    if (!ok)
        return JS_FALSE;

    STOBJ_SET_SLOT(obj, JSSLOT_ITER_STATE, state);
    if (JSVAL_IS_NULL(state))
        goto stop;

    if (foreach) {
#if JS_HAS_XML_SUPPORT
        if (!OBJECT_IS_XML(cx, iterable) &&
            !OBJ_GET_PROPERTY(cx, iterable, id, rval)) {
            return JS_FALSE;
        }
#endif
        if (!NewKeyValuePair(cx, id, *rval, rval))
            return JS_FALSE;
    } else {
        *rval = ID_TO_VALUE(id);
    }
    return JS_TRUE;

  stop:
    JS_ASSERT(STOBJ_GET_SLOT(obj, JSSLOT_ITER_STATE) == JSVAL_NULL);
    *rval = JSVAL_HOLE;
    return JS_TRUE;
}
Esempio n. 4
0
static int
sort_compare(const void *a, const void *b, void *arg)
{
    jsval av = *(const jsval *)a, bv = *(const jsval *)b;
    CompareArgs *ca = (CompareArgs *) arg;
    JSContext *cx = ca->context;
    jsdouble cmp = -1;
    jsval fval, argv[2], rval;
    JSBool ok;

    fval = ca->fval;
    if (fval == JSVAL_NULL) {
        JSString *astr, *bstr;

        if (av == bv) {
            cmp = 0;
        } else if (av == JSVAL_VOID || bv == JSVAL_VOID) {
            /* Put undefined properties at the end. */
            cmp = (av == JSVAL_VOID) ? 1 : -1;
        } else if ((astr = js_ValueToString(cx, av)) != NULL &&
                   (bstr = js_ValueToString(cx, bv)) != NULL) {
            cmp = js_CompareStrings(astr, bstr);
        } else {
            ca->status = JS_FALSE;
        }
    } else {
        argv[0] = av;
        argv[1] = bv;
        ok = js_InternalCall(cx,
                             OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fval)),
                             fval, 2, argv, &rval);
        if (ok) {
            ok = js_ValueToNumber(cx, rval, &cmp);
            /* Clamp cmp to -1, 0, 1. */
            if (JSDOUBLE_IS_NaN(cmp)) {
                /* XXX report some kind of error here?  ECMA talks about
                 * 'consistent compare functions' that don't return NaN, but is
                 * silent about what the result should be.  So we currently
                 * ignore it.
                 */
                cmp = 0;
            } else if (cmp != 0) {
                cmp = cmp > 0 ? 1 : -1;
            }
        } else {
            ca->status = ok;
        }
    }
    return (int)cmp;
}
Esempio n. 5
0
JSBool
js_FindProperty(JSContext *cx, jsval id, JSObject **objp, JSProperty **propp)
{
    JSRuntime *rt;
    JSObject *obj, *parent, *lastobj;
    JSProperty *prop;

    rt = cx->runtime;
    PR_ASSERT(JS_IS_RUNTIME_LOCKED(rt));

    for (obj = cx->fp->scopeChain; obj; obj = parent) {
	/* Try the property cache and return immediately on cache hit. */
	PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, prop);
	if (PROP_FOUND(prop)) {
	    *objp = obj;
	    *propp = prop;
	    return JS_TRUE;
	}

	/*
	 * Set parent here, after cache hit to minimize cycles in that case,
	 * but before js_LookupProperty, which might change obj.
	 */
	parent = OBJ_GET_PARENT(obj);

	/* If cache miss (not cached-as-not-found), take the slow path. */
	if (!prop) {
	    if (!js_LookupProperty(cx, obj, id, &obj, &prop))
		return JS_FALSE;
	    if (prop) {
		PROPERTY_CACHE_FILL(cx, &rt->propertyCache, obj, id, prop);
		*objp = obj;
		*propp = prop;
		return JS_TRUE;
	    }

	    /* No such property -- cache obj[id] as not-found. */
	    PROPERTY_CACHE_FILL(cx, &rt->propertyCache, obj, id,
				PROP_NOT_FOUND);
	}
	lastobj = obj;
    }
    *objp = lastobj;
    *propp = NULL;
    return JS_TRUE;
}
Esempio n. 6
0
JSPropertyOp
js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter)
{
    JSAtom *atom;
    JSFunction *wrapper;

    if (!(attrs & JSPROP_SETTER))
        return &js_watch_set;   /* & to silence schoolmarmish MSVC */

    if (!JSVAL_IS_INT(id)) {
        atom = (JSAtom *)id;
    } else {
        atom = js_AtomizeInt(cx, JSVAL_TO_INT(id), 0);
        if (!atom)
            return NULL;
    }
    wrapper = js_NewFunction(cx, NULL, js_watch_set_wrapper, 1, 0,
                             OBJ_GET_PARENT(cx, (JSObject *)setter),
                             atom);
    if (!wrapper)
        return NULL;
    return (JSPropertyOp) wrapper->object;
}
Esempio n. 7
0
static JSBool
obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    JSStackFrame *fp, *caller;
    JSBool ok;
    JSString *str;
    const char *file;
    uintN line;
    JSPrincipals *principals;
    JSScript *script;
#if JS_HAS_EVAL_THIS_SCOPE
    JSObject *callerScopeChain;
    JSBool implicitWith;
#endif

    if (!JSVAL_IS_STRING(argv[0])) {
	*rval = argv[0];
	return JS_TRUE;
    }

    fp = cx->fp;
    caller = fp->down;
#if !JS_BUG_EVAL_THIS_FUN
    /* Ensure that this flows into eval from the calling function, if any. */
    fp->thisp = caller->thisp;
#endif
#if JS_HAS_SHARP_VARS
    fp->sharpArray = caller->sharpArray;
#endif

#if JS_HAS_EVAL_THIS_SCOPE
    /* If obj.eval(str), emulate 'with (obj) eval(str)' in the calling frame. */
    callerScopeChain = caller->scopeChain;
    implicitWith = (callerScopeChain != obj &&
		    (callerScopeChain->map->clasp != &js_WithClass ||
		     OBJ_GET_PROTO(callerScopeChain) != obj));
    if (implicitWith) {
	obj = js_NewObject(cx, &js_WithClass, obj, callerScopeChain);
	if (!obj)
	    return JS_FALSE;
	caller->scopeChain = obj;
    }
#endif

#if !JS_BUG_EVAL_THIS_SCOPE
    /* Compile using caller's current scope object (might be a function). */
    obj = caller->scopeChain;
#endif

    str = JSVAL_TO_STRING(argv[0]);
    if (caller->script) {
	file = caller->script->filename;
	line = js_PCToLineNumber(caller->script, caller->pc);
	principals = caller->script->principals;
    } else {
	file = NULL;
	line = 0;
	principals = NULL;
    }
    script = JS_CompileUCScriptForPrincipals(cx, obj, principals,
					     str->chars, str->length,
					     file, line);
    if (!script) {
	ok = JS_FALSE;
	goto out;
    }

#if !JS_BUG_EVAL_THIS_SCOPE
    /* Interpret using caller's new scope object (might be a Call object). */
    obj = caller->scopeChain;
#endif
    ok = js_Execute(cx, obj, script, fp, rval);
    JS_DestroyScript(cx, script);

out:
#if JS_HAS_EVAL_THIS_SCOPE
    if (implicitWith) {
	/* Restore OBJ_GET_PARENT(obj) not callerScopeChain in case of Call. */
	caller->scopeChain = OBJ_GET_PARENT(obj);
    }
#endif
    return ok;
}