Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
44266442
Commit
44266442
authored
Jul 03, 2012
by
Jacek Caban
Committed by
Alexandre Julliard
Jul 03, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vbscript: Added interpreter and compiler support for for each loops.
parent
4ca84477
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
130 additions
and
4 deletions
+130
-4
compile.c
dlls/vbscript/compile.c
+46
-2
interp.c
dlls/vbscript/interp.c
+82
-2
vbscript.h
dlls/vbscript/vbscript.h
+2
-0
No files found.
dlls/vbscript/compile.c
View file @
44266442
...
...
@@ -290,6 +290,24 @@ static HRESULT push_instr_bstr_uint(compile_ctx_t *ctx, vbsop_t op, const WCHAR
return
S_OK
;
}
static
HRESULT
push_instr_uint_bstr
(
compile_ctx_t
*
ctx
,
vbsop_t
op
,
unsigned
arg1
,
const
WCHAR
*
arg2
)
{
unsigned
instr
;
BSTR
bstr
;
bstr
=
alloc_bstr_arg
(
ctx
,
arg2
);
if
(
!
bstr
)
return
E_OUTOFMEMORY
;
instr
=
push_instr
(
ctx
,
op
);
if
(
!
instr
)
return
E_OUTOFMEMORY
;
instr_ptr
(
ctx
,
instr
)
->
arg1
.
uint
=
arg1
;
instr_ptr
(
ctx
,
instr
)
->
arg2
.
bstr
=
bstr
;
return
S_OK
;
}
#define LABEL_FLAG 0x80000000
static
unsigned
alloc_label
(
compile_ctx_t
*
ctx
)
...
...
@@ -621,8 +639,34 @@ static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *
static
HRESULT
compile_foreach_statement
(
compile_ctx_t
*
ctx
,
foreach_statement_t
*
stat
)
{
FIXME
(
"for each loop not implemented
\n
"
);
return
E_NOTIMPL
;
unsigned
loop_start
,
loop_end
;
HRESULT
hres
;
hres
=
compile_expression
(
ctx
,
stat
->
group_expr
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
!
push_instr
(
ctx
,
OP_newenum
))
return
E_OUTOFMEMORY
;
loop_start
=
ctx
->
instr_cnt
;
if
(
!
(
loop_end
=
alloc_label
(
ctx
)))
return
E_OUTOFMEMORY
;
hres
=
push_instr_uint_bstr
(
ctx
,
OP_enumnext
,
loop_end
,
stat
->
identifier
);
if
(
FAILED
(
hres
))
return
hres
;
hres
=
compile_statement
(
ctx
,
stat
->
body
);
if
(
FAILED
(
hres
))
return
hres
;
hres
=
push_instr_addr
(
ctx
,
OP_jmp
,
loop_start
);
if
(
FAILED
(
hres
))
return
hres
;
label_set_addr
(
ctx
,
loop_end
);
return
S_OK
;
}
static
HRESULT
compile_forto_statement
(
compile_ctx_t
*
ctx
,
forto_statement_t
*
stat
)
...
...
dlls/vbscript/interp.c
View file @
44266442
...
...
@@ -24,6 +24,8 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
vbscript
);
static
DISPID
propput_dispid
=
DISPID_PROPERTYPUT
;
typedef
struct
{
vbscode_t
*
code
;
instr_t
*
instr
;
...
...
@@ -439,8 +441,6 @@ static inline void instr_jmp(exec_ctx_t *ctx, unsigned addr)
static
void
vbstack_to_dp
(
exec_ctx_t
*
ctx
,
unsigned
arg_cnt
,
BOOL
is_propput
,
DISPPARAMS
*
dp
)
{
static
DISPID
propput_dispid
=
DISPID_PROPERTYPUT
;
dp
->
cNamedArgs
=
is_propput
?
1
:
0
;
dp
->
cArgs
=
arg_cnt
+
dp
->
cNamedArgs
;
dp
->
rgdispidNamedArgs
=
is_propput
?
&
propput_dispid
:
NULL
;
...
...
@@ -901,6 +901,86 @@ static HRESULT interp_step(exec_ctx_t *ctx)
return
S_OK
;
}
static
HRESULT
interp_newenum
(
exec_ctx_t
*
ctx
)
{
VARIANT
*
v
,
r
;
HRESULT
hres
;
TRACE
(
"
\n
"
);
v
=
stack_pop
(
ctx
);
switch
(
V_VT
(
v
))
{
case
VT_DISPATCH
:
{
IEnumVARIANT
*
iter
;
DISPPARAMS
dp
=
{
0
};
VARIANT
iterv
;
hres
=
disp_call
(
ctx
->
script
,
V_DISPATCH
(
v
),
DISPID_NEWENUM
,
&
dp
,
&
iterv
);
VariantClear
(
v
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
V_VT
(
&
iterv
)
!=
VT_UNKNOWN
&&
V_VT
(
&
iterv
)
!=
VT_DISPATCH
)
{
FIXME
(
"Unsupported iterv %s
\n
"
,
debugstr_variant
(
&
iterv
));
VariantClear
(
&
iterv
);
return
hres
;
}
hres
=
IUnknown_QueryInterface
(
V_UNKNOWN
(
&
iterv
),
&
IID_IEnumVARIANT
,
(
void
**
)
&
iter
);
IUnknown_Release
(
V_UNKNOWN
(
&
iterv
));
if
(
FAILED
(
hres
))
{
FIXME
(
"Could not get IEnumVARIANT iface: %08x
\n
"
,
hres
);
return
hres
;
}
V_VT
(
&
r
)
=
VT_UNKNOWN
;
V_UNKNOWN
(
&
r
)
=
(
IUnknown
*
)
iter
;
break
;
}
default:
FIXME
(
"Unsupported for %s
\n
"
,
debugstr_variant
(
v
));
VariantClear
(
v
);
return
E_NOTIMPL
;
}
return
stack_push
(
ctx
,
&
r
);
}
static
HRESULT
interp_enumnext
(
exec_ctx_t
*
ctx
)
{
const
unsigned
loop_end
=
ctx
->
instr
->
arg1
.
uint
;
const
BSTR
ident
=
ctx
->
instr
->
arg2
.
bstr
;
VARIANT
v
;
DISPPARAMS
dp
=
{
&
v
,
&
propput_dispid
,
1
,
1
};
IEnumVARIANT
*
iter
;
BOOL
do_continue
;
HRESULT
hres
;
TRACE
(
"
\n
"
);
assert
(
V_VT
(
stack_top
(
ctx
,
0
))
==
VT_UNKNOWN
);
iter
=
(
IEnumVARIANT
*
)
V_UNKNOWN
(
stack_top
(
ctx
,
0
));
V_VT
(
&
v
)
=
VT_EMPTY
;
hres
=
IEnumVARIANT_Next
(
iter
,
1
,
&
v
,
NULL
);
if
(
FAILED
(
hres
))
return
hres
;
do_continue
=
hres
==
S_OK
;
hres
=
assign_ident
(
ctx
,
ident
,
&
dp
);
VariantClear
(
&
v
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
do_continue
)
{
ctx
->
instr
++
;
}
else
{
stack_pop
(
ctx
);
instr_jmp
(
ctx
,
loop_end
);
}
return
S_OK
;
}
static
HRESULT
interp_jmp
(
exec_ctx_t
*
ctx
)
{
const
unsigned
arg
=
ctx
->
instr
->
arg1
.
uint
;
...
...
dlls/vbscript/vbscript.h
View file @
44266442
...
...
@@ -194,6 +194,7 @@ typedef enum {
X(div, 1, 0, 0) \
X(double, 1, ARG_DOUBLE, 0) \
X(empty, 1, 0, 0) \
X(enumnext, 0, ARG_ADDR, ARG_BSTR) \
X(equal, 1, 0, 0) \
X(errmode, 1, ARG_INT, 0) \
X(eqv, 1, 0, 0) \
...
...
@@ -220,6 +221,7 @@ typedef enum {
X(neg, 1, 0, 0) \
X(nequal, 1, 0, 0) \
X(new, 1, ARG_STR, 0) \
X(newenum, 1, 0, 0) \
X(not, 1, 0, 0) \
X(nothing, 1, 0, 0) \
X(null, 1, 0, 0) \
...
...
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