mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 10:45:24 +00:00
sync jscript with wine 1.1.27
svn path=/trunk/; revision=42496
This commit is contained in:
parent
2a10e77d03
commit
23d4ad046d
|
@ -16,6 +16,8 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "jscript.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
@ -40,7 +42,6 @@ static const WCHAR sortW[] = {'s','o','r','t',0};
|
|||
static const WCHAR spliceW[] = {'s','p','l','i','c','e',0};
|
||||
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
|
||||
static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0};
|
||||
static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
|
||||
static const WCHAR unshiftW[] = {'u','n','s','h','i','f','t',0};
|
||||
static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0};
|
||||
static const WCHAR propertyIsEnumerableW[] =
|
||||
|
@ -61,6 +62,30 @@ static HRESULT Array_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
V_VT(retv) = VT_I4;
|
||||
V_I4(retv) = This->length;
|
||||
break;
|
||||
case DISPATCH_PROPERTYPUT: {
|
||||
VARIANT num;
|
||||
DOUBLE len = -1;
|
||||
DWORD i;
|
||||
HRESULT hres;
|
||||
|
||||
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &num);
|
||||
if(V_VT(&num) == VT_I4)
|
||||
len = V_I4(&num);
|
||||
else
|
||||
len = floor(V_R8(&num));
|
||||
|
||||
if(len!=(DWORD)len)
|
||||
return throw_range_error(dispex->ctx, ei, IDS_INVALID_LENGTH, NULL);
|
||||
|
||||
for(i=len; i<This->length; i++) {
|
||||
hres = jsdisp_delete_idx(dispex, i);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
This->length = len;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
|
@ -394,8 +419,81 @@ static HRESULT Array_shift(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
|
|||
static HRESULT Array_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
DispatchEx *arr;
|
||||
VARIANT v;
|
||||
DOUBLE range;
|
||||
DWORD length, start, end, idx;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_class(dispex, JSCLASS_ARRAY)) {
|
||||
length = ((ArrayInstance*)dispex)->length;
|
||||
}else {
|
||||
FIXME("not Array this\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if(arg_cnt(dp)) {
|
||||
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(V_VT(&v) == VT_I4)
|
||||
range = V_I4(&v);
|
||||
else
|
||||
range = floor(V_R8(&v));
|
||||
|
||||
if(-range>length || isnan(range)) start = 0;
|
||||
else if(range < 0) start = range+length;
|
||||
else if(range <= length) start = range;
|
||||
else start = length;
|
||||
}
|
||||
else start = 0;
|
||||
|
||||
if(arg_cnt(dp)>1) {
|
||||
hres = to_number(dispex->ctx, get_arg(dp, 1), ei, &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(V_VT(&v) == VT_I4)
|
||||
range = V_I4(&v);
|
||||
else
|
||||
range = floor(V_R8(&v));
|
||||
|
||||
if(-range>length) end = 0;
|
||||
else if(range < 0) end = range+length;
|
||||
else if(range <= length) end = range;
|
||||
else end = length;
|
||||
}
|
||||
else end = length;
|
||||
|
||||
hres = create_array(dispex->ctx, (end>start)?end-start:0, &arr);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
for(idx=start; idx<end; idx++) {
|
||||
hres = jsdisp_propget_idx(dispex, idx, lcid, &v, ei, sp);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
continue;
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
hres = jsdisp_propput_idx(arr, idx-start, lcid, &v, ei, sp);
|
||||
|
||||
if(FAILED(hres)) {
|
||||
jsdisp_release(arr);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(arr);
|
||||
}
|
||||
else
|
||||
jsdisp_release(arr);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sort_cmp(script_ctx_t *ctx, DispatchEx *cmp_func, VARIANT *v1, VARIANT *v2, jsexcept_t *ei,
|
||||
|
@ -638,13 +736,6 @@ static HRESULT Array_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, D
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT Array_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT Array_unshift(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
|
@ -679,6 +770,8 @@ static HRESULT Array_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
|
|||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case INVOKE_FUNC:
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
|
||||
case INVOKE_PROPERTYGET:
|
||||
return array_join(dispex, lcid, ((ArrayInstance*)dispex)->length, default_separatorW, retv, ei, sp);
|
||||
default:
|
||||
|
@ -732,7 +825,6 @@ static const builtin_prop_t Array_props[] = {
|
|||
{toLocaleStringW, Array_toLocaleString, PROPF_METHOD},
|
||||
{toStringW, Array_toString, PROPF_METHOD},
|
||||
{unshiftW, Array_unshift, PROPF_METHOD},
|
||||
{valueOfW, Array_valueOf, PROPF_METHOD}
|
||||
};
|
||||
|
||||
static const builtin_info_t Array_info = {
|
||||
|
@ -755,12 +847,11 @@ static HRESULT ArrayConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISP
|
|||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case DISPATCH_METHOD:
|
||||
case DISPATCH_CONSTRUCT: {
|
||||
if(arg_cnt(dp) == 1 && V_VT((arg_var = get_arg(dp, 0))) == VT_I4) {
|
||||
if(V_I4(arg_var) < 0) {
|
||||
FIXME("throw RangeError\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
if(V_I4(arg_var) < 0)
|
||||
return throw_range_error(dispex->ctx, ei, IDS_INVALID_LENGTH, NULL);
|
||||
|
||||
hres = create_array(dispex->ctx, V_I4(arg_var), &obj);
|
||||
if(FAILED(hres))
|
||||
|
@ -809,7 +900,7 @@ static HRESULT alloc_array(script_ctx_t *ctx, BOOL use_constr, ArrayInstance **r
|
|||
if(use_constr)
|
||||
hres = init_dispex_from_constr(&array->dispex, ctx, &Array_info, ctx->array_constr);
|
||||
else
|
||||
hres = init_dispex(&array->dispex, ctx, &Array_info, NULL);
|
||||
hres = init_dispex_from_constr(&array->dispex, ctx, &Array_info, ctx->object_constr);
|
||||
|
||||
if(FAILED(hres)) {
|
||||
heap_free(array);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2008 Jacek Caban for CodeWeavers
|
||||
* Copyright 2009 Piotr Caban
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -36,25 +37,59 @@ static const WCHAR propertyIsEnumerableW[] =
|
|||
{'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0};
|
||||
static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
|
||||
|
||||
/* ECMA-262 3rd Edition 15.6.4.2 */
|
||||
static HRESULT Bool_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
static const WCHAR trueW[] = {'t','r','u','e',0};
|
||||
static const WCHAR falseW[] = {'f','a','l','s','e',0};
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(!is_class(dispex, JSCLASS_BOOLEAN))
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_BOOL, NULL);
|
||||
|
||||
if(retv) {
|
||||
BoolInstance *bool = (BoolInstance*)dispex;
|
||||
BSTR val;
|
||||
|
||||
if(bool->val) val = SysAllocString(trueW);
|
||||
else val = SysAllocString(falseW);
|
||||
|
||||
if(!val)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = val;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT Bool_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
TRACE("\n");
|
||||
return Bool_toString(dispex, lcid, flags, dp, retv, ei, sp);
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.6.4.3 */
|
||||
static HRESULT Bool_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
TRACE("\n");
|
||||
|
||||
if(!is_class(dispex, JSCLASS_BOOLEAN))
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_BOOL, NULL);
|
||||
|
||||
if(retv) {
|
||||
BoolInstance *bool = (BoolInstance*)dispex;
|
||||
|
||||
V_VT(retv) = VT_BOOL;
|
||||
V_BOOL(retv) = bool->val;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT Bool_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
|
@ -81,8 +116,18 @@ static HRESULT Bool_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DIS
|
|||
static HRESULT Bool_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case INVOKE_FUNC:
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
|
||||
default:
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
static const builtin_prop_t Bool_props[] = {
|
||||
|
@ -106,8 +151,41 @@ static const builtin_info_t Bool_info = {
|
|||
static HRESULT BoolConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
HRESULT hres;
|
||||
VARIANT_BOOL value = VARIANT_FALSE;
|
||||
|
||||
if(arg_cnt(dp)) {
|
||||
hres = to_boolean(get_arg(dp,0), &value);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
switch(flags) {
|
||||
case DISPATCH_CONSTRUCT: {
|
||||
DispatchEx *bool;
|
||||
|
||||
hres = create_bool(dispex->ctx, value, &bool);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(bool);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
case INVOKE_FUNC:
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BOOL;
|
||||
V_BOOL(retv) = value;
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
default:
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT alloc_bool(script_ctx_t *ctx, BOOL use_constr, BoolInstance **ret)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -828,7 +828,7 @@ HRESULT jsdisp_call_value(DispatchEx *disp, LCID lcid, WORD flags, DISPPARAMS *d
|
|||
return disp->builtin_info->value_prop.invoke(disp, lcid, flags, dp, retv, ei, caller);
|
||||
}
|
||||
|
||||
static HRESULT jsdisp_call(DispatchEx *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv,
|
||||
HRESULT jsdisp_call(DispatchEx *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv,
|
||||
jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
dispex_prop_t *prop;
|
||||
|
@ -1010,3 +1010,19 @@ HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexce
|
|||
|
||||
return hres;
|
||||
}
|
||||
|
||||
HRESULT jsdisp_delete_idx(DispatchEx *obj, DWORD idx)
|
||||
{
|
||||
static const WCHAR formatW[] = {'%','d',0};
|
||||
WCHAR buf[12];
|
||||
dispex_prop_t *prop;
|
||||
HRESULT hres;
|
||||
|
||||
sprintfW(buf, formatW, idx);
|
||||
|
||||
hres = find_prop_name(obj, buf, &prop);
|
||||
if(FAILED(hres) || !prop)
|
||||
return hres;
|
||||
|
||||
return delete_prop(prop);
|
||||
}
|
||||
|
|
|
@ -179,6 +179,8 @@ HRESULT create_exec_ctx(IDispatch *this_obj, DispatchEx *var_disp, scope_chain_t
|
|||
if(!ctx)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ctx->ref = 1;
|
||||
|
||||
IDispatch_AddRef(this_obj);
|
||||
ctx->this_obj = this_obj;
|
||||
|
||||
|
@ -230,10 +232,8 @@ static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
|
|||
/* ECMA-262 3rd Edition 8.7.2 */
|
||||
static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
|
||||
{
|
||||
if(ref->type != EXPRVAL_IDREF) {
|
||||
FIXME("throw ReferemceError\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
if(ref->type != EXPRVAL_IDREF)
|
||||
return throw_reference_error(ctx, ei, IDS_ILLEGAL_ASSIGN, NULL);
|
||||
|
||||
return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
|
||||
}
|
||||
|
@ -304,7 +304,12 @@ static HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
|
|||
*ret = V_R8(lval) == V_R8(rval);
|
||||
break;
|
||||
case VT_BSTR:
|
||||
*ret = !strcmpW(V_BSTR(lval), V_BSTR(rval));
|
||||
if(!V_BSTR(lval))
|
||||
*ret = SysStringLen(V_BSTR(rval))?FALSE:TRUE;
|
||||
else if(!V_BSTR(rval))
|
||||
*ret = SysStringLen(V_BSTR(lval))?FALSE:TRUE;
|
||||
else
|
||||
*ret = !strcmpW(V_BSTR(lval), V_BSTR(rval));
|
||||
break;
|
||||
case VT_DISPATCH:
|
||||
return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret);
|
||||
|
@ -431,7 +436,7 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so
|
|||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 10.1.4 */
|
||||
static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
|
||||
static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, jsexcept_t *ei, exprval_t *ret)
|
||||
{
|
||||
scope_chain_t *scope;
|
||||
named_item_t *item;
|
||||
|
@ -516,8 +521,7 @@ static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, ex
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("Could not find identifier %s\n", debugstr_w(identifier));
|
||||
return E_FAIL;
|
||||
return throw_type_error(ctx->var_disp->ctx, ei, IDS_UNDEFINED, identifier);
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 12.1 */
|
||||
|
@ -853,7 +857,7 @@ HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t
|
|||
TRACE("iter %s\n", debugstr_w(str));
|
||||
|
||||
if(stat->variable)
|
||||
hres = identifier_eval(ctx, identifier, 0, &exprval);
|
||||
hres = identifier_eval(ctx, identifier, 0, NULL, &exprval);
|
||||
else
|
||||
hres = expr_eval(ctx, stat->expr, EXPR_NEWREF, &rt->ei, &exprval);
|
||||
if(SUCCEEDED(hres)) {
|
||||
|
@ -1536,11 +1540,16 @@ HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags,
|
|||
hres = args_to_param(ctx, expr->argument_list, ei, &dp);
|
||||
if(SUCCEEDED(hres)) {
|
||||
switch(exprval.type) {
|
||||
case EXPRVAL_VARIANT:
|
||||
if(V_VT(&exprval.u.var) != VT_DISPATCH)
|
||||
return throw_type_error(ctx->var_disp->ctx, ei, IDS_NO_PROPERTY, NULL);
|
||||
|
||||
hres = disp_call(V_DISPATCH(&exprval.u.var), DISPID_VALUE, ctx->parser->script->lcid,
|
||||
DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
|
||||
break;
|
||||
case EXPRVAL_IDREF:
|
||||
hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD,
|
||||
&dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
|
||||
if(flags & EXPR_NOVAL)
|
||||
V_VT(&var) = VT_EMPTY;
|
||||
hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid,
|
||||
DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
|
||||
break;
|
||||
default:
|
||||
FIXME("unimplemented type %d\n", exprval.type);
|
||||
|
@ -1554,9 +1563,13 @@ HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags,
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
TRACE("= %s\n", debugstr_variant(&var));
|
||||
ret->type = EXPRVAL_VARIANT;
|
||||
ret->u.var = var;
|
||||
if(flags & EXPR_NOVAL) {
|
||||
V_VT(&ret->u.var) = VT_EMPTY;
|
||||
}else {
|
||||
TRACE("= %s\n", debugstr_variant(&var));
|
||||
ret->u.var = var;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1585,7 +1598,7 @@ HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD f
|
|||
if(!identifier)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hres = identifier_eval(ctx, identifier, flags, ret);
|
||||
hres = identifier_eval(ctx, identifier, flags, ei, ret);
|
||||
|
||||
SysFreeString(identifier);
|
||||
return hres;
|
||||
|
@ -1931,11 +1944,11 @@ static HRESULT add_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_
|
|||
VARIANT r, l;
|
||||
HRESULT hres;
|
||||
|
||||
hres = to_primitive(ctx->parser->script, lval, ei, &l);
|
||||
hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = to_primitive(ctx->parser->script, rval, ei, &r);
|
||||
hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT);
|
||||
if(FAILED(hres)) {
|
||||
VariantClear(&l);
|
||||
return hres;
|
||||
|
@ -2518,7 +2531,7 @@ static HRESULT equal_values(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexc
|
|||
VARIANT v;
|
||||
HRESULT hres;
|
||||
|
||||
hres = to_primitive(ctx->parser->script, rval, ei, &v);
|
||||
hres = to_primitive(ctx->parser->script, rval, ei, &v, NO_HINT);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -2533,7 +2546,7 @@ static HRESULT equal_values(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexc
|
|||
VARIANT v;
|
||||
HRESULT hres;
|
||||
|
||||
hres = to_primitive(ctx->parser->script, lval, ei, &v);
|
||||
hres = to_primitive(ctx->parser->script, lval, ei, &v, NO_HINT);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -2638,11 +2651,11 @@ static HRESULT less_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, BOOL gre
|
|||
VARIANT l, r, ln, rn;
|
||||
HRESULT hres;
|
||||
|
||||
hres = to_primitive(ctx->parser->script, lval, ei, &l);
|
||||
hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = to_primitive(ctx->parser->script, rval, ei, &r);
|
||||
hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT);
|
||||
if(FAILED(hres)) {
|
||||
VariantClear(&l);
|
||||
return hres;
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct _parser_ctx_t {
|
|||
source_elements_t *source;
|
||||
BOOL nl;
|
||||
BOOL is_html;
|
||||
BOOL lexer_error;
|
||||
HRESULT hres;
|
||||
|
||||
jsheap_t heap;
|
||||
|
|
481
reactos/dll/win32/jscript/error.c
Normal file
481
reactos/dll/win32/jscript/error.c
Normal file
|
@ -0,0 +1,481 @@
|
|||
/*
|
||||
* Copyright 2009 Piotr Caban
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "jscript.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
|
||||
|
||||
typedef struct {
|
||||
DispatchEx dispex;
|
||||
|
||||
VARIANT number;
|
||||
VARIANT description;
|
||||
VARIANT message;
|
||||
} ErrorInstance;
|
||||
|
||||
static const WCHAR descriptionW[] = {'d','e','s','c','r','i','p','t','i','o','n',0};
|
||||
static const WCHAR messageW[] = {'m','e','s','s','a','g','e',0};
|
||||
static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
|
||||
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
|
||||
static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0};
|
||||
static const WCHAR propertyIsEnumerableW[] =
|
||||
{'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0};
|
||||
static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
|
||||
|
||||
static HRESULT Error_number(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
ErrorInstance *This = (ErrorInstance*)dispex;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET:
|
||||
return VariantCopy(retv, &This->number);
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
return VariantCopy(&This->number, get_arg(dp, 0));
|
||||
default:
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT Error_description(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
ErrorInstance *This = (ErrorInstance*)dispex;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET:
|
||||
return VariantCopy(retv, &This->description);
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
return VariantCopy(&This->description, get_arg(dp, 0));
|
||||
default:
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.11.4.3 */
|
||||
static HRESULT Error_message(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
ErrorInstance *This = (ErrorInstance*)dispex;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET:
|
||||
return VariantCopy(retv, &This->message);
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
return VariantCopy(&This->message, get_arg(dp, 0));
|
||||
default:
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.11.4.4 */
|
||||
static HRESULT Error_toString(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
static const WCHAR str[] = {'[','o','b','j','e','c','t',' ','E','r','r','o','r',']',0};
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = SysAllocString(str);
|
||||
if(!V_BSTR(retv))
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT Error_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT Error_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT Error_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT Error_value(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case INVOKE_FUNC:
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
|
||||
default:
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void Error_destructor(DispatchEx *dispex)
|
||||
{
|
||||
ErrorInstance *This = (ErrorInstance*)dispex;
|
||||
|
||||
VariantClear(&This->number);
|
||||
VariantClear(&This->description);
|
||||
VariantClear(&This->message);
|
||||
heap_free(This);
|
||||
}
|
||||
|
||||
static const builtin_prop_t Error_props[] = {
|
||||
{descriptionW, Error_description, 0},
|
||||
{hasOwnPropertyW, Error_hasOwnProperty, PROPF_METHOD},
|
||||
{isPrototypeOfW, Error_isPrototypeOf, PROPF_METHOD},
|
||||
{messageW, Error_message, 0},
|
||||
{numberW, Error_number, 0},
|
||||
{propertyIsEnumerableW, Error_propertyIsEnumerable, PROPF_METHOD},
|
||||
{toStringW, Error_toString, PROPF_METHOD}
|
||||
};
|
||||
|
||||
static const builtin_info_t Error_info = {
|
||||
JSCLASS_ERROR,
|
||||
{NULL, Error_value, 0},
|
||||
sizeof(Error_props)/sizeof(*Error_props),
|
||||
Error_props,
|
||||
Error_destructor,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const builtin_prop_t ErrorInst_props[] = {
|
||||
{descriptionW, Error_description, 0},
|
||||
{hasOwnPropertyW, Error_hasOwnProperty, PROPF_METHOD},
|
||||
{isPrototypeOfW, Error_isPrototypeOf, PROPF_METHOD},
|
||||
{messageW, Error_message, 0},
|
||||
{numberW, Error_number, 0},
|
||||
{propertyIsEnumerableW, Error_propertyIsEnumerable, PROPF_METHOD}
|
||||
};
|
||||
|
||||
static const builtin_info_t ErrorInst_info = {
|
||||
JSCLASS_ERROR,
|
||||
{NULL, Error_value, 0},
|
||||
sizeof(ErrorInst_props)/sizeof(*ErrorInst_props),
|
||||
ErrorInst_props,
|
||||
Error_destructor,
|
||||
NULL
|
||||
};
|
||||
|
||||
static HRESULT alloc_error(script_ctx_t *ctx, BOOL error_prototype,
|
||||
DispatchEx *constr, ErrorInstance **ret)
|
||||
{
|
||||
ErrorInstance *err;
|
||||
DispatchEx *inherit;
|
||||
HRESULT hres;
|
||||
|
||||
err = heap_alloc_zero(sizeof(ErrorInstance));
|
||||
if(!err)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
inherit = error_prototype ? ctx->object_constr : ctx->error_constr;
|
||||
hres = init_dispex_from_constr(&err->dispex, ctx,
|
||||
error_prototype ? &Error_info : &ErrorInst_info,
|
||||
constr ? constr : inherit);
|
||||
if(FAILED(hres)) {
|
||||
heap_free(err);
|
||||
return hres;
|
||||
}
|
||||
|
||||
*ret = err;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT create_error(script_ctx_t *ctx, DispatchEx *constr,
|
||||
const UINT *number, const WCHAR *msg, DispatchEx **ret)
|
||||
{
|
||||
ErrorInstance *err;
|
||||
HRESULT hres;
|
||||
|
||||
hres = alloc_error(ctx, FALSE, constr, &err);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(number) {
|
||||
V_VT(&err->number) = VT_I4;
|
||||
V_I4(&err->number) = *number;
|
||||
}
|
||||
|
||||
V_VT(&err->message) = VT_BSTR;
|
||||
if(msg) V_BSTR(&err->message) = SysAllocString(msg);
|
||||
else V_BSTR(&err->message) = SysAllocStringLen(NULL, 0);
|
||||
|
||||
VariantCopy(&err->description, &err->message);
|
||||
|
||||
if(!V_BSTR(&err->message)) {
|
||||
heap_free(err);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
*ret = &err->dispex;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT error_constr(DispatchEx *dispex, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, DispatchEx *constr) {
|
||||
DispatchEx *err;
|
||||
VARIANT numv;
|
||||
UINT num;
|
||||
BSTR msg = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
V_VT(&numv) = VT_NULL;
|
||||
|
||||
if(arg_cnt(dp)) {
|
||||
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &numv);
|
||||
if(FAILED(hres) || (V_VT(&numv)==VT_R8 && isnan(V_R8(&numv))))
|
||||
hres = to_string(dispex->ctx, get_arg(dp, 0), ei, &msg);
|
||||
else if(V_VT(&numv) == VT_I4)
|
||||
num = V_I4(&numv);
|
||||
else
|
||||
num = V_R8(&numv);
|
||||
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(arg_cnt(dp)>1 && !msg) {
|
||||
hres = to_string(dispex->ctx, get_arg(dp, 1), ei, &msg);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
switch(flags) {
|
||||
case INVOKE_FUNC:
|
||||
case DISPATCH_CONSTRUCT:
|
||||
if(V_VT(&numv) == VT_NULL)
|
||||
hres = create_error(dispex->ctx, constr, NULL, msg, &err);
|
||||
else
|
||||
hres = create_error(dispex->ctx, constr, &num, msg, &err);
|
||||
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(err);
|
||||
}
|
||||
else
|
||||
IDispatchEx_Release(_IDispatchEx_(err));
|
||||
|
||||
return S_OK;
|
||||
|
||||
default:
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT ErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
return error_constr(dispex, flags, dp, retv, ei,
|
||||
dispex->ctx->error_constr);
|
||||
}
|
||||
|
||||
static HRESULT EvalErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
return error_constr(dispex, flags, dp, retv, ei,
|
||||
dispex->ctx->eval_error_constr);
|
||||
}
|
||||
|
||||
static HRESULT RangeErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
return error_constr(dispex, flags, dp, retv, ei,
|
||||
dispex->ctx->range_error_constr);
|
||||
}
|
||||
|
||||
static HRESULT ReferenceErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
return error_constr(dispex, flags, dp, retv, ei,
|
||||
dispex->ctx->reference_error_constr);
|
||||
}
|
||||
|
||||
static HRESULT SyntaxErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
return error_constr(dispex, flags, dp, retv, ei,
|
||||
dispex->ctx->syntax_error_constr);
|
||||
}
|
||||
|
||||
static HRESULT TypeErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
return error_constr(dispex, flags, dp, retv, ei,
|
||||
dispex->ctx->type_error_constr);
|
||||
}
|
||||
|
||||
static HRESULT URIErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
return error_constr(dispex, flags, dp, retv, ei,
|
||||
dispex->ctx->uri_error_constr);
|
||||
}
|
||||
|
||||
HRESULT init_error_constr(script_ctx_t *ctx)
|
||||
{
|
||||
static const WCHAR nameW[] = {'n','a','m','e',0};
|
||||
static const WCHAR ErrorW[] = {'E','r','r','o','r',0};
|
||||
static const WCHAR EvalErrorW[] = {'E','v','a','l','E','r','r','o','r',0};
|
||||
static const WCHAR RangeErrorW[] = {'R','a','n','g','e','E','r','r','o','r',0};
|
||||
static const WCHAR ReferenceErrorW[] = {'R','e','f','e','r','e','n','c','e','E','r','r','o','r',0};
|
||||
static const WCHAR SyntaxErrorW[] = {'S','y','n','t','a','x','E','r','r','o','r',0};
|
||||
static const WCHAR TypeErrorW[] = {'T','y','p','e','E','r','r','o','r',0};
|
||||
static const WCHAR URIErrorW[] = {'U','R','I','E','r','r','o','r',0};
|
||||
static const WCHAR *names[] = {ErrorW, EvalErrorW, RangeErrorW,
|
||||
ReferenceErrorW, SyntaxErrorW, TypeErrorW, URIErrorW};
|
||||
DispatchEx **constr_addr[] = {&ctx->error_constr, &ctx->eval_error_constr,
|
||||
&ctx->range_error_constr, &ctx->reference_error_constr,
|
||||
&ctx->syntax_error_constr, &ctx->type_error_constr,
|
||||
&ctx->uri_error_constr};
|
||||
static builtin_invoke_t constr_val[] = {ErrorConstr_value, EvalErrorConstr_value,
|
||||
RangeErrorConstr_value, ReferenceErrorConstr_value, SyntaxErrorConstr_value,
|
||||
TypeErrorConstr_value, URIErrorConstr_value};
|
||||
|
||||
ErrorInstance *err;
|
||||
INT i;
|
||||
VARIANT v;
|
||||
HRESULT hres;
|
||||
|
||||
for(i=0; i<7; i++) {
|
||||
hres = alloc_error(ctx, i==0, NULL, &err);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
V_VT(&v) = VT_BSTR;
|
||||
V_BSTR(&v) = SysAllocString(names[i]);
|
||||
if(!V_BSTR(&v)) {
|
||||
IDispatchEx_Release(_IDispatchEx_(&err->dispex));
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
hres = jsdisp_propput_name(&err->dispex, nameW, ctx->lcid, &v, NULL/*FIXME*/, NULL/*FIXME*/);
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
hres = create_builtin_function(ctx, constr_val[i], NULL,
|
||||
PROPF_CONSTR, &err->dispex, constr_addr[i]);
|
||||
|
||||
IDispatchEx_Release(_IDispatchEx_(&err->dispex));
|
||||
VariantClear(&v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT throw_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str, DispatchEx *constr)
|
||||
{
|
||||
WCHAR buf[1024], *pos = NULL;
|
||||
DispatchEx *err;
|
||||
HRESULT hres;
|
||||
|
||||
buf[0] = '\0';
|
||||
LoadStringW(jscript_hinstance, id&0xFFFF, buf, sizeof(buf)/sizeof(WCHAR));
|
||||
|
||||
if(str) pos = strchrW(buf, '|');
|
||||
if(pos) {
|
||||
int len = strlenW(str);
|
||||
memmove(pos+len, pos+1, (strlenW(pos+1)+1)*sizeof(WCHAR));
|
||||
memcpy(pos, str, len*sizeof(WCHAR));
|
||||
}
|
||||
|
||||
WARN("%s\n", debugstr_w(buf));
|
||||
|
||||
id |= JSCRIPT_ERROR;
|
||||
hres = create_error(ctx, constr, &id, buf, &err);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(!ei)
|
||||
return id;
|
||||
|
||||
V_VT(&ei->var) = VT_DISPATCH;
|
||||
V_DISPATCH(&ei->var) = (IDispatch*)_IDispatchEx_(err);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
HRESULT throw_eval_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
|
||||
{
|
||||
return throw_error(ctx, ei, id, str, ctx->eval_error_constr);
|
||||
}
|
||||
|
||||
HRESULT throw_range_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
|
||||
{
|
||||
return throw_error(ctx, ei, id, str, ctx->range_error_constr);
|
||||
}
|
||||
|
||||
HRESULT throw_reference_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
|
||||
{
|
||||
return throw_error(ctx, ei, id, str, ctx->reference_error_constr);
|
||||
}
|
||||
|
||||
HRESULT throw_syntax_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
|
||||
{
|
||||
return throw_error(ctx, ei, id, str, ctx->syntax_error_constr);
|
||||
}
|
||||
|
||||
HRESULT throw_type_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
|
||||
{
|
||||
return throw_error(ctx, ei, id, str, ctx->type_error_constr);
|
||||
}
|
||||
|
||||
HRESULT throw_uri_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
|
||||
{
|
||||
return throw_error(ctx, ei, id, str, ctx->uri_error_constr);
|
||||
}
|
|
@ -41,7 +41,6 @@ static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
|
|||
static const WCHAR lengthW[] = {'l','e','n','g','t','h',0};
|
||||
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
|
||||
static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0};
|
||||
static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
|
||||
static const WCHAR applyW[] = {'a','p','p','l','y',0};
|
||||
static const WCHAR callW[] = {'c','a','l','l',0};
|
||||
static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0};
|
||||
|
@ -198,9 +197,10 @@ static HRESULT invoke_constructor(FunctionInstance *function, LCID lcid, DISPPAR
|
|||
return hres;
|
||||
|
||||
hres = invoke_source(function, (IDispatch*)_IDispatchEx_(this_obj), lcid, dp, retv, ei, caller);
|
||||
jsdisp_release(this_obj);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
jsdisp_release(this_obj);
|
||||
return hres;
|
||||
}
|
||||
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(this_obj);
|
||||
|
@ -272,10 +272,8 @@ static HRESULT Function_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISP
|
|||
|
||||
TRACE("\n");
|
||||
|
||||
if(!is_class(dispex, JSCLASS_FUNCTION)) {
|
||||
FIXME("throw TypeError\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
if(!is_class(dispex, JSCLASS_FUNCTION))
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
|
||||
|
||||
function = (FunctionInstance*)dispex;
|
||||
|
||||
|
@ -299,13 +297,6 @@ static HRESULT Function_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT Function_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
|
@ -408,8 +399,7 @@ static const builtin_prop_t Function_props[] = {
|
|||
{lengthW, Function_length, 0},
|
||||
{propertyIsEnumerableW, Function_propertyIsEnumerable, PROPF_METHOD},
|
||||
{toLocaleStringW, Function_toLocaleString, PROPF_METHOD},
|
||||
{toStringW, Function_toString, PROPF_METHOD},
|
||||
{valueOfW, Function_valueOf, PROPF_METHOD}
|
||||
{toStringW, Function_toString, PROPF_METHOD}
|
||||
};
|
||||
|
||||
static const builtin_info_t Function_info = {
|
||||
|
@ -457,35 +447,38 @@ static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_
|
|||
function->flags = flags;
|
||||
function->length = flags & PROPF_ARGMASK;
|
||||
|
||||
if(prototype) {
|
||||
jsexcept_t jsexcept;
|
||||
VARIANT var;
|
||||
|
||||
V_VT(&var) = VT_DISPATCH;
|
||||
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(prototype);
|
||||
memset(&jsexcept, 0, sizeof(jsexcept));
|
||||
|
||||
hres = jsdisp_propput_name(&function->dispex, prototypeW, ctx->lcid, &var, &jsexcept, NULL/*FIXME*/);
|
||||
if(FAILED(hres)) {
|
||||
IDispatchEx_Release(_IDispatchEx_(&function->dispex));
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
*ret = function;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT set_prototype(script_ctx_t *ctx, DispatchEx *dispex, DispatchEx *prototype)
|
||||
{
|
||||
jsexcept_t jsexcept;
|
||||
VARIANT var;
|
||||
|
||||
V_VT(&var) = VT_DISPATCH;
|
||||
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(prototype);
|
||||
memset(&jsexcept, 0, sizeof(jsexcept));
|
||||
|
||||
return jsdisp_propput_name(dispex, prototypeW, ctx->lcid, &var, &jsexcept, NULL/*FIXME*/);
|
||||
}
|
||||
|
||||
HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc,
|
||||
const builtin_info_t *builtin_info, DWORD flags, DispatchEx *prototype, DispatchEx **ret)
|
||||
{
|
||||
FunctionInstance *function;
|
||||
HRESULT hres;
|
||||
|
||||
hres = create_function(ctx, builtin_info, flags, FALSE, prototype, &function);
|
||||
hres = create_function(ctx, builtin_info, flags, FALSE, NULL, &function);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = set_prototype(ctx, &function->dispex, prototype);
|
||||
if(FAILED(hres)) {
|
||||
jsdisp_release(&function->dispex);
|
||||
return hres;
|
||||
}
|
||||
|
||||
function->value_proc = value_proc;
|
||||
|
||||
*ret = &function->dispex;
|
||||
|
@ -505,7 +498,12 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_function(ctx->script, NULL, PROPF_CONSTR, FALSE, prototype, &function);
|
||||
hres = create_function(ctx->script, NULL, PROPF_CONSTR, FALSE, NULL, &function);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = set_prototype(ctx->script, &function->dispex, prototype);
|
||||
if(FAILED(hres))
|
||||
jsdisp_release(&function->dispex);
|
||||
}
|
||||
jsdisp_release(prototype);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -532,23 +530,28 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT init_function_constr(script_ctx_t *ctx)
|
||||
HRESULT init_function_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
|
||||
{
|
||||
FunctionInstance *prot, *constr;
|
||||
HRESULT hres;
|
||||
|
||||
hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, NULL, &prot);
|
||||
hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, object_prototype, &prot);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
prot->value_proc = FunctionProt_value;
|
||||
|
||||
hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, &prot->dispex, &constr);
|
||||
if(SUCCEEDED(hres)) {
|
||||
constr->value_proc = FunctionConstr_value;
|
||||
hres = set_prototype(ctx, &constr->dispex, &prot->dispex);
|
||||
if(FAILED(hres))
|
||||
jsdisp_release(&constr->dispex);
|
||||
}
|
||||
jsdisp_release(&prot->dispex);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
constr->value_proc = FunctionConstr_value;
|
||||
ctx->function_constr = &constr->dispex;
|
||||
return hres;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "wine/port.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "jscript.h"
|
||||
#include "engine.h"
|
||||
|
@ -28,11 +29,20 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
|
||||
|
||||
#define LONGLONG_MAX (((LONGLONG)0x7fffffff<<32)|0xffffffff)
|
||||
|
||||
static const WCHAR NaNW[] = {'N','a','N',0};
|
||||
static const WCHAR InfinityW[] = {'I','n','f','i','n','i','t','y',0};
|
||||
static const WCHAR ArrayW[] = {'A','r','r','a','y',0};
|
||||
static const WCHAR BooleanW[] = {'B','o','o','l','e','a','n',0};
|
||||
static const WCHAR DateW[] = {'D','a','t','e',0};
|
||||
static const WCHAR ErrorW[] = {'E','r','r','o','r',0};
|
||||
static const WCHAR EvalErrorW[] = {'E','v','a','l','E','r','r','o','r',0};
|
||||
static const WCHAR RangeErrorW[] = {'R','a','n','g','e','E','r','r','o','r',0};
|
||||
static const WCHAR ReferenceErrorW[] = {'R','e','f','e','r','e','n','c','e','E','r','r','o','r',0};
|
||||
static const WCHAR SyntaxErrorW[] = {'S','y','n','t','a','x','E','r','r','o','r',0};
|
||||
static const WCHAR TypeErrorW[] = {'T','y','p','e','E','r','r','o','r',0};
|
||||
static const WCHAR URIErrorW[] = {'U','R','I','E','r','r','o','r',0};
|
||||
static const WCHAR FunctionW[] = {'F','u','n','c','t','i','o','n',0};
|
||||
static const WCHAR NumberW[] = {'N','u','m','b','e','r',0};
|
||||
static const WCHAR ObjectW[] = {'O','b','j','e','c','t',0};
|
||||
|
@ -165,6 +175,62 @@ static HRESULT JSGlobal_Date(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARA
|
|||
return constructor_call(dispex->ctx->date_constr, lcid, flags, dp, retv, ei, sp);
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_Error(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
return constructor_call(dispex->ctx->error_constr, lcid, flags, dp, retv, ei, sp);
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_EvalError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
return constructor_call(dispex->ctx->eval_error_constr, lcid, flags, dp, retv, ei, sp);
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_RangeError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
return constructor_call(dispex->ctx->range_error_constr, lcid, flags, dp, retv, ei, sp);
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_ReferenceError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
return constructor_call(dispex->ctx->reference_error_constr, lcid, flags, dp, retv, ei, sp);
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_SyntaxError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
return constructor_call(dispex->ctx->syntax_error_constr, lcid, flags, dp, retv, ei, sp);
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_TypeError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
return constructor_call(dispex->ctx->type_error_constr, lcid, flags, dp, retv, ei, sp);
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_URIError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
return constructor_call(dispex->ctx->uri_error_constr, lcid, flags, dp, retv, ei, sp);
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_Function(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
|
@ -267,7 +333,7 @@ static HRESULT JSGlobal_eval(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARA
|
|||
hres = script_parse(dispex->ctx, V_BSTR(arg), NULL, &parser_ctx);
|
||||
if(FAILED(hres)) {
|
||||
WARN("parse (%s) failed: %08x\n", debugstr_w(V_BSTR(arg)), hres);
|
||||
return hres;
|
||||
return throw_syntax_error(dispex->ctx, ei, hres, NULL);
|
||||
}
|
||||
|
||||
hres = exec_source(dispex->ctx->exec_ctx, parser_ctx, parser_ctx->source, ei, retv);
|
||||
|
@ -411,8 +477,103 @@ static HRESULT JSGlobal_parseInt(DispatchEx *dispex, LCID lcid, WORD flags, DISP
|
|||
static HRESULT JSGlobal_parseFloat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
LONGLONG d = 0, hlp;
|
||||
int exp = 0, length;
|
||||
VARIANT *arg;
|
||||
WCHAR *str;
|
||||
BSTR val_str = NULL;
|
||||
BOOL ret_nan = TRUE, positive = TRUE;
|
||||
HRESULT hres;
|
||||
|
||||
if(!arg_cnt(dp)) {
|
||||
if(retv)
|
||||
num_set_nan(retv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
arg = get_arg(dp, 0);
|
||||
hres = to_string(dispex->ctx, arg, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
|
||||
while(isspaceW(*str)) str++;
|
||||
|
||||
if(*str == '+')
|
||||
str++;
|
||||
else if(*str == '-') {
|
||||
positive = FALSE;
|
||||
str++;
|
||||
}
|
||||
|
||||
if(isdigitW(*str))
|
||||
ret_nan = FALSE;
|
||||
|
||||
while(isdigitW(*str)) {
|
||||
hlp = d*10 + *(str++) - '0';
|
||||
if(d>LONGLONG_MAX/10 || hlp<0) {
|
||||
exp++;
|
||||
break;
|
||||
}
|
||||
else
|
||||
d = hlp;
|
||||
}
|
||||
while(isdigitW(*str)) {
|
||||
exp++;
|
||||
str++;
|
||||
}
|
||||
|
||||
if(*str == '.') str++;
|
||||
|
||||
if(isdigitW(*str))
|
||||
ret_nan = FALSE;
|
||||
|
||||
while(isdigitW(*str)) {
|
||||
hlp = d*10 + *(str++) - '0';
|
||||
if(d>LONGLONG_MAX/10 || hlp<0)
|
||||
break;
|
||||
|
||||
d = hlp;
|
||||
exp--;
|
||||
}
|
||||
while(isdigitW(*str))
|
||||
str++;
|
||||
|
||||
if(*str && !ret_nan && (*str=='e' || *str=='E')) {
|
||||
int sign = 1, e = 0;
|
||||
|
||||
str++;
|
||||
if(*str == '+')
|
||||
str++;
|
||||
else if(*str == '-') {
|
||||
sign = -1;
|
||||
str++;
|
||||
}
|
||||
|
||||
while(isdigitW(*str)) {
|
||||
if(e>INT_MAX/10 || (e = e*10 + *str++ - '0')<0)
|
||||
e = INT_MAX;
|
||||
}
|
||||
e *= sign;
|
||||
|
||||
if(exp<0 && e<0 && exp+e>0) exp = INT_MIN;
|
||||
else if(exp>0 && e>0 && exp+e<0) exp = INT_MAX;
|
||||
else exp += e;
|
||||
}
|
||||
|
||||
SysFreeString(val_str);
|
||||
|
||||
if(ret_nan) {
|
||||
if(retv)
|
||||
num_set_nan(retv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
V_VT(retv) = VT_R8;
|
||||
V_R8(retv) = (double)(positive?d:-d)*pow(10, exp);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_unescape(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
|
@ -541,6 +702,8 @@ static const builtin_prop_t JSGlobal_props[] = {
|
|||
{CollectGarbageW, JSGlobal_CollectGarbage, PROPF_METHOD},
|
||||
{DateW, JSGlobal_Date, PROPF_CONSTR},
|
||||
{EnumeratorW, JSGlobal_Enumerator, PROPF_METHOD},
|
||||
{ErrorW, JSGlobal_Error, PROPF_CONSTR},
|
||||
{EvalErrorW, JSGlobal_EvalError, PROPF_CONSTR},
|
||||
{FunctionW, JSGlobal_Function, PROPF_CONSTR},
|
||||
{_GetObjectW, JSGlobal_GetObject, PROPF_METHOD},
|
||||
{InfinityW, JSGlobal_Infinity, 0},
|
||||
|
@ -548,12 +711,17 @@ static const builtin_prop_t JSGlobal_props[] = {
|
|||
{NaNW, JSGlobal_NaN, 0},
|
||||
{NumberW, JSGlobal_Number, PROPF_CONSTR},
|
||||
{ObjectW, JSGlobal_Object, PROPF_CONSTR},
|
||||
{RangeErrorW, JSGlobal_RangeError, PROPF_CONSTR},
|
||||
{ReferenceErrorW, JSGlobal_ReferenceError, PROPF_CONSTR},
|
||||
{RegExpW, JSGlobal_RegExp, PROPF_CONSTR},
|
||||
{ScriptEngineW, JSGlobal_ScriptEngine, PROPF_METHOD},
|
||||
{ScriptEngineBuildVersionW, JSGlobal_ScriptEngineBuildVersion, PROPF_METHOD},
|
||||
{ScriptEngineMajorVersionW, JSGlobal_ScriptEngineMajorVersion, PROPF_METHOD},
|
||||
{ScriptEngineMinorVersionW, JSGlobal_ScriptEngineMinorVersion, PROPF_METHOD},
|
||||
{StringW, JSGlobal_String, PROPF_CONSTR},
|
||||
{SyntaxErrorW, JSGlobal_SyntaxError, PROPF_CONSTR},
|
||||
{TypeErrorW, JSGlobal_TypeError, PROPF_CONSTR},
|
||||
{URIErrorW, JSGlobal_URIError, PROPF_CONSTR},
|
||||
{VBArrayW, JSGlobal_VBArray, PROPF_METHOD},
|
||||
{encodeURIW, JSGlobal_encodeURI, PROPF_METHOD},
|
||||
{escapeW, JSGlobal_escape, PROPF_METHOD},
|
||||
|
@ -574,11 +742,15 @@ static const builtin_info_t JSGlobal_info = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static HRESULT init_constructors(script_ctx_t *ctx)
|
||||
static HRESULT init_constructors(script_ctx_t *ctx, DispatchEx *object_prototype)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
hres = init_function_constr(ctx);
|
||||
hres = init_function_constr(ctx, object_prototype);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_object_constr(ctx, object_prototype, &ctx->object_constr);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -594,11 +766,11 @@ static HRESULT init_constructors(script_ctx_t *ctx)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_number_constr(ctx, &ctx->number_constr);
|
||||
hres = init_error_constr(ctx);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_object_constr(ctx, &ctx->object_constr);
|
||||
hres = create_number_constr(ctx, &ctx->number_constr);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -615,14 +787,19 @@ static HRESULT init_constructors(script_ctx_t *ctx)
|
|||
|
||||
HRESULT init_global(script_ctx_t *ctx)
|
||||
{
|
||||
DispatchEx *math;
|
||||
DispatchEx *math, *object_prototype;
|
||||
VARIANT var;
|
||||
HRESULT hres;
|
||||
|
||||
if(ctx->global)
|
||||
return S_OK;
|
||||
|
||||
hres = init_constructors(ctx);
|
||||
hres = create_object_prototype(ctx, &object_prototype);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = init_constructors(ctx, object_prototype);
|
||||
jsdisp_release(object_prototype);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
|
|
@ -28,9 +28,13 @@
|
|||
#include "dispex.h"
|
||||
#include "activscp.h"
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
#define JSCRIPT_ERROR 0x800A0000
|
||||
|
||||
typedef struct _script_ctx_t script_ctx_t;
|
||||
typedef struct _exec_ctx_t exec_ctx_t;
|
||||
typedef struct _dispex_prop_t dispex_prop_t;
|
||||
|
@ -58,6 +62,8 @@ jsheap_t *jsheap_mark(jsheap_t*);
|
|||
|
||||
typedef struct DispatchEx DispatchEx;
|
||||
|
||||
extern HINSTANCE jscript_hinstance;
|
||||
|
||||
#define PROPF_ARGMASK 0x00ff
|
||||
#define PROPF_METHOD 0x0100
|
||||
#define PROPF_ENUM 0x0200
|
||||
|
@ -68,6 +74,7 @@ typedef enum {
|
|||
JSCLASS_ARRAY,
|
||||
JSCLASS_BOOLEAN,
|
||||
JSCLASS_DATE,
|
||||
JSCLASS_ERROR,
|
||||
JSCLASS_FUNCTION,
|
||||
JSCLASS_GLOBAL,
|
||||
JSCLASS_MATH,
|
||||
|
@ -123,6 +130,7 @@ DispatchEx *iface_to_jsdisp(IUnknown*);
|
|||
|
||||
HRESULT disp_call(IDispatch*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT jsdisp_call_value(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT jsdisp_call(DispatchEx*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT jsdisp_propget(DispatchEx*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
|
@ -131,11 +139,19 @@ HRESULT jsdisp_propput_idx(DispatchEx*,DWORD,LCID,VARIANT*,jsexcept_t*,IServiceP
|
|||
HRESULT jsdisp_propget_name(DispatchEx*,LPCWSTR,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT jsdisp_propget_idx(DispatchEx*,DWORD,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT jsdisp_get_id(DispatchEx*,const WCHAR*,DWORD,DISPID*);
|
||||
HRESULT jsdisp_delete_idx(DispatchEx*,DWORD);
|
||||
|
||||
HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const builtin_info_t*,DWORD,
|
||||
DispatchEx*,DispatchEx**);
|
||||
HRESULT Function_value(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
|
||||
HRESULT throw_eval_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
|
||||
HRESULT throw_range_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
|
||||
HRESULT throw_reference_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
|
||||
HRESULT throw_syntax_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
|
||||
HRESULT throw_type_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
|
||||
HRESULT throw_uri_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
|
||||
|
||||
|
||||
HRESULT create_object(script_ctx_t*,DispatchEx*,DispatchEx**);
|
||||
HRESULT create_math(script_ctx_t*,DispatchEx**);
|
||||
|
@ -145,7 +161,13 @@ HRESULT create_string(script_ctx_t*,const WCHAR*,DWORD,DispatchEx**);
|
|||
HRESULT create_bool(script_ctx_t*,VARIANT_BOOL,DispatchEx**);
|
||||
HRESULT create_number(script_ctx_t*,VARIANT*,DispatchEx**);
|
||||
|
||||
HRESULT to_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
|
||||
typedef enum {
|
||||
NO_HINT,
|
||||
HINT_STRING,
|
||||
HINT_NUMBER
|
||||
} hint_t;
|
||||
|
||||
HRESULT to_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*, hint_t);
|
||||
HRESULT to_boolean(VARIANT*,VARIANT_BOOL*);
|
||||
HRESULT to_number(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
|
||||
HRESULT to_integer(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
|
||||
|
@ -179,6 +201,13 @@ struct _script_ctx_t {
|
|||
DispatchEx *array_constr;
|
||||
DispatchEx *bool_constr;
|
||||
DispatchEx *date_constr;
|
||||
DispatchEx *error_constr;
|
||||
DispatchEx *eval_error_constr;
|
||||
DispatchEx *range_error_constr;
|
||||
DispatchEx *reference_error_constr;
|
||||
DispatchEx *syntax_error_constr;
|
||||
DispatchEx *type_error_constr;
|
||||
DispatchEx *uri_error_constr;
|
||||
DispatchEx *number_constr;
|
||||
DispatchEx *object_constr;
|
||||
DispatchEx *regexp_constr;
|
||||
|
@ -193,13 +222,15 @@ static inline void script_addref(script_ctx_t *ctx)
|
|||
}
|
||||
|
||||
HRESULT init_global(script_ctx_t*);
|
||||
HRESULT init_function_constr(script_ctx_t*);
|
||||
HRESULT init_function_constr(script_ctx_t*,DispatchEx*);
|
||||
HRESULT create_object_prototype(script_ctx_t*,DispatchEx**);
|
||||
|
||||
HRESULT create_array_constr(script_ctx_t*,DispatchEx**);
|
||||
HRESULT create_bool_constr(script_ctx_t*,DispatchEx**);
|
||||
HRESULT create_date_constr(script_ctx_t*,DispatchEx**);
|
||||
HRESULT init_error_constr(script_ctx_t*);
|
||||
HRESULT create_number_constr(script_ctx_t*,DispatchEx**);
|
||||
HRESULT create_object_constr(script_ctx_t*,DispatchEx**);
|
||||
HRESULT create_object_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
|
||||
HRESULT create_regexp_constr(script_ctx_t*,DispatchEx**);
|
||||
HRESULT create_string_constr(script_ctx_t*,DispatchEx**);
|
||||
|
||||
|
|
|
@ -10,11 +10,13 @@
|
|||
<dependency>jsglobal</dependency>
|
||||
<library>wine</library>
|
||||
<library>kernel32</library>
|
||||
<library>user32</library>
|
||||
<library>oleaut32</library>
|
||||
<library>advapi32</library>
|
||||
<file>date.c</file>
|
||||
<file>dispex.c</file>
|
||||
<file>engine.c</file>
|
||||
<file>error.c</file>
|
||||
<file>jscript.c</file>
|
||||
<file>jscript_main.c</file>
|
||||
<file>jsutils.c</file>
|
||||
|
|
43
reactos/dll/win32/jscript/jscript_De.rc
Normal file
43
reactos/dll/win32/jscript/jscript_De.rc
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2009 André Hentschel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#pragma code_page(65001)
|
||||
|
||||
LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_TO_PRIMITIVE "Fehler beim umwandeln des Objektes in einen Grundtyp"
|
||||
IDS_INVALID_CALL_ARG "Ungültiger Funktionsaufruf oder Argument"
|
||||
IDS_NO_PROPERTY "Das Objekt unterstützt diese Eigenschaft oder Methode nicht"
|
||||
IDS_ARG_NOT_OPT "Argument nicht optional"
|
||||
IDS_SYNTAX_ERROR "Syntax Fehler"
|
||||
IDS_SEMICOLON "';' erwartet"
|
||||
IDS_LBRACKET "'(' erwartet"
|
||||
IDS_RBRACKET "')' erwartet"
|
||||
IDS_UNTERMINATED_STR "konstante Zeichenkette nicht terminiert"
|
||||
IDS_NOT_FUNC "Funktion erwartet"
|
||||
IDS_NOT_DATE "'[Objekt]' ist kein Datums-Objekt"
|
||||
IDS_NOT_NUM "Nummer erwartet"
|
||||
IDS_ILLEGAL_ASSIGN "Unzulässige Zuweisung"
|
||||
IDS_UNDEFINED "'|' nicht definiert"
|
||||
IDS_NOT_BOOL "Boolisches Objekt erwartet"
|
||||
IDS_INVALID_LENGTH "Array-Größe muss eine endliche, positive Ganzzahl sein"
|
||||
}
|
41
reactos/dll/win32/jscript/jscript_En.rc
Normal file
41
reactos/dll/win32/jscript/jscript_En.rc
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2009 Piotr Caban
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_TO_PRIMITIVE "Error converting object to primitive type"
|
||||
IDS_INVALID_CALL_ARG "Invalid procedure call or argument"
|
||||
IDS_NO_PROPERTY "Object doesn't support this property or method"
|
||||
IDS_ARG_NOT_OPT "Argument not optional"
|
||||
IDS_SYNTAX_ERROR "Syntax error"
|
||||
IDS_SEMICOLON "Expected ';'"
|
||||
IDS_LBRACKET "Expected '('"
|
||||
IDS_RBRACKET "Expected ')'"
|
||||
IDS_UNTERMINATED_STR "Unterminated string constant"
|
||||
IDS_NOT_FUNC "Function expected"
|
||||
IDS_NOT_DATE "'[object]' is not a date object"
|
||||
IDS_NOT_NUM "Number expected"
|
||||
IDS_ILLEGAL_ASSIGN "Illegal assignment"
|
||||
IDS_UNDEFINED "'|' is undefined"
|
||||
IDS_NOT_BOOL "Boolean object expected"
|
||||
IDS_INVALID_LENGTH "Array length must be a finite positive integer"
|
||||
}
|
46
reactos/dll/win32/jscript/jscript_Fr.rc
Normal file
46
reactos/dll/win32/jscript/jscript_Fr.rc
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* French resources for jscript
|
||||
*
|
||||
* Copyright 2009 Frédéric Delanoy
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
/* UTF-8 */
|
||||
#pragma code_page(65001)
|
||||
|
||||
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_TO_PRIMITIVE "Erreur lors de la conversion de l'objet vers un type primitif"
|
||||
IDS_INVALID_CALL_ARG "Appel de procédure ou argument invalide"
|
||||
IDS_NO_PROPERTY "Cet objet ne supporte pas cette propriété ou méthode"
|
||||
IDS_ARG_NOT_OPT "Argument non optionnel"
|
||||
IDS_SYNTAX_ERROR "Erreur de syntaxe"
|
||||
IDS_SEMICOLON "« ; » attendu"
|
||||
IDS_LBRACKET "« ( » attendu"
|
||||
IDS_RBRACKET "« ) » attendu"
|
||||
IDS_UNTERMINATED_STR "Constante chaîne de caractères non clôturée"
|
||||
IDS_NOT_FUNC "Fonction attendue"
|
||||
IDS_NOT_DATE "« [objet] » n'est pas un objet de type date"
|
||||
IDS_NOT_NUM "Nombre attendu"
|
||||
IDS_ILLEGAL_ASSIGN "Affectation illégale"
|
||||
IDS_UNDEFINED "« | » n'est pas défini"
|
||||
IDS_NOT_BOOL "Booléen attendu"
|
||||
IDS_INVALID_LENGTH "La longueur d'un tableau doit être un entier positif"
|
||||
}
|
44
reactos/dll/win32/jscript/jscript_Lt.rc
Normal file
44
reactos/dll/win32/jscript/jscript_Lt.rc
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2009 Aurimas Fišeras <aurimas@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
/* UTF-8 */
|
||||
#pragma code_page(65001)
|
||||
|
||||
LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_TO_PRIMITIVE "Klaida keičiant objektą į primityvų tipą"
|
||||
IDS_INVALID_CALL_ARG "Netinkamas kreipinys į procedūrą ar argumentas"
|
||||
IDS_NO_PROPERTY "Objektas nepalaiko šios savybės ar metodo"
|
||||
IDS_ARG_NOT_OPT "Argumentas nėra neprivalomas"
|
||||
IDS_SYNTAX_ERROR "Sintaksės klaida"
|
||||
IDS_SEMICOLON "Tikėtasi „;“"
|
||||
IDS_LBRACKET "Tikėtasi „(“"
|
||||
IDS_RBRACKET "Tikėtasi „)“"
|
||||
IDS_UNTERMINATED_STR "Nebaigta eilutės konstanta"
|
||||
IDS_NOT_FUNC "Tikėtasi funkcijos"
|
||||
IDS_NOT_DATE "„[objektas]“ nėra datos objektas"
|
||||
IDS_NOT_NUM "Tikėtasi skaičiaus"
|
||||
IDS_ILLEGAL_ASSIGN "Neleistinas priskyrimas"
|
||||
IDS_UNDEFINED "„|“ yra neapibrėžtas"
|
||||
IDS_NOT_BOOL "Tikėtasi loginio objekto"
|
||||
IDS_INVALID_LENGTH "Masyvo dydis turi būti teigiamas sveikasis skaičius"
|
||||
}
|
40
reactos/dll/win32/jscript/jscript_Nl.rc
Normal file
40
reactos/dll/win32/jscript/jscript_Nl.rc
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2009 Paul Vriens
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_TO_PRIMITIVE "Fout bij het omzetten van het object naar een primitief type"
|
||||
IDS_INVALID_CALL_ARG "Ongeldige procedure-aanroep of argument"
|
||||
IDS_NO_PROPERTY "Dit object ondersteunt deze eigenschap of methode niet"
|
||||
IDS_ARG_NOT_OPT "Argument is niet optioneel"
|
||||
IDS_SYNTAX_ERROR "Syntax fout"
|
||||
IDS_SEMICOLON "';' verwacht"
|
||||
IDS_LBRACKET "'(' verwacht"
|
||||
IDS_RBRACKET "')' verwacht"
|
||||
IDS_NOT_FUNC "Functie verwacht"
|
||||
IDS_NOT_DATE "'[object]' is geen datum object"
|
||||
IDS_NOT_NUM "Getal verwacht"
|
||||
IDS_ILLEGAL_ASSIGN "Ongeldige toekenning"
|
||||
IDS_UNDEFINED "'|' is ongedefinieerd"
|
||||
IDS_NOT_BOOL "Boolean object verwacht"
|
||||
IDS_INVALID_LENGTH "Array lengte moet een eindig, positief geheel getal zijn"
|
||||
}
|
42
reactos/dll/win32/jscript/jscript_Pt.rc
Normal file
42
reactos/dll/win32/jscript/jscript_Pt.rc
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2009 Ricardo Filipe
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#pragma code_page(65001)
|
||||
|
||||
LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_TO_PRIMITIVE "Erro ao converter objecto em tipo primitivo"
|
||||
IDS_INVALID_CALL_ARG "Argumento ou chamada de procedimento inválida"
|
||||
IDS_NO_PROPERTY "O objecto não suporta esta propriedade ou método"
|
||||
IDS_ARG_NOT_OPT "Argumento não opcional"
|
||||
IDS_SYNTAX_ERROR "Erro de sintaxe"
|
||||
IDS_SEMICOLON "';' esperado"
|
||||
IDS_LBRACKET "'(' esperado"
|
||||
IDS_RBRACKET "')' esperado"
|
||||
IDS_NOT_FUNC "Função esperada"
|
||||
IDS_NOT_DATE "'[object]' não é um objecto de data"
|
||||
IDS_NOT_NUM "Número esperado"
|
||||
IDS_ILLEGAL_ASSIGN "Atribuição ilegal"
|
||||
IDS_UNDEFINED "'|' é indefinido"
|
||||
IDS_NOT_BOOL "Objecto boleano esperado"
|
||||
IDS_INVALID_LENGTH "Tamanho do vector tem de ser um inteiro finito positivo"
|
||||
}
|
|
@ -40,7 +40,7 @@ static const CLSID CLSID_JScriptEncode =
|
|||
|
||||
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
|
||||
|
||||
static HINSTANCE jscript_hinstance;
|
||||
HINSTANCE jscript_hinstance;
|
||||
|
||||
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
|
|
|
@ -175,7 +175,7 @@ jsheap_t *jsheap_mark(jsheap_t *heap)
|
|||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 9.1 */
|
||||
HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret)
|
||||
HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret, hint_t hint)
|
||||
{
|
||||
switch(V_VT(v)) {
|
||||
case VT_EMPTY:
|
||||
|
@ -189,8 +189,61 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret
|
|||
V_VT(ret) = VT_BSTR;
|
||||
V_BSTR(ret) = SysAllocString(V_BSTR(v));
|
||||
break;
|
||||
case VT_DISPATCH:
|
||||
return disp_propget(V_DISPATCH(v), DISPID_VALUE, ctx->lcid, ret, ei, NULL /*FIXME*/);
|
||||
case VT_DISPATCH: {
|
||||
DispatchEx *jsdisp;
|
||||
DISPID id;
|
||||
DISPPARAMS dp = {NULL, NULL, 0, 0};
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
|
||||
static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
|
||||
|
||||
jsdisp = iface_to_jsdisp((IUnknown*)V_DISPATCH(v));
|
||||
if(!jsdisp)
|
||||
return disp_propget(V_DISPATCH(v), DISPID_VALUE, ctx->lcid, ret, ei, NULL /*FIXME*/);
|
||||
|
||||
if(hint == NO_HINT)
|
||||
hint = is_class(jsdisp, JSCLASS_DATE) ? HINT_STRING : HINT_NUMBER;
|
||||
|
||||
/* Native implementation doesn't throw TypeErrors, returns strange values */
|
||||
|
||||
hres = jsdisp_get_id(jsdisp, hint == HINT_STRING ? toStringW : valueOfW, 0, &id);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = jsdisp_call(jsdisp, id, ctx->lcid, DISPATCH_METHOD, &dp, ret, ei, NULL /*FIXME*/);
|
||||
if(FAILED(hres)) {
|
||||
WARN("call error - forwarding exception\n");
|
||||
jsdisp_release(jsdisp);
|
||||
return hres;
|
||||
}
|
||||
else if(V_VT(ret) != VT_DISPATCH) {
|
||||
jsdisp_release(jsdisp);
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
IDispatch_Release(V_DISPATCH(ret));
|
||||
}
|
||||
|
||||
hres = jsdisp_get_id(jsdisp, hint == HINT_STRING ? valueOfW : toStringW, 0, &id);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = jsdisp_call(jsdisp, id, ctx->lcid, DISPATCH_METHOD, &dp, ret, ei, NULL /*FIXME*/);
|
||||
if(FAILED(hres)) {
|
||||
WARN("call error - forwarding exception\n");
|
||||
jsdisp_release(jsdisp);
|
||||
return hres;
|
||||
}
|
||||
else if(V_VT(ret) != VT_DISPATCH) {
|
||||
jsdisp_release(jsdisp);
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
IDispatch_Release(V_DISPATCH(ret));
|
||||
}
|
||||
|
||||
jsdisp_release(jsdisp);
|
||||
|
||||
WARN("failed\n");
|
||||
return throw_type_error(ctx, ei, IDS_TO_PRIMITIVE, NULL);
|
||||
}
|
||||
default:
|
||||
FIXME("Unimplemented for vt %d\n", V_VT(v));
|
||||
return E_NOTIMPL;
|
||||
|
@ -211,7 +264,8 @@ HRESULT to_boolean(VARIANT *v, VARIANT_BOOL *b)
|
|||
*b = V_I4(v) ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
break;
|
||||
case VT_R8:
|
||||
*b = V_R8(v) ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
if(isnan(V_R8(v))) *b = VARIANT_FALSE;
|
||||
else *b = V_R8(v) ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
break;
|
||||
case VT_BSTR:
|
||||
*b = V_BSTR(v) && *V_BSTR(v) ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
|
@ -355,7 +409,7 @@ HRESULT to_number(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret)
|
|||
VARIANT prim;
|
||||
HRESULT hres;
|
||||
|
||||
hres = to_primitive(ctx, v, ei, &prim);
|
||||
hres = to_primitive(ctx, v, ei, &prim, HINT_NUMBER);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -458,6 +512,8 @@ HRESULT to_string(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, BSTR *str)
|
|||
const WCHAR nullW[] = {'n','u','l','l',0};
|
||||
const WCHAR trueW[] = {'t','r','u','e',0};
|
||||
const WCHAR falseW[] = {'f','a','l','s','e',0};
|
||||
const WCHAR NaNW[] = {'N','a','N',0};
|
||||
const WCHAR InfinityW[] = {'-','I','n','f','i','n','i','t','y',0};
|
||||
|
||||
switch(V_VT(v)) {
|
||||
case VT_EMPTY:
|
||||
|
@ -470,16 +526,23 @@ HRESULT to_string(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, BSTR *str)
|
|||
*str = int_to_bstr(V_I4(v));
|
||||
break;
|
||||
case VT_R8: {
|
||||
VARIANT strv;
|
||||
HRESULT hres;
|
||||
if(isnan(V_R8(v)))
|
||||
*str = SysAllocString(NaNW);
|
||||
else if(isinf(V_R8(v)))
|
||||
*str = SysAllocString(V_R8(v)<0 ? InfinityW : InfinityW+1);
|
||||
else {
|
||||
VARIANT strv;
|
||||
HRESULT hres;
|
||||
|
||||
V_VT(&strv) = VT_EMPTY;
|
||||
hres = VariantChangeTypeEx(&strv, v, MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT), 0, VT_BSTR);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
V_VT(&strv) = VT_EMPTY;
|
||||
hres = VariantChangeTypeEx(&strv, v, MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT), 0, VT_BSTR);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*str = V_BSTR(&strv);
|
||||
return S_OK;
|
||||
*str = V_BSTR(&strv);
|
||||
return S_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VT_BSTR:
|
||||
*str = SysAllocString(V_BSTR(v));
|
||||
|
@ -488,7 +551,7 @@ HRESULT to_string(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, BSTR *str)
|
|||
VARIANT prim;
|
||||
HRESULT hres;
|
||||
|
||||
hres = to_primitive(ctx, v, ei, &prim);
|
||||
hres = to_primitive(ctx, v, ei, &prim, HINT_STRING);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
|
|
@ -100,7 +100,8 @@ static const struct {
|
|||
|
||||
static int lex_error(parser_ctx_t *ctx, HRESULT hres)
|
||||
{
|
||||
ctx->hres = hres;
|
||||
ctx->hres = JSCRIPT_ERROR|hres;
|
||||
ctx->lexer_error = TRUE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -342,10 +343,8 @@ static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret, WCHAR endc
|
|||
ctx->ptr++;
|
||||
}
|
||||
|
||||
if(ctx->ptr == ctx->end) {
|
||||
WARN("unexpected end of file\n");
|
||||
return lex_error(ctx, E_FAIL);
|
||||
}
|
||||
if(ctx->ptr == ctx->end)
|
||||
return lex_error(ctx, IDS_UNTERMINATED_STR);
|
||||
|
||||
len = ctx->ptr-ptr;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2008 Jacek Caban for CodeWeavers
|
||||
* Copyright 2009 Piotr Caban
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "jscript.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
@ -39,31 +41,126 @@ static const WCHAR propertyIsEnumerableW[] =
|
|||
{'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0};
|
||||
static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
|
||||
|
||||
#define NUMBER_TOSTRING_BUF_SIZE 64
|
||||
/* ECMA-262 3rd Edition 15.7.4.2 */
|
||||
static HRESULT Number_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
NumberInstance *number;
|
||||
INT radix = 10;
|
||||
DOUBLE val;
|
||||
BSTR str;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(!is_class(dispex, JSCLASS_NUMBER)) {
|
||||
FIXME("throw TypeError\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
if(!is_class(dispex, JSCLASS_NUMBER))
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_NUM, NULL);
|
||||
|
||||
number = (NumberInstance*)dispex;
|
||||
|
||||
if(arg_cnt(dp) != 0) {
|
||||
FIXME("unsupported args\n");
|
||||
return E_NOTIMPL;
|
||||
if(arg_cnt(dp)) {
|
||||
hres = to_int32(dispex->ctx, get_arg(dp, 0), ei, &radix);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(radix<2 || radix>36)
|
||||
return throw_type_error(dispex->ctx, ei, IDS_INVALID_CALL_ARG, NULL);
|
||||
}
|
||||
|
||||
hres = to_string(dispex->ctx, &number->num, ei, &str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(V_VT(&number->num) == VT_I4)
|
||||
val = V_I4(&number->num);
|
||||
else
|
||||
val = V_R8(&number->num);
|
||||
|
||||
if(radix==10 || isnan(val) || isinf(val)) {
|
||||
hres = to_string(dispex->ctx, &number->num, ei, &str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
else {
|
||||
INT idx = 0;
|
||||
DOUBLE integ, frac, log_radix = 0;
|
||||
WCHAR buf[NUMBER_TOSTRING_BUF_SIZE+16];
|
||||
BOOL exp = FALSE;
|
||||
|
||||
if(val<0) {
|
||||
val = -val;
|
||||
buf[idx++] = '-';
|
||||
}
|
||||
|
||||
while(1) {
|
||||
integ = floor(val);
|
||||
frac = val-integ;
|
||||
|
||||
if(integ == 0)
|
||||
buf[idx++] = '0';
|
||||
while(integ>=1 && idx<NUMBER_TOSTRING_BUF_SIZE) {
|
||||
buf[idx] = fmod(integ, radix);
|
||||
if(buf[idx]<10) buf[idx] += '0';
|
||||
else buf[idx] += 'a'-10;
|
||||
integ /= radix;
|
||||
idx++;
|
||||
}
|
||||
|
||||
if(idx<NUMBER_TOSTRING_BUF_SIZE) {
|
||||
INT beg = buf[0]=='-'?1:0;
|
||||
INT end = idx-1;
|
||||
WCHAR wch;
|
||||
|
||||
while(end > beg) {
|
||||
wch = buf[beg];
|
||||
buf[beg++] = buf[end];
|
||||
buf[end--] = wch;
|
||||
}
|
||||
}
|
||||
|
||||
if(idx != NUMBER_TOSTRING_BUF_SIZE) buf[idx++] = '.';
|
||||
|
||||
while(frac>0 && idx<NUMBER_TOSTRING_BUF_SIZE) {
|
||||
frac *= radix;
|
||||
buf[idx] = fmod(frac, radix);
|
||||
frac -= buf[idx];
|
||||
if(buf[idx]<10) buf[idx] += '0';
|
||||
else buf[idx] += 'a'-10;
|
||||
idx++;
|
||||
}
|
||||
|
||||
if(idx==NUMBER_TOSTRING_BUF_SIZE && !exp) {
|
||||
exp = TRUE;
|
||||
idx = (buf[0]=='-') ? 1 : 0;
|
||||
log_radix = floor(log(val)/log(radix));
|
||||
val *= pow(radix, -log_radix);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
while(buf[idx-1] == '0') idx--;
|
||||
if(buf[idx-1] == '.') idx--;
|
||||
|
||||
if(exp) {
|
||||
if(log_radix==0)
|
||||
buf[idx++] = '\0';
|
||||
else {
|
||||
static const WCHAR formatW[] = {'(','e','%','c','%','d',')',0};
|
||||
WCHAR ch;
|
||||
|
||||
if(log_radix<0) {
|
||||
log_radix = -log_radix;
|
||||
ch = '-';
|
||||
}
|
||||
else ch = '+';
|
||||
sprintfW(&buf[idx], formatW, ch, (int)log_radix);
|
||||
}
|
||||
}
|
||||
else buf[idx] = '\0';
|
||||
|
||||
str = SysAllocString(buf);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
|
@ -107,10 +204,8 @@ static HRESULT Number_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
|
|||
{
|
||||
TRACE("\n");
|
||||
|
||||
if(!is_class(dispex, JSCLASS_NUMBER)) {
|
||||
FIXME("throw TypeError\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
if(!is_class(dispex, JSCLASS_NUMBER))
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_NUM, NULL);
|
||||
|
||||
if(retv) {
|
||||
NumberInstance *number = (NumberInstance*)dispex;
|
||||
|
@ -146,6 +241,8 @@ static HRESULT Number_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
NumberInstance *number = (NumberInstance*)dispex;
|
||||
|
||||
switch(flags) {
|
||||
case INVOKE_FUNC:
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
|
||||
case DISPATCH_PROPERTYGET:
|
||||
*retv = number->num;
|
||||
break;
|
||||
|
|
|
@ -35,22 +35,62 @@ static const WCHAR default_valueW[] = {'[','o','b','j','e','c','t',' ','O','b','
|
|||
static HRESULT Object_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
static const WCHAR formatW[] = {'[','o','b','j','e','c','t',' ','%','s',']',0};
|
||||
|
||||
static const WCHAR arrayW[] = {'A','r','r','a','y',0};
|
||||
static const WCHAR booleanW[] = {'B','o','o','l','e','a','n',0};
|
||||
static const WCHAR dateW[] = {'D','a','t','e',0};
|
||||
static const WCHAR errorW[] = {'E','r','r','o','r',0};
|
||||
static const WCHAR functionW[] = {'F','u','n','c','t','i','o','n',0};
|
||||
static const WCHAR mathW[] = {'M','a','t','h',0};
|
||||
static const WCHAR numberW[] = {'N','u','m','b','e','r',0};
|
||||
static const WCHAR objectW[] = {'O','b','j','e','c','t',0};
|
||||
static const WCHAR regexpW[] = {'R','e','g','E','x','p',0};
|
||||
static const WCHAR stringW[] = {'S','t','r','i','n','g',0};
|
||||
/* Keep in sync with jsclass_t enum */
|
||||
static const WCHAR *names[] = {NULL, arrayW, booleanW, dateW, errorW,
|
||||
functionW, NULL, mathW, numberW, objectW, regexpW, stringW};
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(names[dispex->builtin_info->class] == NULL) {
|
||||
ERR("dispex->builtin_info->class = %d\n",
|
||||
dispex->builtin_info->class);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = SysAllocStringLen(NULL, 9+strlenW(names[dispex->builtin_info->class]));
|
||||
if(!V_BSTR(retv))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
sprintfW(V_BSTR(retv), formatW, names[dispex->builtin_info->class]);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT Object_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
TRACE("\n");
|
||||
return Object_toString(dispex, lcid, flags, dp, retv, ei, sp);
|
||||
}
|
||||
|
||||
static HRESULT Object_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
TRACE("\n");
|
||||
|
||||
if(retv) {
|
||||
IDispatchEx_AddRef(_IDispatchEx_(dispex));
|
||||
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT Object_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
|
@ -80,6 +120,8 @@ static HRESULT Object_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case INVOKE_FUNC:
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
|
||||
case DISPATCH_PROPERTYGET:
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = SysAllocString(default_valueW);
|
||||
|
@ -145,19 +187,15 @@ static HRESULT ObjectConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DIS
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT create_object_constr(script_ctx_t *ctx, DispatchEx **ret)
|
||||
HRESULT create_object_constr(script_ctx_t *ctx, DispatchEx *object_prototype, DispatchEx **ret)
|
||||
{
|
||||
DispatchEx *object;
|
||||
HRESULT hres;
|
||||
return create_builtin_function(ctx, ObjectConstr_value, NULL, PROPF_CONSTR,
|
||||
object_prototype, ret);
|
||||
}
|
||||
|
||||
hres = create_dispex(ctx, &Object_info, NULL, &object);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_builtin_function(ctx, ObjectConstr_value, NULL, PROPF_CONSTR, object, ret);
|
||||
|
||||
jsdisp_release(object);
|
||||
return hres;
|
||||
HRESULT create_object_prototype(script_ctx_t *ctx, DispatchEx **ret)
|
||||
{
|
||||
return create_dispex(ctx, &Object_info, NULL, ret);
|
||||
}
|
||||
|
||||
HRESULT create_object(script_ctx_t *ctx, DispatchEx *constr, DispatchEx **ret)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -91,7 +91,7 @@ typedef union YYSTYPE
|
|||
{
|
||||
|
||||
/* Line 1676 of yacc.c */
|
||||
#line 149 "parser.y"
|
||||
#line 151 "parser.y"
|
||||
|
||||
int ival;
|
||||
const WCHAR *srcptr;
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#define YYPARSE_PARAM ctx
|
||||
|
||||
static int parser_error(const char*);
|
||||
static void set_error(parser_ctx_t*,UINT);
|
||||
static BOOL explicit_error(parser_ctx_t*,void*,WCHAR);
|
||||
static BOOL allow_auto_semicolon(parser_ctx_t*);
|
||||
static void program_parsed(parser_ctx_t*,source_elements_t*);
|
||||
static source_elements_t *function_body_parsed(parser_ctx_t*,source_elements_t*);
|
||||
|
@ -200,7 +202,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
|
|||
%type <statement> Finally
|
||||
%type <statement_list> StatementList StatementList_opt
|
||||
%type <parameter_list> FormalParameterList FormalParameterList_opt
|
||||
%type <expr> Expression Expression_opt
|
||||
%type <expr> Expression Expression_opt Expression_err
|
||||
%type <expr> ExpressionNoIn ExpressionNoIn_opt
|
||||
%type <expr> FunctionExpression
|
||||
%type <expr> AssignmentExpression AssignmentExpressionNoIn
|
||||
|
@ -266,7 +268,7 @@ SourceElements
|
|||
|
||||
/* ECMA-262 3rd Edition 13 */
|
||||
FunctionExpression
|
||||
: KFunction Identifier_opt '(' FormalParameterList_opt ')' '{' FunctionBody '}'
|
||||
: KFunction Identifier_opt left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}'
|
||||
{ $$ = new_function_expression(ctx, $2, $4, $7, $1, $8-$1+1); }
|
||||
|
||||
KFunction
|
||||
|
@ -379,24 +381,32 @@ ExpressionStatement
|
|||
|
||||
/* ECMA-262 3rd Edition 12.5 */
|
||||
IfStatement
|
||||
: kIF '(' Expression ')' Statement kELSE Statement
|
||||
: kIF left_bracket Expression_err right_bracket Statement kELSE Statement
|
||||
{ $$ = new_if_statement(ctx, $3, $5, $7); }
|
||||
| kIF '(' Expression ')' Statement %prec LOWER_THAN_ELSE
|
||||
| kIF left_bracket Expression_err right_bracket Statement %prec LOWER_THAN_ELSE
|
||||
{ $$ = new_if_statement(ctx, $3, $5, NULL); }
|
||||
|
||||
/* ECMA-262 3rd Edition 12.6 */
|
||||
IterationStatement
|
||||
: kDO Statement kWHILE '(' Expression ')' ';'
|
||||
: kDO Statement kWHILE left_bracket Expression_err right_bracket semicolon_opt
|
||||
{ $$ = new_while_statement(ctx, TRUE, $5, $2); }
|
||||
| kWHILE '(' Expression ')' Statement
|
||||
| kWHILE left_bracket Expression_err right_bracket Statement
|
||||
{ $$ = new_while_statement(ctx, FALSE, $3, $5); }
|
||||
| kFOR '(' ExpressionNoIn_opt ';' Expression_opt ';' Expression_opt ')' Statement
|
||||
{ $$ = new_for_statement(ctx, NULL, $3, $5, $7, $9); }
|
||||
| kFOR '(' kVAR VariableDeclarationListNoIn ';' Expression_opt ';' Expression_opt ')' Statement
|
||||
{ $$ = new_for_statement(ctx, $4, NULL, $6, $8, $10); }
|
||||
| kFOR '(' LeftHandSideExpression kIN Expression ')' Statement
|
||||
| kFOR left_bracket ExpressionNoIn_opt
|
||||
{ if(!explicit_error(ctx, $3, ';')) YYABORT; }
|
||||
semicolon Expression_opt
|
||||
{ if(!explicit_error(ctx, $6, ';')) YYABORT; }
|
||||
semicolon Expression_opt right_bracket Statement
|
||||
{ $$ = new_for_statement(ctx, NULL, $3, $6, $9, $11); }
|
||||
| kFOR left_bracket kVAR VariableDeclarationListNoIn
|
||||
{ if(!explicit_error(ctx, $4, ';')) YYABORT; }
|
||||
semicolon Expression_opt
|
||||
{ if(!explicit_error(ctx, $7, ';')) YYABORT; }
|
||||
semicolon Expression_opt right_bracket Statement
|
||||
{ $$ = new_for_statement(ctx, $4, NULL, $7, $10, $12); }
|
||||
| kFOR left_bracket LeftHandSideExpression kIN Expression_err right_bracket Statement
|
||||
{ $$ = new_forin_statement(ctx, NULL, $3, $5, $7); }
|
||||
| kFOR '(' kVAR VariableDeclarationNoIn kIN Expression ')' Statement
|
||||
| kFOR left_bracket kVAR VariableDeclarationNoIn kIN Expression_err right_bracket Statement
|
||||
{ $$ = new_forin_statement(ctx, $4, NULL, $6, $8); }
|
||||
|
||||
/* ECMA-262 3rd Edition 12.7 */
|
||||
|
@ -416,7 +426,7 @@ ReturnStatement
|
|||
|
||||
/* ECMA-262 3rd Edition 12.10 */
|
||||
WithStatement
|
||||
: kWITH '(' Expression ')' Statement
|
||||
: kWITH left_bracket Expression right_bracket Statement
|
||||
{ $$ = new_with_statement(ctx, $3, $5); }
|
||||
|
||||
/* ECMA-262 3rd Edition 12.12 */
|
||||
|
@ -426,8 +436,8 @@ LabelledStatement
|
|||
|
||||
/* ECMA-262 3rd Edition 12.11 */
|
||||
SwitchStatement
|
||||
: kSWITCH '(' Expression ')' CaseBlock
|
||||
{ $$ = new_switch_statement(ctx, $3, $5); }
|
||||
: kSWITCH left_bracket Expression right_bracket CaseBlock
|
||||
{ $$ = new_switch_statement(ctx, $3, $5); }
|
||||
|
||||
/* ECMA-262 3rd Edition 12.11 */
|
||||
CaseBlock
|
||||
|
@ -471,8 +481,8 @@ TryStatement
|
|||
|
||||
/* ECMA-262 3rd Edition 12.14 */
|
||||
Catch
|
||||
: kCATCH '(' tIdentifier ')' Block
|
||||
{ $$ = new_catch_block(ctx, $3, $5); }
|
||||
: kCATCH left_bracket tIdentifier right_bracket Block
|
||||
{ $$ = new_catch_block(ctx, $3, $5); }
|
||||
|
||||
/* ECMA-262 3rd Edition 12.14 */
|
||||
Finally
|
||||
|
@ -483,6 +493,10 @@ Expression_opt
|
|||
: /* empty */ { $$ = NULL; }
|
||||
| Expression { $$ = $1; }
|
||||
|
||||
Expression_err
|
||||
: Expression { $$ = $1; }
|
||||
| error { set_error(ctx, IDS_SYNTAX_ERROR); YYABORT; }
|
||||
|
||||
/* ECMA-262 3rd Edition 11.14 */
|
||||
Expression
|
||||
: AssignmentExpression { $$ = $1; }
|
||||
|
@ -796,6 +810,18 @@ semicolon_opt
|
|||
: ';'
|
||||
| error { if(!allow_auto_semicolon(ctx)) {YYABORT;} }
|
||||
|
||||
left_bracket
|
||||
: '('
|
||||
| error { set_error(ctx, IDS_LBRACKET); YYABORT; }
|
||||
|
||||
right_bracket
|
||||
: ')'
|
||||
| error { set_error(ctx, IDS_RBRACKET); YYABORT; }
|
||||
|
||||
semicolon
|
||||
: ';'
|
||||
| error { set_error(ctx, IDS_SEMICOLON); YYABORT; }
|
||||
|
||||
%%
|
||||
|
||||
static BOOL allow_auto_semicolon(parser_ctx_t *ctx)
|
||||
|
@ -1434,6 +1460,20 @@ static int parser_error(const char *str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void set_error(parser_ctx_t *ctx, UINT error)
|
||||
{
|
||||
ctx->hres = JSCRIPT_ERROR|error;
|
||||
}
|
||||
|
||||
static BOOL explicit_error(parser_ctx_t *ctx, void *obj, WCHAR next)
|
||||
{
|
||||
if(obj || *(ctx->ptr-1)==next) return TRUE;
|
||||
|
||||
set_error(ctx, IDS_SYNTAX_ERROR);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static expression_t *new_identifier_expression(parser_ctx_t *ctx, const WCHAR *identifier)
|
||||
{
|
||||
identifier_expression_t *ret = parser_alloc(ctx, sizeof(identifier_expression_t));
|
||||
|
@ -1537,7 +1577,8 @@ static void program_parsed(parser_ctx_t *ctx, source_elements_t *source)
|
|||
pop_func(ctx);
|
||||
|
||||
ctx->source = source;
|
||||
ctx->hres = S_OK;
|
||||
if(!ctx->lexer_error)
|
||||
ctx->hres = S_OK;
|
||||
}
|
||||
|
||||
void parser_release(parser_ctx_t *ctx)
|
||||
|
@ -1568,7 +1609,7 @@ HRESULT script_parse(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimite
|
|||
return E_OUTOFMEMORY;
|
||||
|
||||
parser_ctx->ref = 1;
|
||||
parser_ctx->hres = E_FAIL;
|
||||
parser_ctx->hres = JSCRIPT_ERROR|IDS_SYNTAX_ERROR;
|
||||
parser_ctx->is_html = delimiter && !strcmpiW(delimiter, html_tagW);
|
||||
|
||||
parser_ctx->begin = parser_ctx->ptr = code;
|
||||
|
|
|
@ -96,6 +96,7 @@ static const WCHAR propertyIsEnumerableW[] =
|
|||
{'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0};
|
||||
static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
|
||||
static const WCHAR execW[] = {'e','x','e','c',0};
|
||||
static const WCHAR testW[] = {'t','e','s','t',0};
|
||||
|
||||
static const WCHAR emptyW[] = {0};
|
||||
|
||||
|
@ -3505,13 +3506,29 @@ static HRESULT RegExp_exec(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT RegExp_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
static HRESULT RegExp_test(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT RegExp_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case INVOKE_FUNC:
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
|
||||
default:
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void RegExp_destructor(DispatchEx *dispex)
|
||||
{
|
||||
RegExpInstance *This = (RegExpInstance*)dispex;
|
||||
|
@ -3532,6 +3549,7 @@ static const builtin_prop_t RegExp_props[] = {
|
|||
{multilineW, RegExp_multiline, 0},
|
||||
{propertyIsEnumerableW, RegExp_propertyIsEnumerable, PROPF_METHOD},
|
||||
{sourceW, RegExp_source, 0},
|
||||
{testW, RegExp_test, PROPF_METHOD},
|
||||
{toLocaleStringW, RegExp_toLocaleString, PROPF_METHOD},
|
||||
{toStringW, RegExp_toString, PROPF_METHOD}
|
||||
};
|
||||
|
|
36
reactos/dll/win32/jscript/resource.h
Normal file
36
reactos/dll/win32/jscript/resource.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2009 Piotr Caban
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
#define IDS_TO_PRIMITIVE 0x0001
|
||||
#define IDS_INVALID_CALL_ARG 0x0005
|
||||
#define IDS_NO_PROPERTY 0x01B6
|
||||
#define IDS_ARG_NOT_OPT 0x01c1
|
||||
#define IDS_SYNTAX_ERROR 0x03EA
|
||||
#define IDS_SEMICOLON 0x03EC
|
||||
#define IDS_LBRACKET 0x03ED
|
||||
#define IDS_RBRACKET 0x03EE
|
||||
#define IDS_UNTERMINATED_STR 0x03F7
|
||||
#define IDS_NOT_FUNC 0x138A
|
||||
#define IDS_NOT_DATE 0x138E
|
||||
#define IDS_NOT_NUM 0x1389
|
||||
#define IDS_ILLEGAL_ASSIGN 0x1390
|
||||
#define IDS_UNDEFINED 0x1391
|
||||
#define IDS_NOT_BOOL 0x1392
|
||||
#define IDS_INVALID_LENGTH 0x13A5
|
|
@ -21,3 +21,10 @@ REGINST REGINST jscript.inf
|
|||
|
||||
/* @makedep: jsglobal.tlb */
|
||||
1 TYPELIB LOADONCALL DISCARDABLE jsglobal.tlb
|
||||
|
||||
#include "jscript_De.rc"
|
||||
#include "jscript_En.rc"
|
||||
#include "jscript_Fr.rc"
|
||||
#include "jscript_Lt.rc"
|
||||
#include "jscript_Nl.rc"
|
||||
#include "jscript_Pt.rc"
|
||||
|
|
|
@ -66,6 +66,7 @@ static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p',
|
|||
static const WCHAR propertyIsEnumerableW[] =
|
||||
{'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0};
|
||||
static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
|
||||
static const WCHAR fromCharCodeW[] = {'f','r','o','m','C','h','a','r','C','o','d','e',0};
|
||||
|
||||
static HRESULT String_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
|
@ -127,34 +128,123 @@ static HRESULT do_attributeless_tag_format(DispatchEx *dispex, LCID lcid, WORD f
|
|||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp, const WCHAR *tagname)
|
||||
{
|
||||
static const WCHAR tagfmt[] = {'<','%','s','>','%','s','<','/','%','s','>',0};
|
||||
StringInstance *string;
|
||||
BSTR ret;
|
||||
const WCHAR *str;
|
||||
DWORD length;
|
||||
BSTR val_str = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
WARN("this is not a string object\n");
|
||||
return E_NOTIMPL;
|
||||
VARIANT this;
|
||||
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
string = (StringInstance*)dispex;
|
||||
|
||||
if(retv) {
|
||||
ret = SysAllocStringLen(NULL, string->length + 2*strlenW(tagname) + 5);
|
||||
if(!ret)
|
||||
BSTR ret = SysAllocStringLen(NULL, length + 2*strlenW(tagname) + 5);
|
||||
if(!ret) {
|
||||
SysFreeString(val_str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
sprintfW(ret, tagfmt, tagname, string->str, tagname);
|
||||
sprintfW(ret, tagfmt, tagname, str, tagname);
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = ret;
|
||||
}
|
||||
|
||||
SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT do_attribute_tag_format(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp,
|
||||
const WCHAR *tagname, const WCHAR *attr)
|
||||
{
|
||||
static const WCHAR tagfmtW[]
|
||||
= {'<','%','s',' ','%','s','=','\"','%','s','\"','>','%','s','<','/','%','s','>',0};
|
||||
static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
|
||||
|
||||
const WCHAR *str;
|
||||
DWORD length;
|
||||
BSTR attr_value, val_str = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
if(arg_cnt(dp)) {
|
||||
hres = to_string(dispex->ctx, get_arg(dp, 0), ei, &attr_value);
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
else {
|
||||
attr_value = SysAllocString(undefinedW);
|
||||
if(!attr_value) {
|
||||
SysFreeString(val_str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if(retv) {
|
||||
BSTR ret = SysAllocStringLen(NULL, length + 2*strlenW(tagname)
|
||||
+ strlenW(attr) + SysStringLen(attr_value) + 9);
|
||||
if(!ret) {
|
||||
SysFreeString(attr_value);
|
||||
SysFreeString(val_str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
sprintfW(ret, tagfmtW, tagname, attr, attr_value, str, tagname);
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = ret;
|
||||
}
|
||||
|
||||
SysFreeString(attr_value);
|
||||
SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT String_anchor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
static const WCHAR fontW[] = {'A',0};
|
||||
static const WCHAR colorW[] = {'N','A','M','E',0};
|
||||
|
||||
return do_attribute_tag_format(dispex, lcid, flags, dp, retv, ei, sp, fontW, colorW);
|
||||
}
|
||||
|
||||
static HRESULT String_big(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
|
@ -182,26 +272,42 @@ static HRESULT String_bold(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
|
|||
static HRESULT String_charAt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
StringInstance *strobj;
|
||||
BSTR str;
|
||||
const WCHAR *str;
|
||||
DWORD length;
|
||||
BSTR ret, val_str = NULL;
|
||||
INT pos = 0;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(dispex->builtin_info->class != JSCLASS_STRING) {
|
||||
FIXME("not string this not supported\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
strobj = (StringInstance*)dispex;
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
if(arg_cnt(dp)) {
|
||||
VARIANT num;
|
||||
|
||||
hres = to_integer(dispex->ctx, get_arg(dp, 0), ei, &num);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(V_VT(&num) == VT_I4) {
|
||||
pos = V_I4(&num);
|
||||
|
@ -211,18 +317,22 @@ static HRESULT String_charAt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARA
|
|||
}
|
||||
}
|
||||
|
||||
if(!retv)
|
||||
if(!retv) {
|
||||
SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if(0 <= pos && pos < strobj->length)
|
||||
str = SysAllocStringLen(strobj->str+pos, 1);
|
||||
if(0 <= pos && pos < length)
|
||||
ret = SysAllocStringLen(str+pos, 1);
|
||||
else
|
||||
str = SysAllocStringLen(NULL, 0);
|
||||
if(!str)
|
||||
ret = SysAllocStringLen(NULL, 0);
|
||||
SysFreeString(val_str);
|
||||
if(!ret) {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = str;
|
||||
V_BSTR(retv) = ret;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -231,30 +341,44 @@ static HRESULT String_charCodeAt(DispatchEx *dispex, LCID lcid, WORD flags, DISP
|
|||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
const WCHAR *str;
|
||||
BSTR val_str = NULL;
|
||||
DWORD length, idx = 0;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(dispex->builtin_info->class == JSCLASS_STRING) {
|
||||
StringInstance *string = (StringInstance*)dispex;
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
str = string->str;
|
||||
length = string->length;
|
||||
}else {
|
||||
FIXME("not string this not supported\n");
|
||||
return E_NOTIMPL;
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
if(arg_cnt(dp) > 0) {
|
||||
VARIANT v;
|
||||
|
||||
hres = to_integer(dispex->ctx, get_arg(dp, 0), ei, &v);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(V_VT(&v) != VT_I4 || V_I4(&v) < 0 || V_I4(&v) >= length) {
|
||||
if(retv) num_set_nan(&v);
|
||||
SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -265,6 +389,8 @@ static HRESULT String_charCodeAt(DispatchEx *dispex, LCID lcid, WORD flags, DISP
|
|||
V_VT(retv) = VT_I4;
|
||||
V_I4(retv) = str[idx];
|
||||
}
|
||||
|
||||
SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -336,15 +462,19 @@ static HRESULT String_fixed(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
static HRESULT String_fontcolor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
static const WCHAR fontW[] = {'F','O','N','T',0};
|
||||
static const WCHAR colorW[] = {'C','O','L','O','R',0};
|
||||
|
||||
return do_attribute_tag_format(dispex, lcid, flags, dp, retv, ei, sp, fontW, colorW);
|
||||
}
|
||||
|
||||
static HRESULT String_fontsize(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
static const WCHAR fontW[] = {'F','O','N','T',0};
|
||||
static const WCHAR colorW[] = {'S','I','Z','E',0};
|
||||
|
||||
return do_attribute_tag_format(dispex, lcid, flags, dp, retv, ei, sp, fontW, colorW);
|
||||
}
|
||||
|
||||
static HRESULT String_indexOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
|
@ -352,20 +482,30 @@ static HRESULT String_indexOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
|
|||
{
|
||||
DWORD length, pos = 0;
|
||||
const WCHAR *str;
|
||||
BSTR search_str;
|
||||
BSTR search_str, val_str = NULL;
|
||||
INT ret = -1;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_class(dispex, JSCLASS_STRING)) {
|
||||
StringInstance *string = (StringInstance*)dispex;
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
str = string->str;
|
||||
length = string->length;
|
||||
}else {
|
||||
FIXME("not String this\n");
|
||||
return E_NOTIMPL;
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
if(!arg_cnt(dp)) {
|
||||
|
@ -373,12 +513,15 @@ static HRESULT String_indexOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
|
|||
V_VT(retv) = VT_I4;
|
||||
V_I4(retv) = -1;
|
||||
}
|
||||
SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hres = to_string(dispex->ctx, get_arg(dp,0), ei, &search_str);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(arg_cnt(dp) >= 2) {
|
||||
VARIANT ival;
|
||||
|
@ -405,6 +548,7 @@ static HRESULT String_indexOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
|
|||
}
|
||||
|
||||
SysFreeString(search_str);
|
||||
SysFreeString(val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -432,27 +576,33 @@ static HRESULT String_lastIndexOf(DispatchEx *dispex, LCID lcid, WORD flags, DIS
|
|||
static HRESULT String_link(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
static const WCHAR fontW[] = {'A',0};
|
||||
static const WCHAR colorW[] = {'H','R','E','F',0};
|
||||
|
||||
return do_attribute_tag_format(dispex, lcid, flags, dp, retv, ei, sp, fontW, colorW);
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.5.4.10 */
|
||||
static HRESULT String_match(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
StringInstance *This = (StringInstance*)dispex;
|
||||
const WCHAR *str;
|
||||
match_result_t *match_result;
|
||||
DispatchEx *regexp;
|
||||
DispatchEx *array;
|
||||
VARIANT var, *arg_var;
|
||||
DWORD match_cnt, i;
|
||||
DWORD length, match_cnt, i;
|
||||
BSTR val_str = NULL;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(arg_cnt(dp) != 1) {
|
||||
FIXME("unsupported args\n");
|
||||
return E_NOTIMPL;
|
||||
if(!arg_cnt(dp)) {
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_NULL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
arg_var = get_arg(dp, 0);
|
||||
|
@ -478,22 +628,50 @@ static HRESULT String_match(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
}
|
||||
}
|
||||
|
||||
hres = regexp_match(regexp, This->str, This->length, FALSE, &match_result, &match_cnt);
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres)) {
|
||||
jsdisp_release(regexp);
|
||||
return hres;
|
||||
}
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
hres = regexp_match(regexp, str, length, FALSE, &match_result, &match_cnt);
|
||||
jsdisp_release(regexp);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(!match_cnt) {
|
||||
TRACE("no match\n");
|
||||
|
||||
if(retv)
|
||||
V_VT(retv) = VT_NULL;
|
||||
|
||||
SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hres = create_array(dispex->ctx, match_cnt, &array);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
|
||||
V_VT(&var) = VT_BSTR;
|
||||
|
||||
|
@ -510,6 +688,8 @@ static HRESULT String_match(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
break;
|
||||
}
|
||||
|
||||
SysFreeString(val_str);
|
||||
|
||||
if(SUCCEEDED(hres) && retv) {
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(array);
|
||||
|
@ -618,11 +798,11 @@ static HRESULT rep_call(DispatchEx *func, const WCHAR *str, match_result_t *matc
|
|||
static HRESULT String_replace(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
const WCHAR *str;
|
||||
DWORD parens_cnt = 0, parens_size=0, rep_len=0, length;
|
||||
BSTR rep_str = NULL, match_str = NULL, ret_str;
|
||||
BSTR rep_str = NULL, match_str = NULL, ret_str, val_str = NULL;
|
||||
DispatchEx *rep_func = NULL, *regexp = NULL;
|
||||
match_result_t *parens = NULL, match;
|
||||
const WCHAR *str;
|
||||
strbuf_t ret = {NULL,0,0};
|
||||
BOOL gcheck = FALSE;
|
||||
VARIANT *arg_var;
|
||||
|
@ -630,23 +810,36 @@ static HRESULT String_replace(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
|
|||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_class(dispex, JSCLASS_STRING)) {
|
||||
StringInstance *string = (StringInstance*)dispex;
|
||||
str = string->str;
|
||||
length = string->length;
|
||||
}else {
|
||||
FIXME("not String this\n");
|
||||
return E_NOTIMPL;
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
if(!arg_cnt(dp)) {
|
||||
if(retv) {
|
||||
ret_str = SysAllocString(str);
|
||||
if(!ret_str)
|
||||
return E_OUTOFMEMORY;
|
||||
if(!val_str) {
|
||||
val_str = SysAllocStringLen(str, length);
|
||||
if(!val_str)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = ret_str;
|
||||
V_BSTR(retv) = val_str;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -666,8 +859,10 @@ static HRESULT String_replace(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
|
|||
|
||||
default:
|
||||
hres = to_string(dispex->ctx, arg_var, ei, &match_str);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
if(arg_cnt(dp) >= 2) {
|
||||
|
@ -760,6 +955,7 @@ static HRESULT String_replace(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
|
|||
jsdisp_release(rep_func);
|
||||
if(regexp)
|
||||
jsdisp_release(regexp);
|
||||
SysFreeString(val_str);
|
||||
SysFreeString(rep_str);
|
||||
SysFreeString(match_str);
|
||||
heap_free(parens);
|
||||
|
@ -790,6 +986,7 @@ static HRESULT String_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
const WCHAR *str;
|
||||
BSTR val_str = NULL;
|
||||
DWORD length;
|
||||
INT start=0, end;
|
||||
VARIANT v;
|
||||
|
@ -797,20 +994,32 @@ static HRESULT String_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_class(dispex, JSCLASS_STRING)) {
|
||||
StringInstance *string = (StringInstance*)dispex;
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
str = string->str;
|
||||
length = string->length;
|
||||
}else {
|
||||
FIXME("this is not a string class\n");
|
||||
return E_NOTIMPL;
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
if(arg_cnt(dp)) {
|
||||
hres = to_integer(dispex->ctx, dp->rgvarg + dp->cArgs-1, ei, &v);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(V_VT(&v) == VT_I4) {
|
||||
start = V_I4(&v);
|
||||
|
@ -830,8 +1039,10 @@ static HRESULT String_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
|
||||
if(arg_cnt(dp) >= 2) {
|
||||
hres = to_integer(dispex->ctx, dp->rgvarg + dp->cArgs-2, ei, &v);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(V_VT(&v) == VT_I4) {
|
||||
end = V_I4(&v);
|
||||
|
@ -854,12 +1065,16 @@ static HRESULT String_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
|
||||
if(retv) {
|
||||
BSTR retstr = SysAllocStringLen(str+start, end-start);
|
||||
if(!str)
|
||||
if(!retstr) {
|
||||
SysFreeString(val_str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = retstr;
|
||||
}
|
||||
|
||||
SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -874,28 +1089,40 @@ static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
match_result_t *match_result = NULL;
|
||||
DWORD match_cnt, i, match_len = 0;
|
||||
StringInstance *string;
|
||||
const WCHAR *ptr, *ptr2;
|
||||
DWORD length, match_cnt, i, match_len = 0;
|
||||
const WCHAR *str, *ptr, *ptr2;
|
||||
VARIANT *arg, var;
|
||||
DispatchEx *array;
|
||||
BSTR match_str = NULL;
|
||||
BSTR val_str = NULL, match_str = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
FIXME("not String this\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
string = (StringInstance*)dispex;
|
||||
|
||||
if(arg_cnt(dp) != 1) {
|
||||
FIXME("unsupported args\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
arg = get_arg(dp, 0);
|
||||
switch(V_VT(arg)) {
|
||||
case VT_DISPATCH: {
|
||||
|
@ -904,10 +1131,12 @@ static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
regexp = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg));
|
||||
if(regexp) {
|
||||
if(is_class(regexp, JSCLASS_REGEXP)) {
|
||||
hres = regexp_match(regexp, string->str, string->length, TRUE, &match_result, &match_cnt);
|
||||
hres = regexp_match(regexp, str, length, TRUE, &match_result, &match_cnt);
|
||||
jsdisp_release(regexp);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
break;
|
||||
}
|
||||
jsdisp_release(regexp);
|
||||
|
@ -915,8 +1144,10 @@ static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
}
|
||||
default:
|
||||
hres = to_string(dispex->ctx, arg, ei, &match_str);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
|
||||
match_len = SysStringLen(match_str);
|
||||
if(!match_len) {
|
||||
|
@ -928,7 +1159,7 @@ static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
hres = create_array(dispex->ctx, 0, &array);
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
ptr = string->str;
|
||||
ptr = str;
|
||||
for(i=0;; i++) {
|
||||
if(match_result) {
|
||||
if(i == match_cnt)
|
||||
|
@ -966,7 +1197,7 @@ static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
}
|
||||
|
||||
if(SUCCEEDED(hres) && (match_str || match_result)) {
|
||||
DWORD len = (string->str+string->length) - ptr;
|
||||
DWORD len = (str+length) - ptr;
|
||||
|
||||
if(len || match_str) {
|
||||
V_VT(&var) = VT_BSTR;
|
||||
|
@ -982,6 +1213,7 @@ static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
}
|
||||
|
||||
SysFreeString(match_str);
|
||||
SysFreeString(val_str);
|
||||
heap_free(match_result);
|
||||
|
||||
if(SUCCEEDED(hres) && retv) {
|
||||
|
@ -1013,6 +1245,7 @@ static HRESULT String_substring(DispatchEx *dispex, LCID lcid, WORD flags, DISPP
|
|||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
const WCHAR *str;
|
||||
BSTR val_str = NULL;
|
||||
INT start=0, end;
|
||||
DWORD length;
|
||||
VARIANT v;
|
||||
|
@ -1020,20 +1253,32 @@ static HRESULT String_substring(DispatchEx *dispex, LCID lcid, WORD flags, DISPP
|
|||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_class(dispex, JSCLASS_STRING)) {
|
||||
StringInstance *string = (StringInstance*)dispex;
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
length = string->length;
|
||||
str = string->str;
|
||||
}else {
|
||||
FIXME("not string this not supported\n");
|
||||
return E_NOTIMPL;
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
if(arg_cnt(dp) >= 1) {
|
||||
hres = to_integer(dispex->ctx, dp->rgvarg + dp->cArgs-1, ei, &v);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(V_VT(&v) == VT_I4) {
|
||||
start = V_I4(&v);
|
||||
|
@ -1048,8 +1293,10 @@ static HRESULT String_substring(DispatchEx *dispex, LCID lcid, WORD flags, DISPP
|
|||
|
||||
if(arg_cnt(dp) >= 2) {
|
||||
hres = to_integer(dispex->ctx, dp->rgvarg + dp->cArgs-2, ei, &v);
|
||||
if(FAILED(hres))
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(V_VT(&v) == VT_I4) {
|
||||
end = V_I4(&v);
|
||||
|
@ -1073,9 +1320,12 @@ static HRESULT String_substring(DispatchEx *dispex, LCID lcid, WORD flags, DISPP
|
|||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = SysAllocStringLen(str+start, end-start);
|
||||
if(!V_BSTR(retv))
|
||||
if(!V_BSTR(retv)) {
|
||||
SysFreeString(val_str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1096,66 +1346,92 @@ static HRESULT String_sup(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
|
|||
static HRESULT String_toLowerCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
StringInstance *string;
|
||||
const WCHAR* str;
|
||||
DWORD length;
|
||||
BSTR bstr;
|
||||
BSTR val_str = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_class(dispex, JSCLASS_STRING)) {
|
||||
string = (StringInstance*)dispex;
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
length = string->length;
|
||||
str = string->str;
|
||||
}else {
|
||||
FIXME("not string this not supported\n");
|
||||
return E_NOTIMPL;
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
if(retv) {
|
||||
bstr = SysAllocStringLen(str, length);
|
||||
if (!bstr)
|
||||
return E_OUTOFMEMORY;
|
||||
if(!val_str) {
|
||||
val_str = SysAllocStringLen(str, length);
|
||||
if(!val_str)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
strlwrW(bstr);
|
||||
strlwrW(val_str);
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = bstr;
|
||||
V_BSTR(retv) = val_str;
|
||||
}
|
||||
else SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT String_toUpperCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
StringInstance *string;
|
||||
const WCHAR* str;
|
||||
DWORD length;
|
||||
BSTR bstr;
|
||||
BSTR val_str = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_class(dispex, JSCLASS_STRING)) {
|
||||
string = (StringInstance*)dispex;
|
||||
if(!is_class(dispex, JSCLASS_STRING)) {
|
||||
VARIANT this;
|
||||
|
||||
length = string->length;
|
||||
str = string->str;
|
||||
}else {
|
||||
FIXME("not string this not supported\n");
|
||||
return E_NOTIMPL;
|
||||
V_VT(&this) = VT_DISPATCH;
|
||||
V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex);
|
||||
|
||||
hres = to_string(dispex->ctx, &this, ei, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
length = SysStringLen(val_str);
|
||||
}
|
||||
else {
|
||||
StringInstance *this = (StringInstance*)dispex;
|
||||
|
||||
str = this->str;
|
||||
length = this->length;
|
||||
}
|
||||
|
||||
if(retv) {
|
||||
bstr = SysAllocStringLen(str, length);
|
||||
if (!bstr)
|
||||
return E_OUTOFMEMORY;
|
||||
if(!val_str) {
|
||||
val_str = SysAllocStringLen(str, length);
|
||||
if(!val_str)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
struprW(bstr);
|
||||
struprW(val_str);
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = bstr;
|
||||
V_BSTR(retv) = val_str;
|
||||
}
|
||||
else SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1209,6 +1485,8 @@ static HRESULT String_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
|
|||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case INVOKE_FUNC:
|
||||
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
|
||||
case DISPATCH_PROPERTYGET: {
|
||||
BSTR str = SysAllocString(This->str);
|
||||
if(!str)
|
||||
|
@ -1282,6 +1560,37 @@ static const builtin_info_t String_info = {
|
|||
NULL
|
||||
};
|
||||
|
||||
/* ECMA-262 3rd Edition 15.5.3.2 */
|
||||
static HRESULT StringConstr_fromCharCode(DispatchEx *dispex, LCID lcid, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
DWORD i, code;
|
||||
BSTR ret;
|
||||
HRESULT hres;
|
||||
|
||||
ret = SysAllocStringLen(NULL, arg_cnt(dp));
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
for(i=0; i<arg_cnt(dp); i++) {
|
||||
hres = to_uint32(dispex->ctx, get_arg(dp, i), ei, &code);
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(ret);
|
||||
return hres;
|
||||
}
|
||||
|
||||
ret[i] = code;
|
||||
}
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = ret;
|
||||
}
|
||||
else SysFreeString(ret);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT StringConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
|
@ -1361,6 +1670,19 @@ static HRESULT string_alloc(script_ctx_t *ctx, BOOL use_constr, StringInstance *
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static const builtin_prop_t StringConstr_props[] = {
|
||||
{fromCharCodeW, StringConstr_fromCharCode, PROPF_METHOD},
|
||||
};
|
||||
|
||||
static const builtin_info_t StringConstr_info = {
|
||||
JSCLASS_FUNCTION,
|
||||
{NULL, Function_value, 0},
|
||||
sizeof(StringConstr_props)/sizeof(*StringConstr_props),
|
||||
StringConstr_props,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
HRESULT create_string_constr(script_ctx_t *ctx, DispatchEx **ret)
|
||||
{
|
||||
StringInstance *string;
|
||||
|
@ -1370,7 +1692,7 @@ HRESULT create_string_constr(script_ctx_t *ctx, DispatchEx **ret)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_builtin_function(ctx, StringConstr_value, NULL, PROPF_CONSTR, &string->dispex, ret);
|
||||
hres = create_builtin_function(ctx, StringConstr_value, &StringConstr_info, PROPF_CONSTR, &string->dispex, ret);
|
||||
|
||||
jsdisp_release(&string->dispex);
|
||||
return hres;
|
||||
|
|
Loading…
Reference in a new issue