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 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. 3
0
// ES6: 23.2.3.9
// get Set.prototype.size
static ejsval
_ejs_Set_prototype_get_size (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    // 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 size getter 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 size getter called with non-Set this.");
    }

    EJSSet* _set = EJSVAL_TO_SET(S);

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

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

    // 6. Let count be 0.
    uint32_t count = 0;
    // 7. For each e that is an element of entries
    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))
            //      i. Set count to count+1.
            count ++;
    }
    // 8. Return count.
    return NUMBER_TO_EJSVAL(count);
}
Esempio n. 4
0
// ES6: 23.1.3.1
// Map.prototype.clear ()
ejsval
_ejs_Set_prototype_clear (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    // 1. Let S be 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.clear 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.clear called with non-Set this.");

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

    // 5. Let entries be the List that is the value of S’s [[SetData]] internal slot. 
    EJSSetValueEntry* entries = EJSVAL_TO_SET(S)->head_insert;
    // 6. Repeat for each e that is an element of entries, 
    for (EJSSetValueEntry* e = entries; e; e = e->next_insert) {
        //    a. Replace the element of entries whose value is e with an element whose value is empty. 
        e->value = MAGIC_TO_EJSVAL_IMPL(EJS_NO_ITER_VALUE);
    }
    // 7. Return undefined. 
    return _ejs_undefined;
}
Esempio n. 5
0
// ES6: 23.2.3.7
// Set.prototype.has ( value )
ejsval
_ejs_Set_prototype_has (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    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, "Set.prototype.has 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.has called with non-Set this.");

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

    EJSSet* _set = EJSVAL_TO_SET(S);

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

    // 6. Repeat for each e that is an element of entries, 
    for (EJSSetValueEntry* e = entries; e; e = e->next_insert) {
        // a. If e is not empty and SameValueZero(e, value) is true, then return true.
        if (SameValueZero (e->value, value))
            return _ejs_true;
    }
    // 7. Return false. 
    return _ejs_false;
}
Esempio n. 6
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. 7
0
// ECMA262 25.4.1.6.2 GetCapabilitiesExecutor Functions 
static ejsval
capabilitiesExecutor(ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    ejsval resolve = _ejs_undefined;
    if (argc > 0) resolve = args[0];
    ejsval reject = _ejs_undefined;
    if (argc > 1) reject = args[1];

    // 1. Assert: F has a [[Capability]] internal slot whose value is a PromiseCapability Record. 
    // 2. Let promiseCapability be the value of F's [[Capability]] internal slot. 
    ejsval promiseCapability = env;

    // 3. If promiseCapability.[[Resolve]] is not undefined, then throw a TypeError exception. 
    if (!EJSVAL_IS_UNDEFINED(EJS_CAPABILITY_GET_RESOLVE(promiseCapability)))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, ""); // XXX

    // 4. If promiseCapability.[[Reject]] is not undefined, then throw a TypeError exception. 
    if (!EJSVAL_IS_UNDEFINED(EJS_CAPABILITY_GET_REJECT(promiseCapability)))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, ""); // XXX

    // 5. Set promiseCapability.[[Resolve]] to resolve.
    EJS_CAPABILITY_SET_RESOLVE(promiseCapability, resolve);

    // 6. Set promiseCapability.[[Reject]] to reject. 
    EJS_CAPABILITY_SET_REJECT(promiseCapability, reject);

    // 7. Return undefined.
    return _ejs_undefined;
}
Esempio n. 8
0
ejsval
_ejs_set_iterator_new (ejsval set, EJSSetIteratorKind kind)
{
    /* 1. If Type(set) is not Object, throw a TypeError exception. */
    if (!EJSVAL_IS_OBJECT(set))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "set is not a Object");

    /* 2. If set does not have a [[SetData]] internal slot throw a TypeError exception. */
    if (!EJSVAL_IS_SET(set))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "value is not a Set");

    /* 3. If set’s [[SetData]] internal slot is undefined, then throw a TypeError exception. */

    /* 4. Let iterator be the result of ObjectCreate(%SetIteratorPrototype%,
     * ([[IteratedSet]], [[SetNextIndex]], [[SetIterationKind]])). */
    EJSSetIterator *iter = _ejs_gc_new (EJSSetIterator);
    _ejs_init_object ((EJSObject*) iter, _ejs_SetIterator_prototype, &_ejs_SetIterator_specops);

    /* 5. Set iterator’s [[IteratedSet]] internal slot to set. */
    iter->iterated = set;

    /* 6. Set iterator’s [[SetNextIndex]] internal slot to 0. */
    iter->next_index = 0;

    /* 7. Set iterator’s [[SetIterationKind]] internal slot to kind. */
    iter->kind = kind;

    /* 8. Return iterator */
    return OBJECT_TO_EJSVAL(iter);
}
Esempio n. 9
0
static EJS_NATIVE_FUNC(_ejs_Generator_prototype_next) {
    ejsval O = *_this;
    if (!EJSVAL_IS_OBJECT(O))
        _ejs_throw_nativeerror_utf8(EJS_TYPE_ERROR, ".next called on non-object");

    if (!EJSVAL_IS_GENERATOR(O))
        _ejs_throw_nativeerror_utf8(EJS_TYPE_ERROR, ".next called on non-generator");

    return _ejs_generator_send(O, argc > 0 ? args[0] : _ejs_undefined);
}
Esempio n. 10
0
static ejsval
_ejs_fs_readFileSync (ejsval env, ejsval _this, uint32_t argc, ejsval* args)
{
    // FIXME we currently ignore the encoding and just slam the entire thing into a buffer and return a utf8 string...
    char* utf8_path = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(args[0]));

    int fd = open (utf8_path, O_RDONLY);
    if (fd == -1) {
        char buf[256];
        snprintf (buf, sizeof(buf), "%s: `%s`", strerror(errno), utf8_path);
        free(utf8_path);
        _ejs_throw_nativeerror_utf8 (EJS_ERROR, buf);
    }

    struct stat fd_stat;

    int stat_rv = fstat (fd, &fd_stat);
    if (stat_rv == -1) {
        char buf[256];
        snprintf (buf, sizeof(buf), "%s: `%s`", strerror(errno), utf8_path);
        free(utf8_path);
        close(fd);
        _ejs_throw_nativeerror_utf8 (EJS_ERROR, buf);
    }

    int amount_to_read = fd_stat.st_size;
    int amount_read = 0;
    char *buf = (char*)calloc (1, amount_to_read+1);
    do {
        int c = read(fd, buf + amount_read, amount_to_read);
        if (c == -1) {
            if (errno == EINTR)
                continue;
            else {
                char msg[256];
                snprintf (msg, sizeof(msg), "%s: `%s`", strerror(errno), utf8_path);
                free(utf8_path);
                close(fd);
                free (buf);
                _ejs_throw_nativeerror_utf8 (EJS_ERROR, msg);
            }
        }
        else {
            amount_to_read -= c;
            amount_read += c;
        }
    } while (amount_to_read > 0);

    free(utf8_path);

    ejsval rv = _ejs_string_new_utf8_len(buf, amount_read);
    free(buf);
    return rv;
}
Esempio n. 11
0
// ES6: 23.2.3.1 Set.prototype.add ( value )
ejsval
_ejs_Set_prototype_add (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    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, "Set.prototype.add 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.set called with non-Set this.");

    // 4. If S’s [[SetData]] internal slot is undefined, then throw a TypeError exception. 
    EJSSet* _set = EJSVAL_TO_SET(S);

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

    EJSSetValueEntry* e;
    // 6. Repeat for each e that is an element of entries, 
    for (e = entries; e; e = e->next_insert) {
        //    a. If e is not empty and SameValueZero(e, value) is true, then 
        if (SameValueZero(e->value, value))
        //       i. Return S. 
            return S;
    }
    // 7. If value is −0, then let value be +0. 
    if (EJSVAL_IS_NUMBER(value) && EJSDOUBLE_IS_NEGZERO(EJSVAL_TO_NUMBER(value)))
        value = NUMBER_TO_EJSVAL(0);
    // 8. Append value as the last element of entries. 
    e = calloc (1, sizeof (EJSSetValueEntry));
    e->value = value;

    if (!_set->head_insert)
        _set->head_insert = e;

    if (_set->tail_insert) {
        _set->tail_insert->next_insert = e;
        _set->tail_insert = e;
    }
    else {
        _set->tail_insert = e;
    }

    // 9. Return S.
    return S;
}
Esempio n. 12
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. 13
0
static ejsval
_ejs_Generator_prototype_throw (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    ejsval O = _this;
    if (!EJSVAL_IS_OBJECT(O))
        _ejs_throw_nativeerror_utf8(EJS_TYPE_ERROR, ".throw called on non-object");

    if (!EJSVAL_IS_GENERATOR(O))
        _ejs_throw_nativeerror_utf8(EJS_TYPE_ERROR, ".throw called on non-generator");

    return _ejs_generator_throw(O, argc > 0 ? args[0] : _ejs_undefined);
}
Esempio n. 14
0
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);
}
Esempio n. 15
0
// ECMA262 25.4.4.6 Promise [ @@create ] ( )
static ejsval
_ejs_Promise_create (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    // 1. Let F be the this value
    ejsval F = _this;

    // 2. Return AllocatePromise(F). 
    //    1. Let obj be OrdinaryCreateFromConstructor(constructor, "%PromisePrototype%", ([[PromiseState]], [[PromiseConstructor]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]]) ). 
    ejsval proto = _ejs_undefined;
    if (!EJSVAL_IS_UNDEFINED(F)) {
        if (!EJSVAL_IS_CONSTRUCTOR(F))
            _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "'this' in Promise[Symbol.create] is not a constructor");

        EJSObject* F_ = EJSVAL_TO_OBJECT(F);

        proto = OP(F_,Get)(F, _ejs_atom_prototype, F);
    }
    if (EJSVAL_IS_UNDEFINED(proto))
        proto = _ejs_Promise_prototype;

    EJSObject* obj = (EJSObject*)_ejs_gc_new (EJSPromise);
    _ejs_init_object (obj, proto, &_ejs_Promise_specops);

    //    2. Set the value of obj’s [[PromiseConstructor]] internal slot to constructor. 
    ((EJSPromise*)obj)->constructor = F;

    //    3. Return obj. 
    return OBJECT_TO_EJSVAL(obj);
}
Esempio n. 16
0
// ECMA262: 19.4.1
static EJS_NATIVE_FUNC(_ejs_Symbol_impl) {
    if (!EJSVAL_IS_UNDEFINED(newTarget)) {
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Symbol cannot be called as a constructor");
    }

    ejsval description = _ejs_undefined;
    if (argc > 0) description = args[0];
    return _ejs_symbol_new(description);
}
Esempio n. 17
0
// ES2015, June 2015
// 19.4.3.3 Symbol.prototype.valueOf ( )
static EJS_NATIVE_FUNC(_ejs_Symbol_prototype_valueOf) {
    // 1. Let s be the this value.
    ejsval s = *_this;

    // 2. If Type(s) is Symbol, return s.
    if (EJSVAL_IS_SYMBOL(s))
        return s;

    // 3. If Type(s) is not Object, throw a TypeError exception.
    if (!EJSVAL_IS_OBJECT(s))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Symbol.prototype.valueOf called with non-object this");
        
    // 4. If s does not have a [[SymbolData]] internal slot, throw a TypeError exception.
    if (!EJSVAL_IS_SYMBOL_OBJECT(s))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Symbol.prototype.valueOf called with non-symbol this");

    // 5. Return the value of s’s [[SymbolData]] internal slot.
    return EJSVAL_TO_SYMBOL_OBJECT(s)->primSymbol;
}
Esempio n. 18
0
// 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
}
Esempio n. 19
0
// 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
}
Esempio n. 20
0
// 23.2.3.4 Set.prototype.delete ( value ) 
ejsval
_ejs_Set_prototype_delete (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    // NOTE The value empty is used as a specification device to
    // indicate that an entry has been deleted. Actual implementations
    // may take other actions such as physically removing the entry
    // from internal data structures.

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

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

    // 5. Let entries be the List that is the value of S’s [[SetData]] internal slot. 
    EJSSetValueEntry* entries = EJSVAL_TO_SET(S)->head_insert;
    // 6. Repeat for each e that is an element of entries, 
    for (EJSSetValueEntry* e = entries; e; e = e->next_insert) {
        //    a. If e is not empty and SameValueZero(e, value) is true, then 
        if (SameValueZero(e->value, value)) {
            // i. Replace the element of entries whose value is e with an element whose value is empty. 
            e->value = MAGIC_TO_EJSVAL_IMPL(EJS_NO_ITER_VALUE);
            // ii. Return true. 
            return _ejs_true;
        }
    }
    // 7. Return false. 
    return _ejs_false;
}
Esempio n. 21
0
static ejsval
_ejs_RegExp_impl (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    EJSRegExp *re;

    if (EJSVAL_IS_UNDEFINED(_this)) {
        // called as a function
        _this = _ejs_object_new(_ejs_RegExp_prototype, &_ejs_RegExp_specops);
    }

    re = (EJSRegExp*)EJSVAL_TO_OBJECT(_this);

    re->pattern = _ejs_undefined;
    re->flags = _ejs_undefined;

    if (argc > 0) re->pattern = args[0];
    if (argc > 1) re->flags = args[1];

    if (!EJSVAL_IS_STRING(re->pattern))
        EJS_NOT_IMPLEMENTED();

    EJSPrimString *flat_pattern = _ejs_string_flatten (re->pattern);
    jschar* chars = flat_pattern->data.flat;

    const unsigned char* pcre16_tables = pcre16_maketables();
    const char *pcre_error;
    int pcre_erroffset;

    re->compiled_pattern = pcre16_compile(chars,
                                          PCRE_UTF16 | PCRE_NO_UTF16_CHECK,
                                          &pcre_error, &pcre_erroffset,
                                          pcre16_tables);

    _ejs_object_define_value_property (_this, _ejs_atom_source, re->pattern, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE | EJS_PROP_NOT_WRITABLE);

    if (EJSVAL_IS_STRING(re->flags)) {
        EJSPrimString *flat_flags = _ejs_string_flatten(re->flags);
        chars = flat_flags->data.flat;

        for (int i = 0; i < flat_flags->length; i ++) {
            if      (chars[i] == 'g' && !re->global)     { re->global     = EJS_TRUE; continue; }
            else if (chars[i] == 'i' && !re->ignoreCase) { re->ignoreCase = EJS_TRUE; continue; }
            else if (chars[i] == 'm' && !re->multiline)  { re->multiline  = EJS_TRUE; continue; }
            else if (chars[i] == 'y' && !re->sticky)     { re->sticky     = EJS_TRUE; continue; }
            else if (chars[i] == 'u' && !re->unicode)    { re->unicode    = EJS_TRUE; continue; }
            _ejs_throw_nativeerror_utf8 (EJS_SYNTAX_ERROR, "Invalid flag supplied to RegExp constructor");
        }
    }

    return _this;
}
Esempio n. 22
0
static EJS_NATIVE_FUNC(_ejs_Process_chdir) {
    ejsval dir = _ejs_undefined;
    if (argc > 0)
        dir = args[0];

    if (!EJSVAL_IS_STRING(dir))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "chdir passed non-string");
        
    char *dir_utf8 = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(dir));
    chdir(dir_utf8);
    free(dir_utf8);

    return _ejs_undefined;
}
Esempio n. 23
0
    static ejsval
    Module_create (ejsval env, ejsval _this, int argc, ejsval *args)
    {
        ejsval F = _this;
        if (!EJSVAL_IS_CONSTRUCTOR(F)) 
            _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "'this' in Module[Symbol.create] is not a constructor");
        EJSObject* F_ = EJSVAL_TO_OBJECT(F);
        // 2. Let obj be the result of calling OrdinaryCreateFromConstructor(F, "%DatePrototype%", ([[DateData]]) ). 
        ejsval proto = OP(F_,Get)(F, _ejs_atom_prototype, F);
        if (EJSVAL_IS_UNDEFINED(proto))
            proto = _ejs_Module_prototype;

        EJSObject* obj = (EJSObject*)_ejs_gc_new (Module);
        _ejs_init_object (obj, proto, &_ejs_Module_specops);
        return OBJECT_TO_EJSVAL(obj);
    }
Esempio n. 24
0
static ejsval
_ejs_Process_chdir (ejsval env, ejsval _this, uint32_t argc, ejsval* args)
{
    ejsval dir = _ejs_undefined;
    if (argc > 0)
        dir = args[0];

    if (!EJSVAL_IS_STRING(dir))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "chdir passed non-string");
        
    char *dir_utf8 = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(dir));
    chdir(dir_utf8);
    free(dir_utf8);

    return _ejs_undefined;
}
Esempio n. 25
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. 26
0
// ECMA262: 19.4.2.7 Symbol.keyFor ( sym ) 
static EJS_NATIVE_FUNC(_ejs_Symbol_keyFor) {
    ejsval sym = _ejs_undefined;
    if (argc > 0) sym = args[0];

    // 1. If Type(sym) is not Symbol, then throw a TypeError exception. 
    if (!EJSVAL_IS_SYMBOL(sym))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Symbol.keyFor called with non-symbol argument");
        
    // 2. For each element e of the GlobalSymbolRegistry List (see 19.4.2.2), 
    //    a. If SameValue(e.[[symbol]], sym) is true, then return e.[[key]]. 
    // 3. Assert: GlobalSymbolRegistry does not current contain an entry for sym. 

    // XXX

    // 4. Return undefined. 
    return _ejs_undefined;
}
Esempio n. 27
0
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);
}
Esempio n. 28
0
// ECMA262 15.3.4.2
static ejsval
_ejs_Function_prototype_toString (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    char terrible_fixed_buffer[256];

    if (!EJSVAL_IS_FUNCTION(_this))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Function.prototype.toString is not generic.");

    ejsval func_name = _ejs_object_getprop (_this, _ejs_atom_name);

    char *utf8_funcname = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(func_name));
    
    snprintf (terrible_fixed_buffer, sizeof (terrible_fixed_buffer), "function %s() {}", utf8_funcname);

    free (utf8_funcname);

    return _ejs_string_new_utf8(terrible_fixed_buffer);
}
Esempio n. 29
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. 30
0
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);
}