Exemple #1
0
static HRESULT create_arguments(script_ctx_t *ctx, FunctionInstance *calee, jsdisp_t *var_obj,
        unsigned argc, jsval_t *argv, jsdisp_t **ret)
{
    ArgumentsInstance *args;
    unsigned i;
    HRESULT hres;

    static const WCHAR caleeW[] = {'c','a','l','l','e','e',0};

    args = heap_alloc_zero(sizeof(*args));
    if(!args)
        return E_OUTOFMEMORY;

    hres = init_dispex_from_constr(&args->jsdisp, ctx, &Arguments_info, ctx->object_constr);
    if(FAILED(hres)) {
        heap_free(args);
        return hres;
    }

    jsdisp_addref(&calee->dispex);
    args->function = calee;
    args->var_obj = jsdisp_addref(var_obj);

    /* Store unnamed arguments directly in arguments object */
    for(i = calee->length; i < argc; i++) {
        WCHAR buf[12];

        static const WCHAR formatW[] = {'%','d',0};

        sprintfW(buf, formatW, i);
        hres = jsdisp_propput_dontenum(&args->jsdisp, buf, argv[i]);
        if(FAILED(hres))
            break;
    }

    if(SUCCEEDED(hres)) {
        hres = jsdisp_propput_dontenum(&args->jsdisp, lengthW, jsval_number(argc));
        if(SUCCEEDED(hres))
            hres = jsdisp_propput_dontenum(&args->jsdisp, caleeW, jsval_disp(to_disp(&calee->dispex)));
    }
    if(FAILED(hres)) {
        jsdisp_release(&args->jsdisp);
        return hres;
    }

    *ret = &args->jsdisp;
    return S_OK;
}
Exemple #2
0
static HRESULT Function_arguments(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    FunctionInstance *function = (FunctionInstance*)jsthis->u.jsdisp;
    HRESULT hres = S_OK;

    TRACE("\n");

    switch(flags) {
    case DISPATCH_PROPERTYGET: {
        if(function->arguments) {
            jsdisp_addref(function->arguments);
            var_set_jsdisp(retv, function->arguments);
        }else {
            V_VT(retv) = VT_NULL;
        }
        break;
    }
    case DISPATCH_PROPERTYPUT:
        break;
    default:
        FIXME("unimplemented flags %x\n", flags);
        hres = E_NOTIMPL;
    }

    return hres;
}
Exemple #3
0
static HRESULT constructor_call(jsdisp_t *constr, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    if(flags != DISPATCH_PROPERTYGET)
        return jsdisp_call_value(constr, NULL, flags, argc, argv, r);

    *r = jsval_obj(jsdisp_addref(constr));
    return S_OK;
}
Exemple #4
0
static HRESULT Function_get_arguments(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
{
    FunctionInstance *function = function_from_jsdisp(jsthis);

    TRACE("\n");

    *r = function->arguments ? jsval_obj(jsdisp_addref(function->arguments)) : jsval_null();
    return S_OK;
}
Exemple #5
0
static HRESULT Array_reverse(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
        VARIANT *retv, jsexcept_t *ei)
{
    jsdisp_t *jsthis;
    DWORD length, k, l;
    VARIANT v1, v2;
    HRESULT hres1, hres2;

    TRACE("\n");

    hres1 = get_length(ctx, vthis, ei, &jsthis, &length);
    if(FAILED(hres1))
        return hres1;

    for(k=0; k<length/2; k++) {
        l = length-k-1;

        hres1 = jsdisp_get_idx(jsthis, k, &v1, ei);
        if(FAILED(hres1) && hres1!=DISP_E_UNKNOWNNAME)
            return hres1;

        hres2 = jsdisp_get_idx(jsthis, l, &v2, ei);
        if(FAILED(hres2) && hres2!=DISP_E_UNKNOWNNAME) {
            VariantClear(&v1);
            return hres2;
        }

        if(hres1 == DISP_E_UNKNOWNNAME)
            hres1 = jsdisp_delete_idx(jsthis, l);
        else
            hres1 = jsdisp_propput_idx(jsthis, l, &v1, ei);

        if(FAILED(hres1)) {
            VariantClear(&v1);
            VariantClear(&v2);
            return hres1;
        }

        if(hres2 == DISP_E_UNKNOWNNAME)
            hres2 = jsdisp_delete_idx(jsthis, k);
        else
            hres2 = jsdisp_propput_idx(jsthis, k, &v2, ei);

        if(FAILED(hres2)) {
            VariantClear(&v2);
            return hres2;
        }
    }

    if(retv) {
        jsdisp_addref(jsthis);
        var_set_jsdisp(retv, jsthis);
    }

    return S_OK;
}
Exemple #6
0
static HRESULT constructor_call(jsdisp_t *constr, WORD flags, DISPPARAMS *dp,
        VARIANT *retv, jsexcept_t *ei)
{
    if(flags != DISPATCH_PROPERTYGET)
        return jsdisp_call_value(constr, flags, dp, retv, ei);

    jsdisp_addref(constr);
    var_set_jsdisp(retv, constr);
    return S_OK;
}
Exemple #7
0
static HRESULT Array_reverse(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    jsdisp_t *jsthis;
    DWORD length, k, l;
    jsval_t v1, v2;
    HRESULT hres1, hres2;

    TRACE("\n");

    hres1 = get_length(ctx, vthis, &jsthis, &length);
    if(FAILED(hres1))
        return hres1;

    for(k=0; k<length/2; k++) {
        l = length-k-1;

        hres1 = jsdisp_get_idx(jsthis, k, &v1);
        if(FAILED(hres1) && hres1!=DISP_E_UNKNOWNNAME)
            return hres1;

        hres2 = jsdisp_get_idx(jsthis, l, &v2);
        if(FAILED(hres2) && hres2!=DISP_E_UNKNOWNNAME) {
            jsval_release(v1);
            return hres2;
        }

        if(hres1 == DISP_E_UNKNOWNNAME)
            hres1 = jsdisp_delete_idx(jsthis, l);
        else
            hres1 = jsdisp_propput_idx(jsthis, l, v1);

        if(FAILED(hres1)) {
            jsval_release(v1);
            jsval_release(v2);
            return hres1;
        }

        if(hres2 == DISP_E_UNKNOWNNAME)
            hres2 = jsdisp_delete_idx(jsthis, k);
        else
            hres2 = jsdisp_propput_idx(jsthis, k, v2);

        if(FAILED(hres2)) {
            jsval_release(v2);
            return hres2;
        }
    }

    if(r)
        *r = jsval_obj(jsdisp_addref(jsthis));
    return S_OK;
}
Exemple #8
0
static HRESULT Function_get_arguments(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
{
    FunctionInstance *function = function_from_jsdisp(jsthis);
    call_frame_t *frame;

    TRACE("\n");

    for(frame = ctx->call_ctx; frame; frame = frame->prev_frame) {
        if(frame->function_instance == &function->dispex) {
            *r = jsval_obj(jsdisp_addref(frame->arguments_obj));
            return S_OK;
        }
    }

    *r = jsval_null();
    return S_OK;
}
Exemple #9
0
static HRESULT Function_arguments(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        unsigned argc, jsval_t *argv, jsval_t *r)
{
    FunctionInstance *function = (FunctionInstance*)jsthis->u.jsdisp;
    HRESULT hres = S_OK;

    TRACE("\n");

    switch(flags) {
    case DISPATCH_PROPERTYGET: {
        *r = function->arguments ? jsval_obj(jsdisp_addref(function->arguments)) : jsval_null();
        break;
    }
    case DISPATCH_PROPERTYPUT:
        break;
    default:
        FIXME("unimplemented flags %x\n", flags);
        hres = E_NOTIMPL;
    }

    return hres;
}
Exemple #10
0
/* ECMA-262 3rd Edition    15.4.4.11 */
static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
        VARIANT *retv, jsexcept_t *ei)
{
    jsdisp_t *jsthis, *cmp_func = NULL;
    VARIANT *vtab, **sorttab = NULL;
    DWORD length;
    DWORD i;
    HRESULT hres = S_OK;

    TRACE("\n");

    hres = get_length(ctx, vthis, ei, &jsthis, &length);
    if(FAILED(hres))
        return hres;

    if(arg_cnt(dp) > 1) {
        WARN("invalid arg_cnt %d\n", arg_cnt(dp));
        return E_FAIL;
    }

    if(arg_cnt(dp) == 1) {
        VARIANT *arg = get_arg(dp, 0);

        if(V_VT(arg) != VT_DISPATCH) {
            WARN("arg is not dispatch\n");
            return E_FAIL;
        }


        cmp_func = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg));
        if(!cmp_func || !is_class(cmp_func, JSCLASS_FUNCTION)) {
            WARN("cmp_func is not a function\n");
            if(cmp_func)
                jsdisp_release(cmp_func);
            return E_FAIL;
        }
    }

    if(!length) {
        if(cmp_func)
            jsdisp_release(cmp_func);
        if(retv) {
            jsdisp_addref(jsthis);
            var_set_jsdisp(retv, jsthis);
        }
        return S_OK;
    }

    vtab = heap_alloc_zero(length * sizeof(VARIANT));
    if(vtab) {
        for(i=0; i<length; i++) {
            hres = jsdisp_get_idx(jsthis, i, vtab+i, ei);
            if(hres == DISP_E_UNKNOWNNAME) {
                V_VT(vtab+i) = VT_EMPTY;
                hres = S_OK;
            } else if(FAILED(hres)) {
                WARN("Could not get elem %d: %08x\n", i, hres);
                break;
            }
        }
    }else {
        hres = E_OUTOFMEMORY;
    }

    if(SUCCEEDED(hres)) {
        sorttab = heap_alloc(length*2*sizeof(VARIANT*));
        if(!sorttab)
            hres = E_OUTOFMEMORY;
    }

    /* merge-sort */
    if(SUCCEEDED(hres)) {
        VARIANT *tmpv, **tmpbuf;
        INT cmp;

        tmpbuf = sorttab + length;
        for(i=0; i < length; i++)
            sorttab[i] = vtab+i;

        for(i=0; i < length/2; i++) {
            hres = sort_cmp(ctx, cmp_func, sorttab[2*i+1], sorttab[2*i], ei, &cmp);
            if(FAILED(hres))
                break;

            if(cmp < 0) {
                tmpv = sorttab[2*i];
                sorttab[2*i] = sorttab[2*i+1];
                sorttab[2*i+1] = tmpv;
            }
        }

        if(SUCCEEDED(hres)) {
            DWORD k, a, b, bend;

            for(k=2; k < length; k *= 2) {
                for(i=0; i+k < length; i += 2*k) {
                    a = b = 0;
                    if(i+2*k <= length)
                        bend = k;
                    else
                        bend = length - (i+k);

                    memcpy(tmpbuf, sorttab+i, k*sizeof(VARIANT*));

                    while(a < k && b < bend) {
                        hres = sort_cmp(ctx, cmp_func, tmpbuf[a], sorttab[i+k+b], ei, &cmp);
                        if(FAILED(hres))
                            break;

                        if(cmp < 0) {
                            sorttab[i+a+b] = tmpbuf[a];
                            a++;
                        }else {
                            sorttab[i+a+b] = sorttab[i+k+b];
                            b++;
                        }
                    }

                    if(FAILED(hres))
                        break;

                    if(a < k)
                        memcpy(sorttab+i+a+b, tmpbuf+a, (k-a)*sizeof(VARIANT*));
                }

                if(FAILED(hres))
                    break;
            }
        }

        for(i=0; SUCCEEDED(hres) && i < length; i++)
            hres = jsdisp_propput_idx(jsthis, i, sorttab[i], ei);
    }

    if(vtab) {
        for(i=0; i < length; i++)
            VariantClear(vtab+i);
        heap_free(vtab);
    }
    heap_free(sorttab);
    if(cmp_func)
        jsdisp_release(cmp_func);

    if(FAILED(hres))
        return hres;

    if(retv) {
        jsdisp_addref(jsthis);
        var_set_jsdisp(retv, jsthis);
    }

    return S_OK;
}
Exemple #11
0
/* ECMA-262 3rd Edition    15.4.4.11 */
static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    jsdisp_t *jsthis, *cmp_func = NULL;
    jsval_t *vtab, **sorttab = NULL;
    DWORD length;
    DWORD i;
    HRESULT hres = S_OK;

    TRACE("\n");

    hres = get_length(ctx, vthis, &jsthis, &length);
    if(FAILED(hres))
        return hres;

    if(argc > 1) {
        WARN("invalid arg_cnt %d\n", argc);
        return E_FAIL;
    }

    if(argc == 1) {
        if(!is_object_instance(argv[0])) {
            WARN("arg is not dispatch\n");
            return E_FAIL;
        }

        cmp_func = iface_to_jsdisp((IUnknown*)get_object(argv[0]));
        if(!cmp_func || !is_class(cmp_func, JSCLASS_FUNCTION)) {
            WARN("cmp_func is not a function\n");
            if(cmp_func)
                jsdisp_release(cmp_func);
            return E_FAIL;
        }
    }

    if(!length) {
        if(cmp_func)
            jsdisp_release(cmp_func);
        if(r)
            *r = jsval_obj(jsdisp_addref(jsthis));
        return S_OK;
    }

    vtab = heap_alloc_zero(length * sizeof(*vtab));
    if(vtab) {
        for(i=0; i<length; i++) {
            hres = jsdisp_get_idx(jsthis, i, vtab+i);
            if(hres == DISP_E_UNKNOWNNAME) {
                vtab[i] = jsval_undefined();
                hres = S_OK;
            } else if(FAILED(hres)) {
                WARN("Could not get elem %d: %08x\n", i, hres);
                break;
            }
        }
    }else {
        hres = E_OUTOFMEMORY;
    }

    if(SUCCEEDED(hres)) {
        sorttab = heap_alloc(length*2*sizeof(*sorttab));
        if(!sorttab)
            hres = E_OUTOFMEMORY;
    }

    /* merge-sort */
    if(SUCCEEDED(hres)) {
        jsval_t *tmpv, **tmpbuf;
        INT cmp;

        tmpbuf = sorttab + length;
        for(i=0; i < length; i++)
            sorttab[i] = vtab+i;

        for(i=0; i < length/2; i++) {
            hres = sort_cmp(ctx, cmp_func, *sorttab[2*i+1], *sorttab[2*i], &cmp);
            if(FAILED(hres))
                break;

            if(cmp < 0) {
                tmpv = sorttab[2*i];
                sorttab[2*i] = sorttab[2*i+1];
                sorttab[2*i+1] = tmpv;
            }
        }

        if(SUCCEEDED(hres)) {
            DWORD k, a, b, bend;

            for(k=2; k < length; k *= 2) {
                for(i=0; i+k < length; i += 2*k) {
                    a = b = 0;
                    if(i+2*k <= length)
                        bend = k;
                    else
                        bend = length - (i+k);

                    memcpy(tmpbuf, sorttab+i, k*sizeof(jsval_t*));

                    while(a < k && b < bend) {
                        hres = sort_cmp(ctx, cmp_func, *tmpbuf[a], *sorttab[i+k+b], &cmp);
                        if(FAILED(hres))
                            break;

                        if(cmp < 0) {
                            sorttab[i+a+b] = tmpbuf[a];
                            a++;
                        }else {
                            sorttab[i+a+b] = sorttab[i+k+b];
                            b++;
                        }
                    }

                    if(FAILED(hres))
                        break;

                    if(a < k)
                        memcpy(sorttab+i+a+b, tmpbuf+a, (k-a)*sizeof(jsval_t*));
                }

                if(FAILED(hres))
                    break;
            }
        }

        for(i=0; SUCCEEDED(hres) && i < length; i++)
            hres = jsdisp_propput_idx(jsthis, i, *sorttab[i]);
    }

    if(vtab) {
        for(i=0; i < length; i++)
            jsval_release(vtab[i]);
        heap_free(vtab);
    }
    heap_free(sorttab);
    if(cmp_func)
        jsdisp_release(cmp_func);

    if(FAILED(hres))
        return hres;

    if(r)
        *r = jsval_obj(jsdisp_addref(jsthis));
    return S_OK;
}