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
da02140b
Commit
da02140b
authored
Aug 02, 2016
by
Jacek Caban
Committed by
Alexandre Julliard
Aug 02, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jscript: Allow accessing arguments values directly from stack.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
abba9630
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
107 additions
and
25 deletions
+107
-25
engine.c
dlls/jscript/engine.c
+107
-25
No files found.
dlls/jscript/engine.c
View file @
da02140b
...
@@ -50,6 +50,7 @@ typedef struct {
...
@@ -50,6 +50,7 @@ typedef struct {
enum
{
enum
{
EXPRVAL_JSVAL
,
EXPRVAL_JSVAL
,
EXPRVAL_IDREF
,
EXPRVAL_IDREF
,
EXPRVAL_STACK_REF
,
EXPRVAL_INVALID
EXPRVAL_INVALID
}
type
;
}
type
;
union
{
union
{
...
@@ -58,6 +59,7 @@ typedef struct {
...
@@ -58,6 +59,7 @@ typedef struct {
IDispatch
*
disp
;
IDispatch
*
disp
;
DISPID
id
;
DISPID
id
;
}
idref
;
}
idref
;
unsigned
off
;
HRESULT
hres
;
HRESULT
hres
;
}
u
;
}
u
;
}
exprval_t
;
}
exprval_t
;
...
@@ -103,10 +105,15 @@ static inline jsval_t stack_top(script_ctx_t *ctx)
...
@@ -103,10 +105,15 @@ static inline jsval_t stack_top(script_ctx_t *ctx)
return
ctx
->
stack
[
ctx
->
stack_top
-
1
];
return
ctx
->
stack
[
ctx
->
stack_top
-
1
];
}
}
static
inline
jsval_t
stack_topn
(
script_ctx_t
*
ctx
,
unsigned
n
)
static
inline
jsval_t
*
stack_top_ref
(
script_ctx_t
*
ctx
,
unsigned
n
)
{
{
assert
(
ctx
->
stack_top
>
ctx
->
call_ctx
->
stack_base
+
n
);
assert
(
ctx
->
stack_top
>
ctx
->
call_ctx
->
stack_base
+
n
);
return
ctx
->
stack
[
ctx
->
stack_top
-
1
-
n
];
return
ctx
->
stack
+
ctx
->
stack_top
-
1
-
n
;
}
static
inline
jsval_t
stack_topn
(
script_ctx_t
*
ctx
,
unsigned
n
)
{
return
*
stack_top_ref
(
ctx
,
n
);
}
}
static
inline
jsval_t
*
stack_args
(
script_ctx_t
*
ctx
,
unsigned
n
)
static
inline
jsval_t
*
stack_args
(
script_ctx_t
*
ctx
,
unsigned
n
)
...
@@ -183,6 +190,11 @@ static HRESULT stack_push_exprval(script_ctx_t *ctx, exprval_t *val)
...
@@ -183,6 +190,11 @@ static HRESULT stack_push_exprval(script_ctx_t *ctx, exprval_t *val)
else
else
IDispatch_Release
(
val
->
u
.
idref
.
disp
);
IDispatch_Release
(
val
->
u
.
idref
.
disp
);
return
hres
;
return
hres
;
case
EXPRVAL_STACK_REF
:
hres
=
stack_push
(
ctx
,
jsval_number
(
val
->
u
.
off
));
if
(
SUCCEEDED
(
hres
))
hres
=
stack_push
(
ctx
,
jsval_undefined
());
return
hres
;
case
EXPRVAL_INVALID
:
case
EXPRVAL_INVALID
:
hres
=
stack_push
(
ctx
,
jsval_undefined
());
hres
=
stack_push
(
ctx
,
jsval_undefined
());
if
(
SUCCEEDED
(
hres
))
if
(
SUCCEEDED
(
hres
))
...
@@ -194,19 +206,50 @@ static HRESULT stack_push_exprval(script_ctx_t *ctx, exprval_t *val)
...
@@ -194,19 +206,50 @@ static HRESULT stack_push_exprval(script_ctx_t *ctx, exprval_t *val)
return
E_FAIL
;
return
E_FAIL
;
}
}
static
BOOL
exprval_from_stack
(
jsval_t
v1
,
jsval_t
v2
,
exprval_t
*
r
)
static
BOOL
stack_topn_exprval
(
script_ctx_t
*
ctx
,
unsigned
n
,
exprval_t
*
r
)
{
{
switch
(
jsval_type
(
v1
))
{
jsval_t
v
=
stack_topn
(
ctx
,
n
+
1
);
switch
(
jsval_type
(
v
))
{
case
JSV_NUMBER
:
{
call_frame_t
*
frame
=
ctx
->
call_ctx
;
unsigned
off
=
get_number
(
v
);
if
(
!
frame
->
base_scope
->
frame
&&
off
>=
frame
->
arguments_off
)
{
DISPID
id
;
HRESULT
hres
;
/* Got stack reference in deoptimized code. Need to convert it back to variable object reference. */
hres
=
jsdisp_get_id
(
ctx
->
call_ctx
->
base_scope
->
jsobj
,
frame
->
function
->
params
[
off
-
frame
->
arguments_off
],
0
,
&
id
);
if
(
FAILED
(
hres
))
{
r
->
type
=
EXPRVAL_INVALID
;
r
->
u
.
hres
=
hres
;
return
FALSE
;
}
*
stack_top_ref
(
ctx
,
n
+
1
)
=
jsval_obj
(
jsdisp_addref
(
frame
->
base_scope
->
jsobj
));
*
stack_top_ref
(
ctx
,
n
)
=
jsval_number
(
id
);
r
->
type
=
EXPRVAL_IDREF
;
r
->
u
.
idref
.
disp
=
frame
->
base_scope
->
obj
;
r
->
u
.
idref
.
id
=
id
;
return
TRUE
;
}
r
->
type
=
EXPRVAL_STACK_REF
;
r
->
u
.
off
=
off
;
return
TRUE
;
}
case
JSV_OBJECT
:
case
JSV_OBJECT
:
r
->
type
=
EXPRVAL_IDREF
;
r
->
type
=
EXPRVAL_IDREF
;
r
->
u
.
idref
.
disp
=
get_object
(
v
1
);
r
->
u
.
idref
.
disp
=
get_object
(
v
);
assert
(
is_number
(
v2
));
assert
(
is_number
(
stack_topn
(
ctx
,
n
)
));
r
->
u
.
idref
.
id
=
get_number
(
v2
);
r
->
u
.
idref
.
id
=
get_number
(
stack_topn
(
ctx
,
n
)
);
return
TRUE
;
return
TRUE
;
case
JSV_UNDEFINED
:
case
JSV_UNDEFINED
:
r
->
type
=
EXPRVAL_INVALID
;
r
->
type
=
EXPRVAL_INVALID
;
assert
(
is_number
(
v2
));
assert
(
is_number
(
stack_topn
(
ctx
,
n
)
));
r
->
u
.
hres
=
get_number
(
v2
);
r
->
u
.
hres
=
get_number
(
stack_topn
(
ctx
,
n
)
);
return
FALSE
;
return
FALSE
;
default:
default:
assert
(
0
);
assert
(
0
);
...
@@ -216,31 +259,59 @@ static BOOL exprval_from_stack(jsval_t v1, jsval_t v2, exprval_t *r)
...
@@ -216,31 +259,59 @@ static BOOL exprval_from_stack(jsval_t v1, jsval_t v2, exprval_t *r)
static
inline
BOOL
stack_pop_exprval
(
script_ctx_t
*
ctx
,
exprval_t
*
r
)
static
inline
BOOL
stack_pop_exprval
(
script_ctx_t
*
ctx
,
exprval_t
*
r
)
{
{
jsval_t
v
=
stack_pop
(
ctx
);
BOOL
ret
=
stack_topn_exprval
(
ctx
,
0
,
r
);
return
exprval_from_stack
(
stack_pop
(
ctx
),
v
,
r
);
ctx
->
stack_top
-=
2
;
}
return
ret
;
static
inline
BOOL
stack_topn_exprval
(
script_ctx_t
*
ctx
,
unsigned
n
,
exprval_t
*
r
)
{
return
exprval_from_stack
(
stack_topn
(
ctx
,
n
+
1
),
stack_topn
(
ctx
,
n
),
r
);
}
}
static
HRESULT
exprval_propput
(
script_ctx_t
*
ctx
,
exprval_t
*
ref
,
jsval_t
v
)
static
HRESULT
exprval_propput
(
script_ctx_t
*
ctx
,
exprval_t
*
ref
,
jsval_t
v
)
{
{
assert
(
ref
->
type
==
EXPRVAL_IDREF
);
switch
(
ref
->
type
)
{
return
disp_propput
(
ctx
,
ref
->
u
.
idref
.
disp
,
ref
->
u
.
idref
.
id
,
v
);
case
EXPRVAL_STACK_REF
:
{
jsval_t
*
r
=
ctx
->
stack
+
ref
->
u
.
off
;
jsval_release
(
*
r
);
return
jsval_copy
(
v
,
r
);
}
case
EXPRVAL_IDREF
:
return
disp_propput
(
ctx
,
ref
->
u
.
idref
.
disp
,
ref
->
u
.
idref
.
id
,
v
);
default:
assert
(
0
);
return
E_FAIL
;
}
}
}
static
HRESULT
exprval_propget
(
script_ctx_t
*
ctx
,
exprval_t
*
ref
,
jsval_t
*
r
)
static
HRESULT
exprval_propget
(
script_ctx_t
*
ctx
,
exprval_t
*
ref
,
jsval_t
*
r
)
{
{
assert
(
ref
->
type
==
EXPRVAL_IDREF
);
switch
(
ref
->
type
)
{
return
disp_propget
(
ctx
,
ref
->
u
.
idref
.
disp
,
ref
->
u
.
idref
.
id
,
r
);
case
EXPRVAL_STACK_REF
:
return
jsval_copy
(
ctx
->
stack
[
ref
->
u
.
off
],
r
);
case
EXPRVAL_IDREF
:
return
disp_propget
(
ctx
,
ref
->
u
.
idref
.
disp
,
ref
->
u
.
idref
.
id
,
r
);
default:
assert
(
0
);
return
E_FAIL
;
}
}
}
static
HRESULT
exprval_call
(
script_ctx_t
*
ctx
,
exprval_t
*
ref
,
WORD
flags
,
unsigned
argc
,
jsval_t
*
argv
,
jsval_t
*
r
)
static
HRESULT
exprval_call
(
script_ctx_t
*
ctx
,
exprval_t
*
ref
,
WORD
flags
,
unsigned
argc
,
jsval_t
*
argv
,
jsval_t
*
r
)
{
{
assert
(
ref
->
type
==
EXPRVAL_IDREF
);
switch
(
ref
->
type
)
{
return
disp_call
(
ctx
,
ref
->
u
.
idref
.
disp
,
ref
->
u
.
idref
.
id
,
flags
,
argc
,
argv
,
r
);
case
EXPRVAL_STACK_REF
:
{
jsval_t
v
=
ctx
->
stack
[
ref
->
u
.
off
];
if
(
!
is_object_instance
(
v
))
{
FIXME
(
"invoke %s
\n
"
,
debugstr_jsval
(
v
));
return
E_FAIL
;
}
return
disp_call_value
(
ctx
,
get_object
(
v
),
NULL
,
flags
,
argc
,
argv
,
r
);
}
case
EXPRVAL_IDREF
:
return
disp_call
(
ctx
,
ref
->
u
.
idref
.
disp
,
ref
->
u
.
idref
.
id
,
flags
,
argc
,
argv
,
r
);
default:
assert
(
0
);
return
E_FAIL
;
}
}
}
/* ECMA-262 3rd Edition 8.7.1 */
/* ECMA-262 3rd Edition 8.7.1 */
...
@@ -271,6 +342,7 @@ static void exprval_release(exprval_t *val)
...
@@ -271,6 +342,7 @@ static void exprval_release(exprval_t *val)
if
(
val
->
u
.
idref
.
disp
)
if
(
val
->
u
.
idref
.
disp
)
IDispatch_Release
(
val
->
u
.
idref
.
disp
);
IDispatch_Release
(
val
->
u
.
idref
.
disp
);
return
;
return
;
case
EXPRVAL_STACK_REF
:
case
EXPRVAL_INVALID
:
case
EXPRVAL_INVALID
:
return
;
return
;
}
}
...
@@ -530,9 +602,16 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re
...
@@ -530,9 +602,16 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re
if
(
ctx
->
call_ctx
)
{
if
(
ctx
->
call_ctx
)
{
for
(
scope
=
ctx
->
call_ctx
->
scope
;
scope
;
scope
=
scope
->
next
)
{
for
(
scope
=
ctx
->
call_ctx
->
scope
;
scope
;
scope
=
scope
->
next
)
{
if
(
scope
->
frame
)
{
if
(
scope
->
frame
)
{
hres
=
detach_variable_object
(
ctx
,
scope
->
frame
);
function_code_t
*
func
=
scope
->
frame
->
function
;
if
(
FAILED
(
hres
))
int
i
;
return
hres
;
for
(
i
=
0
;
i
<
func
->
param_cnt
;
i
++
)
{
if
(
!
strcmpW
(
identifier
,
func
->
params
[
i
]))
{
ret
->
type
=
EXPRVAL_STACK_REF
;
ret
->
u
.
off
=
scope
->
frame
->
arguments_off
+
i
;
return
S_OK
;
}
}
}
}
if
(
scope
->
jsobj
)
if
(
scope
->
jsobj
)
hres
=
jsdisp_get_id
(
scope
->
jsobj
,
identifier
,
fdexNameImplicit
,
&
id
);
hres
=
jsdisp_get_id
(
scope
->
jsobj
,
identifier
,
fdexNameImplicit
,
&
id
);
...
@@ -1677,6 +1756,9 @@ static HRESULT interp_delete_ident(script_ctx_t *ctx)
...
@@ -1677,6 +1756,9 @@ static HRESULT interp_delete_ident(script_ctx_t *ctx)
return
hres
;
return
hres
;
switch
(
exprval
.
type
)
{
switch
(
exprval
.
type
)
{
case
EXPRVAL_STACK_REF
:
ret
=
FALSE
;
break
;
case
EXPRVAL_IDREF
:
case
EXPRVAL_IDREF
:
hres
=
disp_delete
(
exprval
.
u
.
idref
.
disp
,
exprval
.
u
.
idref
.
id
,
&
ret
);
hres
=
disp_delete
(
exprval
.
u
.
idref
.
disp
,
exprval
.
u
.
idref
.
id
,
&
ret
);
IDispatch_Release
(
exprval
.
u
.
idref
.
disp
);
IDispatch_Release
(
exprval
.
u
.
idref
.
disp
);
...
...
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