2 * Copyright 2008 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(jscript
);
31 #define CTXARG_T DWORDLONG
32 #define IActiveScriptParseVtbl IActiveScriptParse64Vtbl
33 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_64Vtbl
37 #define CTXARG_T DWORD
38 #define IActiveScriptParseVtbl IActiveScriptParse32Vtbl
39 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_32Vtbl
44 IActiveScript IActiveScript_iface
;
45 IActiveScriptParse IActiveScriptParse_iface
;
46 IActiveScriptParseProcedure2 IActiveScriptParseProcedure2_iface
;
47 IActiveScriptProperty IActiveScriptProperty_iface
;
48 IObjectSafety IObjectSafety_iface
;
49 IVariantChangeType IVariantChangeType_iface
;
62 IActiveScriptSite
*site
;
64 struct list persistent_code
;
65 struct list queued_code
;
69 IActiveScriptError IActiveScriptError_iface
;
74 void script_release(script_ctx_t
*ctx
)
79 jsval_release(ctx
->acc
);
82 heap_pool_free(&ctx
->tmp_heap
);
84 jsstr_release(ctx
->last_match
);
85 assert(!ctx
->stack_top
);
86 heap_free(ctx
->stack
);
88 ctx
->jscaller
->ctx
= NULL
;
89 IServiceProvider_Release(&ctx
->jscaller
->IServiceProvider_iface
);
94 static void change_state(JScript
*This
, SCRIPTSTATE state
)
96 if(This
->ctx
->state
== state
)
99 This
->ctx
->state
= state
;
101 IActiveScriptSite_OnStateChange(This
->site
, state
);
104 static inline BOOL
is_started(script_ctx_t
*ctx
)
106 return ctx
->state
== SCRIPTSTATE_STARTED
107 || ctx
->state
== SCRIPTSTATE_CONNECTED
108 || ctx
->state
== SCRIPTSTATE_DISCONNECTED
;
111 HRESULT
create_named_item_script_obj(script_ctx_t
*ctx
, named_item_t
*item
)
113 static const builtin_info_t disp_info
= {
121 return create_dispex(ctx
, &disp_info
, NULL
, &item
->script_obj
);
124 static void release_named_item_script_obj(named_item_t
*item
)
126 if(!item
->script_obj
) return;
128 jsdisp_release(item
->script_obj
);
129 item
->script_obj
= NULL
;
132 static HRESULT
retrieve_named_item_disp(IActiveScriptSite
*site
, named_item_t
*item
)
140 hr
= IActiveScriptSite_GetItemInfo(site
, item
->name
, SCRIPTINFO_IUNKNOWN
, &unk
, NULL
);
142 WARN("GetItemInfo failed: %08x\n", hr
);
146 hr
= IUnknown_QueryInterface(unk
, &IID_IDispatch
, (void**)&item
->disp
);
147 IUnknown_Release(unk
);
149 WARN("object does not implement IDispatch\n");
156 named_item_t
*lookup_named_item(script_ctx_t
*ctx
, const WCHAR
*item_name
, unsigned flags
)
161 LIST_FOR_EACH_ENTRY(item
, &ctx
->named_items
, named_item_t
, entry
) {
162 if((item
->flags
& flags
) == flags
&& !wcscmp(item
->name
, item_name
)) {
163 if(!item
->script_obj
&& !(item
->flags
& SCRIPTITEM_GLOBALMEMBERS
)) {
164 hr
= create_named_item_script_obj(ctx
, item
);
165 if(FAILED(hr
)) return NULL
;
168 if(!item
->disp
&& (flags
|| !(item
->flags
& SCRIPTITEM_CODEONLY
))) {
169 hr
= retrieve_named_item_disp(ctx
->site
, item
);
170 if(FAILED(hr
)) continue;
180 void release_named_item(named_item_t
*item
)
182 if(--item
->ref
) return;
184 heap_free(item
->name
);
188 static inline JScriptError
*impl_from_IActiveScriptError(IActiveScriptError
*iface
)
190 return CONTAINING_RECORD(iface
, JScriptError
, IActiveScriptError_iface
);
193 static HRESULT WINAPI
JScriptError_QueryInterface(IActiveScriptError
*iface
, REFIID riid
, void **ppv
)
195 JScriptError
*This
= impl_from_IActiveScriptError(iface
);
197 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
198 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
199 *ppv
= &This
->IActiveScriptError_iface
;
200 }else if(IsEqualGUID(riid
, &IID_IActiveScriptError
)) {
201 TRACE("(%p)->(IID_IActiveScriptError %p)\n", This
, ppv
);
202 *ppv
= &This
->IActiveScriptError_iface
;
204 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
206 return E_NOINTERFACE
;
209 IUnknown_AddRef((IUnknown
*)*ppv
);
213 static ULONG WINAPI
JScriptError_AddRef(IActiveScriptError
*iface
)
215 JScriptError
*This
= impl_from_IActiveScriptError(iface
);
216 LONG ref
= InterlockedIncrement(&This
->ref
);
218 TRACE("(%p) ref=%d\n", This
, ref
);
223 static ULONG WINAPI
JScriptError_Release(IActiveScriptError
*iface
)
225 JScriptError
*This
= impl_from_IActiveScriptError(iface
);
226 LONG ref
= InterlockedDecrement(&This
->ref
);
228 TRACE("(%p) ref=%d\n", This
, ref
);
238 static HRESULT WINAPI
JScriptError_GetExceptionInfo(IActiveScriptError
*iface
, EXCEPINFO
*excepinfo
)
240 JScriptError
*This
= impl_from_IActiveScriptError(iface
);
242 TRACE("(%p)->(%p)\n", This
, excepinfo
);
247 memset(excepinfo
, 0, sizeof(*excepinfo
));
248 excepinfo
->scode
= This
->ei
.error
;
250 jsstr_to_bstr(This
->ei
.source
, &excepinfo
->bstrSource
);
252 jsstr_to_bstr(This
->ei
.message
, &excepinfo
->bstrDescription
);
256 static HRESULT WINAPI
JScriptError_GetSourcePosition(IActiveScriptError
*iface
, DWORD
*source_context
, ULONG
*line
, LONG
*character
)
258 JScriptError
*This
= impl_from_IActiveScriptError(iface
);
259 bytecode_t
*code
= This
->ei
.code
;
260 unsigned line_pos
, char_pos
;
262 TRACE("(%p)->(%p %p %p)\n", This
, source_context
, line
, character
);
265 FIXME("unknown position\n");
270 *source_context
= This
->ei
.code
->source_context
;
271 if(!line
&& !character
)
274 line_pos
= get_location_line(code
, This
->ei
.loc
, &char_pos
);
278 *character
= char_pos
;
282 static HRESULT WINAPI
JScriptError_GetSourceLineText(IActiveScriptError
*iface
, BSTR
*source
)
284 JScriptError
*This
= impl_from_IActiveScriptError(iface
);
286 TRACE("(%p)->(%p)\n", This
, source
);
296 return jsstr_to_bstr(This
->ei
.line
, source
);
299 static const IActiveScriptErrorVtbl JScriptErrorVtbl
= {
300 JScriptError_QueryInterface
,
302 JScriptError_Release
,
303 JScriptError_GetExceptionInfo
,
304 JScriptError_GetSourcePosition
,
305 JScriptError_GetSourceLineText
308 void reset_ei(jsexcept_t
*ei
)
311 if(ei
->valid_value
) {
312 jsval_release(ei
->value
);
313 ei
->valid_value
= FALSE
;
316 release_bytecode(ei
->code
);
321 jsstr_release(ei
->source
);
325 jsstr_release(ei
->message
);
329 jsstr_release(ei
->line
);
334 void enter_script(script_ctx_t
*ctx
, jsexcept_t
*ei
)
336 memset(ei
, 0, sizeof(*ei
));
339 TRACE("ctx %p ei %p prev %p\n", ctx
, ei
, ei
->prev
);
342 HRESULT
leave_script(script_ctx_t
*ctx
, HRESULT result
)
344 jsexcept_t
*ei
= ctx
->ei
;
345 BOOL enter_notified
= ei
->enter_notified
;
348 TRACE("ctx %p ei %p prev %p\n", ctx
, ei
, ei
->prev
);
351 if(result
== DISP_E_EXCEPTION
) {
358 WARN("%08x\n", result
);
359 if(ctx
->site
&& (error
= heap_alloc(sizeof(*error
)))) {
362 error
->IActiveScriptError_iface
.lpVtbl
= &JScriptErrorVtbl
;
365 memset(ei
, 0, sizeof(*ei
));
367 hres
= IActiveScriptSite_OnScriptError(ctx
->site
, &error
->IActiveScriptError_iface
);
368 IActiveScriptError_Release(&error
->IActiveScriptError_iface
);
370 result
= SCRIPT_E_REPORTED
;
373 if(enter_notified
&& ctx
->site
)
374 IActiveScriptSite_OnLeaveScript(ctx
->site
);
379 static void clear_script_queue(JScript
*This
)
381 while(!list_empty(&This
->queued_code
))
383 bytecode_t
*iter
= LIST_ENTRY(list_head(&This
->queued_code
), bytecode_t
, entry
);
384 list_remove(&iter
->entry
);
385 if (iter
->is_persistent
)
386 list_add_tail(&This
->persistent_code
, &iter
->entry
);
388 release_bytecode(iter
);
392 static void clear_persistent_code_list(JScript
*This
)
394 while(!list_empty(&This
->persistent_code
))
396 bytecode_t
*iter
= LIST_ENTRY(list_head(&This
->persistent_code
), bytecode_t
, entry
);
397 list_remove(&iter
->entry
);
398 release_bytecode(iter
);
402 static void release_persistent_script_objs(JScript
*This
)
406 LIST_FOR_EACH_ENTRY(iter
, &This
->persistent_code
, bytecode_t
, entry
)
408 release_named_item_script_obj(iter
->named_item
);
411 static void release_named_item_list(JScript
*This
)
413 while(!list_empty(&This
->ctx
->named_items
)) {
414 named_item_t
*iter
= LIST_ENTRY(list_head(&This
->ctx
->named_items
), named_item_t
, entry
);
415 list_remove(&iter
->entry
);
416 release_named_item(iter
);
420 static void exec_queued_code(JScript
*This
)
426 LIST_FOR_EACH_ENTRY(iter
, &This
->queued_code
, bytecode_t
, entry
) {
427 enter_script(This
->ctx
, &ei
);
428 hres
= exec_source(This
->ctx
, EXEC_GLOBAL
, iter
, &iter
->global_code
, NULL
, NULL
, NULL
, 0, NULL
, NULL
);
429 leave_script(This
->ctx
, hres
);
434 clear_script_queue(This
);
437 static void decrease_state(JScript
*This
, SCRIPTSTATE state
)
439 named_item_t
*item
, *item_next
;
442 switch(This
->ctx
->state
) {
443 case SCRIPTSTATE_CONNECTED
:
444 change_state(This
, SCRIPTSTATE_DISCONNECTED
);
445 if(state
== SCRIPTSTATE_DISCONNECTED
)
448 case SCRIPTSTATE_STARTED
:
449 case SCRIPTSTATE_DISCONNECTED
:
450 clear_script_queue(This
);
452 if(This
->ctx
->state
== SCRIPTSTATE_DISCONNECTED
)
453 change_state(This
, SCRIPTSTATE_INITIALIZED
);
454 if(state
== SCRIPTSTATE_INITIALIZED
)
457 case SCRIPTSTATE_INITIALIZED
:
458 clear_script_queue(This
);
459 release_persistent_script_objs(This
);
461 LIST_FOR_EACH_ENTRY_SAFE(item
, item_next
, &This
->ctx
->named_items
, named_item_t
, entry
)
465 IDispatch_Release(item
->disp
);
468 release_named_item_script_obj(item
);
469 if(!(item
->flags
& SCRIPTITEM_ISPERSISTENT
))
471 list_remove(&item
->entry
);
472 release_named_item(item
);
476 if(This
->ctx
->secmgr
) {
477 IInternetHostSecurityManager_Release(This
->ctx
->secmgr
);
478 This
->ctx
->secmgr
= NULL
;
481 if(This
->ctx
->site
) {
482 IActiveScriptSite_Release(This
->ctx
->site
);
483 This
->ctx
->site
= NULL
;
486 if(This
->ctx
->object_prototype
) {
487 jsdisp_release(This
->ctx
->object_prototype
);
488 This
->ctx
->object_prototype
= NULL
;
491 if(This
->ctx
->global
) {
492 jsdisp_release(This
->ctx
->global
);
493 This
->ctx
->global
= NULL
;
496 case SCRIPTSTATE_UNINITIALIZED
:
497 change_state(This
, state
);
503 change_state(This
, state
);
504 }else if(state
== SCRIPTSTATE_UNINITIALIZED
) {
506 IActiveScriptSite_OnStateChange(This
->site
, state
);
511 if(state
== SCRIPTSTATE_UNINITIALIZED
|| state
== SCRIPTSTATE_CLOSED
)
515 IActiveScriptSite_Release(This
->site
);
521 IServiceProvider IServiceProvider_iface
;
525 IServiceProvider
*sp
;
528 static inline AXSite
*impl_from_IServiceProvider(IServiceProvider
*iface
)
530 return CONTAINING_RECORD(iface
, AXSite
, IServiceProvider_iface
);
533 static HRESULT WINAPI
AXSite_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **ppv
)
535 AXSite
*This
= impl_from_IServiceProvider(iface
);
537 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
538 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
539 *ppv
= &This
->IServiceProvider_iface
;
540 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
541 TRACE("(%p)->(IID_IServiceProvider %p)\n", This
, ppv
);
542 *ppv
= &This
->IServiceProvider_iface
;
544 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
546 return E_NOINTERFACE
;
549 IUnknown_AddRef((IUnknown
*)*ppv
);
553 static ULONG WINAPI
AXSite_AddRef(IServiceProvider
*iface
)
555 AXSite
*This
= impl_from_IServiceProvider(iface
);
556 LONG ref
= InterlockedIncrement(&This
->ref
);
558 TRACE("(%p) ref=%d\n", This
, ref
);
563 static ULONG WINAPI
AXSite_Release(IServiceProvider
*iface
)
565 AXSite
*This
= impl_from_IServiceProvider(iface
);
566 LONG ref
= InterlockedDecrement(&This
->ref
);
568 TRACE("(%p) ref=%d\n", This
, ref
);
573 IServiceProvider_Release(This
->sp
);
581 static HRESULT WINAPI
AXSite_QueryService(IServiceProvider
*iface
,
582 REFGUID guidService
, REFIID riid
, void **ppv
)
584 AXSite
*This
= impl_from_IServiceProvider(iface
);
586 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
589 return E_NOINTERFACE
;
591 return IServiceProvider_QueryService(This
->sp
, guidService
, riid
, ppv
);
594 static IServiceProviderVtbl AXSiteVtbl
= {
595 AXSite_QueryInterface
,
601 IUnknown
*create_ax_site(script_ctx_t
*ctx
)
603 IServiceProvider
*sp
= NULL
;
607 hres
= IActiveScriptSite_QueryInterface(ctx
->site
, &IID_IServiceProvider
, (void**)&sp
);
609 TRACE("Could not get IServiceProvider iface: %08x\n", hres
);
612 ret
= heap_alloc(sizeof(AXSite
));
614 IServiceProvider_Release(sp
);
618 ret
->IServiceProvider_iface
.lpVtbl
= &AXSiteVtbl
;
622 return (IUnknown
*)&ret
->IServiceProvider_iface
;
625 static inline JScript
*impl_from_IActiveScript(IActiveScript
*iface
)
627 return CONTAINING_RECORD(iface
, JScript
, IActiveScript_iface
);
630 static HRESULT WINAPI
JScript_QueryInterface(IActiveScript
*iface
, REFIID riid
, void **ppv
)
632 JScript
*This
= impl_from_IActiveScript(iface
);
636 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
637 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
638 *ppv
= &This
->IActiveScript_iface
;
639 }else if(IsEqualGUID(riid
, &IID_IActiveScript
)) {
640 TRACE("(%p)->(IID_IActiveScript %p)\n", This
, ppv
);
641 *ppv
= &This
->IActiveScript_iface
;
642 }else if(IsEqualGUID(riid
, &IID_IActiveScriptParse
)) {
643 TRACE("(%p)->(IID_IActiveScriptParse %p)\n", This
, ppv
);
644 *ppv
= &This
->IActiveScriptParse_iface
;
645 }else if(IsEqualGUID(riid
, &IID_IActiveScriptParseProcedure
)) {
646 TRACE("(%p)->(IID_IActiveScriptParseProcedure %p)\n", This
, ppv
);
647 *ppv
= &This
->IActiveScriptParseProcedure2_iface
;
648 }else if(IsEqualGUID(riid
, &IID_IActiveScriptParseProcedure2
)) {
649 TRACE("(%p)->(IID_IActiveScriptParseProcedure2 %p)\n", This
, ppv
);
650 *ppv
= &This
->IActiveScriptParseProcedure2_iface
;
651 }else if(IsEqualGUID(riid
, &IID_IActiveScriptProperty
)) {
652 TRACE("(%p)->(IID_IActiveScriptProperty %p)\n", This
, ppv
);
653 *ppv
= &This
->IActiveScriptProperty_iface
;
654 }else if(IsEqualGUID(riid
, &IID_IObjectSafety
)) {
655 TRACE("(%p)->(IID_IObjectSafety %p)\n", This
, ppv
);
656 *ppv
= &This
->IObjectSafety_iface
;
657 }else if(IsEqualGUID(riid
, &IID_IVariantChangeType
)) {
658 TRACE("(%p)->(IID_IVariantChangeType %p)\n", This
, ppv
);
659 *ppv
= &This
->IVariantChangeType_iface
;
663 IUnknown_AddRef((IUnknown
*)*ppv
);
667 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
668 return E_NOINTERFACE
;
671 static ULONG WINAPI
JScript_AddRef(IActiveScript
*iface
)
673 JScript
*This
= impl_from_IActiveScript(iface
);
674 LONG ref
= InterlockedIncrement(&This
->ref
);
676 TRACE("(%p) ref=%d\n", This
, ref
);
681 static ULONG WINAPI
JScript_Release(IActiveScript
*iface
)
683 JScript
*This
= impl_from_IActiveScript(iface
);
684 LONG ref
= InterlockedDecrement(&This
->ref
);
686 TRACE("(%p) ref=%d\n", iface
, ref
);
689 if(This
->ctx
&& This
->ctx
->state
!= SCRIPTSTATE_CLOSED
)
690 IActiveScript_Close(&This
->IActiveScript_iface
);
692 This
->ctx
->active_script
= NULL
;
693 script_release(This
->ctx
);
702 static HRESULT WINAPI
JScript_SetScriptSite(IActiveScript
*iface
,
703 IActiveScriptSite
*pass
)
705 JScript
*This
= impl_from_IActiveScript(iface
);
710 TRACE("(%p)->(%p)\n", This
, pass
);
718 if(InterlockedCompareExchange(&This
->thread_id
, GetCurrentThreadId(), 0))
722 script_ctx_t
*ctx
= heap_alloc_zero(sizeof(script_ctx_t
));
724 return E_OUTOFMEMORY
;
727 ctx
->state
= SCRIPTSTATE_UNINITIALIZED
;
728 ctx
->active_script
= &This
->IActiveScript_iface
;
729 ctx
->safeopt
= This
->safeopt
;
730 ctx
->version
= This
->version
;
731 ctx
->html_mode
= This
->html_mode
;
732 ctx
->acc
= jsval_undefined();
733 list_init(&ctx
->named_items
);
734 heap_pool_init(&ctx
->tmp_heap
);
736 hres
= create_jscaller(ctx
);
742 ctx
->last_match
= jsstr_empty();
744 ctx
= InterlockedCompareExchangePointer((void**)&This
->ctx
, ctx
, NULL
);
751 /* Retrieve new dispatches for persistent named items */
752 LIST_FOR_EACH_ENTRY(item
, &This
->ctx
->named_items
, named_item_t
, entry
)
756 hres
= retrieve_named_item_disp(pass
, item
);
757 if(FAILED(hres
)) return hres
;
760 /* For some reason, CODEONLY flag is lost in re-initialized scripts */
761 item
->flags
&= ~SCRIPTITEM_CODEONLY
;
765 IActiveScriptSite_AddRef(This
->site
);
767 hres
= IActiveScriptSite_GetLCID(This
->site
, &lcid
);
771 This
->ctx
->lcid
= This
->lcid
;
773 hres
= init_global(This
->ctx
);
777 IActiveScriptSite_AddRef(This
->site
);
778 This
->ctx
->site
= This
->site
;
780 if(This
->is_initialized
)
781 change_state(This
, SCRIPTSTATE_INITIALIZED
);
785 static HRESULT WINAPI
JScript_GetScriptSite(IActiveScript
*iface
, REFIID riid
,
788 JScript
*This
= impl_from_IActiveScript(iface
);
789 FIXME("(%p)->()\n", This
);
793 static HRESULT WINAPI
JScript_SetScriptState(IActiveScript
*iface
, SCRIPTSTATE ss
)
795 JScript
*This
= impl_from_IActiveScript(iface
);
797 TRACE("(%p)->(%d)\n", This
, ss
);
799 if(This
->thread_id
&& GetCurrentThreadId() != This
->thread_id
)
802 if(ss
== SCRIPTSTATE_UNINITIALIZED
) {
803 if(This
->ctx
&& This
->ctx
->state
== SCRIPTSTATE_CLOSED
)
806 decrease_state(This
, SCRIPTSTATE_UNINITIALIZED
);
807 list_move_tail(&This
->queued_code
, &This
->persistent_code
);
811 if(!This
->is_initialized
|| !This
->ctx
)
815 case SCRIPTSTATE_STARTED
:
816 case SCRIPTSTATE_CONNECTED
: /* FIXME */
817 if(This
->ctx
->state
== SCRIPTSTATE_CLOSED
)
820 exec_queued_code(This
);
822 case SCRIPTSTATE_INITIALIZED
:
823 FIXME("unimplemented SCRIPTSTATE_INITIALIZED\n");
826 FIXME("unimplemented state %d\n", ss
);
830 change_state(This
, ss
);
834 static HRESULT WINAPI
JScript_GetScriptState(IActiveScript
*iface
, SCRIPTSTATE
*pssState
)
836 JScript
*This
= impl_from_IActiveScript(iface
);
838 TRACE("(%p)->(%p)\n", This
, pssState
);
843 if(This
->thread_id
&& This
->thread_id
!= GetCurrentThreadId())
846 *pssState
= This
->ctx
? This
->ctx
->state
: SCRIPTSTATE_UNINITIALIZED
;
850 static HRESULT WINAPI
JScript_Close(IActiveScript
*iface
)
852 JScript
*This
= impl_from_IActiveScript(iface
);
854 TRACE("(%p)->()\n", This
);
856 if(This
->thread_id
&& This
->thread_id
!= GetCurrentThreadId())
859 decrease_state(This
, SCRIPTSTATE_CLOSED
);
860 clear_persistent_code_list(This
);
861 release_named_item_list(This
);
865 static HRESULT WINAPI
JScript_AddNamedItem(IActiveScript
*iface
,
866 LPCOLESTR pstrName
, DWORD dwFlags
)
868 JScript
*This
= impl_from_IActiveScript(iface
);
870 IDispatch
*disp
= NULL
;
873 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(pstrName
), dwFlags
);
875 if(This
->thread_id
!= GetCurrentThreadId() || !This
->ctx
|| This
->ctx
->state
== SCRIPTSTATE_CLOSED
)
878 if(dwFlags
& SCRIPTITEM_GLOBALMEMBERS
) {
881 hres
= IActiveScriptSite_GetItemInfo(This
->site
, pstrName
, SCRIPTINFO_IUNKNOWN
, &unk
, NULL
);
883 WARN("GetItemInfo failed: %08x\n", hres
);
887 hres
= IUnknown_QueryInterface(unk
, &IID_IDispatch
, (void**)&disp
);
888 IUnknown_Release(unk
);
890 WARN("object does not implement IDispatch\n");
895 item
= heap_alloc(sizeof(*item
));
898 IDispatch_Release(disp
);
899 return E_OUTOFMEMORY
;
904 item
->flags
= dwFlags
;
905 item
->script_obj
= NULL
;
906 item
->name
= heap_strdupW(pstrName
);
909 IDispatch_Release(disp
);
911 return E_OUTOFMEMORY
;
914 list_add_tail(&This
->ctx
->named_items
, &item
->entry
);
918 static HRESULT WINAPI
JScript_AddTypeLib(IActiveScript
*iface
, REFGUID rguidTypeLib
,
919 DWORD dwMajor
, DWORD dwMinor
, DWORD dwFlags
)
921 JScript
*This
= impl_from_IActiveScript(iface
);
922 FIXME("(%p)->()\n", This
);
926 static HRESULT WINAPI
JScript_GetScriptDispatch(IActiveScript
*iface
, LPCOLESTR pstrItemName
,
929 JScript
*This
= impl_from_IActiveScript(iface
);
930 jsdisp_t
*script_obj
;
932 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pstrItemName
), ppdisp
);
937 if(This
->thread_id
!= GetCurrentThreadId() || !This
->ctx
->global
) {
942 script_obj
= This
->ctx
->global
;
944 named_item_t
*item
= lookup_named_item(This
->ctx
, pstrItemName
, 0);
945 if(!item
) return E_INVALIDARG
;
946 if(item
->script_obj
) script_obj
= item
->script_obj
;
949 *ppdisp
= to_disp(script_obj
);
950 IDispatch_AddRef(*ppdisp
);
954 static HRESULT WINAPI
JScript_GetCurrentScriptThreadID(IActiveScript
*iface
,
955 SCRIPTTHREADID
*pstridThread
)
957 JScript
*This
= impl_from_IActiveScript(iface
);
958 FIXME("(%p)->()\n", This
);
962 static HRESULT WINAPI
JScript_GetScriptThreadID(IActiveScript
*iface
,
963 DWORD dwWin32ThreadId
, SCRIPTTHREADID
*pstidThread
)
965 JScript
*This
= impl_from_IActiveScript(iface
);
966 FIXME("(%p)->()\n", This
);
970 static HRESULT WINAPI
JScript_GetScriptThreadState(IActiveScript
*iface
,
971 SCRIPTTHREADID stidThread
, SCRIPTTHREADSTATE
*pstsState
)
973 JScript
*This
= impl_from_IActiveScript(iface
);
974 FIXME("(%p)->()\n", This
);
978 static HRESULT WINAPI
JScript_InterruptScriptThread(IActiveScript
*iface
,
979 SCRIPTTHREADID stidThread
, const EXCEPINFO
*pexcepinfo
, DWORD dwFlags
)
981 JScript
*This
= impl_from_IActiveScript(iface
);
982 FIXME("(%p)->()\n", This
);
986 static HRESULT WINAPI
JScript_Clone(IActiveScript
*iface
, IActiveScript
**ppscript
)
988 JScript
*This
= impl_from_IActiveScript(iface
);
989 FIXME("(%p)->()\n", This
);
993 static const IActiveScriptVtbl JScriptVtbl
= {
994 JScript_QueryInterface
,
997 JScript_SetScriptSite
,
998 JScript_GetScriptSite
,
999 JScript_SetScriptState
,
1000 JScript_GetScriptState
,
1002 JScript_AddNamedItem
,
1004 JScript_GetScriptDispatch
,
1005 JScript_GetCurrentScriptThreadID
,
1006 JScript_GetScriptThreadID
,
1007 JScript_GetScriptThreadState
,
1008 JScript_InterruptScriptThread
,
1012 static inline JScript
*impl_from_IActiveScriptParse(IActiveScriptParse
*iface
)
1014 return CONTAINING_RECORD(iface
, JScript
, IActiveScriptParse_iface
);
1017 static HRESULT WINAPI
JScriptParse_QueryInterface(IActiveScriptParse
*iface
, REFIID riid
, void **ppv
)
1019 JScript
*This
= impl_from_IActiveScriptParse(iface
);
1020 return IActiveScript_QueryInterface(&This
->IActiveScript_iface
, riid
, ppv
);
1023 static ULONG WINAPI
JScriptParse_AddRef(IActiveScriptParse
*iface
)
1025 JScript
*This
= impl_from_IActiveScriptParse(iface
);
1026 return IActiveScript_AddRef(&This
->IActiveScript_iface
);
1029 static ULONG WINAPI
JScriptParse_Release(IActiveScriptParse
*iface
)
1031 JScript
*This
= impl_from_IActiveScriptParse(iface
);
1032 return IActiveScript_Release(&This
->IActiveScript_iface
);
1035 static HRESULT WINAPI
JScriptParse_InitNew(IActiveScriptParse
*iface
)
1037 JScript
*This
= impl_from_IActiveScriptParse(iface
);
1039 TRACE("(%p)\n", This
);
1041 if(This
->is_initialized
)
1042 return E_UNEXPECTED
;
1043 This
->is_initialized
= TRUE
;
1046 change_state(This
, SCRIPTSTATE_INITIALIZED
);
1050 static HRESULT WINAPI
JScriptParse_AddScriptlet(IActiveScriptParse
*iface
,
1051 LPCOLESTR pstrDefaultName
, LPCOLESTR pstrCode
, LPCOLESTR pstrItemName
,
1052 LPCOLESTR pstrSubItemName
, LPCOLESTR pstrEventName
, LPCOLESTR pstrDelimiter
,
1053 CTXARG_T dwSourceContextCookie
, ULONG ulStartingLineNumber
, DWORD dwFlags
,
1054 BSTR
*pbstrName
, EXCEPINFO
*pexcepinfo
)
1056 JScript
*This
= impl_from_IActiveScriptParse(iface
);
1057 FIXME("(%p)->(%s %s %s %s %s %s %s %u %x %p %p)\n", This
, debugstr_w(pstrDefaultName
),
1058 debugstr_w(pstrCode
), debugstr_w(pstrItemName
), debugstr_w(pstrSubItemName
),
1059 debugstr_w(pstrEventName
), debugstr_w(pstrDelimiter
), wine_dbgstr_longlong(dwSourceContextCookie
),
1060 ulStartingLineNumber
, dwFlags
, pbstrName
, pexcepinfo
);
1064 static HRESULT WINAPI
JScriptParse_ParseScriptText(IActiveScriptParse
*iface
,
1065 LPCOLESTR pstrCode
, LPCOLESTR pstrItemName
, IUnknown
*punkContext
,
1066 LPCOLESTR pstrDelimiter
, CTXARG_T dwSourceContextCookie
, ULONG ulStartingLine
,
1067 DWORD dwFlags
, VARIANT
*pvarResult
, EXCEPINFO
*pexcepinfo
)
1069 JScript
*This
= impl_from_IActiveScriptParse(iface
);
1070 named_item_t
*item
= NULL
;
1075 TRACE("(%p)->(%s %s %p %s %s %u %x %p %p)\n", This
, debugstr_w(pstrCode
),
1076 debugstr_w(pstrItemName
), punkContext
, debugstr_w(pstrDelimiter
),
1077 wine_dbgstr_longlong(dwSourceContextCookie
), ulStartingLine
, dwFlags
, pvarResult
, pexcepinfo
);
1079 if(This
->thread_id
!= GetCurrentThreadId() || This
->ctx
->state
== SCRIPTSTATE_CLOSED
)
1080 return E_UNEXPECTED
;
1083 item
= lookup_named_item(This
->ctx
, pstrItemName
, 0);
1085 WARN("Unknown context %s\n", debugstr_w(pstrItemName
));
1086 return E_INVALIDARG
;
1088 if(!item
->script_obj
) item
= NULL
;
1091 enter_script(This
->ctx
, &ei
);
1092 hres
= compile_script(This
->ctx
, pstrCode
, dwSourceContextCookie
, ulStartingLine
, NULL
, pstrDelimiter
,
1093 (dwFlags
& SCRIPTTEXT_ISEXPRESSION
) != 0, This
->is_encode
, item
, &code
);
1095 return leave_script(This
->ctx
, hres
);
1097 if(dwFlags
& SCRIPTTEXT_ISEXPRESSION
) {
1100 hres
= exec_source(This
->ctx
, EXEC_GLOBAL
, code
, &code
->global_code
, NULL
, NULL
, NULL
, 0, NULL
, &r
);
1101 if(SUCCEEDED(hres
)) {
1103 hres
= jsval_to_variant(r
, pvarResult
);
1107 return leave_script(This
->ctx
, hres
);
1110 code
->is_persistent
= (dwFlags
& SCRIPTTEXT_ISPERSISTENT
) != 0;
1113 * Although pvarResult is not really used without SCRIPTTEXT_ISEXPRESSION flag, if it's not NULL,
1114 * script is executed immediately, even if it's not in started state yet.
1116 if(!pvarResult
&& !is_started(This
->ctx
)) {
1117 list_add_tail(&This
->queued_code
, &code
->entry
);
1119 hres
= exec_source(This
->ctx
, EXEC_GLOBAL
, code
, &code
->global_code
, NULL
, NULL
, NULL
, 0, NULL
, NULL
);
1120 if(code
->is_persistent
)
1121 list_add_tail(&This
->persistent_code
, &code
->entry
);
1123 release_bytecode(code
);
1126 if(FAILED(hres
= leave_script(This
->ctx
, hres
)))
1130 V_VT(pvarResult
) = VT_EMPTY
;
1134 static const IActiveScriptParseVtbl JScriptParseVtbl
= {
1135 JScriptParse_QueryInterface
,
1136 JScriptParse_AddRef
,
1137 JScriptParse_Release
,
1138 JScriptParse_InitNew
,
1139 JScriptParse_AddScriptlet
,
1140 JScriptParse_ParseScriptText
1143 static inline JScript
*impl_from_IActiveScriptParseProcedure2(IActiveScriptParseProcedure2
*iface
)
1145 return CONTAINING_RECORD(iface
, JScript
, IActiveScriptParseProcedure2_iface
);
1148 static HRESULT WINAPI
JScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2
*iface
, REFIID riid
, void **ppv
)
1150 JScript
*This
= impl_from_IActiveScriptParseProcedure2(iface
);
1151 return IActiveScript_QueryInterface(&This
->IActiveScript_iface
, riid
, ppv
);
1154 static ULONG WINAPI
JScriptParseProcedure_AddRef(IActiveScriptParseProcedure2
*iface
)
1156 JScript
*This
= impl_from_IActiveScriptParseProcedure2(iface
);
1157 return IActiveScript_AddRef(&This
->IActiveScript_iface
);
1160 static ULONG WINAPI
JScriptParseProcedure_Release(IActiveScriptParseProcedure2
*iface
)
1162 JScript
*This
= impl_from_IActiveScriptParseProcedure2(iface
);
1163 return IActiveScript_Release(&This
->IActiveScript_iface
);
1166 static HRESULT WINAPI
JScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2
*iface
,
1167 LPCOLESTR pstrCode
, LPCOLESTR pstrFormalParams
, LPCOLESTR pstrProcedureName
,
1168 LPCOLESTR pstrItemName
, IUnknown
*punkContext
, LPCOLESTR pstrDelimiter
,
1169 CTXARG_T dwSourceContextCookie
, ULONG ulStartingLineNumber
, DWORD dwFlags
, IDispatch
**ppdisp
)
1171 JScript
*This
= impl_from_IActiveScriptParseProcedure2(iface
);
1172 named_item_t
*item
= NULL
;
1178 TRACE("(%p)->(%s %s %s %s %p %s %s %u %x %p)\n", This
, debugstr_w(pstrCode
), debugstr_w(pstrFormalParams
),
1179 debugstr_w(pstrProcedureName
), debugstr_w(pstrItemName
), punkContext
, debugstr_w(pstrDelimiter
),
1180 wine_dbgstr_longlong(dwSourceContextCookie
), ulStartingLineNumber
, dwFlags
, ppdisp
);
1182 if(This
->thread_id
!= GetCurrentThreadId() || This
->ctx
->state
== SCRIPTSTATE_CLOSED
)
1183 return E_UNEXPECTED
;
1186 item
= lookup_named_item(This
->ctx
, pstrItemName
, 0);
1188 WARN("Unknown context %s\n", debugstr_w(pstrItemName
));
1189 return E_INVALIDARG
;
1191 if(!item
->script_obj
) item
= NULL
;
1194 enter_script(This
->ctx
, &ei
);
1195 hres
= compile_script(This
->ctx
, pstrCode
, dwSourceContextCookie
, ulStartingLineNumber
, pstrFormalParams
,
1196 pstrDelimiter
, FALSE
, This
->is_encode
, item
, &code
);
1198 hres
= create_source_function(This
->ctx
, code
, &code
->global_code
, NULL
, &dispex
);
1199 release_bytecode(code
);
1200 hres
= leave_script(This
->ctx
, hres
);
1204 *ppdisp
= to_disp(dispex
);
1208 static const IActiveScriptParseProcedure2Vtbl JScriptParseProcedureVtbl
= {
1209 JScriptParseProcedure_QueryInterface
,
1210 JScriptParseProcedure_AddRef
,
1211 JScriptParseProcedure_Release
,
1212 JScriptParseProcedure_ParseProcedureText
,
1215 static inline JScript
*impl_from_IActiveScriptProperty(IActiveScriptProperty
*iface
)
1217 return CONTAINING_RECORD(iface
, JScript
, IActiveScriptProperty_iface
);
1220 static HRESULT WINAPI
JScriptProperty_QueryInterface(IActiveScriptProperty
*iface
, REFIID riid
, void **ppv
)
1222 JScript
*This
= impl_from_IActiveScriptProperty(iface
);
1223 return IActiveScript_QueryInterface(&This
->IActiveScript_iface
, riid
, ppv
);
1226 static ULONG WINAPI
JScriptProperty_AddRef(IActiveScriptProperty
*iface
)
1228 JScript
*This
= impl_from_IActiveScriptProperty(iface
);
1229 return IActiveScript_AddRef(&This
->IActiveScript_iface
);
1232 static ULONG WINAPI
JScriptProperty_Release(IActiveScriptProperty
*iface
)
1234 JScript
*This
= impl_from_IActiveScriptProperty(iface
);
1235 return IActiveScript_Release(&This
->IActiveScript_iface
);
1238 static HRESULT WINAPI
JScriptProperty_GetProperty(IActiveScriptProperty
*iface
, DWORD dwProperty
,
1239 VARIANT
*pvarIndex
, VARIANT
*pvarValue
)
1241 JScript
*This
= impl_from_IActiveScriptProperty(iface
);
1242 FIXME("(%p)->(%x %p %p)\n", This
, dwProperty
, pvarIndex
, pvarValue
);
1246 static HRESULT WINAPI
JScriptProperty_SetProperty(IActiveScriptProperty
*iface
, DWORD dwProperty
,
1247 VARIANT
*pvarIndex
, VARIANT
*pvarValue
)
1249 JScript
*This
= impl_from_IActiveScriptProperty(iface
);
1251 TRACE("(%p)->(%x %s %s)\n", This
, dwProperty
, debugstr_variant(pvarIndex
), debugstr_variant(pvarValue
));
1254 FIXME("unsupported pvarIndex\n");
1256 switch(dwProperty
) {
1257 case SCRIPTPROP_INVOKEVERSIONING
:
1258 if(V_VT(pvarValue
) != VT_I4
|| V_I4(pvarValue
) < 0
1259 || (V_I4(pvarValue
) > 15 && !(V_I4(pvarValue
) & SCRIPTLANGUAGEVERSION_HTML
))) {
1260 WARN("invalid value %s\n", debugstr_variant(pvarValue
));
1261 return E_INVALIDARG
;
1264 This
->version
= V_I4(pvarValue
) & 0x1ff;
1265 This
->html_mode
= (V_I4(pvarValue
) & SCRIPTLANGUAGEVERSION_HTML
) != 0;
1268 FIXME("Unimplemented property %x\n", dwProperty
);
1275 static const IActiveScriptPropertyVtbl JScriptPropertyVtbl
= {
1276 JScriptProperty_QueryInterface
,
1277 JScriptProperty_AddRef
,
1278 JScriptProperty_Release
,
1279 JScriptProperty_GetProperty
,
1280 JScriptProperty_SetProperty
1283 static inline JScript
*impl_from_IObjectSafety(IObjectSafety
*iface
)
1285 return CONTAINING_RECORD(iface
, JScript
, IObjectSafety_iface
);
1288 static HRESULT WINAPI
JScriptSafety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
1290 JScript
*This
= impl_from_IObjectSafety(iface
);
1291 return IActiveScript_QueryInterface(&This
->IActiveScript_iface
, riid
, ppv
);
1294 static ULONG WINAPI
JScriptSafety_AddRef(IObjectSafety
*iface
)
1296 JScript
*This
= impl_from_IObjectSafety(iface
);
1297 return IActiveScript_AddRef(&This
->IActiveScript_iface
);
1300 static ULONG WINAPI
JScriptSafety_Release(IObjectSafety
*iface
)
1302 JScript
*This
= impl_from_IObjectSafety(iface
);
1303 return IActiveScript_Release(&This
->IActiveScript_iface
);
1306 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER)
1308 static HRESULT WINAPI
JScriptSafety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
1309 DWORD
*pdwSupportedOptions
, DWORD
*pdwEnabledOptions
)
1311 JScript
*This
= impl_from_IObjectSafety(iface
);
1313 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), pdwSupportedOptions
, pdwEnabledOptions
);
1315 if(!pdwSupportedOptions
|| !pdwEnabledOptions
)
1318 *pdwSupportedOptions
= SUPPORTED_OPTIONS
;
1319 *pdwEnabledOptions
= This
->safeopt
;
1324 static HRESULT WINAPI
JScriptSafety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
1325 DWORD dwOptionSetMask
, DWORD dwEnabledOptions
)
1327 JScript
*This
= impl_from_IObjectSafety(iface
);
1329 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), dwOptionSetMask
, dwEnabledOptions
);
1331 if(dwOptionSetMask
& ~SUPPORTED_OPTIONS
)
1334 This
->safeopt
= (dwEnabledOptions
& dwOptionSetMask
) | (This
->safeopt
& ~dwOptionSetMask
) | INTERFACE_USES_DISPEX
;
1338 static const IObjectSafetyVtbl JScriptSafetyVtbl
= {
1339 JScriptSafety_QueryInterface
,
1340 JScriptSafety_AddRef
,
1341 JScriptSafety_Release
,
1342 JScriptSafety_GetInterfaceSafetyOptions
,
1343 JScriptSafety_SetInterfaceSafetyOptions
1346 static inline JScript
*impl_from_IVariantChangeType(IVariantChangeType
*iface
)
1348 return CONTAINING_RECORD(iface
, JScript
, IVariantChangeType_iface
);
1351 static HRESULT WINAPI
VariantChangeType_QueryInterface(IVariantChangeType
*iface
, REFIID riid
, void **ppv
)
1353 JScript
*This
= impl_from_IVariantChangeType(iface
);
1354 return IActiveScript_QueryInterface(&This
->IActiveScript_iface
, riid
, ppv
);
1357 static ULONG WINAPI
VariantChangeType_AddRef(IVariantChangeType
*iface
)
1359 JScript
*This
= impl_from_IVariantChangeType(iface
);
1360 return IActiveScript_AddRef(&This
->IActiveScript_iface
);
1363 static ULONG WINAPI
VariantChangeType_Release(IVariantChangeType
*iface
)
1365 JScript
*This
= impl_from_IVariantChangeType(iface
);
1366 return IActiveScript_Release(&This
->IActiveScript_iface
);
1369 static HRESULT WINAPI
VariantChangeType_ChangeType(IVariantChangeType
*iface
, VARIANT
*dst
, VARIANT
*src
, LCID lcid
, VARTYPE vt
)
1371 JScript
*This
= impl_from_IVariantChangeType(iface
);
1376 TRACE("(%p)->(%p %s %x %s)\n", This
, dst
, debugstr_variant(src
), lcid
, debugstr_vt(vt
));
1379 FIXME("Object uninitialized\n");
1380 return E_UNEXPECTED
;
1383 enter_script(This
->ctx
, &ei
);
1384 hres
= variant_change_type(This
->ctx
, &res
, src
, vt
);
1385 hres
= leave_script(This
->ctx
, hres
);
1389 hres
= VariantClear(dst
);
1399 static const IVariantChangeTypeVtbl VariantChangeTypeVtbl
= {
1400 VariantChangeType_QueryInterface
,
1401 VariantChangeType_AddRef
,
1402 VariantChangeType_Release
,
1403 VariantChangeType_ChangeType
1406 HRESULT
create_jscript_object(BOOL is_encode
, REFIID riid
, void **ppv
)
1411 ret
= heap_alloc_zero(sizeof(*ret
));
1413 return E_OUTOFMEMORY
;
1417 ret
->IActiveScript_iface
.lpVtbl
= &JScriptVtbl
;
1418 ret
->IActiveScriptParse_iface
.lpVtbl
= &JScriptParseVtbl
;
1419 ret
->IActiveScriptParseProcedure2_iface
.lpVtbl
= &JScriptParseProcedureVtbl
;
1420 ret
->IActiveScriptProperty_iface
.lpVtbl
= &JScriptPropertyVtbl
;
1421 ret
->IObjectSafety_iface
.lpVtbl
= &JScriptSafetyVtbl
;
1422 ret
->IVariantChangeType_iface
.lpVtbl
= &VariantChangeTypeVtbl
;
1424 ret
->safeopt
= INTERFACE_USES_DISPEX
;
1425 ret
->is_encode
= is_encode
;
1426 list_init(&ret
->persistent_code
);
1427 list_init(&ret
->queued_code
);
1429 hres
= IActiveScript_QueryInterface(&ret
->IActiveScript_iface
, riid
, ppv
);
1430 IActiveScript_Release(&ret
->IActiveScript_iface
);