Beispiel #1
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();
}
Beispiel #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;
}
Beispiel #3
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);
}
Beispiel #4
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;
}
Beispiel #5
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
}
Beispiel #6
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
}