Esempio n. 1
0
// 25.4.3.1 Promise ( executor ) 
static ejsval
_ejs_Promise_impl (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    ejsval executor = _ejs_undefined;
    if (argc > 0) executor = args[0];

    // 1. Let promise be the this value.
    ejsval promise = _this;

    // 2. If Type(promise) is not Object, then throw a TypeError exception.
    if (!EJSVAL_IS_OBJECT(promise))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "`this' is not an object");

    // 3. If promise does not have a [[PromiseState]] internal slot, then throw a TypeError exception.
    if (!EJSVAL_IS_PROMISE(promise))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "`this' is not an promise");

    EJSPromise* _promise = EJSVAL_TO_PROMISE(promise);
    
    // 4. If promise's [[PromiseState]] internal slot is not undefined, then throw a TypeError exception.
    if (_promise->state != PROMISE_STATE_UNINITIALIZED)
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Promise constructor called on previously created object");

    // 5. If IsCallable(executor) is false, then throw a TypeError exception.
    if (!EJSVAL_IS_CALLABLE(executor))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "executor is not callable");

    // 6. Return InitializePromise(promise, executor).
    //    1. Assert: promise has a [[PromiseState]] internal slot and it’s value is undefined. 
    //    2. Assert: IsCallable(executor) is true. 
    //    3. Set promise's [[PromiseState]] internal slot to "pending". 
    _promise->state = PROMISE_STATE_PENDING;

    //    4. Set promise's [[PromiseFulfillReactions]] internal slot to a new empty List. 
    _promise->fulfillReactions = NULL;

    //    5. Set promise's [[PromiseRejectReactions]] internal slot to a new empty List. 
    _promise->rejectReactions = NULL;

    //    6. Let resolvingFunctions be CreateResolvingFunctions(promise). 
    ejsval resolvingFunctions_resolve;
    ejsval resolvingFunctions_reject;

    CreateResolvingFunctions(promise, &resolvingFunctions_resolve, &resolvingFunctions_reject);

    //    7. Let completion be the result of calling the [[Call]] internal method of executor with undefined as thisArgument and (resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]) a argumentsList. 
    ejsval completion;
    ejsval executor_args[] = { resolvingFunctions_resolve, resolvingFunctions_reject };

    EJSBool success = _ejs_invoke_closure_catch(&completion, executor, _ejs_undefined, 2, executor_args);
    //    8. If completion is an abrupt completion, then 
    if (!success) {
        //       a. Let status be the result of calling the [[Call]] internal method of resolvingFunctions.[[Reject]] with undefined as thisArgument and (completion.[[value]]) as argumentsList. 
        //       b. ReturnIfAbrupt(status). 
        _ejs_invoke_closure(resolvingFunctions_reject, _ejs_undefined, 1, &completion);
    }

    //    9. Return promise.
    return promise;
}
Esempio n. 2
0
// 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));
}
Esempio n. 3
0
// ECMA262 25.4.1.6.1 CreatePromiseCapabilityRecord( promise, constructor ) 
static ejsval
CreatePromiseCapabilityRecord (ejsval promise, ejsval constructor)
{
    // 1. Assert: promise is an uninitialized object created as if by invoking @@create on constructor.
    // 2. Assert: IsConstructor(constructor) is true.
    // 3. Let promiseCapability be a new PromiseCapability { [[Promise]]: promise, [[Resolve]]: undefined, [[Reject]]: undefined }.
    ejsval promiseCapability = EJS_CAPABILITY_NEW();
    EJS_CAPABILITY_SET_PROMISE(promiseCapability, promise);
    EJS_CAPABILITY_SET_RESOLVE(promiseCapability, _ejs_undefined);
    EJS_CAPABILITY_SET_REJECT(promiseCapability, _ejs_undefined);

    // 4. Let executor be a new built-in function object as defined in GetCapabilitiesExecutor Functions (25.4.1.5.1).
    ejsval executor = _ejs_function_new_anon (promiseCapability, capabilitiesExecutor);

    // 5. Set the [[Capability]] internal slot of executor to promiseCapability.

    // 6. Let constructorResult be the result of calling the [[Call]] internal method of constructor, passing promise and (executor) as the arguments.
    // 7. ReturnIfAbrupt(constructorResult).
    ejsval constructorResult = _ejs_invoke_closure (constructor, promise, 1, &executor);

    // 8. If IsCallable(promiseCapability.[[Resolve]]) is false, then throw a TypeError exception. 
    if (!EJSVAL_IS_CALLABLE(EJS_CAPABILITY_GET_RESOLVE(promiseCapability)))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, ""); // XXX
    // 9. If IsCallable(promiseCapability.[[Reject]]) is false, then throw a TypeError exception. 
    if (!EJSVAL_IS_CALLABLE(EJS_CAPABILITY_GET_REJECT(promiseCapability)))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, ""); // XXX
    // 10. If Type(constructorResult) is Object and SameValue(promise, constructorResult) is false, then throw a TypeError exception. 
    if (EJSVAL_IS_OBJECT(constructorResult) && !SameValue(promise, constructorResult))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "1"); // XXX
        
    // 11. Return promiseCapability. 
    return promiseCapability;
}
Esempio n. 4
0
// ECMA262 25.4.4.5 Promise.resolve ( x )
static ejsval
_ejs_Promise_resolve (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    ejsval x = _ejs_undefined;
    if (argc > 0) x = args[0];

    // 1. Let C be the this value. 
    ejsval C = _this;
    // 2. If IsPromise(x) is true, 
    if (EJSVAL_IS_PROMISE(x)) {
        EJSPromise* _x = EJSVAL_TO_PROMISE(x);
        //    a. Let constructor be the value of x's [[PromiseConstructor]] internal slot. 
        //    b. If SameValue(constructor, C) is true, return x. 
        if (SameValue(_x->constructor, C))
            return x;
    }

    // 3. Let promiseCapability be NewPromiseCapability(C). 
    // 4. ReturnIfAbrupt(promiseCapability). 
    ejsval promiseCapability = NewPromiseCapability(C);

    // 5. Let resolveResult be the result of calling the [[Call]] internal method of promiseCapability.[[Resolve]] with undefined as thisArgument and (x) as argumentsList. 
    // 6. ReturnIfAbrupt(resolveResult). 
    _ejs_invoke_closure(EJS_CAPABILITY_GET_RESOLVE(promiseCapability), _ejs_undefined, 1, &x);

    // 7. Return promiseCapability.[[Promise]]. 
    return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
}
Esempio n. 5
0
// returns an EJSPrimString*.
// maybe we could change it to return a char* to match ToDouble?  that way string concat wouldn't create
// temporary strings for non-PrimString objects only to throw them away after concatenation?
ejsval ToString(ejsval exp)
{
    if (EJSVAL_IS_MAGIC_IMPL(exp)) {
        // holes in dense arrays end up here
        return _ejs_atom_empty;
    }
    else if (EJSVAL_IS_NULL(exp))
        return _ejs_atom_null;
    else if (EJSVAL_IS_UNDEFINED(exp))
        return _ejs_atom_undefined;
    else if (EJSVAL_IS_BOOLEAN(exp)) 
        return EJSVAL_TO_BOOLEAN(exp) ? _ejs_atom_true : _ejs_atom_false;
    else if (EJSVAL_IS_NUMBER(exp))
        return NumberToString(EJSVAL_TO_NUMBER(exp));
    else if (EJSVAL_IS_STRING(exp))
        return exp;
    else if (EJSVAL_IS_OBJECT(exp)) {
        ejsval toString = _ejs_object_getprop (exp, _ejs_atom_toString);
        if (!EJSVAL_IS_FUNCTION(toString)) {
            return _ejs_Object_prototype_toString(_ejs_null, exp, 0, NULL);
        }

        // should we be checking if this returns a string?  i'd assume so...
        return _ejs_invoke_closure (toString, exp, 0, NULL);
    }
    else
        EJS_NOT_IMPLEMENTED();
}
Esempio n. 6
0
static void
_ejs_generator_start(EJSGenerator* gen)
{
    _ejs_gc_push_generator(gen);
    _ejs_invoke_closure(gen->body, _ejs_undefined, 0, NULL);
    _ejs_gc_pop_generator();

    gen->yielded_value = _ejs_create_iter_result(_ejs_undefined, _ejs_true);
}
Esempio n. 7
0
static ejsval
bound_wrapper (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    ejsval target = EJS_BOUNDFUNC_ENV_GET_TARGET(env);
    ejsval thisArg = EJS_BOUNDFUNC_ENV_GET_THIS(env);
    uint32_t bound_argc = ToUint32(EJS_BOUNDFUNC_ENV_GET_ARGC(env));

    if (bound_argc == 0) {
        return _ejs_invoke_closure(target, thisArg, argc, args);
    }
    else if (argc == 0) {
        return _ejs_invoke_closure(target, thisArg, bound_argc, _ejs_closureenv_get_slot_ref(env, EJS_BOUNDFUNC_FIRST_ARG_SLOT));
    }
    else {
        uint32_t call_argc = argc + bound_argc;
        ejsval* call_args = alloca(sizeof(ejsval) * call_argc);
        memcpy (call_args, _ejs_closureenv_get_slot_ref(env, EJS_BOUNDFUNC_FIRST_ARG_SLOT), sizeof(ejsval) * bound_argc);
        memcpy (call_args + bound_argc, args, sizeof(ejsval) * argc);
        return _ejs_invoke_closure(target, thisArg, call_argc, call_args);
    }
}
Esempio n. 8
0
// ES6: 23.2.3.6 Set.prototype.forEach ( callbackfn , thisArg = undefined )
ejsval
_ejs_Set_prototype_forEach (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    ejsval callbackfn = _ejs_undefined;
    ejsval thisArg = _ejs_undefined;

    if (argc > 0) callbackfn = args[0];
    if (argc > 1) thisArg = args[1];

    // 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, "Set.prototype.forEach called with non-object this.");

    // 3. If S does not have a [[SetData]] internal slot throw a TypeError exception. 
    if (!EJSVAL_IS_SET(S))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Set.prototype.forEach called with non-Set this.");

    // 4. If S’s [[SetData]] internal slot is undefined, then throw a TypeError exception. 

    // 5. If IsCallable(callbackfn) is false, throw a TypeError exception. 
    if (!EJSVAL_IS_CALLABLE(callbackfn))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Set.prototype.forEach callbackfn isn't a function.");

    // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. 
    ejsval T = thisArg;

    EJSSet* set = EJSVAL_TO_SET(S);

    // 7. Let entries be the List that is the value of S’s [[SetData]] internal slot. 
    EJSSetValueEntry* entries = set->head_insert;

    // 8. Repeat for each e that is an element of entries, in original insertion order 
    for (EJSSetValueEntry *e = entries; e; e = e->next_insert) {
        //    a. If e is not empty, then 
        if (EJSVAL_IS_NO_ITER_VALUE_MAGIC(e->value))
            continue;

        //       i. Let funcResult be the result of calling the [[Call]] internal method of callbackfn with T as thisArgument and a List containing e, e, and S as argumentsList. 
        //       ii. ReturnIfAbrupt(funcResult). 
        ejsval callback_args[3];
        callback_args[0] = e->value;
        callback_args[1] = e->value;
        callback_args[2] = S;
        _ejs_invoke_closure (callbackfn, T, 3, callback_args);

    }

    // 9. Return undefined. 
    return _ejs_undefined;
}
Esempio n. 9
0
// ECMA262 25.4.5.1 Promise.prototype.catch ( onRejected ) 
static ejsval
_ejs_Promise_prototype_catch (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    ejsval onRejected = _ejs_undefined;
    if (argc > 0) onRejected = args[0];

    // 1. Let promise be the this value. 
    ejsval promise = _this;

    // 2. Return Invoke(promise, "then", (undefined, onRejected)). 
    ejsval thenargs[] = { _ejs_undefined, onRejected };
    return _ejs_invoke_closure(Get(promise, _ejs_atom_then), promise, 2, thenargs);
}
Esempio n. 10
0
ejsval ToObject(ejsval exp)
{
    if (EJSVAL_IS_BOOLEAN(exp)) {
        ejsval new_boolean = _ejs_object_new (_ejs_Boolean_proto, &_ejs_Boolean_specops);
        _ejs_invoke_closure (_ejs_Boolean, new_boolean, 1, &exp);
        return new_boolean;
    }
    else if (EJSVAL_IS_NUMBER(exp)) {
        ejsval new_number = _ejs_object_new (_ejs_Number_proto, &_ejs_Number_specops);
        _ejs_invoke_closure (_ejs_Number, new_number, 1, &exp);
        return new_number;
    }
    else if (EJSVAL_IS_STRING(exp)) {
        ejsval new_str = _ejs_object_new (_ejs_String_prototype, &_ejs_String_specops);
        _ejs_invoke_closure (_ejs_String, new_str, 1, &exp);
        return new_str;
    }
    else if (EJSVAL_IS_UNDEFINED(exp))
        return exp; // XXX
    else if (EJSVAL_IS_OBJECT(exp))
        return exp;
    else
        EJS_NOT_IMPLEMENTED();
}
Esempio n. 11
0
// ECMA262 25.4.1.6 NewPromiseCapability ( C ) 
static ejsval
NewPromiseCapability(ejsval C)
{
    // 1. If IsConstructor(C) is false, throw a TypeError exception. 
    // 2. Assert: C is a constructor function that supports the parameter conventions of the Promise constructor (see 25.4.3.1). 
    // 3. Let promise be CreateFromConstructor(C). 
    ejsval creator = Get(C, _ejs_Symbol_create);
    // 4. ReturnIfAbrupt(promise). 
    ejsval promise = _ejs_invoke_closure (creator, _ejs_undefined, 0, NULL);

    // 5. If Type(promise) is not Object, then throw a TypeError exception. 
    if (!EJSVAL_IS_OBJECT(promise))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "promise constructor returned non-object");

    // 6. Return CreatePromiseCapabilityRecord(promise, C). 
    return CreatePromiseCapabilityRecord(promise, C);
}
Esempio n. 12
0
// ES6 Draft rev32 Feb 2, 2015
// 9.2.3
// [[Construct]] ( argumentsList, newTarget)
ejsval
_ejs_construct_closure (ejsval _closure, ejsval newTarget, uint32_t argc, ejsval* args)
{
    // 1. Assert: F is an ECMAScript function object.
    EJSFunction* F = (EJSFunction*)EJSVAL_TO_OBJECT(_closure);

    // 2. Assert: Type(newTarget) is Object.
    // 3. Let callerContext be the running execution context.

    // 4. Let kind be F’s [[ConstructorKind]] internal slot.
    EJSConstructorKind kind = F->constructor_kind;

    ejsval thisArgument = _ejs_undefined;
    // 5. If kind is "base", then
    if (kind == CONSTRUCTOR_KIND_BASE) {
        //    a. Let thisArgument be OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%").
        //    b. ReturnIfAbrupt(thisArgument).
    }
    // 6. Let calleeContext be PrepareForOrdinaryCall(F, newTarget).
    // 7. ReturnIfAbrupt(calleeContext).
    // 8. Assert: calleeContext is now the active execution context.
    // 9. If kind is "base", then
    if (kind == CONSTRUCTOR_KIND_BASE) {
        //    a. Let status be OrdinaryCallBindThis(F, calleeContext, thisArgument).
        //    b. If status is an abrupt completion, then
        //       i. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
        //       ii. Return status.
    }
    // 10. Let constructorEnv be the LexicalEnvironment of calleeContext.
    // 11. Let envRec be constructorEnv’s environment record.
    // 12. Let result be OrdinaryCallEvaluateBody(F, calleeContext, argumentsList).
    ejsval result = _ejs_invoke_closure(_closure, thisArgument, argc, args);
    // 13. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
    // 14. If result.[[type]] is return, then
    //     a. If Type(result.[[value]]) is Object, return NormalCompletion(result.[[value]]).
    if (EJSVAL_IS_OBJECT(result)) return result;
    //     b. If kind is "base", return NormalCompletion(thisArgument).
    if (kind == CONSTRUCTOR_KIND_BASE) return thisArgument;
    //     c. Throw a TypeError exception.
    _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "9.2.3/14.c");
    // 15. ReturnIfAbrupt(result).
    // 16. Return the result of calling the GetThisBinding concrete method of envRec’s with no arguments
    EJS_NOT_IMPLEMENTED();
}
Esempio n. 13
0
// ECMA262 25.4.4.4 Promise.reject ( r )
static ejsval
_ejs_Promise_reject (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    ejsval r = _ejs_undefined;
    if (argc > 0) r = args[0];

    // 1. Let C be the this value. 
    ejsval C = _this;

    // 2. Let promiseCapability be NewPromiseCapability(C). 
    // 3. ReturnIfAbrupt(promiseCapability). 
    ejsval promiseCapability = NewPromiseCapability(C);

    // 4. Let rejectResult be the result of calling the [[Call]] internal method of promiseCapability.[[Reject]] with undefined as thisArgument and (r) as argumentsList. 
    // 5. ReturnIfAbrupt(rejectResult). 
    _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &r);

    // 6. Return promiseCapability.[[Promise]]. 
    return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
}
Esempio n. 14
0
ejsval
_ejs_regexp_replace(ejsval str, ejsval search_re, ejsval replace)
{
    EJSRegExp* re = (EJSRegExp*)EJSVAL_TO_OBJECT(search_re);

    pcre16_extra extra;
    memset (&extra, 0, sizeof(extra));

    pcre16* code = (pcre16*)re->compiled_pattern;

    int capture_count;
    pcre16_fullinfo (code, NULL, PCRE_INFO_CAPTURECOUNT, &capture_count);

    int ovec_count = 3 * (1 + capture_count);
    int* ovec = malloc(sizeof(int) * ovec_count);
    int cur_off = 0;

    do {
        EJSPrimString *flat_str = _ejs_string_flatten (str);
        jschar *chars_str = flat_str->data.flat;

        int rv = pcre16_exec(code, &extra,
                             chars_str, flat_str->length, cur_off,
                             PCRE_NO_UTF16_CHECK, ovec, ovec_count);

        if (rv < 0)
            break;

        ejsval replaceval;

        if (EJSVAL_IS_FUNCTION(replace)) {
            ejsval substr_match = _ejs_string_new_substring (str, ovec[0], ovec[1] - ovec[0]);
            ejsval capture = _ejs_string_new_substring (str, ovec[2], ovec[3] - ovec[2]);

            _ejs_log ("substring match is %s\n", ucs2_to_utf8(_ejs_string_flatten(substr_match)->data.flat));
            _ejs_log ("capture is %s\n", ucs2_to_utf8(_ejs_string_flatten(capture)->data.flat));

            int argc = 3;
            ejsval args[3];

            args[0] = substr_match;
            args[1] = capture;
            args[2] = _ejs_undefined;

            replaceval = ToString(_ejs_invoke_closure (replace, _ejs_undefined, argc, args));
        }
        else {
            replaceval = ToString(replace);
        }

        if (ovec[0] == 0) {
            // we matched from the beginning of the string, so nothing from there to prepend
            str = _ejs_string_concat (replaceval, _ejs_string_new_substring (str, ovec[1], flat_str->length - ovec[1]));
        }
        else {
            str = _ejs_string_concatv (_ejs_string_new_substring (str, 0, ovec[0]),
                                       replaceval,
                                       _ejs_string_new_substring (str, ovec[1], flat_str->length - ovec[1]),
                                       _ejs_null);
        }

        cur_off = ovec[1];

        // if the RegExp object was created without a 'g' flag, only replace the first match
        if (!re->global)
            break;
    } while (EJS_TRUE);

    free (ovec);
    return str;
}
Esempio n. 15
0
// ES6: 23.2.1.1 Set ( [ iterable ] )
static ejsval
_ejs_Set_impl (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    // 1. Let set be the this value. 
    ejsval set = _this;

    if (EJSVAL_IS_UNDEFINED(set)) {
        EJSObject* obj = (EJSObject*)_ejs_gc_new(EJSSet);
        _ejs_init_object (obj, _ejs_Set_prototype, &_ejs_Set_specops);
        set = OBJECT_TO_EJSVAL(obj);
    }

    // 2. If Type(set) is not Object then, throw a TypeError exception. 
    if (!EJSVAL_IS_OBJECT(set))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Set constructor called with non-object this.");

    // 3. If set does not have a [[SetData]] internal slot, then throw a TypeError exception. 
    if (!EJSVAL_IS_SET(set))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Set constructor called with non-Set this.");

    EJSSet* _set = EJSVAL_TO_SET(set);

    // 4. If set’s [[SetData]] internal slot is not undefined, then throw a TypeError exception.
    if (_set->head_insert)
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Set constructor called with an already initialized Set");

    // 5. If iterable is not present, let iterable be undefined. 
    ejsval iterable = _ejs_undefined;
    if (argc > 0)
        iterable = args[0];
    ejsval iter = _ejs_undefined;
    ejsval adder = _ejs_undefined;

    // 6. If iterable is either undefined or null, then let iter be undefined.
    // 7. Else, 
    if (!EJSVAL_IS_UNDEFINED(iterable) && !EJSVAL_IS_NULL(iterable)) {
        //    a. Let iter be the result of GetIterator(iterable). 
        //    b. ReturnIfAbrupt(iter). 
        iter = GetIterator (iterable, _ejs_undefined);
        //    c. Let adder be the result of Get(set, "add").
        //    d. ReturnIfAbrupt(adder). 
        adder = Get (set, _ejs_atom_add);
        //    e. If IsCallable(adder) is false, throw a TypeError Exception.
        if (!EJSVAL_IS_CALLABLE(adder))
            _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Set.prototype.add is not a function");
    }
    // 8. If the value of sets’s [[SetData]] internal slot is not undefined, then throw a TypeError exception. 
    // 9. Assert: set has not been reentrantly initialized. 
    // 10. Set set’s [[SetData]] internal slot to a new empty List.

    // 11. If iter is undefined, then return set. 
    if (EJSVAL_IS_UNDEFINED(iter))
        return set;

    // 12. Repeat 
    for (;;) {
        //    a. Let next be the result of IteratorStep(iter).
        //    b. ReturnIfAbrupt(next).
        ejsval next = IteratorStep (iter);

        //    c. If next is false, then 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 the result of calling the [[Call]] internal method of adder with set as thisArgument
        //       and a List whose sole element is nextValue as argumentsList.
        //    g. ReturnIfAbrupt(status).
        _ejs_invoke_closure (adder, set, 1, &nextValue);
    }

    return set;
}
Esempio n. 16
0
// ECMA262 15.3.4.3
static ejsval
_ejs_Function_prototype_apply (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    ejsval func = _this;

    /* 1. If IsCallable(func) is false, then throw a TypeError exception. */
    if (!EJSVAL_IS_CALLABLE(_this)) {
        printf ("throw TypeError, func is not callable\n");
        EJS_NOT_IMPLEMENTED();
    }

    ejsval thisArg = _ejs_undefined;
    ejsval argArray = _ejs_undefined;
    if (argc > 0) thisArg = args[0];
    if (argc > 1) argArray = args[1];

    /* 2. If argArray is null or undefined, then */
    if (EJSVAL_IS_UNDEFINED(argArray) || EJSVAL_IS_NULL(argArray)) {
        /*    a. Return the result of calling the [[Call]] internal method of func, providing thisArg as the this value */
        /*       and an empty list of arguments. */
        return _ejs_invoke_closure (func, thisArg, 0, NULL);
    }
    /* 3. If Type(argArray) is not Object, then throw a TypeError exception. */
    if (!EJSVAL_IS_OBJECT(argArray)) {
        printf ("throw TypeError, argArray is not an object\n");
        EJS_NOT_IMPLEMENTED();
    }
    EJSObject* argArray_ = EJSVAL_TO_OBJECT(argArray);

    /* 4. Let len be the result of calling the [[Get]] internal method of argArray with argument "length". */
    ejsval len = OP(argArray_,Get) (argArray, _ejs_atom_length, argArray);

    /* 5. Let n be ToUint32(len). */
    uint32_t n = (uint32_t)EJSVAL_TO_NUMBER(len);

    ejsval* argList;
    EJSBool argList_allocated = EJS_FALSE;

    if (EJSVAL_IS_DENSE_ARRAY(argArray)) {
        argList = EJSDENSEARRAY_ELEMENTS(argArray_);
    }
    else {
        /* 6. Let argList be an empty List. */
        argList = (ejsval*)malloc(sizeof(ejsval) * n);
        argList_allocated = EJS_TRUE;

        /* 7. Let index be 0. */
        int index = 0;

        /* 8. Repeat while index < n */
        while (index < n) {
            /*    a. Let indexName be ToString(index). */
            ejsval indexName = NUMBER_TO_EJSVAL(index);
            /*    b. Let nextArg be the result of calling the [[Get]] internal method of argArray with indexName as the  */
            /*       argument. */
            ejsval nextArg = OP(argArray_,Get)(argArray, indexName, argArray);
            /*    c. Append nextArg as the last element of argList. */
            argList[index] = nextArg;
            /*    d. Set index to index + 1. */
            ++index;
        }
    }

    /* 9. Return the result of calling the [[Call]] internal method of func, providing thisArg as the this value and */
    /*    argList as the list of arguments. */
    ejsval rv = EJSVAL_TO_FUNC(func) (EJSVAL_TO_ENV(func), thisArg, n, argList);

    if (argList_allocated)
        free (argList);
    return rv;
}
Esempio n. 17
0
// ECMA262 25.4.4.3 Promise.race ( iterable ) 
static ejsval
_ejs_Promise_race (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    EJSBool success;

    ejsval iterable = _ejs_undefined;
    if (argc > 0) iterable = args[0];

    // 1. Let C be the this value. 
    ejsval C = _this;

    // 2. Let promiseCapability be NewPromiseCapability(C). 
    // 3. ReturnIfAbrupt(promiseCapability). 
    ejsval promiseCapability = NewPromiseCapability(C);

    // 4. Let iterator be GetIterator(iterable). 
    ejsval iterator;
    success = GetIteratorP(&iterator, iterable);
    
    // 5. IfAbruptRejectPromise(iterator, promiseCapability).
    if (!success) {
        _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &iterator);
        return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
    }

    // 6. Repeat 
    while (EJS_TRUE) {
        ejsval next;

        //    a. Let next be IteratorStep(iterator). 
        EJSBool success = IteratorStepP(&next, iterator);
        //    b. IfAbruptRejectPromise(next, promiseCapability). 
        if (!success) {
            _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &next);
            return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
        }

        //    c. If next is false, return promiseCapability.[[Promise]]. 
        if (EJSVAL_IS_BOOLEAN(next) && !EJSVAL_TO_BOOLEAN(next))
            return EJS_CAPABILITY_GET_PROMISE(promiseCapability);

        //    d. Let nextValue be IteratorValue(next). 
        ejsval nextValue;
        success = IteratorValueP(&nextValue, next);

        //    e. IfAbruptRejectPromise(nextValue, promiseCapability). 
        if (!success) {
            _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &nextValue);
            return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
        }

        //    f. Let nextPromise be Invoke(C, "resolve", (nextValue)). 
        ejsval nextPromise;
        success = _ejs_invoke_closure_catch(&nextPromise, C, _ejs_atom_resolve, 1, &nextValue);
        //    g. IfAbruptRejectPromise(nextPromise, promiseCapability). 
        if (!success) {
            _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &nextPromise);
            return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
        }

        //    h. Let result be Invoke(nextPromise, "then", (promiseCapability.[[Resolve]], promiseCapability.[[Reject]])). 
        ejsval result;
        ejsval args[] = { EJS_CAPABILITY_GET_RESOLVE(promiseCapability), EJS_CAPABILITY_GET_REJECT(promiseCapability) };
        success = _ejs_invoke_closure_catch(&result, nextPromise, _ejs_atom_then, 2, args);

        //    i. IfAbruptRejectPromise(result, promiseCapability). 
        if (!success) {
            _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &result);
            return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
        }
    }
}
Esempio n. 18
0
// ECMA262 25.4.4.1 Promise.all ( iterable )
static ejsval
_ejs_Promise_all (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    EJSBool success;

    ejsval iterable = _ejs_undefined;
    if (argc > 0) iterable = args[0];

    // 1. Let C be the this value. 
    ejsval C = _this;

    // 2. Let promiseCapability be NewPromiseCapability(C). 
    // 3. ReturnIfAbrupt(promiseCapability). 
    ejsval promiseCapability = NewPromiseCapability(C);

    // 4. Let iterator be GetIterator(iterable). 
    ejsval iterator;
    success = GetIteratorP(&iterator, iterable);

    // 5. IfAbruptRejectPromise(iterator, promiseCapability). 
    if (!success) {
        _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &iterator);
        return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
    }

    // 6. Let values be ArrayCreate(0). 
    ejsval values = _ejs_array_new(0, EJS_FALSE);

    // 7. Let remainingElementsCount be a new Record { [[value]]: 1 }. 
    int remainingElementsCount = 1;

    // 8. Let index be 0. 
    int index = 0;

    // 9. Repeat 
    while (EJS_TRUE) {
        //    a. Let next be IteratorStep(iterator). 
        ejsval next;
        success = IteratorStepP(&next, iterator);

        //    b. IfAbruptRejectPromise(next, promiseCapability). 
        if (!success) {
            _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &next);
            return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
        }
        //    c. If next is false, 
        if (EJSVAL_IS_BOOLEAN(next) && !EJSVAL_TO_BOOLEAN(next)) {
            //       i. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] - 1. 
            remainingElementsCount --;
            //       ii. If remainingElementsCount.[[value]] is 0, 
            if (remainingElementsCount == 0) {
                //           1. Let resolveResult be the result of calling the [[Call]] internal method of promiseCapability.[[Resolve]] with undefined as thisArgument and (values) as argumentsList. 
                ejsval resolveResult;
                success = _ejs_invoke_closure_catch(&resolveResult, EJS_CAPABILITY_GET_RESOLVE(promiseCapability), _ejs_undefined, 1, &values);
                //           2. ReturnIfAbrupt(resolveResult). 
                if (!success) {
                    _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &resolveResult);
                    return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
                }
            }
            //       iii. Return promiseCapability.[[Promise]]. 
            return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
        }

        //    d. Let nextValue be IteratorValue(next). 
        ejsval nextValue;
        success = IteratorValueP(&nextValue, next);
        //    e. IfAbruptRejectPromise(nextValue, promiseCapability). 
        if (!success) {
            _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &nextValue);
            return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
        }
        //    f. Let nextPromise be Invoke(C, "resolve", (nextValue)). 
        ejsval nextPromise;
        success =  _ejs_invoke_closure_catch (&nextPromise, Get(C, _ejs_atom_resolve), C, 1, &nextValue);
        
        //    g. IfAbruptRejectPromise(nextPromise, promiseCapability).
        if (!success) {
            _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &nextPromise);
            return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
        }
 
        //    h. Let resolveElement be a new built-in function object as defined in Promise.all Resolve Element Functions. 
        ejsval resolvingElement_env = _ejs_closureenv_new(6);
        ejsval resolveElement = _ejs_function_new_anon(resolvingElement_env, resolve_element);

        //    i. Set the [[AlreadyCalled]] internal slot of resolveElement to false. 
        EJS_RESOLVEELEMENT_SET_ALREADY_CALLED(resolvingElement_env, _ejs_false);
        //    j. Set the [[Index]] internal slot of resolveElement to index. 
        EJS_RESOLVEELEMENT_SET_INDEX(resolvingElement_env, NUMBER_TO_EJSVAL(index));
        //    k. Set the [[Values]] internal slot of resolveElement to values. 
        EJS_RESOLVEELEMENT_SET_VALUES(resolvingElement_env, values);
        //    l. Set the [[Capabilities]] internal slot of resolveElement to promiseCapability. 
        EJS_RESOLVEELEMENT_SET_CAPABILITIES(resolvingElement_env, promiseCapability);
        //    m. Set the [[RemainingElements]] internal slot of resolveElement to remainingElementsCount. 
        EJS_RESOLVEELEMENT_SET_REMAINING_ELEMENTS(resolvingElement_env, NUMBER_TO_EJSVAL(remainingElementsCount));
        //    n. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] + 1. 
        remainingElementsCount++;
        //    o. Let result be Invoke(nextPromise, "then", (resolveElement, promiseCapability.[[Reject]])). 
        ejsval thenargs[] = { resolveElement, EJS_CAPABILITY_GET_REJECT(promiseCapability) };
        ejsval result;
        success =  _ejs_invoke_closure_catch (&result, Get(nextPromise, _ejs_atom_then), nextPromise, 2, thenargs);
        //    p. IfAbruptRejectPromise(result, promiseCapability). 
        if (!success) {
            _ejs_invoke_closure(EJS_CAPABILITY_GET_REJECT(promiseCapability), _ejs_undefined, 1, &result);
            return EJS_CAPABILITY_GET_PROMISE(promiseCapability);
        }
        //    q. Set index to index + 1.
        index ++;
    }
}
Esempio n. 19
0
void allinone_for_load_just_ensure_these_functions_and_variables_are_included_please_do_not_call()
{
    JSValueHash(_ejs_nan);
    JSValueHash(jsPositiveInfinity);
    JSValueHash(jsNegativeInfinity);
    JSValueHash(jsMax);
    JSValueHash(jsMin);
    JSValueHash(_ejs_null);
    JSValueHash(_ejs_undefined);
    JSValueHash(_ejs_true);
    JSValueHash(_ejs_false);
    JSValueHash(_ejs_one);
    JSValueHash(_ejs_zero);
    JSValueHash(_ejs_global);
    JSValueHash(_ejs_console);
    JSValueHash(_ejs_Object);
    JSValueHash(_ejs_Boolean);
    JSValueHash(_ejs_Number);
    JSValueHash(_ejs_String);
    JSValueHash(_ejs_Array);
    JSValueHash(_ejs_Function);
    JSValueHash(_ejs_Process);
    JSValueHash(_ejs_Symbol_create);
    JSValueHash(_ejs_Math);
    JSValueHash(_ejs_JSON);

    jsextern_print_tick();
    jsextern_os_msleep(0);
    jsextern_os_swap(NULL, 0, 0);
    jsextern_pcre_compile(NULL);
    jsextern_pcre_study(NULL);
    jsextern_pcre_bracketcount(NULL);
    jsextern_pcre_exec(NULL, NULL, NULL, 0, 0, NULL, 0);
    jsextern_pcre_free(NULL);
    jsextern_thread_create((void *(*)(void *))NULL, NULL);
    jsextern_thread_destroy(0);
    jsextern_mutex_create();
    jsextern_mutex_destroy(0);
    jsextern_mutex_lock(0);
    jsextern_mutex_unlock(0);
    jsextern_signal_create();
    jsextern_signal_destroy(0);
    jsextern_signal_wait(0);
    jsextern_signal_send(0);

    JSValueHash(_ejs_undefined);
    
    _ejs_eval(_ejs_undefined, _ejs_undefined, 0, NULL);

    //Object
    _ejs_object_getprop_utf8(_ejs_undefined, NULL);
    _ejs_object_setprop_utf8(_ejs_global, NULL, _ejs_undefined);
    _ejs_object_define_value_property(_ejs_undefined, _ejs_undefined, _ejs_undefined, 0);
    _ejs_object_define_getter_property(_ejs_undefined, _ejs_undefined, _ejs_undefined, 0);
    _ejs_object_define_setter_property(_ejs_undefined, _ejs_undefined, _ejs_undefined, 0);
    _ejs_Object_create(_ejs_undefined, _ejs_undefined, 0, NULL);
    _ejs_Object_getOwnPropertyNames(_ejs_undefined, _ejs_undefined, 0, NULL);
    //vtable
    _ejs_specop_get(_ejs_undefined, _ejs_undefined, _ejs_undefined);
    _ejs_specop_set(_ejs_undefined, _ejs_undefined, _ejs_undefined, _ejs_undefined);
    //option
    ToEJSBool(_ejs_undefined);
    ToDouble(_ejs_undefined);
    ToUint32(_ejs_undefined);
    _ejs_op_typeof(_ejs_undefined);
    _ejs_op_instanceof(_ejs_undefined, _ejs_undefined);
    _ejs_op_typeof_is_array(_ejs_undefined);
    _ejs_op_plusplus(_ejs_undefined, EJS_FALSE);
    _ejs_op_minusminus(_ejs_undefined, EJS_FALSE);
    _ejs_op_bitwise_xor(_ejs_undefined, _ejs_undefined);
    _ejs_op_bitwise_and(_ejs_undefined, _ejs_undefined);
    _ejs_op_bitwise_or(_ejs_undefined, _ejs_undefined);
    _ejs_op_rsh(_ejs_undefined, _ejs_undefined);
    _ejs_op_ursh(_ejs_undefined, _ejs_undefined);
    _ejs_op_lsh(_ejs_undefined, _ejs_undefined);
    _ejs_op_ulsh(_ejs_undefined, _ejs_undefined);
    _ejs_op_mod(_ejs_undefined, _ejs_undefined);
    _ejs_op_add(_ejs_undefined, _ejs_undefined);
    _ejs_op_sub(_ejs_undefined, _ejs_undefined);
    _ejs_op_mult(_ejs_undefined, _ejs_undefined);
    _ejs_op_div(_ejs_undefined, _ejs_undefined);
    _ejs_op_lt(_ejs_undefined, _ejs_undefined);
    _ejs_op_le(_ejs_undefined, _ejs_undefined);
    _ejs_op_gt(_ejs_undefined, _ejs_undefined);
    _ejs_op_ge(_ejs_undefined, _ejs_undefined);
    _ejs_op_strict_eq(_ejs_undefined, _ejs_undefined);
    _ejs_op_strict_neq(_ejs_undefined, _ejs_undefined);
    _ejs_op_eq(_ejs_undefined, _ejs_undefined);
    _ejs_op_neq(_ejs_undefined, _ejs_undefined);
    //arguments
    _ejs_arguments_new(0, NULL);

    //Array
    _ejs_array_new(jsValue32Size, false);
    //String
    _ejs_string_new_utf8_len(NULL, 0);
    //Function
    _ejs_function_new_utf8(_ejs_undefined, NULL, (EJSClosureFunc)NULL);
    _ejs_invoke_closure(_ejs_undefined, _ejs_undefined, 0, NULL);
    //RegExp
    _ejs_regexp_new_utf8(NULL, NULL);
}