// ECMA262: 26.1.1 Reflect.apply ( target, thisArgument, argumentsList ) static ejsval _ejs_Reflect_apply (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { ejsval target = _ejs_undefined; ejsval thisArgument = _ejs_undefined; ejsval argumentsList = _ejs_undefined; if (argc > 0) target = args[0]; if (argc > 1) thisArgument = args[1]; if (argc > 2) argumentsList = args[2]; // 1. Let obj be ToObject(target). // 2. ReturnIfAbrupt(obj). ejsval obj = ToObject(target); // 3. If IsCallable(obj) is false, then throw a TypeError exception. if (!EJSVAL_IS_CALLABLE(obj)) _ejs_throw_nativeerror_utf8(EJS_TYPE_ERROR, "target is not callable"); // 4. Let args be CreateListFromArray (argumentsList). // 5. ReturnIfAbrupt(args). if (!EJSVAL_IS_ARRAY(argumentsList)) _ejs_throw_nativeerror_utf8(EJS_TYPE_ERROR, "argumentsList is not an array"); // sparse arrays kinda suck here... if (!EJSVAL_IS_DENSE_ARRAY(argumentsList)) _ejs_throw_nativeerror_utf8(EJS_TYPE_ERROR, "argumentsList is not a dense array"); // 6. Perform the PrepareForTailCall abstract operation. // 7. Return the result of calling the [[Call]] internal method of obj with arguments thisArgument and args. return _ejs_invoke_closure(obj, thisArgument, EJS_ARRAY_LEN(argumentsList), EJS_DENSE_ARRAY_ELEMENTS(argumentsList)); }
ejsval ToNumber(ejsval exp) { if (EJSVAL_IS_NUMBER(exp)) return exp; else if (EJSVAL_IS_BOOLEAN(exp)) return EJSVAL_TO_BOOLEAN(exp) ? _ejs_one : _ejs_zero; else if (EJSVAL_IS_STRING(exp)) { char* num_utf8 = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(exp)); char *endptr; double d = strtod(num_utf8, &endptr); if (*endptr != '\0') return _ejs_nan; ejsval rv = NUMBER_TO_EJSVAL(d); // XXX NaN free (num_utf8); return rv; } else if (EJSVAL_IS_UNDEFINED(exp)) return _ejs_nan; else if (EJSVAL_IS_OBJECT(exp)) { if (EJSVAL_IS_DATE(exp)) { return NUMBER_TO_EJSVAL(_ejs_date_get_time ((EJSDate*)EJSVAL_TO_OBJECT(exp))); } else if (EJSVAL_IS_ARRAY(exp)) { int len = EJS_ARRAY_LEN(exp); if (len == 0) return _ejs_zero; else if (len > 1) return _ejs_nan; else { // XXX we need to support sparse arrays here too EJS_ASSERT (EJSVAL_IS_DENSE_ARRAY(exp)); return ToNumber(EJS_DENSE_ARRAY_ELEMENTS(exp)[0]); } } else return _ejs_nan; } else EJS_NOT_IMPLEMENTED(); }