diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 183eca44279..42db70a8a42 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -326,6 +326,7 @@ static HRESULT literal_to_var(literal_t *literal, VARIANT *v) HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv) { script_ctx_t *script = parser->script; + function_declaration_t *func; parser_ctx_t *prev_parser; VARIANT val, tmp; statement_t *stat; @@ -333,6 +334,22 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so return_type_t rt; HRESULT hres = S_OK; + for(func = source->functions; func; func = func->next) { + DispatchEx *func_obj; + VARIANT var; + + hres = create_source_function(parser, func->parameter_list, func->source_elements, ctx->scope_chain, &func_obj); + if(FAILED(hres)) + return hres; + + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(func_obj); + hres = jsdisp_propput_name(ctx->var_disp, func->identifier, script->lcid, &var, ei, NULL); + IDispatchEx_Release(_IDispatchEx_(func_obj)); + if(FAILED(hres)) + return hres; + } + prev_ctx = script->exec_ctx; script->exec_ctx = ctx; diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index ce9253d8bd6..c8f41b0105c 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -91,6 +91,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**); + typedef struct { VARTYPE vt; union { diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 56895a1df25..96fbf787ec5 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -17,6 +17,7 @@ */ #include "jscript.h" +#include "engine.h" #include "wine/debug.h" @@ -26,6 +27,10 @@ typedef struct { DispatchEx dispex; builtin_invoke_t value_proc; DWORD flags; + source_elements_t *source; + parameter_t *parameters; + scope_chain_t *scope_chain; + parser_ctx_t *parser; DWORD length; } FunctionInstance; @@ -126,6 +131,10 @@ static void Function_destructor(DispatchEx *dispex) { FunctionInstance *This = (FunctionInstance*)dispex; + if(This->parser) + parser_release(This->parser); + if(This->scope_chain) + scope_release(This->scope_chain); heap_free(This); } @@ -193,3 +202,34 @@ HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, *ret = &function->dispex; return S_OK; } + +HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, source_elements_t *source, + scope_chain_t *scope_chain, DispatchEx **ret) +{ + FunctionInstance *function; + parameter_t *iter; + DWORD length = 0; + HRESULT hres; + + hres = create_function(ctx->script, PROPF_CONSTR, NULL, &function); + if(FAILED(hres)) + return hres; + + function->source = source; + function->parameters = parameters; + + if(scope_chain) { + scope_addref(scope_chain); + function->scope_chain = scope_chain; + } + + parser_addref(ctx); + function->parser = ctx; + + for(iter = parameters; iter; iter = iter->next) + length++; + function->length = length; + + *ret = &function->dispex; + return S_OK; +} diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index dd7669152a3..67ed6861174 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -40,4 +40,10 @@ ok(trueVar, "trueVar is not true"); ok(ScriptEngine.length === 0, "ScriptEngine.length is not 0"); +function testFunc1(x, y) { + return true; +} + +ok(testFunc1.length === 2, "testFunc1.length is not 2"); + reportSuccess();