// ECMA262 15.3.4.5 static ejsval _ejs_Function_prototype_bind (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { /* 1. Let Target be the this value. */ ejsval Target = _this; /* 2. If IsCallable(Target) is false, throw a TypeError exception. */ if (!EJSVAL_IS_CALLABLE(Target)) { _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "object not a function"); } ejsval thisArg = _ejs_undefined; if (argc > 0) thisArg = args[0]; /* 3. Let A be a new (possibly empty) internal list of all of the argument values provided after thisArg (arg1, arg2 etc), in order. */ int bound_argc = argc > 1 ? argc - 1 : 0; /* 4. Let F be a new native ECMAScript object . */ ejsval bound_env = EJS_BOUNDFUNC_ENV_NEW(bound_argc); EJS_BOUNDFUNC_ENV_SET_TARGET(bound_env, Target); EJS_BOUNDFUNC_ENV_SET_THIS(bound_env, thisArg); EJS_BOUNDFUNC_ENV_SET_ARGC(bound_env, NUMBER_TO_EJSVAL(bound_argc)); for (int i = 0; i < bound_argc; i ++) { EJS_BOUNDFUNC_ENV_SET_ARG(bound_env, i, args[i+1]); } ejsval target_name = _ejs_object_getprop (Target, _ejs_atom_name); ejsval bound_name; if (EJSVAL_IS_STRING(target_name)) bound_name = _ejs_string_concat(_ejs_atom_bound_space, target_name); else bound_name = _ejs_atom_bound_space; ejsval F = _ejs_function_new (bound_env, bound_name, bound_wrapper); EJSFunction *F_ = (EJSFunction*)EJSVAL_TO_OBJECT(F); F_->bound = EJS_TRUE; return F; }
// ECMA262 15.3.4.5 static ejsval _ejs_Function_prototype_bind (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { /* 1. Let Target be the this value. */ ejsval Target = _this; /* 2. If IsCallable(Target) is false, throw a TypeError exception. */ if (!EJSVAL_IS_CALLABLE(Target)) { _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "object not a function"); } ejsval thisArg = _ejs_undefined; if (argc > 0) thisArg = args[0]; /* 3. Let A be a new (possibly empty) internal list of all of the argument values provided after thisArg (arg1, arg2 etc), in order. */ int bound_argc = argc > 1 ? argc - 1 : 0; /* 4. Let F be a new native ECMAScript object . */ ejsval bound_env = EJS_BOUNDFUNC_ENV_NEW(bound_argc); EJS_BOUNDFUNC_ENV_SET_TARGET(bound_env, Target); EJS_BOUNDFUNC_ENV_SET_THIS(bound_env, thisArg); EJS_BOUNDFUNC_ENV_SET_ARGC(bound_env, NUMBER_TO_EJSVAL(bound_argc)); for (int i = 0; i < bound_argc; i ++) { EJS_BOUNDFUNC_ENV_SET_ARG(bound_env, i, args[i+1]); } ejsval F = _ejs_function_new_anon (bound_env, bound_wrapper); EJSFunction *F_ = (EJSFunction*)EJSVAL_TO_OBJECT(F); F_->bound = EJS_TRUE; #if not_anymore /* 5. Set all the internal methods, except for [[Get]], of F as specified in 8.12. */ /* 6. Set the [[Get]] internal property of F as specified in 15.3.5.4. */ /* 7. Set the [[TargetFunction]] internal property of F to Target. */ /* 8. Set the [[BoundThis]] internal property of F to the value of thisArg. */ F_->bound_this = thisArg; /* 9. Set the [[BoundArgs]] internal property of F to A. */ F_->bound_argc = bound_argc; F_->bound_args = bound_args; /* 10. Set the [[Class]] internal property of F to "Function". */ /* 11. Set the [[Prototype]] internal property of F to the standard built-in Function prototype object as specified in 15.3.3.1. */ /* 12. Set the [[Call]] internal property of F as described in 15.3.4.5.1. */ /* 13. Set the [[Construct]] internal property of F as described in 15.3.4.5.2. */ /* 14. Set the [[HasInstance]] internal property of F as described in 15.3.4.5.3. */ /* 15. If the [[Class]] internal property of Target is "Function", then */ /* a. Let L be the length property of Target minus the length of A. */ /* b. Set the length own property of F to either 0 or L, whichever is larger. */ /* 16. Else set the length own property of F to 0. */ /* 17. Set the attributes of the length own property of F to the values specified in 15.3.5.1. */ /* 18. Set the [[Extensible]] internal property of F to true. */ /* 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). */ /* 20. Call the [[DefineOwnProperty]] internal method of F with arguments "caller", PropertyDescriptor */ /* {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, and false. */ /* 21. Call the [[DefineOwnProperty]] internal method of F with arguments "arguments", PropertyDescriptor */ /* {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, and false. */ /* 22. Return F. */ #endif return F; }