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
61734cd9
Commit
61734cd9
authored
Sep 09, 2008
by
Jacek Caban
Committed by
Alexandre Julliard
Sep 09, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jscript: Added InvokeEx implementation.
parent
8c0e089d
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
309 additions
and
2 deletions
+309
-2
dispex.c
dlls/jscript/dispex.c
+282
-2
jscript.h
dlls/jscript/jscript.h
+3
-0
jscript_main.c
dlls/jscript/jscript_main.c
+2
-0
jsutils.c
dlls/jscript/jsutils.c
+22
-0
No files found.
dlls/jscript/dispex.c
View file @
61734cd9
...
@@ -23,6 +23,13 @@
...
@@ -23,6 +23,13 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
jscript
);
WINE_DEFAULT_DEBUG_CHANNEL
(
jscript
);
/*
* This IID is used to get DispatchEx objecto from interface.
* We might consider using private insteface instead.
*/
static
const
IID
IID_IDispatchJS
=
{
0x719c3050
,
0xf9d3
,
0x11cf
,{
0xa4
,
0x93
,
0x00
,
0x40
,
0x05
,
0x23
,
0xa8
,
0xa6
}};
typedef
enum
{
typedef
enum
{
PROP_VARIANT
,
PROP_VARIANT
,
PROP_BUILTIN
,
PROP_BUILTIN
,
...
@@ -47,6 +54,14 @@ static inline DISPID prop_to_id(DispatchEx *This, dispex_prop_t *prop)
...
@@ -47,6 +54,14 @@ static inline DISPID prop_to_id(DispatchEx *This, dispex_prop_t *prop)
return
prop
-
This
->
props
;
return
prop
-
This
->
props
;
}
}
static
inline
dispex_prop_t
*
get_prop
(
DispatchEx
*
This
,
DISPID
id
)
{
if
(
id
<
0
||
id
>=
This
->
prop_cnt
||
This
->
props
[
id
].
type
==
PROP_DELETED
)
return
NULL
;
return
This
->
props
+
id
;
}
static
const
builtin_prop_t
*
find_builtin_prop
(
DispatchEx
*
This
,
const
WCHAR
*
name
)
static
const
builtin_prop_t
*
find_builtin_prop
(
DispatchEx
*
This
,
const
WCHAR
*
name
)
{
{
int
min
=
0
,
max
,
i
,
r
;
int
min
=
0
,
max
,
i
,
r
;
...
@@ -167,6 +182,171 @@ static HRESULT find_prop_name_prot(DispatchEx *This, const WCHAR *name, BOOL all
...
@@ -167,6 +182,171 @@ static HRESULT find_prop_name_prot(DispatchEx *This, const WCHAR *name, BOOL all
return
S_OK
;
return
S_OK
;
}
}
static
HRESULT
set_this
(
DISPPARAMS
*
dp
,
DISPPARAMS
*
olddp
,
IDispatch
*
jsthis
)
{
VARIANTARG
*
oldargs
;
int
i
;
static
DISPID
this_id
=
DISPID_THIS
;
*
dp
=
*
olddp
;
for
(
i
=
0
;
i
<
dp
->
cNamedArgs
;
i
++
)
{
if
(
dp
->
rgdispidNamedArgs
[
i
]
==
DISPID_THIS
)
return
S_OK
;
}
oldargs
=
dp
->
rgvarg
;
dp
->
rgvarg
=
heap_alloc
((
dp
->
cArgs
+
1
)
*
sizeof
(
VARIANTARG
));
if
(
!
dp
->
rgvarg
)
return
E_OUTOFMEMORY
;
memcpy
(
dp
->
rgvarg
+
1
,
oldargs
,
dp
->
cArgs
*
sizeof
(
VARIANTARG
));
V_VT
(
dp
->
rgvarg
)
=
VT_DISPATCH
;
V_DISPATCH
(
dp
->
rgvarg
)
=
jsthis
;
dp
->
cArgs
++
;
if
(
dp
->
cNamedArgs
)
{
DISPID
*
old
=
dp
->
rgdispidNamedArgs
;
dp
->
rgdispidNamedArgs
=
heap_alloc
((
dp
->
cNamedArgs
+
1
)
*
sizeof
(
DISPID
));
if
(
!
dp
->
rgdispidNamedArgs
)
{
heap_free
(
dp
->
rgvarg
);
return
E_OUTOFMEMORY
;
}
memcpy
(
dp
->
rgdispidNamedArgs
+
1
,
old
,
dp
->
cNamedArgs
*
sizeof
(
DISPID
));
dp
->
rgdispidNamedArgs
[
0
]
=
DISPID_THIS
;
dp
->
cNamedArgs
++
;
}
else
{
dp
->
rgdispidNamedArgs
=
&
this_id
;
dp
->
cNamedArgs
=
1
;
}
return
S_OK
;
}
static
HRESULT
invoke_prop_func
(
DispatchEx
*
This
,
DispatchEx
*
jsthis
,
dispex_prop_t
*
prop
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
dp
,
VARIANT
*
retv
,
jsexcept_t
*
ei
,
IServiceProvider
*
caller
)
{
HRESULT
hres
;
switch
(
prop
->
type
)
{
case
PROP_BUILTIN
:
if
(
flags
==
DISPATCH_CONSTRUCT
&&
(
prop
->
flags
&
DISPATCH_METHOD
))
{
WARN
(
"%s is not a constructor
\n
"
,
debugstr_w
(
prop
->
name
));
return
E_INVALIDARG
;
}
return
prop
->
u
.
p
->
invoke
(
jsthis
,
lcid
,
flags
,
dp
,
retv
,
ei
,
caller
);
case
PROP_PROTREF
:
return
invoke_prop_func
(
This
->
prototype
,
jsthis
,
This
->
prototype
->
props
+
prop
->
u
.
ref
,
lcid
,
flags
,
dp
,
retv
,
ei
,
caller
);
case
PROP_VARIANT
:
{
DISPPARAMS
new_dp
;
if
(
V_VT
(
&
prop
->
u
.
var
)
!=
VT_DISPATCH
)
{
FIXME
(
"invoke vt %d
\n
"
,
V_VT
(
&
prop
->
u
.
var
));
return
E_FAIL
;
}
TRACE
(
"call %s %p
\n
"
,
debugstr_w
(
prop
->
name
),
V_DISPATCH
(
&
prop
->
u
.
var
));
hres
=
set_this
(
&
new_dp
,
dp
,
(
IDispatch
*
)
_IDispatchEx_
(
jsthis
));
if
(
FAILED
(
hres
))
return
hres
;
hres
=
disp_call
(
V_DISPATCH
(
&
prop
->
u
.
var
),
DISPID_VALUE
,
lcid
,
flags
,
&
new_dp
,
retv
,
ei
,
caller
);
if
(
new_dp
.
rgvarg
!=
dp
->
rgvarg
)
{
heap_free
(
new_dp
.
rgvarg
);
if
(
new_dp
.
cNamedArgs
>
1
)
heap_free
(
new_dp
.
rgdispidNamedArgs
);
}
return
hres
;
}
default:
ERR
(
"type %d
\n
"
,
prop
->
type
);
}
return
E_FAIL
;
}
static
HRESULT
prop_get
(
DispatchEx
*
This
,
dispex_prop_t
*
prop
,
LCID
lcid
,
DISPPARAMS
*
dp
,
VARIANT
*
retv
,
jsexcept_t
*
ei
,
IServiceProvider
*
caller
)
{
HRESULT
hres
;
switch
(
prop
->
type
)
{
case
PROP_BUILTIN
:
if
(
prop
->
u
.
p
->
flags
&
PROPF_METHOD
)
{
FIXME
(
"function objects not supported
\n
"
);
return
E_NOTIMPL
;
}
else
{
hres
=
prop
->
u
.
p
->
invoke
(
This
,
lcid
,
DISPATCH_PROPERTYGET
,
dp
,
retv
,
ei
,
caller
);
}
break
;
case
PROP_PROTREF
:
hres
=
prop_get
(
This
->
prototype
,
This
->
prototype
->
props
+
prop
->
u
.
ref
,
lcid
,
dp
,
retv
,
ei
,
caller
);
break
;
case
PROP_VARIANT
:
hres
=
VariantCopy
(
retv
,
&
prop
->
u
.
var
);
break
;
default:
ERR
(
"type %d
\n
"
,
prop
->
type
);
return
E_FAIL
;
}
if
(
FAILED
(
hres
))
{
TRACE
(
"fail %08x
\n
"
,
hres
);
return
hres
;
}
TRACE
(
"%s ret %s
\n
"
,
debugstr_w
(
prop
->
name
),
debugstr_variant
(
retv
));
return
hres
;
}
static
HRESULT
prop_put
(
DispatchEx
*
This
,
dispex_prop_t
*
prop
,
LCID
lcid
,
DISPPARAMS
*
dp
,
jsexcept_t
*
ei
,
IServiceProvider
*
caller
)
{
DWORD
i
;
HRESULT
hres
;
switch
(
prop
->
type
)
{
case
PROP_BUILTIN
:
if
(
!
(
prop
->
flags
&
PROPF_METHOD
))
return
prop
->
u
.
p
->
invoke
(
This
,
lcid
,
DISPATCH_PROPERTYPUT
,
dp
,
NULL
,
ei
,
caller
);
case
PROP_PROTREF
:
prop
->
type
=
PROP_VARIANT
;
prop
->
flags
=
PROPF_ENUM
;
V_VT
(
&
prop
->
u
.
var
)
=
VT_EMPTY
;
break
;
case
PROP_VARIANT
:
VariantClear
(
&
prop
->
u
.
var
);
break
;
default:
ERR
(
"type %d
\n
"
,
prop
->
type
);
return
E_FAIL
;
}
for
(
i
=
0
;
i
<
dp
->
cNamedArgs
;
i
++
)
{
if
(
dp
->
rgdispidNamedArgs
[
i
]
==
DISPID_PROPERTYPUT
)
break
;
}
if
(
i
==
dp
->
cNamedArgs
)
{
TRACE
(
"no value to set
\n
"
);
return
DISP_E_PARAMNOTOPTIONAL
;
}
hres
=
VariantCopy
(
&
prop
->
u
.
var
,
dp
->
rgvarg
+
i
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
This
->
builtin_info
->
on_put
)
This
->
builtin_info
->
on_put
(
This
,
prop
->
name
);
TRACE
(
"%s = %s
\n
"
,
debugstr_w
(
prop
->
name
),
debugstr_variant
(
dp
->
rgvarg
+
i
));
return
S_OK
;
}
#define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface)
#define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface)
static
HRESULT
WINAPI
DispatchEx_QueryInterface
(
IDispatchEx
*
iface
,
REFIID
riid
,
void
**
ppv
)
static
HRESULT
WINAPI
DispatchEx_QueryInterface
(
IDispatchEx
*
iface
,
REFIID
riid
,
void
**
ppv
)
...
@@ -182,6 +362,11 @@ static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid,
...
@@ -182,6 +362,11 @@ static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid,
}
else
if
(
IsEqualGUID
(
&
IID_IDispatchEx
,
riid
))
{
}
else
if
(
IsEqualGUID
(
&
IID_IDispatchEx
,
riid
))
{
TRACE
(
"(%p)->(IID_IDispatchEx %p)
\n
"
,
This
,
ppv
);
TRACE
(
"(%p)->(IID_IDispatchEx %p)
\n
"
,
This
,
ppv
);
*
ppv
=
_IDispatchEx_
(
This
);
*
ppv
=
_IDispatchEx_
(
This
);
}
else
if
(
IsEqualGUID
(
&
IID_IDispatchJS
,
riid
))
{
TRACE
(
"(%p)->(IID_IDispatchJS %p)
\n
"
,
This
,
ppv
);
IUnknown_AddRef
(
_IDispatchEx_
(
This
));
*
ppv
=
This
;
return
S_OK
;
}
else
{
}
else
{
WARN
(
"(%p)->(%s %p)
\n
"
,
This
,
debugstr_guid
(
riid
),
ppv
);
WARN
(
"(%p)->(%s %p)
\n
"
,
This
,
debugstr_guid
(
riid
),
ppv
);
*
ppv
=
NULL
;
*
ppv
=
NULL
;
...
@@ -309,8 +494,43 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
...
@@ -309,8 +494,43 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
VARIANT
*
pvarRes
,
EXCEPINFO
*
pei
,
IServiceProvider
*
pspCaller
)
VARIANT
*
pvarRes
,
EXCEPINFO
*
pei
,
IServiceProvider
*
pspCaller
)
{
{
DispatchEx
*
This
=
DISPATCHEX_THIS
(
iface
);
DispatchEx
*
This
=
DISPATCHEX_THIS
(
iface
);
FIXME
(
"(%p)->(%x %x %x %p %p %p %p)
\n
"
,
This
,
id
,
lcid
,
wFlags
,
pdp
,
pvarRes
,
pei
,
pspCaller
);
dispex_prop_t
*
prop
;
return
E_NOTIMPL
;
jsexcept_t
jsexcept
;
HRESULT
hres
;
TRACE
(
"(%p)->(%x %x %x %p %p %p %p)
\n
"
,
This
,
id
,
lcid
,
wFlags
,
pdp
,
pvarRes
,
pei
,
pspCaller
);
if
(
pvarRes
)
V_VT
(
pvarRes
)
=
VT_EMPTY
;
prop
=
get_prop
(
This
,
id
);
if
(
!
prop
||
prop
->
type
==
PROP_DELETED
)
{
TRACE
(
"invalid id
\n
"
);
return
DISP_E_MEMBERNOTFOUND
;
}
memset
(
&
jsexcept
,
0
,
sizeof
(
jsexcept
));
switch
(
wFlags
)
{
case
DISPATCH_METHOD
:
case
DISPATCH_CONSTRUCT
:
hres
=
invoke_prop_func
(
This
,
This
,
prop
,
lcid
,
wFlags
,
pdp
,
pvarRes
,
&
jsexcept
,
pspCaller
);
break
;
case
DISPATCH_PROPERTYGET
:
hres
=
prop_get
(
This
,
prop
,
lcid
,
pdp
,
pvarRes
,
&
jsexcept
,
pspCaller
);
break
;
case
DISPATCH_PROPERTYPUT
:
hres
=
prop_put
(
This
,
prop
,
lcid
,
pdp
,
&
jsexcept
,
pspCaller
);
break
;
default:
FIXME
(
"Unimplemented flags %x
\n
"
,
wFlags
);
return
E_INVALIDARG
;
}
if
(
pei
)
*
pei
=
jsexcept
.
ei
;
return
hres
;
}
}
static
HRESULT
WINAPI
DispatchEx_DeleteMemberByName
(
IDispatchEx
*
iface
,
BSTR
bstrName
,
DWORD
grfdex
)
static
HRESULT
WINAPI
DispatchEx_DeleteMemberByName
(
IDispatchEx
*
iface
,
BSTR
bstrName
,
DWORD
grfdex
)
...
@@ -464,3 +684,63 @@ HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, Dis
...
@@ -464,3 +684,63 @@ HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, Dis
*
dispex
=
ret
;
*
dispex
=
ret
;
return
S_OK
;
return
S_OK
;
}
}
DispatchEx
*
iface_to_jsdisp
(
IUnknown
*
iface
)
{
DispatchEx
*
ret
;
HRESULT
hres
;
hres
=
IUnknown_QueryInterface
(
iface
,
&
IID_IDispatchJS
,
(
void
**
)
&
ret
);
if
(
FAILED
(
hres
))
return
NULL
;
return
ret
;
}
HRESULT
jsdisp_call
(
DispatchEx
*
disp
,
DISPID
id
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
dp
,
VARIANT
*
retv
,
jsexcept_t
*
ei
,
IServiceProvider
*
caller
)
{
dispex_prop_t
*
prop
;
memset
(
ei
,
0
,
sizeof
(
*
ei
));
if
(
retv
)
V_VT
(
retv
)
=
VT_EMPTY
;
prop
=
get_prop
(
disp
,
id
);
if
(
!
prop
)
return
DISP_E_MEMBERNOTFOUND
;
return
invoke_prop_func
(
disp
,
disp
,
prop
,
lcid
,
flags
,
dp
,
retv
,
ei
,
caller
);
}
HRESULT
disp_call
(
IDispatch
*
disp
,
DISPID
id
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
dp
,
VARIANT
*
retv
,
jsexcept_t
*
ei
,
IServiceProvider
*
caller
)
{
DispatchEx
*
jsdisp
;
IDispatchEx
*
dispex
;
HRESULT
hres
;
jsdisp
=
iface_to_jsdisp
((
IUnknown
*
)
disp
);
if
(
jsdisp
)
{
hres
=
jsdisp_call
(
jsdisp
,
id
,
lcid
,
flags
,
dp
,
retv
,
ei
,
caller
);
IDispatchEx_Release
(
_IDispatchEx_
(
jsdisp
));
return
hres
;
}
memset
(
ei
,
0
,
sizeof
(
*
ei
));
if
(
retv
)
V_VT
(
retv
)
=
VT_EMPTY
;
hres
=
IDispatch_QueryInterface
(
disp
,
&
IID_IDispatchEx
,
(
void
**
)
&
dispex
);
if
(
FAILED
(
hres
))
{
UINT
err
=
0
;
TRACE
(
"using IDispatch
\n
"
);
return
IDispatch_Invoke
(
disp
,
id
,
&
IID_NULL
,
lcid
,
flags
,
dp
,
retv
,
&
ei
->
ei
,
&
err
);
}
hres
=
IDispatchEx_InvokeEx
(
dispex
,
id
,
lcid
,
flags
,
dp
,
retv
,
&
ei
->
ei
,
caller
);
IDispatchEx_Release
(
dispex
);
return
hres
;
}
dlls/jscript/jscript.h
View file @
61734cd9
...
@@ -86,6 +86,7 @@ struct DispatchEx {
...
@@ -86,6 +86,7 @@ struct DispatchEx {
#define _IDispatchEx_(x) ((IDispatchEx*) &(x)->lpIDispatchExVtbl)
#define _IDispatchEx_(x) ((IDispatchEx*) &(x)->lpIDispatchExVtbl)
HRESULT
create_dispex
(
script_ctx_t
*
,
const
builtin_info_t
*
,
DispatchEx
*
,
DispatchEx
**
);
HRESULT
create_dispex
(
script_ctx_t
*
,
const
builtin_info_t
*
,
DispatchEx
*
,
DispatchEx
**
);
HRESULT
disp_call
(
IDispatch
*
,
DISPID
,
LCID
,
WORD
,
DISPPARAMS
*
,
VARIANT
*
,
jsexcept_t
*
,
IServiceProvider
*
);
struct
_script_ctx_t
{
struct
_script_ctx_t
{
LONG
ref
;
LONG
ref
;
...
@@ -104,6 +105,8 @@ static inline void script_addref(script_ctx_t *ctx)
...
@@ -104,6 +105,8 @@ static inline void script_addref(script_ctx_t *ctx)
ctx
->
ref
++
;
ctx
->
ref
++
;
}
}
const
char
*
debugstr_variant
(
const
VARIANT
*
);
HRESULT
WINAPI
JScriptFactory_CreateInstance
(
IClassFactory
*
,
IUnknown
*
,
REFIID
,
void
**
);
HRESULT
WINAPI
JScriptFactory_CreateInstance
(
IClassFactory
*
,
IUnknown
*
,
REFIID
,
void
**
);
typedef
struct
{
typedef
struct
{
...
...
dlls/jscript/jscript_main.c
View file @
61734cd9
...
@@ -38,6 +38,8 @@ static const CLSID CLSID_JScriptAuthor =
...
@@ -38,6 +38,8 @@ static const CLSID CLSID_JScriptAuthor =
static
const
CLSID
CLSID_JScriptEncode
=
static
const
CLSID
CLSID_JScriptEncode
=
{
0xf414c262
,
0x6ac0
,
0x11cf
,{
0xb6
,
0xd1
,
0x00
,
0xaa
,
0x00
,
0xbb
,
0xbb
,
0x58
}};
{
0xf414c262
,
0x6ac0
,
0x11cf
,{
0xb6
,
0xd1
,
0x00
,
0xaa
,
0x00
,
0xbb
,
0xbb
,
0x58
}};
DEFINE_GUID
(
GUID_NULL
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
static
HINSTANCE
jscript_hinstance
;
static
HINSTANCE
jscript_hinstance
;
static
HRESULT
WINAPI
ClassFactory_QueryInterface
(
IClassFactory
*
iface
,
REFIID
riid
,
void
**
ppv
)
static
HRESULT
WINAPI
ClassFactory_QueryInterface
(
IClassFactory
*
iface
,
REFIID
riid
,
void
**
ppv
)
...
...
dlls/jscript/jsutils.c
View file @
61734cd9
...
@@ -22,6 +22,28 @@
...
@@ -22,6 +22,28 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
jscript
);
WINE_DEFAULT_DEBUG_CHANNEL
(
jscript
);
const
char
*
debugstr_variant
(
const
VARIANT
*
v
)
{
switch
(
V_VT
(
v
))
{
case
VT_EMPTY
:
return
wine_dbg_sprintf
(
"{VT_EMPTY}"
);
case
VT_NULL
:
return
wine_dbg_sprintf
(
"{VT_NULL}"
);
case
VT_I4
:
return
wine_dbg_sprintf
(
"{VT_I4: %d}"
,
V_I4
(
v
));
case
VT_R8
:
return
wine_dbg_sprintf
(
"{VT_R8: %lf}"
,
V_R8
(
v
));
case
VT_BSTR
:
return
wine_dbg_sprintf
(
"{VT_BSTR: %s}"
,
debugstr_w
(
V_BSTR
(
v
)));
case
VT_DISPATCH
:
return
wine_dbg_sprintf
(
"{VT_DISPATCH: %p}"
,
V_DISPATCH
(
v
));
case
VT_BOOL
:
return
wine_dbg_sprintf
(
"{VT_BOOL: %x}"
,
V_BOOL
(
v
));
default:
return
wine_dbg_sprintf
(
"{vt %d}"
,
V_VT
(
v
));
}
}
#define MIN_BLOCK_SIZE 128
#define MIN_BLOCK_SIZE 128
static
inline
DWORD
block_size
(
DWORD
block
)
static
inline
DWORD
block_size
(
DWORD
block
)
...
...
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