Example #1
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);
}
Example #2
0
ejsval
_ejs_typedarray_new_from_array (EJSTypedArrayType element_type, ejsval arrayObj)
{
    EJSObject *arr = EJSVAL_TO_OBJECT(arrayObj);
    int arrlen = EJSARRAY_LEN(arr);
    ejsval typedarr = _ejs_typedarray_new (element_type, arrlen);
    int i;

    void* data = _ejs_typedarray_get_data (EJSVAL_TO_OBJECT(typedarr));

    // this is woefully underoptimized...

    for (i = 0; i < arrlen; i ++) {
        ejsval item = _ejs_object_getprop (arrayObj, NUMBER_TO_EJSVAL(i));
        switch (element_type) {
        case EJS_TYPEDARRAY_INT8: ((int8_t*)data)[i] = (int8_t)EJSVAL_TO_NUMBER(item); break;
        case EJS_TYPEDARRAY_UINT8: ((uint8_t*)data)[i] = (uint8_t)EJSVAL_TO_NUMBER(item); break;
        case EJS_TYPEDARRAY_UINT8CLAMPED: EJS_NOT_IMPLEMENTED();
        case EJS_TYPEDARRAY_INT16: ((int16_t*)data)[i] = (int16_t)EJSVAL_TO_NUMBER(item); break;
        case EJS_TYPEDARRAY_UINT16: ((uint16_t*)data)[i] = (uint16_t)EJSVAL_TO_NUMBER(item); break;
        case EJS_TYPEDARRAY_INT32: ((int32_t*)data)[i] = (int32_t)EJSVAL_TO_NUMBER(item); break;
        case EJS_TYPEDARRAY_UINT32: ((uint32_t*)data)[i] = (uint32_t)EJSVAL_TO_NUMBER(item); break;
        case EJS_TYPEDARRAY_FLOAT32: ((float*)data)[i] = (float)EJSVAL_TO_NUMBER(item); break;
        case EJS_TYPEDARRAY_FLOAT64: ((double*)data)[i] = (double)EJSVAL_TO_NUMBER(item); break;
        default: EJS_NOT_REACHED();
        }
    }

    return typedarr;
}
Example #3
0
static ejsval
_ejs_arguments_specop_get (ejsval obj, ejsval propertyName, ejsval receiver)
{
    EJSArguments* arguments = EJSVAL_TO_ARGUMENTS(obj);

    // check if propertyName is an integer, or a string that we can convert to an int
    EJSBool is_index = EJS_FALSE;
    ejsval idx_val = ToNumber(propertyName);
    int idx;
    if (EJSVAL_IS_NUMBER(idx_val)) {
        double n = EJSVAL_TO_NUMBER(idx_val);
        if (floor(n) == n) {
            idx = (int)n;
            is_index = EJS_TRUE;
        }
    }

    if (is_index) {
        if (idx < 0 || idx > arguments->argc) {
            printf ("getprop(%d) on an arguments, returning undefined\n", idx);
            return _ejs_undefined;
        }
        return arguments->args[idx];
    }

    // we also handle the length getter here
    if (EJSVAL_IS_STRING(propertyName) && !ucs2_strcmp (_ejs_ucs2_length, EJSVAL_TO_FLAT_STRING(propertyName))) {
        return NUMBER_TO_EJSVAL(arguments->argc);
    }

    // otherwise we fallback to the object implementation
    return _ejs_Object_specops.Get (obj, propertyName, receiver);
}
Example #4
0
void
_ejs_function_init(ejsval global)
{
    trace = getenv("EJS_TRACE") != NULL;

    _ejs_function_init_proto();

    _ejs_Function = _ejs_function_new_without_proto (_ejs_null, _ejs_atom_Function, (EJSClosureFunc)_ejs_Function_impl);
    _ejs_object_setprop (global, _ejs_atom_Function, _ejs_Function);

    // ECMA262 15.3.3.1
    _ejs_object_define_value_property (_ejs_Function, _ejs_atom_prototype, _ejs_Function_prototype, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE | EJS_PROP_NOT_WRITABLE);
    // ECMA262 15.3.3.2
    _ejs_object_define_value_property (_ejs_Function, _ejs_atom_length, NUMBER_TO_EJSVAL(1), EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE | EJS_PROP_NOT_WRITABLE);

#define PROTO_METHOD(x) EJS_INSTALL_ATOM_FUNCTION_FLAGS(_ejs_Function_prototype, x, _ejs_Function_prototype_##x, EJS_PROP_NOT_ENUMERABLE)

    PROTO_METHOD(toString);
    PROTO_METHOD(apply);
    PROTO_METHOD(call);
    PROTO_METHOD(bind);

#undef PROTO_METHOD

}
Example #5
0
static ejsval
_ejs_dataview_specop_get (ejsval obj, ejsval propertyName, ejsval receiver)
{
    // check if propertyName is an integer, or a string that we can convert to an int
    EJSBool is_index = EJS_FALSE;
    int idx = 0;
    if (EJSVAL_IS_NUMBER(propertyName)) {
        double n = EJSVAL_TO_NUMBER(propertyName);
        if (floor(n) == n) {
            idx = (int)n;
            is_index = EJS_TRUE;
        }
    }

    // Index for DataView is byte-based.
    if (is_index) {
        if (idx < 0 || idx > EJS_DATA_VIEW_BYTE_LEN(obj))
            return _ejs_undefined;

         void *data = _ejs_dataview_get_data (EJSVAL_TO_OBJECT(obj));
         return NUMBER_TO_EJSVAL ((double)((unsigned char*)data)[idx]);
    }

    // otherwise we fallback to the object implementation
    return _ejs_Object_specops.get (obj, propertyName, receiver);
}
Example #6
0
static ejsval
_ejs_arraybuffer_specop_get (ejsval obj, ejsval propertyName, ejsval receiver)
{
    // check if propertyName is an integer, or a string that we can convert to an int
    EJSBool is_index = EJS_FALSE;
    int idx = 0;
    if (EJSVAL_IS_NUMBER(propertyName)) {
        double n = EJSVAL_TO_NUMBER(propertyName);
        if (floor(n) == n) {
            idx = (int)n;
            is_index = EJS_TRUE;
        }
    }

    if (is_index) {
        if (idx < 0 || idx > EJS_ARRAY_LEN(obj)) {
            printf ("getprop(%d) on an array, returning undefined\n", idx);
            return _ejs_undefined;
        }
        return EJS_DENSE_ARRAY_ELEMENTS(obj)[idx];
    }

    // we also handle the length getter here
    if (EJSVAL_IS_STRING(propertyName) && !ucs2_strcmp (_ejs_ucs2_byteLength, EJSVAL_TO_FLAT_STRING(propertyName))) {
        return NUMBER_TO_EJSVAL (EJS_ARRAY_BUFFER_BYTE_LEN(obj));
    }

    // otherwise we fallback to the object implementation
    return _ejs_Object_specops.get (obj, propertyName, receiver);
}
Example #7
0
ejsval
_ejs_op_bitwise_or (ejsval lhs, ejsval rhs)
{
    int lhs_int = ToInteger(lhs);
    int rhs_int = ToInteger(rhs);
    return NUMBER_TO_EJSVAL (lhs_int | rhs_int);
}
Example #8
0
void
_ejs_process_init(ejsval global, uint32_t argc, char **argv)
{
    _ejs_Process = _ejs_object_new (_ejs_null, &_ejs_Object_specops);
    _ejs_object_setprop (global, _ejs_atom_process, _ejs_Process);

    ejsval _argv = _ejs_array_new (argc, EJS_FALSE);
    _ejs_object_setprop (_ejs_Process, _ejs_atom_argv, _argv);

    for (int i = 0; i < argc; i ++)
        _ejs_object_setprop (_argv, NUMBER_TO_EJSVAL(i), _ejs_string_new_utf8(argv[i]));

#define OBJ_PROP(x) EJS_INSTALL_ATOM_GETTER(_ejs_Process, x, _ejs_Process_get_##x)
#define OBJ_METHOD(x) EJS_INSTALL_ATOM_FUNCTION(_ejs_Process, x, _ejs_Process_##x)

    OBJ_PROP(env);

    OBJ_METHOD(exit);

    OBJ_METHOD(chdir);
    OBJ_METHOD(cwd);

#undef OBJ_PROP
#undef OBJ_METHOD
}
Example #9
0
static EJSBool
json_value_to_ejsval(JSON_Value *v, ejsval *rv)
{
    switch (json_value_get_type (v)) {
    case JSONNull:
        *rv = _ejs_null;
        return EJS_TRUE;

    case JSONString:
        *rv = _ejs_string_new_utf8 (json_value_get_string(v));
        return EJS_TRUE;

    case JSONNumber:
        *rv = NUMBER_TO_EJSVAL(json_value_get_number(v));
        return EJS_TRUE;

    case JSONObject: {
        JSON_Object *obj = json_value_get_object (v);
        *rv = _ejs_object_create (_ejs_null);

        int count = json_object_get_count (obj);
        for (int i = 0; i < count; i ++) {
            const char *propkey = json_object_get_name (obj, i);
            ejsval propval;
            if (!json_value_to_ejsval (json_object_get_value (obj, propkey), &propval))
                return EJS_FALSE;
            _ejs_object_setprop_utf8 (*rv, propkey, propval);
        }

        return EJS_TRUE;
    }
        
    case JSONArray: {
        JSON_Array *arr = json_value_get_array (v);
        int count = json_array_get_count (arr);

        *rv = _ejs_array_new (count, EJS_FALSE);

        for (int i = 0; i < count; i ++) {
            ejsval propkey = _ejs_number_new (i);
            ejsval propval;
            if (!json_value_to_ejsval (json_array_get_value (arr, i), &propval))
                return EJS_FALSE;
            _ejs_object_setprop (*rv, propkey, propval);
        }

        return EJS_TRUE;
    }
    case JSONBoolean:
        *rv = BOOLEAN_TO_EJSVAL(json_value_get_boolean(v));
        return EJS_TRUE;


    case JSONError:
        EJS_NOT_IMPLEMENTED();
        return EJS_FALSE;
    }
}
Example #10
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;
}
Example #11
0
static ejsval
_ejs_wrapFdWithStream (int fd)
{
    ejsval stream = _ejs_object_create(_ejs_null);

    EJS_INSTALL_FUNCTION (stream, "write", _ejs_stream_write);
    EJS_INSTALL_FUNCTION (stream, "end", _ejs_stream_end);

    _ejs_object_setprop_utf8 (stream, "%internal_fd", NUMBER_TO_EJSVAL(fd));

    return stream;
}
Example #12
0
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();
}
Example #13
0
// 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;
}
Example #14
0
ejsval
_ejs_fs_createWriteStream (ejsval env, ejsval _this, uint32_t argc, ejsval* args)
{
    ejsval stream = _ejs_object_create(_ejs_null);

    EJS_INSTALL_FUNCTION (stream, "write", _ejs_stream_write);
    EJS_INSTALL_FUNCTION (stream, "end", _ejs_stream_end);

    char *utf8_path = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(args[0]));

    int fd = open (utf8_path, O_CREAT | O_TRUNC | O_WRONLY, 0777);
    free (utf8_path);
    if (fd == -1) {
        perror ("open");
        printf ("we should totally throw an exception here\n");
        return _ejs_undefined;
    }

    _ejs_object_setprop_utf8 (stream, "%internal_fd", NUMBER_TO_EJSVAL(fd));

    return stream;
}
Example #15
0
ejsval
_ejs_op_mod (ejsval lhs, ejsval rhs)
{
    if (EJSVAL_IS_NUMBER(lhs)) {
        if (EJSVAL_IS_NUMBER(rhs)) {
            return NUMBER_TO_EJSVAL (fmod(EJSVAL_TO_NUMBER(lhs), EJSVAL_TO_NUMBER(rhs)));
        }
        else {
            // need to call valueOf() on the object, or convert the string to a number
            EJS_NOT_IMPLEMENTED();
        }
    }
    else if (EJSVAL_IS_STRING(lhs)) {
        // string+ with anything we don't implement yet - it will call toString() on objects, and convert a number to a string
        EJS_NOT_IMPLEMENTED();
    }
    else {
        // object+... how does js implement this anyway?
        EJS_NOT_IMPLEMENTED();
    }

    return _ejs_nan;
}
Example #16
0
static ejsval
_ejs_RegExp_prototype_get_lastIndex (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    EJSRegExp* re = (EJSRegExp*)EJSVAL_TO_OBJECT(_this);
    return NUMBER_TO_EJSVAL(re->lastIndex);
}
Example #17
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;
}
Example #18
0
// 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;
}
Example #19
0
void
_ejs_init(int argc, char** argv)
{
    // process class inheritance
    _ejs_init_classes();

    // initialize our atoms before anything else
    _ejs_init_static_strings();

    _ejs_gc_init();
    _ejs_exception_init();

    // initialization or ECMA262 builtins
    _ejs_gc_add_root (&_ejs_global);
    _ejs_global = _ejs_object_new (_ejs_null, &_ejs_Object_specops);

    _ejs_nan = NUMBER_TO_EJSVAL(nan("7734"));

    _ejs_object_setprop (_ejs_global, _ejs_atom_undefined, _ejs_undefined);
    _ejs_object_setprop (_ejs_global, _ejs_atom_NaN, _ejs_nan);
    _ejs_object_setprop (_ejs_global, _ejs_atom_Infinity, _ejs_Infinity);
    _ejs_object_setprop (_ejs_global, _ejs_atom_eval, _ejs_function_new_native (_ejs_undefined, _ejs_atom_eval, _ejs_eval));


    _ejs_object_init_proto();

    _ejs_function_init(_ejs_global);

    _ejs_object_init(_ejs_global);

    _ejs_symbol_init(_ejs_global);

    _ejs_error_init(_ejs_global);
    _ejs_arguments_init(_ejs_global);
    _ejs_array_init(_ejs_global);
    _ejs_boolean_init (_ejs_global);
    _ejs_string_init(_ejs_global);
    _ejs_number_init(_ejs_global);
    _ejs_regexp_init(_ejs_global);
    _ejs_date_init(_ejs_global);
    _ejs_json_init(_ejs_global);
    _ejs_math_init(_ejs_global);

    // ES6 bits
    _ejs_proxy_init(_ejs_global);
    _ejs_map_init(_ejs_global);
    _ejs_set_init(_ejs_global);

    _ejs_typedarrays_init(_ejs_global);
#if IOS
    _ejs_webgl_init(_ejs_global);
#endif

#define GLOBAL_METHOD(x) EJS_MACRO_START                                \
    _ejs_##x = _ejs_function_new_native (_ejs_null, _ejs_atom_##x, (EJSClosureFunc)_ejs_##x##_impl); \
    _ejs_object_setprop (_ejs_global, _ejs_atom_##x, _ejs_##x);         \
    EJS_MACRO_END

    GLOBAL_METHOD(isNaN);
    GLOBAL_METHOD(isFinite);
    GLOBAL_METHOD(parseInt);
    GLOBAL_METHOD(parseFloat);

    GLOBAL_METHOD(decodeURI);
    GLOBAL_METHOD(decodeURIComponent);
    GLOBAL_METHOD(encodeURI);
    GLOBAL_METHOD(encodeURIComponent);

#undef GLOBAL_METHOD

    // the node-like api we support in order for our driver to
    // function.  this should really be a separate opt-in .a/.so.
    _ejs_require_init(_ejs_global);
    _ejs_console_init(_ejs_global);
    _ejs_process_init(_ejs_global, argc, argv);

    _ejs_xmlhttprequest_init(_ejs_global);

    // a special global (__ejs) under which we can stuff other
    // semi-useful runtime features, like a call to force a GC.  the
    // compiler also uses the presence of __ejs to disable
    // buggy/nonfunctional code (like those that use regexps)
    ejsval _ejs_ejs_global = _ejs_object_new (_ejs_null, &_ejs_Object_specops);
    _ejs_object_setprop (_ejs_global, _ejs_atom___ejs, _ejs_ejs_global);

    _ejs_GC_init(_ejs_ejs_global);
    _ejs_gc_allocate_oom_exceptions();
}
Example #20
0
 ejsval
 Function_prototype_get_argSize(ejsval env, ejsval _this, int argc, ejsval *args)
 {
     Function* fun = ((Function*)EJSVAL_TO_OBJECT(_this));
     return NUMBER_TO_EJSVAL (fun->llvm_fun->arg_size());
 }
Example #21
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 ++;
    }
}
Example #22
0
ejsval
_ejs_op_neg (ejsval exp)
{
    return NUMBER_TO_EJSVAL (-ToDouble(exp));
}
Example #23
0
static ejsval
_ejs_SetIterator_prototype_next (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    /* 1. Let O be the this value. */
    ejsval O = _this;

    /* 2. If Type(O) is not Object, throw a TypeError exception. */
    if (!EJSVAL_IS_OBJECT(O))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, ".next called on non-object");

    /* 3. If O does not have all of the internal slots of a Set Iterator Instance (23.2.5.3),
     * throw a TypeError exception. */
    if (!EJSVAL_IS_SETITERATOR(O))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, ".next called on non-SetIterator instance");

    EJSSetIterator *OObj = (EJSSetIterator*)EJSVAL_TO_OBJECT(O);

    /* 4. Let s be the value of the [[IteratedSet]] internal slot of O. */
    ejsval s = OObj->iterated;

    /* 5. Let index be the value of the [[SetNextIndex]] internal slot of O. */
    uint32_t index = OObj->next_index;

    /* 6. Let itemKind be the value of the [[SetIterationKind]] internal slot of O. */
    EJSSetIteratorKind itemKind = OObj->kind;

    /* 7. If s is undefined, then return CreateIterResultObject(undefined, true). */
    if (EJSVAL_IS_UNDEFINED(s))
        return _ejs_create_iter_result (_ejs_undefined, _ejs_true);

    /* 8. Assert: s has a [[SetData]] internal slot and s has been initialized so the value of
     * [[SetData]] is not undefined. */

    /* 9. Let entries be the List that is the value of the [[SetData]] internal slot of s. */
    EJSSetValueEntry *entries = EJSVAL_TO_SET(s)->head_insert;

    /* 10. Repeat while index is less than the total number of elements of entries. The number of elements must
     * be redetermined each time this method is evaluated. */
    uint32_t i = 0;
    for (EJSSetValueEntry *entry = entries; entry; entry = entry->next_insert) {

        /* Ignore this item if is marked as empty */
        if (EJSVAL_IS_NO_ITER_VALUE_MAGIC(entry->value))
            continue;

        /* Ignore this item if we haven't reached the initial needed point/index */
        if (index > i++)
            continue;

        /* a. Let e be entries[index]. */
        ejsval e = entry->value;

        /* b. Set index to index+1; */
        index = index + 1;

        /* c. Set the [[SetNextIndex]] internal slot of O to index. */
        OObj->next_index = index;

        /* d. If e is not empty, then */
        /*  (see EJSVAL_IS_NO_ITER_VALUE_MAGIC check at the beginning of the loop */

        /*      i. If itemKind is "key+value" then, */
        if (itemKind == EJS_SET_ITER_KIND_KEYVALUE) {
            /* 1. Let result be the result of performing ArrayCreate(2). */
            /* 2. Assert: result is a new, well-formed Array object so the following operations will never fail. */
            ejsval result = _ejs_array_new (2, EJS_FALSE);

            /* 3. Call CreateDataProperty(result, "0", e) . */
            _ejs_object_setprop (result, NUMBER_TO_EJSVAL(0), e);

            /* 4. Call CreateDataProperty(result, "1", e) . */
            _ejs_object_setprop (result, NUMBER_TO_EJSVAL(1), e);

            return _ejs_create_iter_result (result, _ejs_false);
        }

        /*      ii. Return CreateIterResultObject(e, false). */
        return _ejs_create_iter_result (e, _ejs_false);
    }

    /* 11. Set the [[IteratedSet]] internal slot of O to undefined. */
    OObj->iterated = _ejs_undefined;

    /* 12. Return CreateIterResultObject(undefined, true). */
    return _ejs_create_iter_result (_ejs_undefined, _ejs_true);
}
Example #24
0
ejsval
_ejs_op_plus (ejsval exp)
{
    return NUMBER_TO_EJSVAL (ToDouble(exp));
}
Example #25
0
ejsval
_ejs_op_bitwise_not (ejsval val)
{
    int val_int = ToInteger(val);
    return NUMBER_TO_EJSVAL (~val_int);
}