rpcrt4: Write the function header into the procedure format string.
[wine.git] / dlls / jscript / jscript.c
blob75eef39e355ff9f155269d9d135220f1e09db648
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 html_mode;
59 BOOL is_encode;
61 IActiveScriptSite *site;
63 bytecode_t *queue_head;
64 bytecode_t *queue_tail;
65 } JScript;
67 void script_release(script_ctx_t *ctx)
69 if(--ctx->ref)
70 return;
72 jsval_release(ctx->acc);
73 clear_ei(ctx);
74 if(ctx->cc)
75 release_cc(ctx->cc);
76 heap_pool_free(&ctx->tmp_heap);
77 if(ctx->last_match)
78 jsstr_release(ctx->last_match);
79 assert(!ctx->stack_top);
80 heap_free(ctx->stack);
82 ctx->jscaller->ctx = NULL;
83 IServiceProvider_Release(&ctx->jscaller->IServiceProvider_iface);
85 heap_free(ctx);
88 static void change_state(JScript *This, SCRIPTSTATE state)
90 if(This->ctx->state == state)
91 return;
93 This->ctx->state = state;
94 if(This->site)
95 IActiveScriptSite_OnStateChange(This->site, state);
98 static inline BOOL is_started(script_ctx_t *ctx)
100 return ctx->state == SCRIPTSTATE_STARTED
101 || ctx->state == SCRIPTSTATE_CONNECTED
102 || ctx->state == SCRIPTSTATE_DISCONNECTED;
105 static HRESULT exec_global_code(JScript *This, bytecode_t *code)
107 HRESULT hres;
109 IActiveScriptSite_OnEnterScript(This->site);
111 clear_ei(This->ctx);
112 hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, NULL);
114 IActiveScriptSite_OnLeaveScript(This->site);
115 return hres;
118 static void clear_script_queue(JScript *This)
120 bytecode_t *iter, *iter2;
122 if(!This->queue_head)
123 return;
125 iter = This->queue_head;
126 while(iter) {
127 iter2 = iter->next;
128 iter->next = NULL;
129 release_bytecode(iter);
130 iter = iter2;
133 This->queue_head = This->queue_tail = NULL;
136 static void exec_queued_code(JScript *This)
138 bytecode_t *iter;
140 for(iter = This->queue_head; iter; iter = iter->next)
141 exec_global_code(This, iter);
143 clear_script_queue(This);
146 static HRESULT set_ctx_site(JScript *This)
148 HRESULT hres;
150 This->ctx->lcid = This->lcid;
152 hres = init_global(This->ctx);
153 if(FAILED(hres))
154 return hres;
156 IActiveScriptSite_AddRef(This->site);
157 This->ctx->site = This->site;
159 change_state(This, SCRIPTSTATE_INITIALIZED);
160 return S_OK;
163 static void decrease_state(JScript *This, SCRIPTSTATE state)
165 if(This->ctx) {
166 switch(This->ctx->state) {
167 case SCRIPTSTATE_CONNECTED:
168 change_state(This, SCRIPTSTATE_DISCONNECTED);
169 if(state == SCRIPTSTATE_DISCONNECTED)
170 return;
171 /* FALLTHROUGH */
172 case SCRIPTSTATE_STARTED:
173 case SCRIPTSTATE_DISCONNECTED:
174 clear_script_queue(This);
176 if(This->ctx->state == SCRIPTSTATE_DISCONNECTED)
177 change_state(This, SCRIPTSTATE_INITIALIZED);
178 if(state == SCRIPTSTATE_INITIALIZED)
179 return;
180 /* FALLTHROUGH */
181 case SCRIPTSTATE_INITIALIZED:
182 if(This->ctx->host_global) {
183 IDispatch_Release(This->ctx->host_global);
184 This->ctx->host_global = NULL;
187 if(This->ctx->named_items) {
188 named_item_t *iter, *iter2;
190 iter = This->ctx->named_items;
191 while(iter) {
192 iter2 = iter->next;
194 if(iter->disp)
195 IDispatch_Release(iter->disp);
196 heap_free(iter->name);
197 heap_free(iter);
198 iter = iter2;
201 This->ctx->named_items = NULL;
204 if(This->ctx->secmgr) {
205 IInternetHostSecurityManager_Release(This->ctx->secmgr);
206 This->ctx->secmgr = NULL;
209 if(This->ctx->site) {
210 IActiveScriptSite_Release(This->ctx->site);
211 This->ctx->site = NULL;
214 if(This->ctx->global) {
215 jsdisp_release(This->ctx->global);
216 This->ctx->global = NULL;
218 /* FALLTHROUGH */
219 case SCRIPTSTATE_UNINITIALIZED:
220 change_state(This, state);
221 break;
222 default:
223 assert(0);
226 change_state(This, state);
227 }else if(state == SCRIPTSTATE_UNINITIALIZED) {
228 if(This->site)
229 IActiveScriptSite_OnStateChange(This->site, state);
230 }else {
231 FIXME("NULL ctx\n");
234 if(state == SCRIPTSTATE_UNINITIALIZED)
235 This->thread_id = 0;
237 if(This->site) {
238 IActiveScriptSite_Release(This->site);
239 This->site = NULL;
243 typedef struct {
244 IServiceProvider IServiceProvider_iface;
246 LONG ref;
248 IServiceProvider *sp;
249 } AXSite;
251 static inline AXSite *impl_from_IServiceProvider(IServiceProvider *iface)
253 return CONTAINING_RECORD(iface, AXSite, IServiceProvider_iface);
256 static HRESULT WINAPI AXSite_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
258 AXSite *This = impl_from_IServiceProvider(iface);
260 if(IsEqualGUID(&IID_IUnknown, riid)) {
261 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
262 *ppv = &This->IServiceProvider_iface;
263 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
264 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
265 *ppv = &This->IServiceProvider_iface;
266 }else {
267 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
268 *ppv = NULL;
269 return E_NOINTERFACE;
272 IUnknown_AddRef((IUnknown*)*ppv);
273 return S_OK;
276 static ULONG WINAPI AXSite_AddRef(IServiceProvider *iface)
278 AXSite *This = impl_from_IServiceProvider(iface);
279 LONG ref = InterlockedIncrement(&This->ref);
281 TRACE("(%p) ref=%d\n", This, ref);
283 return ref;
286 static ULONG WINAPI AXSite_Release(IServiceProvider *iface)
288 AXSite *This = impl_from_IServiceProvider(iface);
289 LONG ref = InterlockedDecrement(&This->ref);
291 TRACE("(%p) ref=%d\n", This, ref);
293 if(!ref)
295 if(This->sp)
296 IServiceProvider_Release(This->sp);
298 heap_free(This);
301 return ref;
304 static HRESULT WINAPI AXSite_QueryService(IServiceProvider *iface,
305 REFGUID guidService, REFIID riid, void **ppv)
307 AXSite *This = impl_from_IServiceProvider(iface);
309 TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
311 if(!This->sp)
312 return E_NOINTERFACE;
314 return IServiceProvider_QueryService(This->sp, guidService, riid, ppv);
317 static IServiceProviderVtbl AXSiteVtbl = {
318 AXSite_QueryInterface,
319 AXSite_AddRef,
320 AXSite_Release,
321 AXSite_QueryService
324 IUnknown *create_ax_site(script_ctx_t *ctx)
326 IServiceProvider *sp = NULL;
327 AXSite *ret;
328 HRESULT hres;
330 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
331 if(FAILED(hres)) {
332 TRACE("Could not get IServiceProvider iface: %08x\n", hres);
335 ret = heap_alloc(sizeof(AXSite));
336 if(!ret) {
337 IServiceProvider_Release(sp);
338 return NULL;
341 ret->IServiceProvider_iface.lpVtbl = &AXSiteVtbl;
342 ret->ref = 1;
343 ret->sp = sp;
345 return (IUnknown*)&ret->IServiceProvider_iface;
348 static inline JScript *impl_from_IActiveScript(IActiveScript *iface)
350 return CONTAINING_RECORD(iface, JScript, IActiveScript_iface);
353 static HRESULT WINAPI JScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
355 JScript *This = impl_from_IActiveScript(iface);
357 *ppv = NULL;
359 if(IsEqualGUID(riid, &IID_IUnknown)) {
360 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
361 *ppv = &This->IActiveScript_iface;
362 }else if(IsEqualGUID(riid, &IID_IActiveScript)) {
363 TRACE("(%p)->(IID_IActiveScript %p)\n", This, ppv);
364 *ppv = &This->IActiveScript_iface;
365 }else if(IsEqualGUID(riid, &IID_IActiveScriptParse)) {
366 TRACE("(%p)->(IID_IActiveScriptParse %p)\n", This, ppv);
367 *ppv = &This->IActiveScriptParse_iface;
368 }else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure)) {
369 TRACE("(%p)->(IID_IActiveScriptParseProcedure %p)\n", This, ppv);
370 *ppv = &This->IActiveScriptParseProcedure2_iface;
371 }else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure2)) {
372 TRACE("(%p)->(IID_IActiveScriptParseProcedure2 %p)\n", This, ppv);
373 *ppv = &This->IActiveScriptParseProcedure2_iface;
374 }else if(IsEqualGUID(riid, &IID_IActiveScriptProperty)) {
375 TRACE("(%p)->(IID_IActiveScriptProperty %p)\n", This, ppv);
376 *ppv = &This->IActiveScriptProperty_iface;
377 }else if(IsEqualGUID(riid, &IID_IObjectSafety)) {
378 TRACE("(%p)->(IID_IObjectSafety %p)\n", This, ppv);
379 *ppv = &This->IObjectSafety_iface;
380 }else if(IsEqualGUID(riid, &IID_IVariantChangeType)) {
381 TRACE("(%p)->(IID_IVariantChangeType %p)\n", This, ppv);
382 *ppv = &This->IVariantChangeType_iface;
385 if(*ppv) {
386 IUnknown_AddRef((IUnknown*)*ppv);
387 return S_OK;
390 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
391 return E_NOINTERFACE;
394 static ULONG WINAPI JScript_AddRef(IActiveScript *iface)
396 JScript *This = impl_from_IActiveScript(iface);
397 LONG ref = InterlockedIncrement(&This->ref);
399 TRACE("(%p) ref=%d\n", This, ref);
401 return ref;
404 static ULONG WINAPI JScript_Release(IActiveScript *iface)
406 JScript *This = impl_from_IActiveScript(iface);
407 LONG ref = InterlockedDecrement(&This->ref);
409 TRACE("(%p) ref=%d\n", iface, ref);
411 if(!ref) {
412 if(This->ctx && This->ctx->state != SCRIPTSTATE_CLOSED)
413 IActiveScript_Close(&This->IActiveScript_iface);
414 if(This->ctx) {
415 This->ctx->active_script = NULL;
416 script_release(This->ctx);
418 heap_free(This);
419 unlock_module();
422 return ref;
425 static HRESULT WINAPI JScript_SetScriptSite(IActiveScript *iface,
426 IActiveScriptSite *pass)
428 JScript *This = impl_from_IActiveScript(iface);
429 LCID lcid;
430 HRESULT hres;
432 TRACE("(%p)->(%p)\n", This, pass);
434 if(!pass)
435 return E_POINTER;
437 if(This->site)
438 return E_UNEXPECTED;
440 if(InterlockedCompareExchange(&This->thread_id, GetCurrentThreadId(), 0))
441 return E_UNEXPECTED;
443 This->site = pass;
444 IActiveScriptSite_AddRef(This->site);
446 hres = IActiveScriptSite_GetLCID(This->site, &lcid);
447 if(hres == S_OK)
448 This->lcid = lcid;
450 return This->ctx ? set_ctx_site(This) : S_OK;
453 static HRESULT WINAPI JScript_GetScriptSite(IActiveScript *iface, REFIID riid,
454 void **ppvObject)
456 JScript *This = impl_from_IActiveScript(iface);
457 FIXME("(%p)->()\n", This);
458 return E_NOTIMPL;
461 static HRESULT WINAPI JScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
463 JScript *This = impl_from_IActiveScript(iface);
465 TRACE("(%p)->(%d)\n", This, ss);
467 if(This->thread_id && GetCurrentThreadId() != This->thread_id)
468 return E_UNEXPECTED;
470 if(ss == SCRIPTSTATE_UNINITIALIZED) {
471 if(This->ctx && This->ctx->state == SCRIPTSTATE_CLOSED)
472 return E_UNEXPECTED;
474 decrease_state(This, SCRIPTSTATE_UNINITIALIZED);
475 return S_OK;
478 if(!This->ctx)
479 return E_UNEXPECTED;
481 switch(ss) {
482 case SCRIPTSTATE_STARTED:
483 case SCRIPTSTATE_CONNECTED: /* FIXME */
484 if(This->ctx->state == SCRIPTSTATE_CLOSED)
485 return E_UNEXPECTED;
487 exec_queued_code(This);
488 break;
489 case SCRIPTSTATE_INITIALIZED:
490 FIXME("unimplemented SCRIPTSTATE_INITIALIZED\n");
491 return S_OK;
492 default:
493 FIXME("unimplemented state %d\n", ss);
494 return E_NOTIMPL;
497 change_state(This, ss);
498 return S_OK;
501 static HRESULT WINAPI JScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
503 JScript *This = impl_from_IActiveScript(iface);
505 TRACE("(%p)->(%p)\n", This, pssState);
507 if(!pssState)
508 return E_POINTER;
510 if(This->thread_id && This->thread_id != GetCurrentThreadId())
511 return E_UNEXPECTED;
513 *pssState = This->ctx ? This->ctx->state : SCRIPTSTATE_UNINITIALIZED;
514 return S_OK;
517 static HRESULT WINAPI JScript_Close(IActiveScript *iface)
519 JScript *This = impl_from_IActiveScript(iface);
521 TRACE("(%p)->()\n", This);
523 if(This->thread_id && This->thread_id != GetCurrentThreadId())
524 return E_UNEXPECTED;
526 decrease_state(This, SCRIPTSTATE_CLOSED);
527 return S_OK;
530 static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface,
531 LPCOLESTR pstrName, DWORD dwFlags)
533 JScript *This = impl_from_IActiveScript(iface);
534 named_item_t *item;
535 IDispatch *disp = NULL;
536 HRESULT hres;
538 TRACE("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);
540 if(This->thread_id != GetCurrentThreadId() || !This->ctx || This->ctx->state == SCRIPTSTATE_CLOSED)
541 return E_UNEXPECTED;
543 if(dwFlags & SCRIPTITEM_GLOBALMEMBERS) {
544 IUnknown *unk;
546 hres = IActiveScriptSite_GetItemInfo(This->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL);
547 if(FAILED(hres)) {
548 WARN("GetItemInfo failed: %08x\n", hres);
549 return hres;
552 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
553 IUnknown_Release(unk);
554 if(FAILED(hres)) {
555 WARN("object does not implement IDispatch\n");
556 return hres;
559 if(This->ctx->host_global)
560 IDispatch_Release(This->ctx->host_global);
561 IDispatch_AddRef(disp);
562 This->ctx->host_global = disp;
565 item = heap_alloc(sizeof(*item));
566 if(!item) {
567 if(disp)
568 IDispatch_Release(disp);
569 return E_OUTOFMEMORY;
572 item->disp = disp;
573 item->flags = dwFlags;
574 item->name = heap_strdupW(pstrName);
575 if(!item->name) {
576 if(disp)
577 IDispatch_Release(disp);
578 heap_free(item);
579 return E_OUTOFMEMORY;
582 item->next = This->ctx->named_items;
583 This->ctx->named_items = item;
585 return S_OK;
588 static HRESULT WINAPI JScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
589 DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
591 JScript *This = impl_from_IActiveScript(iface);
592 FIXME("(%p)->()\n", This);
593 return E_NOTIMPL;
596 static HRESULT WINAPI JScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
597 IDispatch **ppdisp)
599 JScript *This = impl_from_IActiveScript(iface);
601 TRACE("(%p)->(%p)\n", This, ppdisp);
603 if(!ppdisp)
604 return E_POINTER;
606 if(This->thread_id != GetCurrentThreadId() || !This->ctx->global) {
607 *ppdisp = NULL;
608 return E_UNEXPECTED;
611 *ppdisp = to_disp(This->ctx->global);
612 IDispatch_AddRef(*ppdisp);
613 return S_OK;
616 static HRESULT WINAPI JScript_GetCurrentScriptThreadID(IActiveScript *iface,
617 SCRIPTTHREADID *pstridThread)
619 JScript *This = impl_from_IActiveScript(iface);
620 FIXME("(%p)->()\n", This);
621 return E_NOTIMPL;
624 static HRESULT WINAPI JScript_GetScriptThreadID(IActiveScript *iface,
625 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
627 JScript *This = impl_from_IActiveScript(iface);
628 FIXME("(%p)->()\n", This);
629 return E_NOTIMPL;
632 static HRESULT WINAPI JScript_GetScriptThreadState(IActiveScript *iface,
633 SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
635 JScript *This = impl_from_IActiveScript(iface);
636 FIXME("(%p)->()\n", This);
637 return E_NOTIMPL;
640 static HRESULT WINAPI JScript_InterruptScriptThread(IActiveScript *iface,
641 SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
643 JScript *This = impl_from_IActiveScript(iface);
644 FIXME("(%p)->()\n", This);
645 return E_NOTIMPL;
648 static HRESULT WINAPI JScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
650 JScript *This = impl_from_IActiveScript(iface);
651 FIXME("(%p)->()\n", This);
652 return E_NOTIMPL;
655 static const IActiveScriptVtbl JScriptVtbl = {
656 JScript_QueryInterface,
657 JScript_AddRef,
658 JScript_Release,
659 JScript_SetScriptSite,
660 JScript_GetScriptSite,
661 JScript_SetScriptState,
662 JScript_GetScriptState,
663 JScript_Close,
664 JScript_AddNamedItem,
665 JScript_AddTypeLib,
666 JScript_GetScriptDispatch,
667 JScript_GetCurrentScriptThreadID,
668 JScript_GetScriptThreadID,
669 JScript_GetScriptThreadState,
670 JScript_InterruptScriptThread,
671 JScript_Clone
674 static inline JScript *impl_from_IActiveScriptParse(IActiveScriptParse *iface)
676 return CONTAINING_RECORD(iface, JScript, IActiveScriptParse_iface);
679 static HRESULT WINAPI JScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
681 JScript *This = impl_from_IActiveScriptParse(iface);
682 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
685 static ULONG WINAPI JScriptParse_AddRef(IActiveScriptParse *iface)
687 JScript *This = impl_from_IActiveScriptParse(iface);
688 return IActiveScript_AddRef(&This->IActiveScript_iface);
691 static ULONG WINAPI JScriptParse_Release(IActiveScriptParse *iface)
693 JScript *This = impl_from_IActiveScriptParse(iface);
694 return IActiveScript_Release(&This->IActiveScript_iface);
697 static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface)
699 JScript *This = impl_from_IActiveScriptParse(iface);
700 script_ctx_t *ctx;
701 HRESULT hres;
703 TRACE("(%p)\n", This);
705 if(This->ctx)
706 return E_UNEXPECTED;
708 ctx = heap_alloc_zero(sizeof(script_ctx_t));
709 if(!ctx)
710 return E_OUTOFMEMORY;
712 ctx->ref = 1;
713 ctx->state = SCRIPTSTATE_UNINITIALIZED;
714 ctx->active_script = &This->IActiveScript_iface;
715 ctx->safeopt = This->safeopt;
716 ctx->version = This->version;
717 ctx->html_mode = This->html_mode;
718 ctx->ei.val = jsval_undefined();
719 ctx->acc = jsval_undefined();
720 heap_pool_init(&ctx->tmp_heap);
722 hres = create_jscaller(ctx);
723 if(FAILED(hres)) {
724 heap_free(ctx);
725 return hres;
728 ctx->last_match = jsstr_empty();
730 ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
731 if(ctx) {
732 script_release(ctx);
733 return E_UNEXPECTED;
736 return This->site ? set_ctx_site(This) : S_OK;
739 static HRESULT WINAPI JScriptParse_AddScriptlet(IActiveScriptParse *iface,
740 LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
741 LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
742 CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
743 BSTR *pbstrName, EXCEPINFO *pexcepinfo)
745 JScript *This = impl_from_IActiveScriptParse(iface);
746 FIXME("(%p)->(%s %s %s %s %s %s %s %u %x %p %p)\n", This, debugstr_w(pstrDefaultName),
747 debugstr_w(pstrCode), debugstr_w(pstrItemName), debugstr_w(pstrSubItemName),
748 debugstr_w(pstrEventName), debugstr_w(pstrDelimiter), wine_dbgstr_longlong(dwSourceContextCookie),
749 ulStartingLineNumber, dwFlags, pbstrName, pexcepinfo);
750 return E_NOTIMPL;
753 static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
754 LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
755 LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
756 DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
758 JScript *This = impl_from_IActiveScriptParse(iface);
759 bytecode_t *code;
760 HRESULT hres;
762 TRACE("(%p)->(%s %s %p %s %s %u %x %p %p)\n", This, debugstr_w(pstrCode),
763 debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
764 wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLine, dwFlags, pvarResult, pexcepinfo);
766 if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED)
767 return E_UNEXPECTED;
769 hres = compile_script(This->ctx, pstrCode, NULL, pstrDelimiter, (dwFlags & SCRIPTTEXT_ISEXPRESSION) != 0,
770 This->is_encode, &code);
771 if(FAILED(hres))
772 return hres;
774 if(dwFlags & SCRIPTTEXT_ISEXPRESSION) {
775 jsval_t r;
777 IActiveScriptSite_OnEnterScript(This->site);
779 clear_ei(This->ctx);
780 hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, &r);
781 if(SUCCEEDED(hres)) {
782 if(pvarResult)
783 hres = jsval_to_variant(r, pvarResult);
784 jsval_release(r);
787 IActiveScriptSite_OnLeaveScript(This->site);
788 return hres;
792 * Although pvarResult is not really used without SCRIPTTEXT_ISEXPRESSION flag, if it's not NULL,
793 * script is executed immediately, even if it's not in started state yet.
795 if(!pvarResult && !is_started(This->ctx)) {
796 if(This->queue_tail)
797 This->queue_tail = This->queue_tail->next = code;
798 else
799 This->queue_head = This->queue_tail = code;
800 return S_OK;
803 hres = exec_global_code(This, code);
804 release_bytecode(code);
805 if(FAILED(hres))
806 return hres;
808 if(pvarResult)
809 V_VT(pvarResult) = VT_EMPTY;
810 return S_OK;
813 static const IActiveScriptParseVtbl JScriptParseVtbl = {
814 JScriptParse_QueryInterface,
815 JScriptParse_AddRef,
816 JScriptParse_Release,
817 JScriptParse_InitNew,
818 JScriptParse_AddScriptlet,
819 JScriptParse_ParseScriptText
822 static inline JScript *impl_from_IActiveScriptParseProcedure2(IActiveScriptParseProcedure2 *iface)
824 return CONTAINING_RECORD(iface, JScript, IActiveScriptParseProcedure2_iface);
827 static HRESULT WINAPI JScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2 *iface, REFIID riid, void **ppv)
829 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
830 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
833 static ULONG WINAPI JScriptParseProcedure_AddRef(IActiveScriptParseProcedure2 *iface)
835 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
836 return IActiveScript_AddRef(&This->IActiveScript_iface);
839 static ULONG WINAPI JScriptParseProcedure_Release(IActiveScriptParseProcedure2 *iface)
841 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
842 return IActiveScript_Release(&This->IActiveScript_iface);
845 static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2 *iface,
846 LPCOLESTR pstrCode, LPCOLESTR pstrFormalParams, LPCOLESTR pstrProcedureName,
847 LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter,
848 CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
850 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
851 bytecode_t *code;
852 jsdisp_t *dispex;
853 HRESULT hres;
855 TRACE("(%p)->(%s %s %s %s %p %s %s %u %x %p)\n", This, debugstr_w(pstrCode), debugstr_w(pstrFormalParams),
856 debugstr_w(pstrProcedureName), debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
857 wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLineNumber, dwFlags, ppdisp);
859 if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED)
860 return E_UNEXPECTED;
862 hres = compile_script(This->ctx, pstrCode, pstrFormalParams, pstrDelimiter, FALSE, This->is_encode, &code);
863 if(FAILED(hres)) {
864 WARN("Parse failed %08x\n", hres);
865 return hres;
868 hres = create_source_function(This->ctx, code, &code->global_code, NULL, &dispex);
869 release_bytecode(code);
870 if(FAILED(hres))
871 return hres;
873 *ppdisp = to_disp(dispex);
874 return S_OK;
877 static const IActiveScriptParseProcedure2Vtbl JScriptParseProcedureVtbl = {
878 JScriptParseProcedure_QueryInterface,
879 JScriptParseProcedure_AddRef,
880 JScriptParseProcedure_Release,
881 JScriptParseProcedure_ParseProcedureText,
884 static inline JScript *impl_from_IActiveScriptProperty(IActiveScriptProperty *iface)
886 return CONTAINING_RECORD(iface, JScript, IActiveScriptProperty_iface);
889 static HRESULT WINAPI JScriptProperty_QueryInterface(IActiveScriptProperty *iface, REFIID riid, void **ppv)
891 JScript *This = impl_from_IActiveScriptProperty(iface);
892 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
895 static ULONG WINAPI JScriptProperty_AddRef(IActiveScriptProperty *iface)
897 JScript *This = impl_from_IActiveScriptProperty(iface);
898 return IActiveScript_AddRef(&This->IActiveScript_iface);
901 static ULONG WINAPI JScriptProperty_Release(IActiveScriptProperty *iface)
903 JScript *This = impl_from_IActiveScriptProperty(iface);
904 return IActiveScript_Release(&This->IActiveScript_iface);
907 static HRESULT WINAPI JScriptProperty_GetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
908 VARIANT *pvarIndex, VARIANT *pvarValue)
910 JScript *This = impl_from_IActiveScriptProperty(iface);
911 FIXME("(%p)->(%x %p %p)\n", This, dwProperty, pvarIndex, pvarValue);
912 return E_NOTIMPL;
915 static HRESULT WINAPI JScriptProperty_SetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
916 VARIANT *pvarIndex, VARIANT *pvarValue)
918 JScript *This = impl_from_IActiveScriptProperty(iface);
920 TRACE("(%p)->(%x %s %s)\n", This, dwProperty, debugstr_variant(pvarIndex), debugstr_variant(pvarValue));
922 if(pvarIndex)
923 FIXME("unsupported pvarIndex\n");
925 switch(dwProperty) {
926 case SCRIPTPROP_INVOKEVERSIONING:
927 if(V_VT(pvarValue) != VT_I4 || V_I4(pvarValue) < 0
928 || (V_I4(pvarValue) > 15 && !(V_I4(pvarValue) & SCRIPTLANGUAGEVERSION_HTML))) {
929 WARN("invalid value %s\n", debugstr_variant(pvarValue));
930 return E_INVALIDARG;
933 This->version = V_I4(pvarValue) & 0x1ff;
934 This->html_mode = (V_I4(pvarValue) & SCRIPTLANGUAGEVERSION_HTML) != 0;
935 break;
936 default:
937 FIXME("Unimplemented property %x\n", dwProperty);
938 return E_NOTIMPL;
941 return S_OK;
944 static const IActiveScriptPropertyVtbl JScriptPropertyVtbl = {
945 JScriptProperty_QueryInterface,
946 JScriptProperty_AddRef,
947 JScriptProperty_Release,
948 JScriptProperty_GetProperty,
949 JScriptProperty_SetProperty
952 static inline JScript *impl_from_IObjectSafety(IObjectSafety *iface)
954 return CONTAINING_RECORD(iface, JScript, IObjectSafety_iface);
957 static HRESULT WINAPI JScriptSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
959 JScript *This = impl_from_IObjectSafety(iface);
960 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
963 static ULONG WINAPI JScriptSafety_AddRef(IObjectSafety *iface)
965 JScript *This = impl_from_IObjectSafety(iface);
966 return IActiveScript_AddRef(&This->IActiveScript_iface);
969 static ULONG WINAPI JScriptSafety_Release(IObjectSafety *iface)
971 JScript *This = impl_from_IObjectSafety(iface);
972 return IActiveScript_Release(&This->IActiveScript_iface);
975 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER)
977 static HRESULT WINAPI JScriptSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
978 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
980 JScript *This = impl_from_IObjectSafety(iface);
982 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
984 if(!pdwSupportedOptions || !pdwEnabledOptions)
985 return E_POINTER;
987 *pdwSupportedOptions = SUPPORTED_OPTIONS;
988 *pdwEnabledOptions = This->safeopt;
990 return S_OK;
993 static HRESULT WINAPI JScriptSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
994 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
996 JScript *This = impl_from_IObjectSafety(iface);
998 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
1000 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
1001 return E_FAIL;
1003 This->safeopt = (dwEnabledOptions & dwOptionSetMask) | (This->safeopt & ~dwOptionSetMask) | INTERFACE_USES_DISPEX;
1004 return S_OK;
1007 static const IObjectSafetyVtbl JScriptSafetyVtbl = {
1008 JScriptSafety_QueryInterface,
1009 JScriptSafety_AddRef,
1010 JScriptSafety_Release,
1011 JScriptSafety_GetInterfaceSafetyOptions,
1012 JScriptSafety_SetInterfaceSafetyOptions
1015 static inline JScript *impl_from_IVariantChangeType(IVariantChangeType *iface)
1017 return CONTAINING_RECORD(iface, JScript, IVariantChangeType_iface);
1020 static HRESULT WINAPI VariantChangeType_QueryInterface(IVariantChangeType *iface, REFIID riid, void **ppv)
1022 JScript *This = impl_from_IVariantChangeType(iface);
1023 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
1026 static ULONG WINAPI VariantChangeType_AddRef(IVariantChangeType *iface)
1028 JScript *This = impl_from_IVariantChangeType(iface);
1029 return IActiveScript_AddRef(&This->IActiveScript_iface);
1032 static ULONG WINAPI VariantChangeType_Release(IVariantChangeType *iface)
1034 JScript *This = impl_from_IVariantChangeType(iface);
1035 return IActiveScript_Release(&This->IActiveScript_iface);
1038 static HRESULT WINAPI VariantChangeType_ChangeType(IVariantChangeType *iface, VARIANT *dst, VARIANT *src, LCID lcid, VARTYPE vt)
1040 JScript *This = impl_from_IVariantChangeType(iface);
1041 VARIANT res;
1042 HRESULT hres;
1044 TRACE("(%p)->(%p %p%s %x %d)\n", This, dst, src, debugstr_variant(src), lcid, vt);
1046 if(!This->ctx) {
1047 FIXME("Object uninitialized\n");
1048 return E_UNEXPECTED;
1051 hres = variant_change_type(This->ctx, &res, src, vt);
1052 if(FAILED(hres))
1053 return hres;
1055 hres = VariantClear(dst);
1056 if(FAILED(hres)) {
1057 VariantClear(&res);
1058 return hres;
1061 *dst = res;
1062 return S_OK;
1065 static const IVariantChangeTypeVtbl VariantChangeTypeVtbl = {
1066 VariantChangeType_QueryInterface,
1067 VariantChangeType_AddRef,
1068 VariantChangeType_Release,
1069 VariantChangeType_ChangeType
1072 HRESULT create_jscript_object(BOOL is_encode, REFIID riid, void **ppv)
1074 JScript *ret;
1075 HRESULT hres;
1077 ret = heap_alloc_zero(sizeof(*ret));
1078 if(!ret)
1079 return E_OUTOFMEMORY;
1081 lock_module();
1083 ret->IActiveScript_iface.lpVtbl = &JScriptVtbl;
1084 ret->IActiveScriptParse_iface.lpVtbl = &JScriptParseVtbl;
1085 ret->IActiveScriptParseProcedure2_iface.lpVtbl = &JScriptParseProcedureVtbl;
1086 ret->IActiveScriptProperty_iface.lpVtbl = &JScriptPropertyVtbl;
1087 ret->IObjectSafety_iface.lpVtbl = &JScriptSafetyVtbl;
1088 ret->IVariantChangeType_iface.lpVtbl = &VariantChangeTypeVtbl;
1089 ret->ref = 1;
1090 ret->safeopt = INTERFACE_USES_DISPEX;
1091 ret->is_encode = is_encode;
1093 hres = IActiveScript_QueryInterface(&ret->IActiveScript_iface, riid, ppv);
1094 IActiveScript_Release(&ret->IActiveScript_iface);
1095 return hres;