jscript: Added Function.toString implementation.

This commit is contained in:
Jacek Caban 2008-09-21 15:47:47 +02:00 committed by Alexandre Julliard
parent 68bd72c7cd
commit 5760eb808b
7 changed files with 97 additions and 19 deletions

View File

@ -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;

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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();