// ECMA262: 15.3.5.3 static EJSBool _ejs_function_specop_has_instance (ejsval F, ejsval V) { /* 1. If V is not an object, return false. */ if (!EJSVAL_IS_OBJECT(V)) return EJS_FALSE; /* 2. Let O be the result of calling the [[Get]] internal method of F with property name "prototype". */ ejsval O = OP(EJSVAL_TO_OBJECT(F),Get)(F, _ejs_atom_prototype, F); /* 3. If Type(O) is not Object, throw a TypeError exception. */ if (!EJSVAL_IS_OBJECT(O)) { printf ("throw TypeError, O is not an object\n"); EJS_NOT_IMPLEMENTED(); } /* 4. Repeat */ while (1) { /* a. Let V be the value of the [[Prototype]] internal property of V. */ V = EJSVAL_TO_OBJECT(V)->proto; /* b. If V is null, return false. */ if (EJSVAL_IS_NULL(V)) return EJS_FALSE; /* c. If O and V refer to the same object, return true. */ if (EJSVAL_EQ(O, V)) return EJS_TRUE; } }
// same as SameValue, except in its treatment of +/- 0 EJSBool SameValueZero(ejsval x, ejsval y) { // 1. ReturnIfAbrupt(x). // 2. ReturnIfAbrupt(y). // 3. If Type(x) is different from Type(y), return false. if (EJSVAL_TO_TAG(x) != EJSVAL_TO_TAG(y)) return EJS_FALSE; // 4. If Type(x) is Undefined, return true. if (EJSVAL_IS_UNDEFINED(x)) return EJS_TRUE; // 5. If Type(x) is Null, return true. if (EJSVAL_IS_NULL(x)) return EJS_TRUE; // 6. If Type(x) is Number, then if (EJSVAL_IS_NUMBER(x)) { // a. If x is NaN and y is NaN, return true. if (isnan(EJSVAL_TO_NUMBER(x)) && isnan(EJSVAL_TO_NUMBER(y))) return EJS_TRUE; // b. If x is +0 and y is -0, return true. if (EJSVAL_TO_NUMBER(x) == 0.0 && EJSDOUBLE_IS_NEGZERO(EJSVAL_TO_NUMBER(y))) return EJS_TRUE; // c. If x is -0 and y is +0, return tryue. if (EJSDOUBLE_IS_NEGZERO(EJSVAL_TO_NUMBER(x)) == 0.0 && EJSVAL_TO_NUMBER(y) == 0) return EJS_TRUE; // d. If x is the same Number value as y, return true. if (EJSVAL_TO_NUMBER(x) == EJSVAL_TO_NUMBER(y)) return EJS_TRUE; // e. Return false. return EJS_FALSE; } // 7. If Type(x) is String, then if (EJSVAL_IS_STRING(x)) { // a. If x and y are exactly the same sequence of code units (same length and same code units in corresponding positions) return true; // otherwise, return false. if (EJSVAL_TO_STRLEN(x) != EJSVAL_TO_STRLEN(y)) return EJS_FALSE; // XXX there is doubtless a more efficient way to compare two ropes, but we convert but to flat strings for now. return ucs2_strcmp (EJSVAL_TO_FLAT_STRING(x), EJSVAL_TO_FLAT_STRING(y)) ? EJS_FALSE : EJS_TRUE; } // 8. If Type(x) is Boolean, then if (EJSVAL_IS_BOOLEAN(x)) { // a. If x and y are both true or both false, then return true; otherwise, return false. return EJSVAL_TO_BOOLEAN(x) == EJSVAL_TO_BOOLEAN(y) ? EJS_TRUE : EJS_FALSE; } // 9. If Type(x) is Symbol, then if (EJSVAL_IS_SYMBOL(x)) { // a. If x and y are both the same Symbol value, then return true; otherwise, return false. EJS_NOT_IMPLEMENTED(); } // 10. Return true if x and y are the same Object value. Otherwise, return false. return EJSVAL_EQ(x, y); }
int32_t ToInteger(ejsval exp) { // XXX sorely lacking /* 1. Let number be the result of calling ToNumber on the input argument. */ ejsval number = ToNumber(exp); /* 2. If number is NaN, return +0. */ if (EJSVAL_EQ(number, _ejs_nan)) return 0; /* 3. If number is +0, 0, +, or , return number. */ double d = ToDouble(number); int classified = fpclassify(d); if (classified == FP_ZERO || classified == FP_INFINITE) return d; /* 4. Return the result of computing sign(number) floor(abs(number) */ int sign = d < 0 ? -1 : 1; return (int)(sign * floor(abs(d))); }