ejsval _ejs_invoke_closure (ejsval closure, ejsval _this, uint32_t argc, ejsval* args) { if (!EJSVAL_IS_FUNCTION(closure)) { #if DEBUG_LAST_LOOKUP extern jschar* last_lookup; if (last_lookup) { char *last_utf8 = ucs2_to_utf8(last_lookup); _ejs_log ("last property lookup was for: %s\n", last_utf8); free (last_utf8); } #endif _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "object not a function"); } #if 0 if (!EJSVAL_IS_NULL_OR_UNDEFINED(_this) && EJSVAL_IS_PRIMITIVE(_this)) { _this = ToObject(_this); } #endif EJSFunction *fun = (EJSFunction*)EJSVAL_TO_OBJECT(closure); return fun->func (fun->env, _this, argc, args); }
static EJS_NATIVE_FUNC(_ejs_Error_prototype_toString) { ejsval O = *_this; if (!EJSVAL_IS_OBJECT(O)) { _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Error.prototype.toString called on non-object"); } EJSObject *_thisobj = EJSVAL_TO_OBJECT(O); ejsval name = OP(_thisobj,Get)(O, _ejs_atom_name, O); if (EJSVAL_IS_NULL_OR_UNDEFINED(name)) name = _ejs_atom_Error; ejsval message = OP(_thisobj,Get)(O, _ejs_atom_message, O); if (EJSVAL_IS_NULL_OR_UNDEFINED(message)) return name; ejsval sep = _ejs_string_new_utf8(": "); return _ejs_string_concatv (name, sep, message, _ejs_null); }
static ejsval _ejs_Error_prototype_toString (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { if (!EJSVAL_IS_OBJECT(_this)) { _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Error.prototype.toString called on non-object"); } EJSObject *_thisobj = EJSVAL_TO_OBJECT(_this); ejsval name = OP(_thisobj,Get)(_this, _ejs_atom_name, _this); if (EJSVAL_IS_NULL_OR_UNDEFINED(name)) name = _ejs_atom_Error; ejsval message = OP(_thisobj,Get)(_this, _ejs_atom_message, _this); if (EJSVAL_IS_NULL_OR_UNDEFINED(message)) return name; ejsval sep = _ejs_string_new_utf8(": "); return _ejs_string_concatv (name, sep, message, _ejs_null); }
ejsval _ejs_invoke_closure (ejsval closure, ejsval _this, uint32_t argc, ejsval* args) { if (!EJSVAL_IS_FUNCTION(closure)) { #if DEBUG_LAST_LOOKUP extern jschar* last_lookup; if (last_lookup) { char *last_utf8 = ucs2_to_utf8(last_lookup); _ejs_log ("last property lookup was for: %s\n", last_utf8); free (last_utf8); } #endif _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "object not a function"); } if (!EJSVAL_IS_NULL_OR_UNDEFINED(_this) && EJSVAL_IS_PRIMITIVE(_this)) { _this = ToObject(_this); } EJSFunction *fun = (EJSFunction*)EJSVAL_TO_OBJECT(closure); return fun->func (fun->env, _this, argc, args); #if not_anymore if (fun->bound_argc > 0) { ejsval* new_args = (ejsval*)malloc(sizeof(ejsval) * (fun->bound_argc + argc)); memmove (new_args, fun->bound_args, sizeof(ejsval) * fun->bound_argc); memmove (&new_args[fun->bound_argc], args, argc); args = new_args; argc += fun->bound_argc; } DEBUG_FUNCTION_ENTER (closure); ejsval rv = fun->func (fun->env, fun->bound_this, argc, args); DEBUG_FUNCTION_EXIT (closure); if (fun->bound_argc > 0) free (args); return rv; #endif }
// ES6: 23.4.3.3 // WeakSet.prototype.delete ( value ) static EJS_NATIVE_FUNC(_ejs_WeakSet_prototype_delete) { ejsval value = _ejs_undefined; if (argc > 0) value = args[0]; // 1. Let S be the this value. ejsval S = *_this; // 2. If Type(S) is not Object, then throw a TypeError exception. if (!EJSVAL_IS_OBJECT(S)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "delete called with non-object this."); // 3. If S does not have a [[WeakSetData]] internal slot throw a TypeError exception. if (!EJSVAL_IS_WEAKSET(S)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "delete called with non-WeakSet this."); // 4. If S’s [[WeakSetData]] internal slot is undefined, then throw a TypeError exception. // 5. If Type(value) is not Object, then return false. if (!EJSVAL_IS_OBJECT(value)) return _ejs_false; // 6. Let entries be the List that is the value of M’s [[WeakSetData]] internal slot. #if WEAK_COLLECTIONS_USE_INVERTED_REP ejsval iset = _ejs_object_getprop(value, _ejs_WeakSetData_symbol); if (EJSVAL_IS_NULL_OR_UNDEFINED(iset)) return _ejs_false; if (!EJSVAL_IS_SET(iset)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "[[WeakSetData]] internal error"); return _ejs_set_delete (iset, S); #else // 7. Repeat for each e that is an element of entries, // a. If e is not empty and SameValue(e, value) is true, then // i. Replace the element of entries whose value is e with an element whose value is empty. // ii. Return true. // 8. Return false. return _ejs_false; #endif }
// ES6: 23.4.3.1 // WeakSet.prototype.add ( value ) static EJS_NATIVE_FUNC(_ejs_WeakSet_prototype_add) { ejsval value = _ejs_undefined; if (argc > 0) value = args[0]; // 1. Let S be the this value. ejsval S = *_this; // 2. If Type(S) is not Object, then throw a TypeError exception. if (!EJSVAL_IS_OBJECT(S)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "add called with non-object this."); // 3. If S does not have a [[WeakSetData]] internal slot throw a TypeError exception. if (!EJSVAL_IS_WEAKSET(S)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "add called with non-WeakSet this."); // 4. If S’s [[WeakSetData]] internal slot is undefined, then throw a TypeError exception. // 6. If Type(value) is not Object, then throw a TypeError exception. if (!EJSVAL_IS_OBJECT(value)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "add called with non-Object value."); #if WEAK_COLLECTIONS_USE_INVERTED_REP ejsval iset = _ejs_object_getprop(value, _ejs_WeakSetData_symbol); if (EJSVAL_IS_NULL_OR_UNDEFINED(iset)) { iset = _ejs_set_new(); _ejs_object_setprop(value, _ejs_WeakSetData_symbol, iset); } if (!EJSVAL_IS_SET(iset)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "[[WeakSetData]] internal error"); _ejs_set_add (iset, S); return S; #else // 7. Let entries be the List that is the value of S’s [[WeakSetData]] internal slot. // a. If e is not empty and SameValue(e, value) is true, then // 1. Return S. // 8. Append value as the last element of entries. // 9. Return S. #endif }
// ES2015, June 2015 // 23.4.1.1 WeakSet ( [ iterable ] ) static EJS_NATIVE_FUNC(_ejs_WeakSet_impl) { ejsval iterable = _ejs_undefined; if (argc > 0) iterable = args[0]; // 1. If NewTarget is undefined, throw a TypeError exception. if (EJSVAL_IS_UNDEFINED(newTarget)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "WeakSet constructor must be called with new"); // 2. Let set be OrdinaryCreateFromConstructor(NewTarget, "%WeakSetPrototype%", «[[WeakSetData]]»). // 3. ReturnIfAbrupt(set). // 4. Set set’s [[WeakSetData]] internal slot to a new empty List. ejsval set = OrdinaryCreateFromConstructor(newTarget, _ejs_WeakSet_prototype, &_ejs_WeakSet_specops); *_this = set; // 5. If iterable is not present, let iterable be undefined. // 6. If iterable is either undefined or null, let iter be undefined. ejsval iter; ejsval adder; if (EJSVAL_IS_NULL_OR_UNDEFINED(iterable)) { iter = _ejs_undefined; } // 7. Else, else { // a. Let adder be Get(set, "add"). // b. ReturnIfAbrupt(adder). adder = Get (set, _ejs_atom_add); // c. If IsCallable(adder) is false, throw a TypeError exception. if (!IsCallable(adder)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "WeakSet.prototype.add is not a function"); // d. Let iter be GetIterator(iterable). // e. ReturnIfAbrupt(iter). iter = GetIterator(iterable, _ejs_undefined); } // 8. If iter is undefined, return set. if (EJSVAL_IS_UNDEFINED(iter)) return set; // 9. Repeat for (;;) { // a. Let next be IteratorStep(iter). // b. ReturnIfAbrupt(next). ejsval next = IteratorStep (iter); // c. If next is false, return set. if (!EJSVAL_TO_BOOLEAN(next)) return set; // d. Let nextValue be IteratorValue(next). // e. ReturnIfAbrupt(nextValue). ejsval nextValue = IteratorValue (next); // f. Let status be Call(adder, set, «nextValue »). // XXX _ejs_invoke_closure won't call proxy methods ejsval rv; EJSBool status = _ejs_invoke_closure_catch (&rv, adder, &set, 1, &nextValue, _ejs_undefined); // g. If status is an abrupt completion, return IteratorClose(iter, status). if (!status) return IteratorClose(iter, rv, EJS_TRUE); } }