mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
jscript: Added Function.toString implementation.
This commit is contained in:
parent
68bd72c7cd
commit
5760eb808b
@ -367,7 +367,8 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so
|
||||
DispatchEx *func_obj;
|
||||
VARIANT var;
|
||||
|
||||
hres = create_source_function(parser, func->parameter_list, func->source_elements, ctx->scope_chain, &func_obj);
|
||||
hres = create_source_function(parser, func->parameter_list, func->source_elements,
|
||||
ctx->scope_chain, func->src_str, func->src_len, &func_obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
@ -1242,7 +1243,8 @@ HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD fla
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, &dispex);
|
||||
hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain,
|
||||
expr->src_str, expr->src_len, &dispex);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -98,7 +98,8 @@ typedef struct _statement_t statement_t;
|
||||
typedef struct _expression_t expression_t;
|
||||
typedef struct _parameter_t parameter_t;
|
||||
|
||||
HRESULT create_source_function(parser_ctx_t*,parameter_t*,source_elements_t*,scope_chain_t*,DispatchEx**);
|
||||
HRESULT create_source_function(parser_ctx_t*,parameter_t*,source_elements_t*,scope_chain_t*,
|
||||
const WCHAR*,DWORD,DispatchEx**);
|
||||
|
||||
typedef struct {
|
||||
VARTYPE vt;
|
||||
@ -277,6 +278,8 @@ typedef struct _function_declaration_t {
|
||||
const WCHAR *identifier;
|
||||
parameter_t *parameter_list;
|
||||
source_elements_t *source_elements;
|
||||
const WCHAR *src_str;
|
||||
DWORD src_len;
|
||||
|
||||
struct _function_declaration_t *next;
|
||||
} function_declaration_t;
|
||||
@ -293,6 +296,8 @@ typedef struct {
|
||||
const WCHAR *identifier;
|
||||
parameter_t *parameter_list;
|
||||
source_elements_t *source_elements;
|
||||
const WCHAR *src_str;
|
||||
DWORD src_len;
|
||||
} function_expression_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -31,6 +31,8 @@ typedef struct {
|
||||
parameter_t *parameters;
|
||||
scope_chain_t *scope_chain;
|
||||
parser_ctx_t *parser;
|
||||
const WCHAR *src_str;
|
||||
DWORD src_len;
|
||||
DWORD length;
|
||||
} FunctionInstance;
|
||||
|
||||
@ -226,6 +228,23 @@ static HRESULT invoke_value_proc(FunctionInstance *function, LCID lcid, WORD fla
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT function_to_string(FunctionInstance *function, BSTR *ret)
|
||||
{
|
||||
BSTR str;
|
||||
|
||||
if(function->value_proc) {
|
||||
FIXME("Builtin functions not implemented\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
str = SysAllocStringLen(function->src_str, function->src_len);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
*ret = str;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT Function_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
@ -249,8 +268,30 @@ static HRESULT Function_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPA
|
||||
static HRESULT Function_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
FunctionInstance *function;
|
||||
BSTR str;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(!is_class(dispex, JSCLASS_FUNCTION)) {
|
||||
FIXME("throw TypeError\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
function = (FunctionInstance*)dispex;
|
||||
|
||||
hres = function_to_string(function, &str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = str;
|
||||
}else {
|
||||
SysFreeString(str);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT Function_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||
@ -438,7 +479,7 @@ HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc,
|
||||
}
|
||||
|
||||
HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, source_elements_t *source,
|
||||
scope_chain_t *scope_chain, DispatchEx **ret)
|
||||
scope_chain_t *scope_chain, const WCHAR *src_str, DWORD src_len, DispatchEx **ret)
|
||||
{
|
||||
FunctionInstance *function;
|
||||
DispatchEx *prototype;
|
||||
@ -470,6 +511,9 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc
|
||||
length++;
|
||||
function->length = length;
|
||||
|
||||
function->src_str = src_str;
|
||||
function->src_len = src_len;
|
||||
|
||||
*ret = &function->dispex;
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -621,7 +621,7 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = create_source_function(parser_ctx, NULL, parser_ctx->source, NULL, &dispex);
|
||||
hres = create_source_function(parser_ctx, NULL, parser_ctx->source, NULL, NULL, 0, &dispex);
|
||||
parser_release(parser_ctx);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -101,7 +101,7 @@ static int lex_error(parser_ctx_t *ctx, HRESULT hres)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int check_keyword(parser_ctx_t *ctx, const WCHAR *word)
|
||||
static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lval)
|
||||
{
|
||||
const WCHAR *p1 = ctx->ptr;
|
||||
const WCHAR *p2 = word;
|
||||
@ -116,6 +116,7 @@ static int check_keyword(parser_ctx_t *ctx, const WCHAR *word)
|
||||
if(*p2 || (p1 < ctx->end && isalnumW(*p1)))
|
||||
return 1;
|
||||
|
||||
*lval = ctx->ptr;
|
||||
ctx->ptr = p1;
|
||||
return 0;
|
||||
}
|
||||
@ -145,14 +146,14 @@ static int hex_to_int(WCHAR c)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int check_keywords(parser_ctx_t *ctx)
|
||||
static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval)
|
||||
{
|
||||
int min = 0, max = sizeof(keywords)/sizeof(keywords[0])-1, r, i;
|
||||
|
||||
while(min <= max) {
|
||||
i = (min+max)/2;
|
||||
|
||||
r = check_keyword(ctx, keywords[i].word);
|
||||
r = check_keyword(ctx, keywords[i].word, lval);
|
||||
if(!r)
|
||||
return keywords[i].token;
|
||||
|
||||
@ -468,7 +469,7 @@ int parser_lex(void *lval, parser_ctx_t *ctx)
|
||||
}while(skip_comment(ctx));
|
||||
|
||||
if(isalphaW(*ctx->ptr)) {
|
||||
ret = check_keywords(ctx);
|
||||
ret = check_keywords(ctx, lval);
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
@ -480,7 +481,6 @@ int parser_lex(void *lval, parser_ctx_t *ctx)
|
||||
|
||||
switch(*ctx->ptr) {
|
||||
case '{':
|
||||
case '}':
|
||||
case '(':
|
||||
case ')':
|
||||
case '[':
|
||||
@ -492,6 +492,10 @@ int parser_lex(void *lval, parser_ctx_t *ctx)
|
||||
case ':':
|
||||
return *ctx->ptr++;
|
||||
|
||||
case '}':
|
||||
*(const WCHAR**)lval = ctx->ptr++;
|
||||
return '}';
|
||||
|
||||
case '.':
|
||||
if(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
|
||||
return parse_double_literal(ctx, 0, lval);
|
||||
|
@ -120,7 +120,8 @@ typedef struct _parameter_list_t {
|
||||
static parameter_list_t *new_parameter_list(parser_ctx_t*,const WCHAR*);
|
||||
static parameter_list_t *parameter_list_add(parser_ctx_t*,parameter_list_t*,const WCHAR*);
|
||||
|
||||
static expression_t *new_function_expression(parser_ctx_t*,const WCHAR*,parameter_list_t*,source_elements_t*);
|
||||
static expression_t *new_function_expression(parser_ctx_t*,const WCHAR*,parameter_list_t*,
|
||||
source_elements_t*,const WCHAR*,DWORD);
|
||||
static expression_t *new_binary_expression(parser_ctx_t*,expression_type_t,expression_t*,expression_t*);
|
||||
static expression_t *new_unary_expression(parser_ctx_t*,expression_type_t,expression_t*);
|
||||
static expression_t *new_conditional_expression(parser_ctx_t*,expression_t*,expression_t*,expression_t*);
|
||||
@ -134,7 +135,8 @@ static expression_t *new_literal_expression(parser_ctx_t*,literal_t*);
|
||||
static expression_t *new_array_literal_expression(parser_ctx_t*,element_list_t*,int);
|
||||
static expression_t *new_prop_and_value_expression(parser_ctx_t*,property_list_t*);
|
||||
|
||||
static function_declaration_t *new_function_declaration(parser_ctx_t*,const WCHAR*,parameter_list_t*,source_elements_t*);
|
||||
static function_declaration_t *new_function_declaration(parser_ctx_t*,const WCHAR*,parameter_list_t*,
|
||||
source_elements_t*,const WCHAR*,DWORD);
|
||||
static source_elements_t *new_source_elements(parser_ctx_t*);
|
||||
static source_elements_t *source_elements_add_statement(source_elements_t*,statement_t*);
|
||||
static source_elements_t *source_elements_add_function(source_elements_t*,function_declaration_t*);
|
||||
@ -146,6 +148,7 @@ static source_elements_t *source_elements_add_function(source_elements_t*,functi
|
||||
|
||||
%union {
|
||||
int ival;
|
||||
const WCHAR *srcptr;
|
||||
LPCWSTR wstr;
|
||||
literal_t *literal;
|
||||
struct _argument_list_t *argument_list;
|
||||
@ -166,10 +169,12 @@ static source_elements_t *source_elements_add_function(source_elements_t*,functi
|
||||
}
|
||||
|
||||
/* keywords */
|
||||
%token kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE kIF kFINALLY kFOR kFUNCTION kIN
|
||||
%token kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE kIF kFINALLY kFOR kIN
|
||||
%token kINSTANCEOF kNEW kNULL kUNDEFINED kRETURN kSWITCH kTHIS kTHROW kTRUE kFALSE kTRY kTYPEOF kVAR kVOID kWHILE kWITH
|
||||
%token tANDAND tOROR tINC tDEC
|
||||
|
||||
%token <srcptr> kFUNCTION '}'
|
||||
|
||||
/* tokens */
|
||||
%token <identifier> tIdentifier
|
||||
%token <ival> tAssignOper tEqOper tShiftOper tRelOper
|
||||
@ -257,12 +262,12 @@ SourceElements
|
||||
/* ECMA-262 3rd Edition 13 */
|
||||
FunctionDeclaration
|
||||
: kFUNCTION tIdentifier '(' FormalParameterList_opt ')' '{' FunctionBody '}'
|
||||
{ $$ = new_function_declaration(ctx, $2, $4, $7); }
|
||||
{ $$ = new_function_declaration(ctx, $2, $4, $7, $1, $8-$1+1); }
|
||||
|
||||
/* ECMA-262 3rd Edition 13 */
|
||||
FunctionExpression
|
||||
: kFUNCTION Identifier_opt '(' FormalParameterList_opt ')' '{' FunctionBody '}'
|
||||
{ $$ = new_function_expression(ctx, $2, $4, $7); }
|
||||
{ $$ = new_function_expression(ctx, $2, $4, $7, $1, $8-$1+1); }
|
||||
|
||||
/* ECMA-262 3rd Edition 13 */
|
||||
FunctionBody
|
||||
@ -1247,7 +1252,7 @@ static parameter_list_t *parameter_list_add(parser_ctx_t *ctx, parameter_list_t
|
||||
}
|
||||
|
||||
static expression_t *new_function_expression(parser_ctx_t *ctx, const WCHAR *identifier,
|
||||
parameter_list_t *parameter_list, source_elements_t *source_elements)
|
||||
parameter_list_t *parameter_list, source_elements_t *source_elements, const WCHAR *src_str, DWORD src_len)
|
||||
{
|
||||
function_expression_t *ret = parser_alloc(ctx, sizeof(function_expression_t));
|
||||
|
||||
@ -1255,6 +1260,8 @@ static expression_t *new_function_expression(parser_ctx_t *ctx, const WCHAR *ide
|
||||
ret->identifier = identifier;
|
||||
ret->parameter_list = parameter_list ? parameter_list->head : NULL;
|
||||
ret->source_elements = source_elements;
|
||||
ret->src_str = src_str;
|
||||
ret->src_len = src_len;
|
||||
|
||||
return &ret->expr;
|
||||
}
|
||||
@ -1444,13 +1451,15 @@ static expression_t *new_literal_expression(parser_ctx_t *ctx, literal_t *litera
|
||||
}
|
||||
|
||||
static function_declaration_t *new_function_declaration(parser_ctx_t *ctx, const WCHAR *identifier,
|
||||
parameter_list_t *parameter_list, source_elements_t *source_elements)
|
||||
parameter_list_t *parameter_list, source_elements_t *source_elements, const WCHAR *src_str, DWORD src_len)
|
||||
{
|
||||
function_declaration_t *ret = parser_alloc(ctx, sizeof(function_declaration_t));
|
||||
|
||||
ret->identifier = identifier;
|
||||
ret->parameter_list = parameter_list ? parameter_list->head : NULL;
|
||||
ret->source_elements = source_elements;
|
||||
ret->src_str = src_str;
|
||||
ret->src_len = src_len;
|
||||
ret->next = NULL;
|
||||
|
||||
return ret;
|
||||
|
@ -315,4 +315,18 @@ ok(tmp === 2, "Math.pow(2, 2) = " + tmp);
|
||||
tmp = Math.pow(2, 2, 3);
|
||||
ok(tmp === 4, "Math.pow(2, 2, 3) = " + tmp);
|
||||
|
||||
var func = function (a) {
|
||||
var a = 1;
|
||||
if(a) return;
|
||||
}.toString();
|
||||
ok(func.toString() === "function (a) {\n var a = 1;\n if(a) return;\n }",
|
||||
"func.toString() = " + func.toString());
|
||||
|
||||
function testFuncToString(x,y) {
|
||||
return x+y;
|
||||
}
|
||||
|
||||
ok(testFuncToString.toString() === "function testFuncToString(x,y) {\n return x+y;\n}",
|
||||
"testFuncToString.toString() = " + testFuncToString.toString());
|
||||
|
||||
reportSuccess();
|
||||
|
Loading…
Reference in New Issue
Block a user