Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
162f2e6b
Commit
162f2e6b
authored
Dec 13, 2012
by
Jacek Caban
Committed by
Alexandre Julliard
Dec 13, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jscript: Moved eval return value logic to specific statement handlers.
parent
86787db2
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
93 additions
and
115 deletions
+93
-115
compile.c
dlls/jscript/compile.c
+45
-95
engine.c
dlls/jscript/engine.c
+16
-20
engine.h
dlls/jscript/engine.h
+2
-0
lang.js
dlls/jscript/tests/lang.js
+6
-0
run.c
dlls/jscript/tests/run.c
+24
-0
No files found.
dlls/jscript/compile.c
View file @
162f2e6b
...
...
@@ -1016,21 +1016,12 @@ static HRESULT compile_block_statement(compiler_ctx_t *ctx, statement_t *iter)
{
HRESULT
hres
;
/* FIXME: do it only if needed */
if
(
!
iter
)
return
push_instr
(
ctx
,
OP_undefined
)
?
S_OK
:
E_OUTOFMEMORY
;
while
(
1
)
{
while
(
iter
)
{
hres
=
compile_statement
(
ctx
,
NULL
,
iter
);
if
(
FAILED
(
hres
))
return
hres
;
iter
=
iter
->
next
;
if
(
!
iter
)
break
;
if
(
!
push_instr
(
ctx
,
OP_pop
))
return
E_OUTOFMEMORY
;
}
return
S_OK
;
...
...
@@ -1073,28 +1064,31 @@ static HRESULT compile_variable_list(compiler_ctx_t *ctx, variable_declaration_t
/* ECMA-262 3rd Edition 12.2 */
static
HRESULT
compile_var_statement
(
compiler_ctx_t
*
ctx
,
var_statement_t
*
stat
)
{
HRESULT
hres
;
hres
=
compile_variable_list
(
ctx
,
stat
->
variable_list
);
if
(
FAILED
(
hres
))
return
hres
;
return
push_instr
(
ctx
,
OP_undefined
)
?
S_OK
:
E_OUTOFMEMORY
;
return
compile_variable_list
(
ctx
,
stat
->
variable_list
);
}
/* ECMA-262 3rd Edition 12.4 */
static
HRESULT
compile_expression_statement
(
compiler_ctx_t
*
ctx
,
expression_statement_t
*
stat
)
{
BOOL
no_ret
=
FALSE
;
HRESULT
hres
;
hres
=
compile_expression_noret
(
ctx
,
stat
->
expr
,
&
no_ret
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
!
ctx
->
from_eval
)
{
BOOL
no_ret
=
FALSE
;
/* FIXME: that's a big potential optimization */
if
(
no_ret
&&
!
push_instr
(
ctx
,
OP_undefined
))
return
E_OUTOFMEMORY
;
hres
=
compile_expression_noret
(
ctx
,
stat
->
expr
,
&
no_ret
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
!
no_ret
&&
!
push_instr
(
ctx
,
OP_pop
))
return
E_OUTOFMEMORY
;
}
else
{
hres
=
compile_expression
(
ctx
,
stat
->
expr
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
!
push_instr
(
ctx
,
OP_setret
))
return
E_OUTOFMEMORY
;
}
return
S_OK
;
}
...
...
@@ -1102,7 +1096,7 @@ static HRESULT compile_expression_statement(compiler_ctx_t *ctx, expression_stat
/* ECMA-262 3rd Edition 12.5 */
static
HRESULT
compile_if_statement
(
compiler_ctx_t
*
ctx
,
if_statement_t
*
stat
)
{
unsigned
jmp_else
,
jmp_end
;
unsigned
jmp_else
;
HRESULT
hres
;
hres
=
compile_expression
(
ctx
,
stat
->
expr
);
...
...
@@ -1117,23 +1111,24 @@ static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat)
if
(
FAILED
(
hres
))
return
hres
;
jmp_end
=
push_instr
(
ctx
,
OP_jmp
);
if
(
!
jmp_end
)
return
E_OUTOFMEMORY
;
if
(
stat
->
else_stat
)
{
unsigned
jmp_end
;
set_arg_uint
(
ctx
,
jmp_else
,
ctx
->
code_off
);
jmp_end
=
push_instr
(
ctx
,
OP_jmp
);
if
(
!
jmp_end
)
return
E_OUTOFMEMORY
;
set_arg_uint
(
ctx
,
jmp_else
,
ctx
->
code_off
);
if
(
stat
->
else_stat
)
{
hres
=
compile_statement
(
ctx
,
NULL
,
stat
->
else_stat
);
if
(
FAILED
(
hres
))
return
hres
;
set_arg_uint
(
ctx
,
jmp_end
,
ctx
->
code_off
);
}
else
{
/* FIXME: We could sometimes avoid it */
if
(
!
push_instr
(
ctx
,
OP_undefined
))
return
E_OUTOFMEMORY
;
set_arg_uint
(
ctx
,
jmp_else
,
ctx
->
code_off
);
}
set_arg_uint
(
ctx
,
jmp_end
,
ctx
->
code_off
);
return
S_OK
;
}
...
...
@@ -1152,12 +1147,9 @@ static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *s
if
(
!
stat_ctx
.
continue_label
)
return
E_OUTOFMEMORY
;
if
(
!
stat
->
do_while
)
{
/* FIXME: avoid */
if
(
!
push_instr
(
ctx
,
OP_undefined
))
return
E_OUTOFMEMORY
;
jmp_off
=
ctx
->
code_off
;
jmp_off
=
ctx
->
code_off
;
if
(
!
stat
->
do_while
)
{
label_set_addr
(
ctx
,
stat_ctx
.
continue_label
);
hres
=
compile_expression
(
ctx
,
stat
->
expr
);
if
(
FAILED
(
hres
))
...
...
@@ -1166,11 +1158,6 @@ static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *s
hres
=
push_instr_uint
(
ctx
,
OP_jmp_z
,
stat_ctx
.
break_label
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
!
push_instr
(
ctx
,
OP_pop
))
return
E_OUTOFMEMORY
;
}
else
{
jmp_off
=
ctx
->
code_off
;
}
hres
=
compile_statement
(
ctx
,
&
stat_ctx
,
stat
->
statement
);
...
...
@@ -1186,9 +1173,6 @@ static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *s
hres
=
push_instr_uint
(
ctx
,
OP_jmp_z
,
stat_ctx
.
break_label
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
!
push_instr
(
ctx
,
OP_pop
))
return
E_OUTOFMEMORY
;
}
hres
=
push_instr_uint
(
ctx
,
OP_jmp
,
jmp_off
);
...
...
@@ -1228,10 +1212,6 @@ static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
if
(
!
stat_ctx
.
continue_label
)
return
E_OUTOFMEMORY
;
/* FIXME: avoid */
if
(
!
push_instr
(
ctx
,
OP_undefined
))
return
E_OUTOFMEMORY
;
expr_off
=
ctx
->
code_off
;
if
(
stat
->
expr
)
{
...
...
@@ -1244,9 +1224,6 @@ static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
return
hres
;
}
if
(
!
push_instr
(
ctx
,
OP_pop
))
return
E_OUTOFMEMORY
;
hres
=
compile_statement
(
ctx
,
&
stat_ctx
,
stat
->
statement
);
if
(
FAILED
(
hres
))
return
hres
;
...
...
@@ -1317,10 +1294,6 @@ static HRESULT compile_forin_statement(compiler_ctx_t *ctx, forin_statement_t *s
if
(
FAILED
(
hres
))
return
hres
;
/* FIXME: avoid */
if
(
!
push_instr
(
ctx
,
OP_undefined
))
return
E_OUTOFMEMORY
;
label_set_addr
(
ctx
,
stat_ctx
.
continue_label
);
hres
=
push_instr_uint
(
ctx
,
OP_forin
,
stat_ctx
.
break_label
);
if
(
FAILED
(
hres
))
...
...
@@ -1361,7 +1334,6 @@ static HRESULT pop_to_stat(compiler_ctx_t *ctx, BOOL var_stack, BOOL scope_stack
}
}
return
S_OK
;
}
...
...
@@ -1415,9 +1387,6 @@ static HRESULT compile_continue_statement(compiler_ctx_t *ctx, branch_statement_
if
(
FAILED
(
hres
))
return
hres
;
if
(
!
push_instr
(
ctx
,
OP_undefined
))
return
E_OUTOFMEMORY
;
return
push_instr_uint
(
ctx
,
OP_jmp
,
pop_ctx
->
continue_label
);
}
...
...
@@ -1455,9 +1424,6 @@ static HRESULT compile_break_statement(compiler_ctx_t *ctx, branch_statement_t *
if
(
FAILED
(
hres
))
return
hres
;
if
(
!
push_instr
(
ctx
,
OP_undefined
))
return
E_OUTOFMEMORY
;
return
push_instr_uint
(
ctx
,
OP_jmp
,
pop_ctx
->
break_label
);
}
...
...
@@ -1475,11 +1441,14 @@ static HRESULT compile_return_statement(compiler_ctx_t *ctx, expression_statemen
if
(
FAILED
(
hres
))
return
hres
;
if
(
stat
->
expr
)
{
if
(
stat
->
expr
)
hres
=
compile_expression
(
ctx
,
stat
->
expr
);
if
(
FAILED
(
hres
))
return
hres
;
}
else
hres
=
push_instr
(
ctx
,
OP_undefined
)
?
S_OK
:
E_OUTOFMEMORY
;
if
(
FAILED
(
hres
))
return
hres
;
if
(
!
push_instr
(
ctx
,
OP_setret
))
return
E_OUTOFMEMORY
;
hres
=
pop_to_stat
(
ctx
,
FALSE
,
TRUE
,
NULL
);
if
(
FAILED
(
hres
))
...
...
@@ -1607,26 +1576,14 @@ static HRESULT compile_switch_statement(compiler_ctx_t *ctx, switch_statement_t
set_arg_uint
(
ctx
,
iter
->
expr
?
case_jmps
[
i
++
]
:
default_jmp
,
ctx
->
code_off
);
if
(
iter
->
stat
)
{
for
(
stat_iter
=
iter
->
stat
;
stat_iter
&&
(
!
iter
->
next
||
iter
->
next
->
stat
!=
stat_iter
);
stat_iter
=
stat_iter
->
next
)
{
hres
=
compile_statement
(
ctx
,
&
stat_ctx
,
stat_iter
);
if
(
FAILED
(
hres
))
break
;
if
(
stat_iter
->
next
&&
!
push_instr
(
ctx
,
OP_pop
))
{
hres
=
E_OUTOFMEMORY
;
break
;
}
}
for
(
stat_iter
=
iter
->
stat
;
stat_iter
&&
(
!
iter
->
next
||
iter
->
next
->
stat
!=
stat_iter
);
stat_iter
=
stat_iter
->
next
)
{
hres
=
compile_statement
(
ctx
,
&
stat_ctx
,
stat_iter
);
if
(
FAILED
(
hres
))
break
;
}
else
{
if
(
!
push_instr
(
ctx
,
OP_undefined
))
{
hres
=
E_OUTOFMEMORY
;
break
;
}
}
if
(
FAILED
(
hres
))
break
;
}
heap_free
(
case_jmps
);
...
...
@@ -1639,8 +1596,6 @@ static HRESULT compile_switch_statement(compiler_ctx_t *ctx, switch_statement_t
if
(
FAILED
(
hres
))
return
hres
;
set_arg_uint
(
ctx
,
default_jmp
,
ctx
->
code_off
);
if
(
!
push_instr
(
ctx
,
OP_undefined
))
return
E_OUTOFMEMORY
;
}
label_set_addr
(
ctx
,
stat_ctx
.
break_label
);
...
...
@@ -1714,10 +1669,6 @@ static HRESULT compile_try_statement(compiler_ctx_t *ctx, try_statement_t *stat)
}
if
(
stat
->
finally_statement
)
{
/* FIXME: avoid */
if
(
!
push_instr
(
ctx
,
OP_pop
))
return
E_OUTOFMEMORY
;
hres
=
compile_statement
(
ctx
,
stat
->
catch_block
?
NULL
:
&
finally_ctx
,
stat
->
finally_statement
);
if
(
FAILED
(
hres
))
return
hres
;
...
...
@@ -1749,7 +1700,8 @@ static HRESULT compile_statement(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx,
hres
=
compile_continue_statement
(
ctx
,
(
branch_statement_t
*
)
stat
);
break
;
case
STAT_EMPTY
:
hres
=
push_instr
(
ctx
,
OP_undefined
)
?
S_OK
:
E_OUTOFMEMORY
;
/* FIXME */
/* nothing to do */
hres
=
S_OK
;
break
;
case
STAT_EXPR
:
hres
=
compile_expression_statement
(
ctx
,
(
expression_statement_t
*
)
stat
);
...
...
@@ -1883,8 +1835,6 @@ static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source,
resolve_labels
(
ctx
,
off
);
if
(
!
from_eval
&&
!
push_instr
(
ctx
,
OP_pop
))
return
E_OUTOFMEMORY
;
if
(
!
push_instr
(
ctx
,
OP_ret
))
return
E_OUTOFMEMORY
;
...
...
dlls/jscript/engine.c
View file @
162f2e6b
...
...
@@ -291,6 +291,7 @@ HRESULT create_exec_ctx(script_ctx_t *script_ctx, IDispatch *this_obj, jsdisp_t
ctx
->
ref
=
1
;
ctx
->
is_global
=
is_global
;
ctx
->
ret
=
jsval_undefined
();
/* ECMA-262 3rd Edition 11.2.3.7 */
if
(
this_obj
)
{
...
...
@@ -340,6 +341,7 @@ void exec_release(exec_ctx_t *ctx)
IDispatch_Release
(
ctx
->
this_obj
);
if
(
ctx
->
script
)
script_release
(
ctx
->
script
);
jsval_release
(
ctx
->
ret
);
heap_free
(
ctx
->
stack
);
heap_free
(
ctx
);
}
...
...
@@ -592,20 +594,16 @@ static HRESULT interp_forin(exec_ctx_t *ctx)
IDispatchEx
*
dispex
;
DISPID
id
,
var_id
;
BSTR
name
=
NULL
;
jsval_t
val
;
HRESULT
hres
;
TRACE
(
"
\n
"
);
val
=
stack_pop
(
ctx
);
assert
(
is_number
(
stack_top
(
ctx
)));
id
=
get_number
(
stack_top
(
ctx
));
var_obj
=
stack_topn_objid
(
ctx
,
1
,
&
var_id
);
if
(
!
var_obj
)
{
FIXME
(
"invalid ref
\n
"
);
jsval_release
(
val
);
return
E_FAIL
;
}
...
...
@@ -619,10 +617,8 @@ static HRESULT interp_forin(exec_ctx_t *ctx)
if
(
hres
==
S_OK
)
hres
=
IDispatchEx_GetMemberName
(
dispex
,
id
,
&
name
);
IDispatchEx_Release
(
dispex
);
if
(
FAILED
(
hres
))
{
jsval_release
(
val
);
if
(
FAILED
(
hres
))
return
hres
;
}
}
else
{
TRACE
(
"No IDispatchEx
\n
"
);
}
...
...
@@ -636,7 +632,6 @@ static HRESULT interp_forin(exec_ctx_t *ctx)
if
(
!
str
)
return
E_OUTOFMEMORY
;
jsval_release
(
val
);
stack_pop
(
ctx
);
stack_push
(
ctx
,
jsval_number
(
id
));
/* safe, just after pop() */
...
...
@@ -649,7 +644,6 @@ static HRESULT interp_forin(exec_ctx_t *ctx)
}
else
{
stack_popn
(
ctx
,
4
);
ctx
->
ip
=
arg
;
return
stack_push
(
ctx
,
val
);
}
return
S_OK
;
}
...
...
@@ -795,8 +789,6 @@ static HRESULT interp_end_finally(exec_ctx_t *ctx)
TRACE
(
"
\n
"
);
v
=
stack_pop
(
ctx
);
assert
(
is_bool
(
stack_top
(
ctx
)));
if
(
!
get_bool
(
stack_top
(
ctx
)))
{
TRACE
(
"passing exception
\n
"
);
...
...
@@ -809,7 +801,7 @@ static HRESULT interp_end_finally(exec_ctx_t *ctx)
}
stack_popn
(
ctx
,
2
);
return
stack_push
(
ctx
,
v
)
;
return
S_OK
;
}
/* ECMA-262 3rd Edition 13 */
...
...
@@ -2361,6 +2353,15 @@ static HRESULT interp_ret(exec_ctx_t *ctx)
return
S_OK
;
}
static
HRESULT
interp_setret
(
exec_ctx_t
*
ctx
)
{
TRACE
(
"
\n
"
);
jsval_release
(
ctx
->
ret
);
ctx
->
ret
=
stack_pop
(
ctx
);
return
S_OK
;
}
typedef
HRESULT
(
*
op_func_t
)(
exec_ctx_t
*
);
static
const
op_func_t
op_funcs
[]
=
{
...
...
@@ -2421,10 +2422,6 @@ static HRESULT unwind_exception(exec_ctx_t *ctx)
return
hres
;
hres
=
stack_push
(
ctx
,
jsval_bool
(
FALSE
));
if
(
FAILED
(
hres
))
return
hres
;
hres
=
stack_push
(
ctx
,
jsval_undefined
());
}
return
hres
;
...
...
@@ -2485,11 +2482,10 @@ static HRESULT enter_bytecode(script_ctx_t *ctx, bytecode_t *code, function_code
assert
(
exec_ctx
->
top
==
prev_top
+
1
||
exec_ctx
->
top
==
prev_top
);
assert
(
exec_ctx
->
scope_chain
==
prev_scope
);
assert
(
exec_ctx
->
top
==
prev_top
);
if
(
exec_ctx
->
top
==
prev_top
)
*
ret
=
jsval_undefined
();
else
*
ret
=
stack_pop
(
exec_ctx
);
*
ret
=
exec_ctx
->
ret
;
exec_ctx
->
ret
=
jsval_undefined
();
return
S_OK
;
}
...
...
dlls/jscript/engine.h
View file @
162f2e6b
...
...
@@ -105,6 +105,7 @@ typedef struct {
X(typeofident,1, 0,0) \
X(refval, 1, 0,0) \
X(ret, 0, 0,0) \
X(setret, 1, 0,0) \
X(sub, 1, 0,0) \
X(undefined, 1, 0,0) \
X(var_set, 1, ARG_BSTR, 0) \
...
...
@@ -238,6 +239,7 @@ struct _exec_ctx_t {
unsigned
stack_size
;
unsigned
top
;
except_frame_t
*
except_frame
;
jsval_t
ret
;
unsigned
ip
;
};
...
...
dlls/jscript/tests/lang.js
View file @
162f2e6b
...
...
@@ -191,6 +191,12 @@ tmp = eval("1,2;");
ok
(
tmp
===
2
,
"tmp = "
+
tmp
);
tmp
=
eval
(
"if(true) {3}"
);
ok
(
tmp
===
3
,
"tmp = "
+
tmp
);
testNoRes
();
eval
(
"testRes(); testRes()"
);
tmp
=
eval
(
"3; if(false) {4;} else {};;;"
)
ok
(
tmp
===
3
,
"tmp = "
+
tmp
);
tmp
=
(
function
(){
return
testRes
();})();
var
obj1
=
new
Object
();
ok
(
typeof
(
obj1
)
===
"object"
,
"typeof(obj1) is not object"
);
...
...
dlls/jscript/tests/run.c
View file @
162f2e6b
...
...
@@ -126,6 +126,8 @@ DEFINE_EXPECT(DeleteMemberByDispID);
#define DISPID_GLOBAL_TESTARGTYPES 0x1015
#define DISPID_GLOBAL_INTPROP 0x1016
#define DISPID_GLOBAL_DISPUNK 0x1017
#define DISPID_GLOBAL_TESTRES 0x1018
#define DISPID_GLOBAL_TESTNORES 0x1019
#define DISPID_GLOBAL_TESTPROPDELETE 0x2000
...
...
@@ -598,6 +600,16 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
return
S_OK
;
}
if
(
!
strcmp_wa
(
bstrName
,
"testRes"
))
{
*
pid
=
DISPID_GLOBAL_TESTRES
;
return
S_OK
;
}
if
(
!
strcmp_wa
(
bstrName
,
"testNoRes"
))
{
*
pid
=
DISPID_GLOBAL_TESTNORES
;
return
S_OK
;
}
if
(
strict_dispid_check
&&
strcmp_wa
(
bstrName
,
"t"
))
ok
(
0
,
"unexpected call %s
\n
"
,
wine_dbgstr_w
(
bstrName
));
return
DISP_E_UNKNOWNNAME
;
...
...
@@ -735,6 +747,18 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
return
S_OK
;
case
DISPID_GLOBAL_TESTRES
:
ok
(
pvarRes
!=
NULL
,
"pvarRes = NULL
\n
"
);
if
(
pvarRes
)
V_VT
(
pvarRes
)
=
VT_NULL
;
return
S_OK
;
case
DISPID_GLOBAL_TESTNORES
:
ok
(
!
pvarRes
,
"pvarRes != NULL
\n
"
);
if
(
pvarRes
)
V_VT
(
pvarRes
)
=
VT_NULL
;
return
S_OK
;
case
DISPID_GLOBAL_TESTOBJ
:
ok
(
wFlags
==
INVOKE_PROPERTYGET
,
"wFlags = %x
\n
"
,
wFlags
);
ok
(
pdp
!=
NULL
,
"pdp == NULL
\n
"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment