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
765a52e8
Commit
765a52e8
authored
Aug 04, 2016
by
Jacek Caban
Committed by
Alexandre Julliard
Aug 04, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jscript: Store variables on the stack if possible.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7694afff
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
86 additions
and
30 deletions
+86
-30
engine.c
dlls/jscript/engine.c
+84
-30
engine.h
dlls/jscript/engine.h
+2
-0
No files found.
dlls/jscript/engine.c
View file @
765a52e8
...
...
@@ -217,11 +217,16 @@ static BOOL stack_topn_exprval(script_ctx_t *ctx, unsigned n, exprval_t *r)
if
(
!
frame
->
base_scope
->
frame
&&
off
>=
frame
->
arguments_off
)
{
DISPID
id
;
BSTR
name
;
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
);
assert
(
off
<
frame
->
variables_off
+
frame
->
function
->
var_cnt
);
name
=
off
>=
frame
->
variables_off
?
frame
->
function
->
variables
[
off
-
frame
->
variables_off
].
name
:
frame
->
function
->
params
[
off
-
frame
->
arguments_off
];
hres
=
jsdisp_get_id
(
ctx
->
call_ctx
->
base_scope
->
jsobj
,
name
,
0
,
&
id
);
if
(
FAILED
(
hres
))
{
r
->
type
=
EXPRVAL_INVALID
;
r
->
u
.
hres
=
hres
;
...
...
@@ -541,6 +546,13 @@ static HRESULT equal2_values(jsval_t lval, jsval_t rval, BOOL *ret)
return
S_OK
;
}
static
inline
unsigned
local_off
(
call_frame_t
*
frame
,
int
ref
)
{
return
ref
<
0
?
frame
->
arguments_off
-
ref
-
1
:
frame
->
variables_off
+
ref
;
}
/*
* Transfers local variables from stack to variable object.
* It's slow, so we want to avoid it as much as possible.
...
...
@@ -566,8 +578,9 @@ static HRESULT detach_variable_object(script_ctx_t *ctx, call_frame_t *frame)
frame
->
base_scope
->
frame
=
NULL
;
for
(
i
=
0
;
i
<
frame
->
function
->
param_cnt
;
i
++
)
{
hres
=
jsdisp_propput_name
(
frame
->
variable_obj
,
frame
->
function
->
params
[
i
],
ctx
->
stack
[
frame
->
arguments_off
+
i
]);
for
(
i
=
0
;
i
<
frame
->
function
->
locals_cnt
;
i
++
)
{
hres
=
jsdisp_propput_name
(
frame
->
variable_obj
,
frame
->
function
->
locals
[
i
].
name
,
ctx
->
stack
[
local_off
(
frame
,
frame
->
function
->
locals
[
i
].
ref
)]);
if
(
FAILED
(
hres
))
return
hres
;
}
...
...
@@ -622,9 +635,10 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re
local_ref_t
*
ref
=
lookup_local
(
func
,
identifier
);
static
const
WCHAR
argumentsW
[]
=
{
'a'
,
'r'
,
'g'
,
'u'
,
'm'
,
'e'
,
'n'
,
't'
,
's'
,
0
};
if
(
ref
&&
ref
->
ref
<
0
)
{
if
(
ref
)
{
ret
->
type
=
EXPRVAL_STACK_REF
;
ret
->
u
.
off
=
scope
->
frame
->
arguments_off
-
ref
->
ref
-
1
;
ret
->
u
.
off
=
local_off
(
scope
->
frame
,
ref
->
ref
);
TRACE
(
"returning ref %d for %d
\n
"
,
ret
->
u
.
off
,
ref
->
ref
);
return
S_OK
;
}
...
...
@@ -2532,20 +2546,24 @@ static void pop_call_frame(script_ctx_t *ctx)
{
call_frame_t
*
frame
=
ctx
->
call_ctx
;
frame
->
stack_base
-=
frame
->
pop_locals
+
frame
->
pop_variables
;
assert
(
frame
->
scope
==
frame
->
base_scope
);
/* If current scope will be kept alive, we need to transfer local variables to its variable object. */
if
(
frame
->
scope
&&
frame
->
scope
->
ref
>
1
)
{
HRESULT
hres
=
detach_variable_object
(
ctx
,
frame
);
if
(
FAILED
(
hres
))
ERR
(
"Failed to detach variable object: %08x
\n
"
,
hres
);
}
if
(
frame
->
arguments_obj
)
detach_arguments_object
(
frame
->
arguments_obj
);
if
(
frame
->
scope
)
{
/* If current scope will be kept alive, we need to transfer local variables to its variable object. */
if
(
frame
->
scope
->
ref
>
1
)
{
HRESULT
hres
=
detach_variable_object
(
ctx
,
frame
);
if
(
FAILED
(
hres
))
ERR
(
"Failed to detach variable object: %08x
\n
"
,
hres
);
}
if
(
frame
->
scope
)
scope_release
(
frame
->
scope
);
}
frame
->
stack_base
-=
frame
->
pop_locals
;
if
(
frame
->
pop_variables
)
stack_popn
(
ctx
,
frame
->
pop_variables
);
stack_popn
(
ctx
,
frame
->
pop_locals
);
ctx
->
call_ctx
=
frame
->
prev_frame
;
...
...
@@ -2738,6 +2756,36 @@ static HRESULT setup_scope(script_ctx_t *ctx, call_frame_t *frame, unsigned argc
}
frame
->
pop_locals
=
ctx
->
stack_top
-
orig_stack
;
frame
->
variables_off
=
ctx
->
stack_top
;
for
(
i
=
0
;
i
<
frame
->
function
->
var_cnt
;
i
++
)
{
hres
=
stack_push
(
ctx
,
jsval_undefined
());
if
(
FAILED
(
hres
))
{
stack_popn
(
ctx
,
ctx
->
stack_top
-
orig_stack
);
return
hres
;
}
}
frame
->
pop_variables
=
i
;
for
(
i
=
0
;
i
<
frame
->
function
->
func_cnt
;
i
++
)
{
if
(
frame
->
function
->
funcs
[
i
].
name
&&
!
frame
->
function
->
funcs
[
i
].
event_target
)
{
jsdisp_t
*
func_obj
;
unsigned
off
;
hres
=
create_source_function
(
ctx
,
frame
->
bytecode
,
frame
->
function
->
funcs
+
i
,
frame
->
base_scope
,
&
func_obj
);
if
(
FAILED
(
hres
))
{
stack_popn
(
ctx
,
ctx
->
stack_top
-
orig_stack
);
return
hres
;
}
off
=
local_off
(
frame
,
frame
->
function
->
funcs
[
i
].
local_ref
);
jsval_release
(
ctx
->
stack
[
off
]);
ctx
->
stack
[
off
]
=
jsval_obj
(
func_obj
);
}
}
frame
->
base_scope
->
frame
=
frame
;
return
S_OK
;
}
...
...
@@ -2752,33 +2800,38 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
for
(
i
=
0
;
i
<
function
->
func_cnt
;
i
++
)
{
jsdisp_t
*
func_obj
;
if
(
!
function
->
funcs
[
i
].
name
)
if
(
!
function
->
funcs
[
i
].
event_target
)
continue
;
hres
=
create_source_function
(
ctx
,
bytecode
,
function
->
funcs
+
i
,
scope
,
&
func_obj
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
function
->
funcs
[
i
].
event_target
)
hres
=
bind_event_target
(
ctx
,
function
->
funcs
+
i
,
func_obj
);
else
hres
=
jsdisp_propput_name
(
variable_obj
,
function
->
funcs
[
i
].
name
,
jsval_obj
(
func_obj
));
hres
=
bind_event_target
(
ctx
,
function
->
funcs
+
i
,
func_obj
);
jsdisp_release
(
func_obj
);
if
(
FAILED
(
hres
))
return
hres
;
}
for
(
i
=
0
;
i
<
function
->
var_cnt
;
i
++
)
{
TRACE
(
"[%d] %s %d
\n
"
,
i
,
debugstr_w
(
function
->
variables
[
i
].
name
),
function
->
variables
[
i
].
func_id
);
if
(
function
->
variables
[
i
].
func_id
!=
-
1
)
continue
;
if
(
flags
&
(
EXEC_GLOBAL
|
EXEC_EVAL
))
{
for
(
i
=
0
;
i
<
function
->
var_cnt
;
i
++
)
{
TRACE
(
"[%d] %s %d
\n
"
,
i
,
debugstr_w
(
function
->
variables
[
i
].
name
),
function
->
variables
[
i
].
func_id
);
if
(
function
->
variables
[
i
].
func_id
!=
-
1
)
{
jsdisp_t
*
func_obj
;
if
(
!
(
flags
&
EXEC_GLOBAL
)
||
!
lookup_global_members
(
ctx
,
function
->
variables
[
i
].
name
,
NULL
))
{
DISPID
id
=
0
;
hres
=
create_source_function
(
ctx
,
bytecode
,
function
->
funcs
+
function
->
variables
[
i
].
func_id
,
scope
,
&
func_obj
);
if
(
FAILED
(
hres
))
return
hres
;
hres
=
jsdisp_get_id
(
variable_obj
,
function
->
variables
[
i
].
name
,
fdexNameEnsure
,
&
id
);
if
(
FAILED
(
hres
))
return
hres
;
hres
=
jsdisp_propput_name
(
variable_obj
,
function
->
variables
[
i
].
name
,
jsval_obj
(
func_obj
));
jsdisp_release
(
func_obj
);
}
else
if
(
!
(
flags
&
EXEC_GLOBAL
)
||
!
lookup_global_members
(
ctx
,
function
->
variables
[
i
].
name
,
NULL
))
{
DISPID
id
=
0
;
hres
=
jsdisp_get_id
(
variable_obj
,
function
->
variables
[
i
].
name
,
fdexNameEnsure
,
&
id
);
if
(
FAILED
(
hres
))
return
hres
;
}
}
}
...
...
@@ -2807,6 +2860,7 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
frame
->
function
=
function
;
frame
->
ret
=
jsval_undefined
();
frame
->
argc
=
argc
;
frame
->
bytecode
=
bytecode_addref
(
bytecode
);
if
(
scope
)
{
frame
->
base_scope
=
frame
->
scope
=
scope_addref
(
scope
);
...
...
@@ -2814,13 +2868,13 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
if
(
!
(
flags
&
(
EXEC_GLOBAL
|
EXEC_EVAL
)))
{
hres
=
setup_scope
(
ctx
,
frame
,
argc
,
argv
);
if
(
FAILED
(
hres
))
{
release_bytecode
(
frame
->
bytecode
);
heap_free
(
frame
);
return
hres
;
}
}
}
frame
->
bytecode
=
bytecode_addref
(
bytecode
);
frame
->
ip
=
function
->
instr_off
;
frame
->
stack_base
=
ctx
->
stack_top
;
if
(
this_obj
)
...
...
dlls/jscript/engine.h
View file @
765a52e8
...
...
@@ -225,6 +225,8 @@ typedef struct _call_frame_t {
unsigned
argc
;
unsigned
pop_locals
;
unsigned
arguments_off
;
unsigned
variables_off
;
unsigned
pop_variables
;
bytecode_t
*
bytecode
;
function_code_t
*
function
;
...
...
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