urlmon: Added Seek implementations for streams using cache file.
[wine.git] / dlls / jscript / jscript.c
blobb7b1e1b74f21bb0279468b1f4d5635f19ced6973
1 /*
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
19 #include <assert.h>
21 #include "jscript.h"
22 #include "engine.h"
23 #include "objsafe.h"
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
29 #ifdef _WIN64
31 #define CTXARG_T DWORDLONG
32 #define IActiveScriptParseVtbl IActiveScriptParse64Vtbl
33 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_64Vtbl
35 #else
37 #define CTXARG_T DWORD
38 #define IActiveScriptParseVtbl IActiveScriptParse32Vtbl
39 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_32Vtbl
41 #endif
43 typedef struct {
44 IActiveScript IActiveScript_iface;
45 IActiveScriptParse IActiveScriptParse_iface;
46 IActiveScriptParseProcedure2 IActiveScriptParseProcedure2_iface;
47 IActiveScriptProperty IActiveScriptProperty_iface;
48 IObjectSafety IObjectSafety_iface;
49 IVariantChangeType IVariantChangeType_iface;
51 LONG ref;
53 DWORD safeopt;
54 script_ctx_t *ctx;
55 LONG thread_id;
56 LCID lcid;
57 DWORD version;
58 BOOL is_encode;
60 IActiveScriptSite *site;
62 bytecode_t *queue_head;
63 bytecode_t *queue_tail;
64 } JScript;
66 void script_release(script_ctx_t *ctx)
68 if(--ctx->ref)
69 return;
71 clear_ei(ctx);
72 if(ctx->cc)
73 release_cc(ctx->cc);
74 heap_pool_free(&ctx->tmp_heap);
75 if(ctx->last_match)
76 jsstr_release(ctx->last_match);
77 assert(!ctx->stack_top);
78 heap_free(ctx->stack);
80 ctx->jscaller->ctx = NULL;
81 IServiceProvider_Release(&ctx->jscaller->IServiceProvider_iface);
83 heap_free(ctx);
86 static void change_state(JScript *This, SCRIPTSTATE state)
88 if(This->ctx->state == state)
89 return;
91 This->ctx->state = state;
92 if(This->site)
93 IActiveScriptSite_OnStateChange(This->site, state);
96 static inline BOOL is_started(script_ctx_t *ctx)
98 return ctx->state == SCRIPTSTATE_STARTED
99 || ctx->state == SCRIPTSTATE_CONNECTED
100 || ctx->state == SCRIPTSTATE_DISCONNECTED;
103 static HRESULT exec_global_code(JScript *This, bytecode_t *code)
105 HRESULT hres;
107 IActiveScriptSite_OnEnterScript(This->site);
109 clear_ei(This->ctx);
110 hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, NULL);
112 IActiveScriptSite_OnLeaveScript(This->site);
113 return hres;
116 static void clear_script_queue(JScript *This)
118 bytecode_t *iter, *iter2;
120 if(!This->queue_head)
121 return;
123 iter = This->queue_head;
124 while(iter) {
125 iter2 = iter->next;
126 iter->next = NULL;
127 release_bytecode(iter);
128 iter = iter2;
131 This->queue_head = This->queue_tail = NULL;
134 static void exec_queued_code(JScript *This)
136 bytecode_t *iter;
138 for(iter = This->queue_head; iter; iter = iter->next)
139 exec_global_code(This, iter);
141 clear_script_queue(This);
144 static HRESULT set_ctx_site(JScript *This)
146 HRESULT hres;
148 This->ctx->lcid = This->lcid;
150 hres = init_global(This->ctx);
151 if(FAILED(hres))
152 return hres;
154 IActiveScriptSite_AddRef(This->site);
155 This->ctx->site = This->site;
157 change_state(This, SCRIPTSTATE_INITIALIZED);
158 return S_OK;
161 static void decrease_state(JScript *This, SCRIPTSTATE state)
163 if(This->ctx) {
164 switch(This->ctx->state) {
165 case SCRIPTSTATE_CONNECTED:
166 change_state(This, SCRIPTSTATE_DISCONNECTED);
167 if(state == SCRIPTSTATE_DISCONNECTED)
168 return;
169 /* FALLTHROUGH */
170 case SCRIPTSTATE_STARTED:
171 case SCRIPTSTATE_DISCONNECTED:
172 clear_script_queue(This);
174 if(This->ctx->state == SCRIPTSTATE_DISCONNECTED)
175 change_state(This, SCRIPTSTATE_INITIALIZED);
176 if(state == SCRIPTSTATE_INITIALIZED)
177 return;
178 /* FALLTHROUGH */
179 case SCRIPTSTATE_INITIALIZED:
180 if(This->ctx->host_global) {
181 IDispatch_Release(This->ctx->host_global);
182 This->ctx->host_global = NULL;
185 if(This->ctx->named_items) {
186 named_item_t *iter, *iter2;
188 iter = This->ctx->named_items;
189 while(iter) {
190 iter2 = iter->next;
192 if(iter->disp)
193 IDispatch_Release(iter->disp);
194 heap_free(iter->name);
195 heap_free(iter);
196 iter = iter2;
199 This->ctx->named_items = NULL;
202 if(This->ctx->secmgr) {
203 IInternetHostSecurityManager_Release(This->ctx->secmgr);
204 This->ctx->secmgr = NULL;
207 if(This->ctx->site) {
208 IActiveScriptSite_Release(This->ctx->site);
209 This->ctx->site = NULL;
212 if(This->ctx->global) {
213 jsdisp_release(This->ctx->global);
214 This->ctx->global = NULL;
216 /* FALLTHROUGH */
217 case SCRIPTSTATE_UNINITIALIZED:
218 change_state(This, state);
219 break;
220 default:
221 assert(0);
224 change_state(This, state);
225 }else if(state == SCRIPTSTATE_UNINITIALIZED) {
226 if(This->site)
227 IActiveScriptSite_OnStateChange(This->site, state);
228 }else {
229 FIXME("NULL ctx\n");
232 if(state == SCRIPTSTATE_UNINITIALIZED)
233 This->thread_id = 0;
235 if(This->site) {
236 IActiveScriptSite_Release(This->site);
237 This->site = NULL;
241 typedef struct {
242 IServiceProvider IServiceProvider_iface;
244 LONG ref;
246 IServiceProvider *sp;
247 } AXSite;
249 static inline AXSite *impl_from_IServiceProvider(IServiceProvider *iface)
251 return CONTAINING_RECORD(iface, AXSite, IServiceProvider_iface);
254 static HRESULT WINAPI AXSite_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
256 AXSite *This = impl_from_IServiceProvider(iface);
258 if(IsEqualGUID(&IID_IUnknown, riid)) {
259 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
260 *ppv = &This->IServiceProvider_iface;
261 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
262 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
263 *ppv = &This->IServiceProvider_iface;
264 }else {
265 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
266 *ppv = NULL;
267 return E_NOINTERFACE;
270 IUnknown_AddRef((IUnknown*)*ppv);
271 return S_OK;
274 static ULONG WINAPI AXSite_AddRef(IServiceProvider *iface)
276 AXSite *This = impl_from_IServiceProvider(iface);
277 LONG ref = InterlockedIncrement(&This->ref);
279 TRACE("(%p) ref=%d\n", This, ref);
281 return ref;
284 static ULONG WINAPI AXSite_Release(IServiceProvider *iface)
286 AXSite *This = impl_from_IServiceProvider(iface);
287 LONG ref = InterlockedDecrement(&This->ref);
289 TRACE("(%p) ref=%d\n", This, ref);
291 if(!ref)
293 if(This->sp)
294 IServiceProvider_Release(This->sp);
296 heap_free(This);
299 return ref;
302 static HRESULT WINAPI AXSite_QueryService(IServiceProvider *iface,
303 REFGUID guidService, REFIID riid, void **ppv)
305 AXSite *This = impl_from_IServiceProvider(iface);
307 TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
309 if(!This->sp)
310 return E_NOINTERFACE;
312 return IServiceProvider_QueryService(This->sp, guidService, riid, ppv);
315 static IServiceProviderVtbl AXSiteVtbl = {
316 AXSite_QueryInterface,
317 AXSite_AddRef,
318 AXSite_Release,
319 AXSite_QueryService
322 IUnknown *create_ax_site(script_ctx_t *ctx)
324 IServiceProvider *sp = NULL;
325 AXSite *ret;
326 HRESULT hres;
328 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
329 if(FAILED(hres)) {
330 TRACE("Could not get IServiceProvider iface: %08x\n", hres);
333 ret = heap_alloc(sizeof(AXSite));
334 if(!ret) {
335 IServiceProvider_Release(sp);
336 return NULL;
339 ret->IServiceProvider_iface.lpVtbl = &AXSiteVtbl;
340 ret->ref = 1;
341 ret->sp = sp;
343 return (IUnknown*)&ret->IServiceProvider_iface;
346 static inline JScript *impl_from_IActiveScript(IActiveScript *iface)
348 return CONTAINING_RECORD(iface, JScript, IActiveScript_iface);
351 static HRESULT WINAPI JScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
353 JScript *This = impl_from_IActiveScript(iface);
355 *ppv = NULL;
357 if(IsEqualGUID(riid, &IID_IUnknown)) {
358 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
359 *ppv = &This->IActiveScript_iface;
360 }else if(IsEqualGUID(riid, &IID_IActiveScript)) {
361 TRACE("(%p)->(IID_IActiveScript %p)\n", This, ppv);
362 *ppv = &This->IActiveScript_iface;
363 }else if(IsEqualGUID(riid, &IID_IActiveScriptParse)) {
364 TRACE("(%p)->(IID_IActiveScriptParse %p)\n", This, ppv);
365 *ppv = &This->IActiveScriptParse_iface;
366 }else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure)) {
367 TRACE("(%p)->(IID_IActiveScriptParseProcedure %p)\n", This, ppv);
368 *ppv = &This->IActiveScriptParseProcedure2_iface;
369 }else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure2)) {
370 TRACE("(%p)->(IID_IActiveScriptParseProcedure2 %p)\n", This, ppv);
371 *ppv = &This->IActiveScriptParseProcedure2_iface;
372 }else if(IsEqualGUID(riid, &IID_IActiveScriptProperty)) {
373 TRACE("(%p)->(IID_IActiveScriptProperty %p)\n", This, ppv);
374 *ppv = &This->IActiveScriptProperty_iface;
375 }else if(IsEqualGUID(riid, &IID_IObjectSafety)) {
376 TRACE("(%p)->(IID_IObjectSafety %p)\n", This, ppv);
377 *ppv = &This->IObjectSafety_iface;
378 }else if(IsEqualGUID(riid, &IID_IVariantChangeType)) {
379 TRACE("(%p)->(IID_IVariantChangeType %p)\n", This, ppv);
380 *ppv = &This->IVariantChangeType_iface;
383 if(*ppv) {
384 IUnknown_AddRef((IUnknown*)*ppv);
385 return S_OK;
388 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
389 return E_NOINTERFACE;
392 static ULONG WINAPI JScript_AddRef(IActiveScript *iface)
394 JScript *This = impl_from_IActiveScript(iface);
395 LONG ref = InterlockedIncrement(&This->ref);
397 TRACE("(%p) ref=%d\n", This, ref);
399 return ref;
402 static ULONG WINAPI JScript_Release(IActiveScript *iface)
404 JScript *This = impl_from_IActiveScript(iface);
405 LONG ref = InterlockedDecrement(&This->ref);
407 TRACE("(%p) ref=%d\n", iface, ref);
409 if(!ref) {
410 if(This->ctx && This->ctx->state != SCRIPTSTATE_CLOSED)
411 IActiveScript_Close(&This->IActiveScript_iface);
412 if(This->ctx) {
413 This->ctx->active_script = NULL;
414 script_release(This->ctx);
416 heap_free(This);
417 unlock_module();
420 return ref;
423 static HRESULT WINAPI JScript_SetScriptSite(IActiveScript *iface,
424 IActiveScriptSite *pass)
426 JScript *This = impl_from_IActiveScript(iface);
427 LCID lcid;
428 HRESULT hres;
430 TRACE("(%p)->(%p)\n", This, pass);
432 if(!pass)
433 return E_POINTER;
435 if(This->site)
436 return E_UNEXPECTED;
438 if(InterlockedCompareExchange(&This->thread_id, GetCurrentThreadId(), 0))
439 return E_UNEXPECTED;
441 This->site = pass;
442 IActiveScriptSite_AddRef(This->site);
444 hres = IActiveScriptSite_GetLCID(This->site, &lcid);
445 if(hres == S_OK)
446 This->lcid = lcid;
448 return This->ctx ? set_ctx_site(This) : S_OK;
451 static HRESULT WINAPI JScript_GetScriptSite(IActiveScript *iface, REFIID riid,
452 void **ppvObject)
454 JScript *This = impl_from_IActiveScript(iface);
455 FIXME("(%p)->()\n", This);
456 return E_NOTIMPL;
459 static HRESULT WINAPI JScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
461 JScript *This = impl_from_IActiveScript(iface);
463 TRACE("(%p)->(%d)\n", This, ss);
465 if(This->thread_id && GetCurrentThreadId() != This->thread_id)
466 return E_UNEXPECTED;
468 if(ss == SCRIPTSTATE_UNINITIALIZED) {
469 if(This->ctx && This->ctx->state == SCRIPTSTATE_CLOSED)
470 return E_UNEXPECTED;
472 decrease_state(This, SCRIPTSTATE_UNINITIALIZED);
473 return S_OK;
476 if(!This->ctx)
477 return E_UNEXPECTED;
479 switch(ss) {
480 case SCRIPTSTATE_STARTED:
481 case SCRIPTSTATE_CONNECTED: /* FIXME */
482 if(This->ctx->state == SCRIPTSTATE_CLOSED)
483 return E_UNEXPECTED;
485 exec_queued_code(This);
486 break;
487 case SCRIPTSTATE_INITIALIZED:
488 FIXME("unimplemented SCRIPTSTATE_INITIALIZED\n");
489 return S_OK;
490 default:
491 FIXME("unimplemented state %d\n", ss);
492 return E_NOTIMPL;
495 change_state(This, ss);
496 return S_OK;
499 static HRESULT WINAPI JScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
501 JScript *This = impl_from_IActiveScript(iface);
503 TRACE("(%p)->(%p)\n", This, pssState);
505 if(!pssState)
506 return E_POINTER;
508 if(This->thread_id && This->thread_id != GetCurrentThreadId())
509 return E_UNEXPECTED;
511 *pssState = This->ctx ? This->ctx->state : SCRIPTSTATE_UNINITIALIZED;
512 return S_OK;
515 static HRESULT WINAPI JScript_Close(IActiveScript *iface)
517 JScript *This = impl_from_IActiveScript(iface);
519 TRACE("(%p)->()\n", This);
521 if(This->thread_id && This->thread_id != GetCurrentThreadId())
522 return E_UNEXPECTED;
524 decrease_state(This, SCRIPTSTATE_CLOSED);
525 return S_OK;
528 static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface,
529 LPCOLESTR pstrName, DWORD dwFlags)
531 JScript *This = impl_from_IActiveScript(iface);
532 named_item_t *item;
533 IDispatch *disp = NULL;
534 HRESULT hres;
536 TRACE("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);
538 if(This->thread_id != GetCurrentThreadId() || !This->ctx || This->ctx->state == SCRIPTSTATE_CLOSED)
539 return E_UNEXPECTED;
541 if(dwFlags & SCRIPTITEM_GLOBALMEMBERS) {
542 IUnknown *unk;
544 hres = IActiveScriptSite_GetItemInfo(This->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL);
545 if(FAILED(hres)) {
546 WARN("GetItemInfo failed: %08x\n", hres);
547 return hres;
550 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
551 IUnknown_Release(unk);
552 if(FAILED(hres)) {
553 WARN("object does not implement IDispatch\n");
554 return hres;
557 if(This->ctx->host_global)
558 IDispatch_Release(This->ctx->host_global);
559 IDispatch_AddRef(disp);
560 This->ctx->host_global = disp;
563 item = heap_alloc(sizeof(*item));
564 if(!item) {
565 if(disp)
566 IDispatch_Release(disp);
567 return E_OUTOFMEMORY;
570 item->disp = disp;
571 item->flags = dwFlags;
572 item->name = heap_strdupW(pstrName);
573 if(!item->name) {
574 if(disp)
575 IDispatch_Release(disp);
576 heap_free(item);
577 return E_OUTOFMEMORY;
580 item->next = This->ctx->named_items;
581 This->ctx->named_items = item;
583 return S_OK;
586 static HRESULT WINAPI JScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
587 DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
589 JScript *This = impl_from_IActiveScript(iface);
590 FIXME("(%p)->()\n", This);
591 return E_NOTIMPL;
594 static HRESULT WINAPI JScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
595 IDispatch **ppdisp)
597 JScript *This = impl_from_IActiveScript(iface);
599 TRACE("(%p)->(%p)\n", This, ppdisp);
601 if(!ppdisp)
602 return E_POINTER;
604 if(This->thread_id != GetCurrentThreadId() || !This->ctx->global) {
605 *ppdisp = NULL;
606 return E_UNEXPECTED;
609 *ppdisp = to_disp(This->ctx->global);
610 IDispatch_AddRef(*ppdisp);
611 return S_OK;
614 static HRESULT WINAPI JScript_GetCurrentScriptThreadID(IActiveScript *iface,
615 SCRIPTTHREADID *pstridThread)
617 JScript *This = impl_from_IActiveScript(iface);
618 FIXME("(%p)->()\n", This);
619 return E_NOTIMPL;
622 static HRESULT WINAPI JScript_GetScriptThreadID(IActiveScript *iface,
623 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
625 JScript *This = impl_from_IActiveScript(iface);
626 FIXME("(%p)->()\n", This);
627 return E_NOTIMPL;
630 static HRESULT WINAPI JScript_GetScriptThreadState(IActiveScript *iface,
631 SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
633 JScript *This = impl_from_IActiveScript(iface);
634 FIXME("(%p)->()\n", This);
635 return E_NOTIMPL;
638 static HRESULT WINAPI JScript_InterruptScriptThread(IActiveScript *iface,
639 SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
641 JScript *This = impl_from_IActiveScript(iface);
642 FIXME("(%p)->()\n", This);
643 return E_NOTIMPL;
646 static HRESULT WINAPI JScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
648 JScript *This = impl_from_IActiveScript(iface);
649 FIXME("(%p)->()\n", This);
650 return E_NOTIMPL;
653 static const IActiveScriptVtbl JScriptVtbl = {
654 JScript_QueryInterface,
655 JScript_AddRef,
656 JScript_Release,
657 JScript_SetScriptSite,
658 JScript_GetScriptSite,
659 JScript_SetScriptState,
660 JScript_GetScriptState,
661 JScript_Close,
662 JScript_AddNamedItem,
663 JScript_AddTypeLib,
664 JScript_GetScriptDispatch,
665 JScript_GetCurrentScriptThreadID,
666 JScript_GetScriptThreadID,
667 JScript_GetScriptThreadState,
668 JScript_InterruptScriptThread,
669 JScript_Clone
672 static inline JScript *impl_from_IActiveScriptParse(IActiveScriptParse *iface)
674 return CONTAINING_RECORD(iface, JScript, IActiveScriptParse_iface);
677 static HRESULT WINAPI JScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
679 JScript *This = impl_from_IActiveScriptParse(iface);
680 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
683 static ULONG WINAPI JScriptParse_AddRef(IActiveScriptParse *iface)
685 JScript *This = impl_from_IActiveScriptParse(iface);
686 return IActiveScript_AddRef(&This->IActiveScript_iface);
689 static ULONG WINAPI JScriptParse_Release(IActiveScriptParse *iface)
691 JScript *This = impl_from_IActiveScriptParse(iface);
692 return IActiveScript_Release(&This->IActiveScript_iface);
695 static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface)
697 JScript *This = impl_from_IActiveScriptParse(iface);
698 script_ctx_t *ctx;
699 HRESULT hres;
701 TRACE("(%p)\n", This);
703 if(This->ctx)
704 return E_UNEXPECTED;
706 ctx = heap_alloc_zero(sizeof(script_ctx_t));
707 if(!ctx)
708 return E_OUTOFMEMORY;
710 ctx->ref = 1;
711 ctx->state = SCRIPTSTATE_UNINITIALIZED;
712 ctx->active_script = &This->IActiveScript_iface;
713 ctx->safeopt = This->safeopt;
714 ctx->version = This->version;
715 ctx->ei.val = jsval_undefined();
716 heap_pool_init(&ctx->tmp_heap);
718 hres = create_jscaller(ctx);
719 if(FAILED(hres)) {
720 heap_free(ctx);
721 return hres;
724 ctx->last_match = jsstr_empty();
726 ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
727 if(ctx) {
728 script_release(ctx);
729 return E_UNEXPECTED;
732 return This->site ? set_ctx_site(This) : S_OK;
735 static HRESULT WINAPI JScriptParse_AddScriptlet(IActiveScriptParse *iface,
736 LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
737 LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
738 CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
739 BSTR *pbstrName, EXCEPINFO *pexcepinfo)
741 JScript *This = impl_from_IActiveScriptParse(iface);
742 FIXME("(%p)->(%s %s %s %s %s %s %s %u %x %p %p)\n", This, debugstr_w(pstrDefaultName),
743 debugstr_w(pstrCode), debugstr_w(pstrItemName), debugstr_w(pstrSubItemName),
744 debugstr_w(pstrEventName), debugstr_w(pstrDelimiter), wine_dbgstr_longlong(dwSourceContextCookie),
745 ulStartingLineNumber, dwFlags, pbstrName, pexcepinfo);
746 return E_NOTIMPL;
749 static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
750 LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
751 LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
752 DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
754 JScript *This = impl_from_IActiveScriptParse(iface);
755 bytecode_t *code;
756 HRESULT hres;
758 TRACE("(%p)->(%s %s %p %s %s %u %x %p %p)\n", This, debugstr_w(pstrCode),
759 debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
760 wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLine, dwFlags, pvarResult, pexcepinfo);
762 if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED)
763 return E_UNEXPECTED;
765 hres = compile_script(This->ctx, pstrCode, NULL, pstrDelimiter, (dwFlags & SCRIPTTEXT_ISEXPRESSION) != 0,
766 This->is_encode, &code);
767 if(FAILED(hres))
768 return hres;
770 if(dwFlags & SCRIPTTEXT_ISEXPRESSION) {
771 jsval_t r;
773 IActiveScriptSite_OnEnterScript(This->site);
775 clear_ei(This->ctx);
776 hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, &r);
777 if(SUCCEEDED(hres)) {
778 if(pvarResult)
779 hres = jsval_to_variant(r, pvarResult);
780 jsval_release(r);
783 IActiveScriptSite_OnLeaveScript(This->site);
784 return hres;
788 * Although pvarResult is not really used without SCRIPTTEXT_ISEXPRESSION flag, if it's not NULL,
789 * script is executed immediately, even if it's not in started state yet.
791 if(!pvarResult && !is_started(This->ctx)) {
792 if(This->queue_tail)
793 This->queue_tail = This->queue_tail->next = code;
794 else
795 This->queue_head = This->queue_tail = code;
796 return S_OK;
799 hres = exec_global_code(This, code);
800 release_bytecode(code);
801 if(FAILED(hres))
802 return hres;
804 if(pvarResult)
805 V_VT(pvarResult) = VT_EMPTY;
806 return S_OK;
809 static const IActiveScriptParseVtbl JScriptParseVtbl = {
810 JScriptParse_QueryInterface,
811 JScriptParse_AddRef,
812 JScriptParse_Release,
813 JScriptParse_InitNew,
814 JScriptParse_AddScriptlet,
815 JScriptParse_ParseScriptText
818 static inline JScript *impl_from_IActiveScriptParseProcedure2(IActiveScriptParseProcedure2 *iface)
820 return CONTAINING_RECORD(iface, JScript, IActiveScriptParseProcedure2_iface);
823 static HRESULT WINAPI JScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2 *iface, REFIID riid, void **ppv)
825 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
826 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
829 static ULONG WINAPI JScriptParseProcedure_AddRef(IActiveScriptParseProcedure2 *iface)
831 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
832 return IActiveScript_AddRef(&This->IActiveScript_iface);
835 static ULONG WINAPI JScriptParseProcedure_Release(IActiveScriptParseProcedure2 *iface)
837 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
838 return IActiveScript_Release(&This->IActiveScript_iface);
841 static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2 *iface,
842 LPCOLESTR pstrCode, LPCOLESTR pstrFormalParams, LPCOLESTR pstrProcedureName,
843 LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter,
844 CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
846 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
847 bytecode_t *code;
848 jsdisp_t *dispex;
849 HRESULT hres;
851 TRACE("(%p)->(%s %s %s %s %p %s %s %u %x %p)\n", This, debugstr_w(pstrCode), debugstr_w(pstrFormalParams),
852 debugstr_w(pstrProcedureName), debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
853 wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLineNumber, dwFlags, ppdisp);
855 if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED)
856 return E_UNEXPECTED;
858 hres = compile_script(This->ctx, pstrCode, pstrFormalParams, pstrDelimiter, FALSE, This->is_encode, &code);
859 if(FAILED(hres)) {
860 WARN("Parse failed %08x\n", hres);
861 return hres;
864 hres = create_source_function(This->ctx, code, &code->global_code, NULL, &dispex);
865 release_bytecode(code);
866 if(FAILED(hres))
867 return hres;
869 *ppdisp = to_disp(dispex);
870 return S_OK;
873 static const IActiveScriptParseProcedure2Vtbl JScriptParseProcedureVtbl = {
874 JScriptParseProcedure_QueryInterface,
875 JScriptParseProcedure_AddRef,
876 JScriptParseProcedure_Release,
877 JScriptParseProcedure_ParseProcedureText,
880 static inline JScript *impl_from_IActiveScriptProperty(IActiveScriptProperty *iface)
882 return CONTAINING_RECORD(iface, JScript, IActiveScriptProperty_iface);
885 static HRESULT WINAPI JScriptProperty_QueryInterface(IActiveScriptProperty *iface, REFIID riid, void **ppv)
887 JScript *This = impl_from_IActiveScriptProperty(iface);
888 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
891 static ULONG WINAPI JScriptProperty_AddRef(IActiveScriptProperty *iface)
893 JScript *This = impl_from_IActiveScriptProperty(iface);
894 return IActiveScript_AddRef(&This->IActiveScript_iface);
897 static ULONG WINAPI JScriptProperty_Release(IActiveScriptProperty *iface)
899 JScript *This = impl_from_IActiveScriptProperty(iface);
900 return IActiveScript_Release(&This->IActiveScript_iface);
903 static HRESULT WINAPI JScriptProperty_GetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
904 VARIANT *pvarIndex, VARIANT *pvarValue)
906 JScript *This = impl_from_IActiveScriptProperty(iface);
907 FIXME("(%p)->(%x %p %p)\n", This, dwProperty, pvarIndex, pvarValue);
908 return E_NOTIMPL;
911 static HRESULT WINAPI JScriptProperty_SetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
912 VARIANT *pvarIndex, VARIANT *pvarValue)
914 JScript *This = impl_from_IActiveScriptProperty(iface);
916 TRACE("(%p)->(%x %s %s)\n", This, dwProperty, debugstr_variant(pvarIndex), debugstr_variant(pvarValue));
918 if(pvarIndex)
919 FIXME("unsupported pvarIndex\n");
921 switch(dwProperty) {
922 case SCRIPTPROP_INVOKEVERSIONING:
923 if(V_VT(pvarValue) != VT_I4 || V_I4(pvarValue) < 0 || V_I4(pvarValue) > 15) {
924 WARN("invalid value %s\n", debugstr_variant(pvarValue));
925 return E_INVALIDARG;
928 This->version = V_I4(pvarValue);
929 break;
930 default:
931 FIXME("Unimplemented property %x\n", dwProperty);
932 return E_NOTIMPL;
935 return S_OK;
938 static const IActiveScriptPropertyVtbl JScriptPropertyVtbl = {
939 JScriptProperty_QueryInterface,
940 JScriptProperty_AddRef,
941 JScriptProperty_Release,
942 JScriptProperty_GetProperty,
943 JScriptProperty_SetProperty
946 static inline JScript *impl_from_IObjectSafety(IObjectSafety *iface)
948 return CONTAINING_RECORD(iface, JScript, IObjectSafety_iface);
951 static HRESULT WINAPI JScriptSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
953 JScript *This = impl_from_IObjectSafety(iface);
954 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
957 static ULONG WINAPI JScriptSafety_AddRef(IObjectSafety *iface)
959 JScript *This = impl_from_IObjectSafety(iface);
960 return IActiveScript_AddRef(&This->IActiveScript_iface);
963 static ULONG WINAPI JScriptSafety_Release(IObjectSafety *iface)
965 JScript *This = impl_from_IObjectSafety(iface);
966 return IActiveScript_Release(&This->IActiveScript_iface);
969 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER)
971 static HRESULT WINAPI JScriptSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
972 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
974 JScript *This = impl_from_IObjectSafety(iface);
976 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
978 if(!pdwSupportedOptions || !pdwEnabledOptions)
979 return E_POINTER;
981 *pdwSupportedOptions = SUPPORTED_OPTIONS;
982 *pdwEnabledOptions = This->safeopt;
984 return S_OK;
987 static HRESULT WINAPI JScriptSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
988 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
990 JScript *This = impl_from_IObjectSafety(iface);
992 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
994 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
995 return E_FAIL;
997 This->safeopt = (dwEnabledOptions & dwOptionSetMask) | (This->safeopt & ~dwOptionSetMask) | INTERFACE_USES_DISPEX;
998 return S_OK;
1001 static const IObjectSafetyVtbl JScriptSafetyVtbl = {
1002 JScriptSafety_QueryInterface,
1003 JScriptSafety_AddRef,
1004 JScriptSafety_Release,
1005 JScriptSafety_GetInterfaceSafetyOptions,
1006 JScriptSafety_SetInterfaceSafetyOptions
1009 static inline JScript *impl_from_IVariantChangeType(IVariantChangeType *iface)
1011 return CONTAINING_RECORD(iface, JScript, IVariantChangeType_iface);
1014 static HRESULT WINAPI VariantChangeType_QueryInterface(IVariantChangeType *iface, REFIID riid, void **ppv)
1016 JScript *This = impl_from_IVariantChangeType(iface);
1017 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
1020 static ULONG WINAPI VariantChangeType_AddRef(IVariantChangeType *iface)
1022 JScript *This = impl_from_IVariantChangeType(iface);
1023 return IActiveScript_AddRef(&This->IActiveScript_iface);
1026 static ULONG WINAPI VariantChangeType_Release(IVariantChangeType *iface)
1028 JScript *This = impl_from_IVariantChangeType(iface);
1029 return IActiveScript_Release(&This->IActiveScript_iface);
1032 static HRESULT WINAPI VariantChangeType_ChangeType(IVariantChangeType *iface, VARIANT *dst, VARIANT *src, LCID lcid, VARTYPE vt)
1034 JScript *This = impl_from_IVariantChangeType(iface);
1035 VARIANT res;
1036 HRESULT hres;
1038 TRACE("(%p)->(%p %p%s %x %d)\n", This, dst, src, debugstr_variant(src), lcid, vt);
1040 if(!This->ctx) {
1041 FIXME("Object uninitialized\n");
1042 return E_UNEXPECTED;
1045 hres = variant_change_type(This->ctx, &res, src, vt);
1046 if(FAILED(hres))
1047 return hres;
1049 hres = VariantClear(dst);
1050 if(FAILED(hres)) {
1051 VariantClear(&res);
1052 return hres;
1055 *dst = res;
1056 return S_OK;
1059 static const IVariantChangeTypeVtbl VariantChangeTypeVtbl = {
1060 VariantChangeType_QueryInterface,
1061 VariantChangeType_AddRef,
1062 VariantChangeType_Release,
1063 VariantChangeType_ChangeType
1066 HRESULT create_jscript_object(BOOL is_encode, REFIID riid, void **ppv)
1068 JScript *ret;
1069 HRESULT hres;
1071 ret = heap_alloc_zero(sizeof(*ret));
1072 if(!ret)
1073 return E_OUTOFMEMORY;
1075 lock_module();
1077 ret->IActiveScript_iface.lpVtbl = &JScriptVtbl;
1078 ret->IActiveScriptParse_iface.lpVtbl = &JScriptParseVtbl;
1079 ret->IActiveScriptParseProcedure2_iface.lpVtbl = &JScriptParseProcedureVtbl;
1080 ret->IActiveScriptProperty_iface.lpVtbl = &JScriptPropertyVtbl;
1081 ret->IObjectSafety_iface.lpVtbl = &JScriptSafetyVtbl;
1082 ret->IVariantChangeType_iface.lpVtbl = &VariantChangeTypeVtbl;
1083 ret->ref = 1;
1084 ret->safeopt = INTERFACE_USES_DISPEX;
1085 ret->is_encode = is_encode;
1087 hres = IActiveScript_QueryInterface(&ret->IActiveScript_iface, riid, ppv);
1088 IActiveScript_Release(&ret->IActiveScript_iface);
1089 return hres;