jscript: Don't expose named functions in expressions as a local variable in ES5 mode.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
609e9de65c
commit
e764509466
|
@ -1887,8 +1887,12 @@ static HRESULT visit_function_expression(compiler_ctx_t *ctx, function_expressio
|
||||||
expr->func_id = ctx->func->func_cnt++;
|
expr->func_id = ctx->func->func_cnt++;
|
||||||
ctx->func_tail = ctx->func_tail ? (ctx->func_tail->next = expr) : (ctx->func_head = expr);
|
ctx->func_tail = ctx->func_tail ? (ctx->func_tail->next = expr) : (ctx->func_head = expr);
|
||||||
|
|
||||||
return !expr->identifier || expr->event_target || alloc_variable(ctx, expr->identifier)
|
if(!expr->identifier || expr->event_target)
|
||||||
? S_OK : E_OUTOFMEMORY;
|
return S_OK;
|
||||||
|
if(!expr->is_statement && ctx->parser->script->version >= SCRIPTLANGUAGEVERSION_ES5)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
return alloc_variable(ctx, expr->identifier) ? S_OK : E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT visit_expression(compiler_ctx_t *ctx, expression_t *expr)
|
static HRESULT visit_expression(compiler_ctx_t *ctx, expression_t *expr)
|
||||||
|
@ -2069,7 +2073,15 @@ static HRESULT visit_statement(compiler_ctx_t *ctx, statement_t *stat)
|
||||||
case STAT_CONTINUE:
|
case STAT_CONTINUE:
|
||||||
case STAT_EMPTY:
|
case STAT_EMPTY:
|
||||||
break;
|
break;
|
||||||
case STAT_EXPR:
|
case STAT_EXPR: {
|
||||||
|
expression_statement_t *expr_stat = (expression_statement_t*)stat;
|
||||||
|
if(expr_stat->expr) {
|
||||||
|
if(expr_stat->expr->type == EXPR_FUNC)
|
||||||
|
((function_expression_t*)expr_stat->expr)->is_statement = TRUE;
|
||||||
|
hres = visit_expression(ctx, expr_stat->expr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case STAT_RETURN:
|
case STAT_RETURN:
|
||||||
case STAT_THROW: {
|
case STAT_THROW: {
|
||||||
expression_statement_t *expr_stat = (expression_statement_t*)stat;
|
expression_statement_t *expr_stat = (expression_statement_t*)stat;
|
||||||
|
@ -2410,7 +2422,8 @@ static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source,
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
TRACE("[%d] func %s\n", i, debugstr_w(func->funcs[i].name));
|
TRACE("[%d] func %s\n", i, debugstr_w(func->funcs[i].name));
|
||||||
if(func->funcs[i].name && !func->funcs[i].event_target) {
|
if((ctx->parser->script->version < SCRIPTLANGUAGEVERSION_ES5 || iter->is_statement) &&
|
||||||
|
func->funcs[i].name && !func->funcs[i].event_target) {
|
||||||
local_ref_t *local_ref = lookup_local(func, func->funcs[i].name);
|
local_ref_t *local_ref = lookup_local(func, func->funcs[i].name);
|
||||||
func->funcs[i].local_ref = local_ref->ref;
|
func->funcs[i].local_ref = local_ref->ref;
|
||||||
TRACE("found ref %s %d for %s\n", debugstr_w(local_ref->name), local_ref->ref, debugstr_w(func->funcs[i].name));
|
TRACE("found ref %s %d for %s\n", debugstr_w(local_ref->name), local_ref->ref, debugstr_w(func->funcs[i].name));
|
||||||
|
|
|
@ -302,6 +302,7 @@ typedef struct _function_expression_t {
|
||||||
const WCHAR *src_str;
|
const WCHAR *src_str;
|
||||||
DWORD src_len;
|
DWORD src_len;
|
||||||
unsigned func_id;
|
unsigned func_id;
|
||||||
|
BOOL is_statement;
|
||||||
|
|
||||||
struct _function_expression_t *next; /* for compiler */
|
struct _function_expression_t *next; /* for compiler */
|
||||||
} function_expression_t;
|
} function_expression_t;
|
||||||
|
|
|
@ -1386,6 +1386,7 @@ static expression_t *new_function_expression(parser_ctx_t *ctx, const WCHAR *ide
|
||||||
ret->event_target = event_target;
|
ret->event_target = event_target;
|
||||||
ret->src_str = src_str;
|
ret->src_str = src_str;
|
||||||
ret->src_len = src_len;
|
ret->src_len = src_len;
|
||||||
|
ret->is_statement = FALSE;
|
||||||
ret->next = NULL;
|
ret->next = NULL;
|
||||||
|
|
||||||
return &ret->expr;
|
return &ret->expr;
|
||||||
|
|
|
@ -538,6 +538,7 @@ sync_test("delete_prop", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
var func_scope_val = 1;
|
var func_scope_val = 1;
|
||||||
|
var func_scope_val2 = 2;
|
||||||
|
|
||||||
sync_test("func_scope", function() {
|
sync_test("func_scope", function() {
|
||||||
var func_scope_val = 2;
|
var func_scope_val = 2;
|
||||||
|
@ -571,4 +572,28 @@ sync_test("func_scope", function() {
|
||||||
|
|
||||||
window = 1;
|
window = 1;
|
||||||
ok(window === window.self, "window = " + window);
|
ok(window === window.self, "window = " + window);
|
||||||
|
|
||||||
|
! function func_scope_val2() {};
|
||||||
|
ok(window.func_scope_val2 === 2, "window.func_scope_val2 = " + window.func_scope_val2);
|
||||||
|
|
||||||
|
var o = {};
|
||||||
|
(function(x) {
|
||||||
|
ok(x === o, "x = " + x);
|
||||||
|
! function x() {};
|
||||||
|
ok(x === o, "x != o");
|
||||||
|
})(o);
|
||||||
|
|
||||||
|
(function(x) {
|
||||||
|
ok(x === o, "x = " + x);
|
||||||
|
1, function x() {};
|
||||||
|
ok(x === o, "x != o");
|
||||||
|
})(o);
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
! function x() {};
|
||||||
|
try {
|
||||||
|
x();
|
||||||
|
ok(false, "expected exception");
|
||||||
|
}catch(e) {}
|
||||||
|
})(o);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue