FreeWRL

 view release on metacpan or  search on metacpan

JS/js/jsinterp.c  view on Meta::CPAN

	    /* Try to hit the property cache, FindVariable primes it. */
	    CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));
	    if (!ok)
		goto out;

	    /* Push the right-hand side as our result. */
	    PUSH_OPND(rval);
	    break;

	  case JSOP_BINDNAME:
	    atom = GET_ATOM(cx, script, pc);
	    SAVE_SP(fp);
	    ok = js_FindVariable(cx, (jsid)atom, &obj, &obj2, &prop);
	    if (!ok)
		goto out;
	    OBJ_DROP_PROPERTY(cx, obj2, prop);
	    PUSH_OPND(OBJECT_TO_JSVAL(obj));
	    break;

	  case JSOP_SETNAME2:
	    atom = GET_ATOM(cx, script, pc);
	    id   = (jsid)atom;
	    rval = POP();
	    lval = POP();
	    PR_ASSERT(!JSVAL_IS_PRIMITIVE(lval));
	    obj  = JSVAL_TO_OBJECT(lval);
	    CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));
	    if (!ok)
		goto out;
	    PUSH_OPND(rval);
	    break;

#define INTEGER_OP(OP, EXTRA_CODE) {                                          \
    SAVE_SP(fp);                                                              \
    ok = PopInt(cx, &j) && PopInt(cx, &i);                                    \
    RESTORE_SP(fp);                                                           \
    if (!ok)                                                                  \
	goto out;                                                             \
    EXTRA_CODE                                                                \
    i = i OP j;                                                               \
    PUSH_NUMBER(cx, i);                                                       \
}

#define BITWISE_OP(OP)		INTEGER_OP(OP, (void) 0;)
#define SIGNED_SHIFT_OP(OP)	INTEGER_OP(OP, j &= 31;)

	  case JSOP_BITOR:
	    BITWISE_OP(|);
	    break;

	  case JSOP_BITXOR:
	    BITWISE_OP(^);
	    break;

	  case JSOP_BITAND:
	    BITWISE_OP(&);
	    break;

#ifdef XP_PC
#define COMPARE_DOUBLES(LVAL, OP, RVAL, IFNAN)                                \
    ((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL))                         \
     ? (IFNAN)                                                                \
     : (LVAL) OP (RVAL))
#else
#define COMPARE_DOUBLES(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL))
#endif

#define RELATIONAL_OP(OP) {                                                   \
    rval = POP();                                                             \
    lval = POP();                                                             \
    /* Optimize for two int-tagged operands (typical loop control). */        \
    if ((lval & rval) & JSVAL_INT) {                                          \
	ltmp = lval ^ JSVAL_VOID;                                             \
	rtmp = rval ^ JSVAL_VOID;                                             \
	if (ltmp && rtmp) {                                                   \
	    cond = JSVAL_TO_INT(lval) OP JSVAL_TO_INT(rval);                  \
	} else {                                                              \
	    d  = ltmp ? JSVAL_TO_INT(lval) : *rt->jsNaN;                      \
	    d2 = rtmp ? JSVAL_TO_INT(rval) : *rt->jsNaN;                      \
	    cond = COMPARE_DOUBLES(d, OP, d2, JS_FALSE);                      \
	}                                                                     \
    } else {                                                                  \
	VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_NUMBER, &lval);                   \
	/* Need lval for strcmp or ToNumber later, so root it via sp[0]. */   \
	sp[0] = lval;                                                         \
	VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_NUMBER, &rval);                   \
	if (JSVAL_IS_STRING(lval) && JSVAL_IS_STRING(rval)) {                 \
	    str  = JSVAL_TO_STRING(lval);                                     \
	    str2 = JSVAL_TO_STRING(rval);                                     \
	    cond = js_CompareStrings(str, str2) OP 0;                         \
	} else {                                                              \
	    /* Need rval after ToNumber(lval), so root it via sp[1]. */       \
	    sp[1] = rval;                                                     \
	    VALUE_TO_NUMBER(cx, lval, d);                                     \
	    VALUE_TO_NUMBER(cx, rval, d2);                                    \
	    cond = COMPARE_DOUBLES(d, OP, d2, JS_FALSE);                      \
	}                                                                     \
    }                                                                         \
    PUSH_OPND(BOOLEAN_TO_JSVAL(cond));                                        \
}

#define EQUALITY_OP(OP, IFNAN) {                                              \
    rval = POP();                                                             \
    lval = POP();                                                             \
    ltmp = JSVAL_TAG(lval);                                                   \
    rtmp = JSVAL_TAG(rval);                                                   \
    if (ltmp == rtmp) {                                                       \
	if (ltmp == JSVAL_STRING) {                                           \
	    str  = JSVAL_TO_STRING(lval);                                     \
	    str2 = JSVAL_TO_STRING(rval);                                     \
	    cond = js_CompareStrings(str, str2) OP 0;                         \
	} else if (ltmp == JSVAL_DOUBLE) {                                    \
	    d  = *JSVAL_TO_DOUBLE(lval);                                      \
	    d2 = *JSVAL_TO_DOUBLE(rval);                                      \
	    cond = COMPARE_DOUBLES(d, OP, d2, IFNAN);                         \
	} else {                                                              \
	    /* Handle all undefined (=>NaN) and int combinations. */          \
	    cond = lval OP rval;                                              \
	}                                                                     \
    } else {                                                                  \
	if (JSVAL_IS_NULL(lval) || JSVAL_IS_VOID(lval)) {                     \
	    cond = (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) OP 1;         \
	} else if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) {              \
	    cond = 1 OP 0;                                                    \
	} else {                                                              \
	    if (ltmp == JSVAL_OBJECT) {                                       \
		VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &lval);             \
		ltmp = JSVAL_TAG(lval);                                       \
	    } else if (rtmp == JSVAL_OBJECT) {                                \
		VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &rval);             \
		rtmp = JSVAL_TAG(rval);                                       \
	    }                                                                 \
	    if (ltmp == JSVAL_STRING && rtmp == JSVAL_STRING) {               \
		str  = JSVAL_TO_STRING(lval);                                 \
		str2 = JSVAL_TO_STRING(rval);                                 \
		cond = js_CompareStrings(str, str2) OP 0;                     \
	    } else {                                                          \
		/* Need rval after ToNumber(lval), so root it via sp[1]. */   \
		sp[1] = rval;                                                 \
		VALUE_TO_NUMBER(cx, lval, d);                                 \
		VALUE_TO_NUMBER(cx, rval, d2);                                \
		cond = COMPARE_DOUBLES(d, OP, d2, IFNAN);                     \
	    }                                                                 \
	}                                                                     \
    }                                                                         \
    PUSH_OPND(BOOLEAN_TO_JSVAL(cond));                                        \
}

	  case JSOP_EQ:
	    EQUALITY_OP(==, JS_FALSE);
	    break;

	  case JSOP_NE:
	    EQUALITY_OP(!=, JS_TRUE);
	    break;

#if !JS_BUG_FALLIBLE_EQOPS
#define NEW_EQUALITY_OP(OP, IFNAN) {                                          \
    rval = POP();                                                             \
    lval = POP();                                                             \
    ltmp = JSVAL_TAG(lval);                                                   \
    rtmp = JSVAL_TAG(rval);                                                   \
    if (ltmp == rtmp) {                                                       \
	if (ltmp == JSVAL_STRING) {                                           \
	    str  = JSVAL_TO_STRING(lval);                                     \
	    str2 = JSVAL_TO_STRING(rval);                                     \
	    cond = js_CompareStrings(str, str2) OP 0;                         \
	} else if (ltmp == JSVAL_DOUBLE) {                                    \
	    d  = *JSVAL_TO_DOUBLE(lval);                                      \
	    d2 = *JSVAL_TO_DOUBLE(rval);                                      \
	    cond = COMPARE_DOUBLES(d, OP, d2, IFNAN);                         \
	} else {                                                              \
	    cond = lval OP rval;                                              \
	}                                                                     \
    } else {                                                                  \
	if (ltmp == JSVAL_DOUBLE && JSVAL_IS_INT(rval)) {                     \
	    d  = *JSVAL_TO_DOUBLE(lval);                                      \

JS/js/jsinterp.c  view on Meta::CPAN

		     * Keep rval on the stack so it isn't GC'd during the next
		     * js_ValueToString.
		     */
		    sp[1] = rval;
		    str2 = JSVAL_TO_STRING(rval);
		    SAVE_SP(fp);
		    ok = (str = js_ValueToString(cx, lval)) != NULL;
		}
		if (!ok)
		    goto out;
		if ((length = str->length) == 0) {
		    str3 = str2;
		} else if ((length2 = str2->length) == 0) {
		    str3 = str;
		} else {
		    length3 = length + length2;
		    chars = JS_malloc(cx, (length3 + 1) * sizeof(jschar));
		    if (!chars) {
			ok = JS_FALSE;
			goto out;
		    }
		    js_strncpy(chars, str->chars, length);
		    js_strncpy(chars + length, str2->chars, length2);
		    chars[length3] = 0;
		    str3 = js_NewString(cx, chars, length3, 0);
		    if (!str3) {
			JS_free(cx, chars);
			ok = JS_FALSE;
			goto out;
		    }
		}
		PUSH_OPND(STRING_TO_JSVAL(str3));
	    } else {
		VALUE_TO_NUMBER(cx, ltmp, d);
		VALUE_TO_NUMBER(cx, rtmp, d2);
		d += d2;
		PUSH_NUMBER(cx, d);
	    }
	    break;

#define BINARY_OP(OP) {                                                       \
    POP_NUMBER(cx, d2);                                                       \
    POP_NUMBER(cx, d);                                                        \
    d = d OP d2;                                                              \
    PUSH_NUMBER(cx, d);                                                       \
}

	  case JSOP_SUB:
	    BINARY_OP(-);
	    break;

	  case JSOP_MUL:
	    BINARY_OP(*);
	    break;

	  case JSOP_DIV:
	    POP_NUMBER(cx, d2);
	    POP_NUMBER(cx, d);
	    if (d2 == 0) {
#ifdef XP_PC
		/* XXX MSVC miscompiles such that (NaN == 0) */
		if (JSDOUBLE_IS_NaN(d2))
		    rval = DOUBLE_TO_JSVAL(rt->jsNaN);
		else
#endif
		if (d == 0 || JSDOUBLE_IS_NaN(d))
		    rval = DOUBLE_TO_JSVAL(rt->jsNaN);
		else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31)
		    rval = DOUBLE_TO_JSVAL(rt->jsNegativeInfinity);
		else
		    rval = DOUBLE_TO_JSVAL(rt->jsPositiveInfinity);
		PUSH_OPND(rval);
	    } else {
		d /= d2;
		PUSH_NUMBER(cx, d);
	    }
	    break;

	  case JSOP_MOD:
	    POP_NUMBER(cx, d2);
	    POP_NUMBER(cx, d);
	    if (d2 == 0) {
		PUSH_OPND(DOUBLE_TO_JSVAL(rt->jsNaN));
	    } else {
#ifdef XP_PC
	      /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
	      if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2)))
#endif
		d = fmod(d, d2);
		PUSH_NUMBER(cx, d);
	    }
	    break;

	  case JSOP_NOT:
	    POP_BOOLEAN(cx, rval, cond);
	    PUSH_OPND(BOOLEAN_TO_JSVAL(!cond));
	    break;

	  case JSOP_BITNOT:
	    SAVE_SP(fp);
	    ok = PopInt(cx, &i);
	    RESTORE_SP(fp);
	    if (!ok)
		goto out;
            i = ~i;
            PUSH_NUMBER(cx, i);
	    break;

	  case JSOP_NEG:
	    POP_NUMBER(cx, d);
	    d = -d;
	    PUSH_NUMBER(cx, d);
	    break;

	  case JSOP_POS:
	    POP_NUMBER(cx, d);
	    PUSH_NUMBER(cx, d);
	    break;

	  case JSOP_NEW:
	    /* Get immediate argc and find the constructor function. */
	    argc = GET_ARGC(pc);

	  do_new:
	    vp = sp - (2 + argc);
	    PR_ASSERT(vp >= newsp);

	    lval = *vp;
	    if (!JSVAL_IS_OBJECT(lval) ||
		(obj2 = JSVAL_TO_OBJECT(lval)) == NULL ||
		!obj2->map->ops->construct) {
		fun = js_ValueToFunction(cx, vp, JS_TRUE);
		if (!fun) {
		    ok = JS_FALSE;
		    goto out;
		}
		obj2 = fun->object;
	    }

	    if (!obj2) {
		proto = parent = NULL;
		fun = NULL;
	    } else {
		/* Get the constructor prototype object for this function. */
		ok = OBJ_GET_PROPERTY(cx, obj2,
				      (jsid)rt->atomState.classPrototypeAtom,



( run in 0.568 second using v1.01-cache-2.11-cpan-39bf76dae61 )