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
f1a237d6
Commit
f1a237d6
authored
Sep 02, 2011
by
Piotr Caban
Committed by
Alexandre Julliard
Sep 02, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jscript: Use hash table when accessing object properties by name.
parent
71b58e56
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
124 additions
and
44 deletions
+124
-44
dispex.c
dlls/jscript/dispex.c
+124
-44
No files found.
dlls/jscript/dispex.c
View file @
f1a237d6
...
...
@@ -31,6 +31,7 @@ static const IID IID_IDispatchJS =
{
0x719c3050
,
0xf9d3
,
0x11cf
,{
0xa4
,
0x93
,
0x00
,
0x40
,
0x05
,
0x23
,
0xa8
,
0xa6
}};
#define FDEX_VERSION_MASK 0xf0000000
#define GOLDEN_RATIO 0x9E3779B9U
typedef
enum
{
PROP_VARIANT
,
...
...
@@ -49,6 +50,9 @@ struct _dispex_prop_t {
const
builtin_prop_t
*
p
;
DWORD
ref
;
}
u
;
int
bucket_head
;
int
bucket_next
;
};
static
inline
DISPID
prop_to_id
(
jsdisp_t
*
This
,
dispex_prop_t
*
prop
)
...
...
@@ -100,25 +104,68 @@ static const builtin_prop_t *find_builtin_prop(jsdisp_t *This, const WCHAR *name
return
NULL
;
}
static
dispex_prop_t
*
alloc_prop
(
jsdisp_t
*
This
,
const
WCHAR
*
name
,
prop_type_t
type
,
DWORD
flags
)
static
inline
unsigned
string_hash
(
const
WCHAR
*
name
)
{
dispex_prop_t
*
ret
;
unsigned
h
=
0
;
for
(;
*
name
;
name
++
)
h
=
(
h
>>
(
sizeof
(
unsigned
)
*
8
-
4
))
^
(
h
<<
4
)
^
tolowerW
(
*
name
);
return
h
;
}
static
inline
unsigned
get_props_idx
(
jsdisp_t
*
This
,
unsigned
hash
)
{
return
(
hash
*
GOLDEN_RATIO
)
&
(
This
->
buf_size
-
1
);
}
static
inline
HRESULT
resize_props
(
jsdisp_t
*
This
)
{
dispex_prop_t
*
props
;
int
i
,
bucket
;
if
(
This
->
buf_size
!=
This
->
prop_cnt
)
return
S_FALSE
;
props
=
heap_realloc
(
This
->
props
,
sizeof
(
dispex_prop_t
)
*
This
->
buf_size
*
2
);
if
(
!
props
)
return
E_OUTOFMEMORY
;
This
->
buf_size
*=
2
;
This
->
props
=
props
;
if
(
This
->
buf_size
==
This
->
prop_cnt
)
{
dispex_prop_t
*
tmp
=
heap_realloc
(
This
->
props
,
(
This
->
buf_size
<<=
1
)
*
sizeof
(
*
This
->
props
));
if
(
!
tmp
)
return
NULL
;
This
->
props
=
tmp
;
for
(
i
=
0
;
i
<
This
->
buf_size
;
i
++
)
{
This
->
props
[
i
].
bucket_head
=
0
;
This
->
props
[
i
].
bucket_next
=
0
;
}
ret
=
This
->
props
+
This
->
prop_cnt
++
;
ret
->
type
=
type
;
ret
->
flags
=
flags
;
ret
->
name
=
heap_strdupW
(
name
);
if
(
!
ret
->
name
)
for
(
i
=
1
;
i
<
This
->
prop_cnt
;
i
++
)
{
props
=
This
->
props
+
i
;
bucket
=
get_props_idx
(
This
,
string_hash
(
props
->
name
));
props
->
bucket_next
=
This
->
props
[
bucket
].
bucket_head
;
This
->
props
[
bucket
].
bucket_head
=
i
;
}
return
S_OK
;
}
static
inline
dispex_prop_t
*
alloc_prop
(
jsdisp_t
*
This
,
const
WCHAR
*
name
,
prop_type_t
type
,
DWORD
flags
)
{
dispex_prop_t
*
prop
;
unsigned
bucket
;
if
(
FAILED
(
resize_props
(
This
)))
return
NULL
;
return
ret
;
prop
=
&
This
->
props
[
This
->
prop_cnt
];
prop
->
name
=
heap_strdupW
(
name
);
if
(
!
prop
->
name
)
return
NULL
;
prop
->
type
=
type
;
prop
->
flags
=
flags
;
bucket
=
get_props_idx
(
This
,
string_hash
(
name
));
prop
->
bucket_next
=
This
->
props
[
bucket
].
bucket_head
;
This
->
props
[
bucket
].
bucket_head
=
This
->
prop_cnt
++
;
return
prop
;
}
static
dispex_prop_t
*
alloc_protref
(
jsdisp_t
*
This
,
const
WCHAR
*
name
,
DWORD
ref
)
...
...
@@ -136,13 +183,25 @@ static dispex_prop_t *alloc_protref(jsdisp_t *This, const WCHAR *name, DWORD ref
static
HRESULT
find_prop_name
(
jsdisp_t
*
This
,
const
WCHAR
*
name
,
dispex_prop_t
**
ret
)
{
const
builtin_prop_t
*
builtin
;
unsigned
bucket
,
pos
,
prev
=
0
;
dispex_prop_t
*
prop
;
for
(
prop
=
This
->
props
;
prop
<
This
->
props
+
This
->
prop_cnt
;
prop
++
)
{
if
(
prop
->
name
&&
!
strcmpW
(
prop
->
name
,
name
))
{
*
ret
=
prop
;
bucket
=
get_props_idx
(
This
,
string_hash
(
name
));
pos
=
This
->
props
[
bucket
].
bucket_head
;
while
(
pos
!=
0
)
{
if
(
!
strcmpW
(
name
,
This
->
props
[
pos
].
name
))
{
if
(
prev
!=
0
)
{
This
->
props
[
prev
].
bucket_next
=
This
->
props
[
pos
].
bucket_next
;
This
->
props
[
pos
].
bucket_next
=
This
->
props
[
bucket
].
bucket_head
;
This
->
props
[
bucket
].
bucket_head
=
pos
;
}
*
ret
=
&
This
->
props
[
pos
];
return
S_OK
;
}
prev
=
pos
;
pos
=
This
->
props
[
pos
].
bucket_next
;
}
builtin
=
find_builtin_prop
(
This
,
name
);
...
...
@@ -162,13 +221,15 @@ static HRESULT find_prop_name(jsdisp_t *This, const WCHAR *name, dispex_prop_t *
static
HRESULT
find_prop_name_prot
(
jsdisp_t
*
This
,
const
WCHAR
*
name
,
dispex_prop_t
**
ret
)
{
dispex_prop_t
*
prop
;
dispex_prop_t
*
prop
,
*
del
=
NULL
;
HRESULT
hres
;
hres
=
find_prop_name
(
This
,
name
,
&
prop
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
prop
)
{
if
(
prop
&&
prop
->
type
==
PROP_DELETED
)
{
del
=
prop
;
}
else
if
(
prop
)
{
*
ret
=
prop
;
return
S_OK
;
}
...
...
@@ -178,15 +239,23 @@ static HRESULT find_prop_name_prot(jsdisp_t *This, const WCHAR *name, dispex_pro
if
(
FAILED
(
hres
))
return
hres
;
if
(
prop
)
{
prop
=
alloc_protref
(
This
,
prop
->
name
,
prop
-
This
->
prototype
->
props
);
if
(
!
prop
)
return
E_OUTOFMEMORY
;
if
(
del
)
{
del
->
type
=
PROP_PROTREF
;
del
->
flags
=
0
;
del
->
u
.
ref
=
prop
-
This
->
prototype
->
props
;
prop
=
del
;
}
else
{
prop
=
alloc_protref
(
This
,
prop
->
name
,
prop
-
This
->
prototype
->
props
);
if
(
!
prop
)
return
E_OUTOFMEMORY
;
}
*
ret
=
prop
;
return
S_OK
;
}
}
*
ret
=
prop
;
*
ret
=
del
;
return
S_OK
;
}
...
...
@@ -199,12 +268,18 @@ static HRESULT ensure_prop_name(jsdisp_t *This, const WCHAR *name, BOOL search_p
hres
=
find_prop_name_prot
(
This
,
name
,
&
prop
);
else
hres
=
find_prop_name
(
This
,
name
,
&
prop
);
if
(
SUCCEEDED
(
hres
)
&&
!
prop
)
{
if
(
SUCCEEDED
(
hres
)
&&
(
!
prop
||
prop
->
type
==
PROP_DELETED
)
)
{
TRACE
(
"creating prop %s
\n
"
,
debugstr_w
(
name
));
prop
=
alloc_prop
(
This
,
name
,
PROP_VARIANT
,
create_flags
);
if
(
!
prop
)
return
E_OUTOFMEMORY
;
if
(
prop
)
{
prop
->
type
=
PROP_VARIANT
;
prop
->
flags
=
create_flags
;
}
else
{
prop
=
alloc_prop
(
This
,
name
,
PROP_VARIANT
,
create_flags
);
if
(
!
prop
)
return
E_OUTOFMEMORY
;
}
VariantInit
(
&
prop
->
u
.
var
);
}
...
...
@@ -410,10 +485,16 @@ static HRESULT fill_protrefs(jsdisp_t *This)
hres
=
find_prop_name
(
This
,
iter
->
name
,
&
prop
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
!
prop
)
{
prop
=
alloc_protref
(
This
,
iter
->
name
,
iter
-
This
->
prototype
->
props
);
if
(
!
prop
)
return
E_OUTOFMEMORY
;
if
(
!
prop
||
prop
->
type
==
PROP_DELETED
)
{
if
(
prop
)
{
prop
->
type
=
PROP_PROTREF
;
prop
->
flags
=
0
;
prop
->
u
.
ref
=
iter
-
This
->
prototype
->
props
;
}
else
{
prop
=
alloc_protref
(
This
,
iter
->
name
,
iter
-
This
->
prototype
->
props
);
if
(
!
prop
)
return
E_OUTOFMEMORY
;
}
}
}
...
...
@@ -617,10 +698,10 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
static
HRESULT
delete_prop
(
dispex_prop_t
*
prop
)
{
heap_free
(
prop
->
name
);
prop
->
name
=
NULL
;
prop
->
type
=
PROP_DELETED
;
if
(
prop
->
type
==
PROP_VARIANT
)
{
VariantClear
(
&
prop
->
u
.
var
)
;
prop
->
type
=
PROP_DELETED
;
}
return
S_OK
;
}
...
...
@@ -701,14 +782,15 @@ static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex,
return
hres
;
}
iter
=
get_prop
(
This
,
id
+
1
);
if
(
!
iter
)
{
if
(
id
+
1
>=
0
&&
id
+
1
<
This
->
prop_cnt
)
{
iter
=
&
This
->
props
[
id
+
1
];
}
else
{
*
pid
=
DISPID_STARTENUM
;
return
S_FALSE
;
}
while
(
iter
<
This
->
props
+
This
->
prop_cnt
)
{
if
(
iter
->
name
&&
(
get_flags
(
This
,
iter
)
&
PROPF_ENUM
))
{
if
(
iter
->
name
&&
(
get_flags
(
This
,
iter
)
&
PROPF_ENUM
)
&&
iter
->
type
!=
PROP_DELETED
)
{
*
pid
=
prop_to_id
(
This
,
iter
);
return
S_OK
;
}
...
...
@@ -752,7 +834,7 @@ HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *b
dispex
->
ref
=
1
;
dispex
->
builtin_info
=
builtin_info
;
dispex
->
props
=
heap_alloc
((
dispex
->
buf_size
=
4
)
*
sizeof
(
dispex_prop_t
));
dispex
->
props
=
heap_alloc
_zero
(
sizeof
(
dispex_prop_t
)
*
(
dispex
->
buf_size
=
4
));
if
(
!
dispex
->
props
)
return
E_OUTOFMEMORY
;
...
...
@@ -761,8 +843,6 @@ HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *b
jsdisp_addref
(
prototype
);
dispex
->
prop_cnt
=
1
;
dispex
->
props
[
0
].
name
=
NULL
;
dispex
->
props
[
0
].
flags
=
0
;
if
(
builtin_info
->
value_prop
.
invoke
)
{
dispex
->
props
[
0
].
type
=
PROP_BUILTIN
;
dispex
->
props
[
0
].
u
.
p
=
&
builtin_info
->
value_prop
;
...
...
@@ -811,7 +891,7 @@ HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const built
static
const
WCHAR
prototypeW
[]
=
{
'p'
,
'r'
,
'o'
,
't'
,
'o'
,
't'
,
'y'
,
'p'
,
'e'
,
0
};
hres
=
find_prop_name_prot
(
constr
,
prototypeW
,
&
prop
);
if
(
SUCCEEDED
(
hres
)
&&
prop
)
{
if
(
SUCCEEDED
(
hres
)
&&
prop
&&
prop
->
type
!=
PROP_DELETED
)
{
jsexcept_t
jsexcept
;
VARIANT
var
;
...
...
@@ -874,7 +954,7 @@ HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID *
if
(
FAILED
(
hres
))
return
hres
;
if
(
prop
)
{
if
(
prop
&&
prop
->
type
!=
PROP_DELETED
)
{
*
id
=
prop_to_id
(
jsdisp
,
prop
);
return
S_OK
;
}
...
...
@@ -1048,7 +1128,7 @@ HRESULT jsdisp_propget_name(jsdisp_t *obj, const WCHAR *name, VARIANT *var, jsex
return
hres
;
V_VT
(
var
)
=
VT_EMPTY
;
if
(
!
prop
)
if
(
!
prop
||
prop
->
type
==
PROP_DELETED
)
return
S_OK
;
return
prop_get
(
obj
,
prop
,
&
dp
,
var
,
ei
,
caller
);
...
...
@@ -1070,7 +1150,7 @@ HRESULT jsdisp_get_idx(jsdisp_t *obj, DWORD idx, VARIANT *var, jsexcept_t *ei, I
return
hres
;
V_VT
(
var
)
=
VT_EMPTY
;
if
(
!
prop
)
if
(
!
prop
||
prop
->
type
==
PROP_DELETED
)
return
DISP_E_UNKNOWNNAME
;
return
prop_get
(
obj
,
prop
,
&
dp
,
var
,
ei
,
caller
);
...
...
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