msvcrt: Use fpclass constants from public header.
[wine/zf.git] / dlls / jscript / jscript.c
blob8e729a043244aa62d59f4e55585c68835403f18b
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;
60 BOOL is_initialized;
62 IActiveScriptSite *site;
64 struct list persistent_code;
65 struct list queued_code;
66 } JScript;
68 typedef struct {
69 IActiveScriptError IActiveScriptError_iface;
70 LONG ref;
71 jsexcept_t ei;
72 } JScriptError;
74 void script_release(script_ctx_t *ctx)
76 if(--ctx->ref)
77 return;
79 jsval_release(ctx->acc);
80 if(ctx->cc)
81 release_cc(ctx->cc);
82 heap_pool_free(&ctx->tmp_heap);
83 if(ctx->last_match)
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);
91 heap_free(ctx);
94 static void change_state(JScript *This, SCRIPTSTATE state)
96 if(This->ctx->state == state)
97 return;
99 This->ctx->state = state;
100 if(This->site)
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 = {
114 JSCLASS_GLOBAL,
115 {NULL, NULL, 0},
116 0, NULL,
117 NULL,
118 NULL
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)
134 IUnknown *unk;
135 HRESULT hr;
137 if(!site)
138 return E_UNEXPECTED;
140 hr = IActiveScriptSite_GetItemInfo(site, item->name, SCRIPTINFO_IUNKNOWN, &unk, NULL);
141 if(FAILED(hr)) {
142 WARN("GetItemInfo failed: %08x\n", hr);
143 return hr;
146 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&item->disp);
147 IUnknown_Release(unk);
148 if(FAILED(hr)) {
149 WARN("object does not implement IDispatch\n");
150 return hr;
153 return S_OK;
156 named_item_t *lookup_named_item(script_ctx_t *ctx, const WCHAR *item_name, unsigned flags)
158 named_item_t *item;
159 HRESULT hr;
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;
173 return item;
177 return NULL;
180 void release_named_item(named_item_t *item)
182 if(--item->ref) return;
184 heap_free(item->name);
185 heap_free(item);
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;
203 }else {
204 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
205 *ppv = NULL;
206 return E_NOINTERFACE;
209 IUnknown_AddRef((IUnknown*)*ppv);
210 return S_OK;
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);
220 return 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);
230 if(!ref) {
231 reset_ei(&This->ei);
232 heap_free(This);
235 return 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);
244 if(!excepinfo)
245 return E_POINTER;
247 memset(excepinfo, 0, sizeof(*excepinfo));
248 excepinfo->scode = This->ei.error;
249 if(This->ei.source)
250 jsstr_to_bstr(This->ei.source, &excepinfo->bstrSource);
251 if(This->ei.message)
252 jsstr_to_bstr(This->ei.message, &excepinfo->bstrDescription);
253 return S_OK;
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 const WCHAR *nl, *p;
261 unsigned l;
263 TRACE("(%p)->(%p %p %p)\n", This, source_context, line, character);
265 if(!This->ei.code) {
266 FIXME("unknown position\n");
267 return E_FAIL;
270 if(source_context)
271 *source_context = This->ei.code->source_context;
272 if(!line && !character)
273 return S_OK;
275 l = code->start_line;
276 for(nl = p = code->source; p < code->source + This->ei.loc; p++) {
277 if(*p != '\n') continue;
278 l++;
279 nl = p + 1;
281 if(line)
282 *line = l;
283 if(character)
284 *character = code->source + This->ei.loc - nl;
285 return S_OK;
288 static HRESULT WINAPI JScriptError_GetSourceLineText(IActiveScriptError *iface, BSTR *source)
290 JScriptError *This = impl_from_IActiveScriptError(iface);
292 TRACE("(%p)->(%p)\n", This, source);
294 if(!source)
295 return E_POINTER;
297 if(!This->ei.line) {
298 *source = NULL;
299 return E_FAIL;
302 return jsstr_to_bstr(This->ei.line, source);
305 static const IActiveScriptErrorVtbl JScriptErrorVtbl = {
306 JScriptError_QueryInterface,
307 JScriptError_AddRef,
308 JScriptError_Release,
309 JScriptError_GetExceptionInfo,
310 JScriptError_GetSourcePosition,
311 JScriptError_GetSourceLineText
314 void reset_ei(jsexcept_t *ei)
316 ei->error = S_OK;
317 if(ei->valid_value) {
318 jsval_release(ei->value);
319 ei->valid_value = FALSE;
321 if(ei->code) {
322 release_bytecode(ei->code);
323 ei->code = NULL;
324 ei->loc = 0;
326 if(ei->source) {
327 jsstr_release(ei->source);
328 ei->source = NULL;
330 if(ei->message) {
331 jsstr_release(ei->message);
332 ei->message = NULL;
334 if(ei->line) {
335 jsstr_release(ei->line);
336 ei->line = NULL;
340 void enter_script(script_ctx_t *ctx, jsexcept_t *ei)
342 memset(ei, 0, sizeof(*ei));
343 ei->prev = ctx->ei;
344 ctx->ei = ei;
345 TRACE("ctx %p ei %p prev %p\n", ctx, ei, ei->prev);
348 HRESULT leave_script(script_ctx_t *ctx, HRESULT result)
350 jsexcept_t *ei = ctx->ei;
351 BOOL enter_notified = ei->enter_notified;
352 JScriptError *error;
354 TRACE("ctx %p ei %p prev %p\n", ctx, ei, ei->prev);
356 ctx->ei = ei->prev;
357 if(result == DISP_E_EXCEPTION) {
358 result = ei->error;
359 }else {
360 reset_ei(ei);
361 ei->error = result;
363 if(FAILED(result)) {
364 WARN("%08x\n", result);
365 if(ctx->site && (error = heap_alloc(sizeof(*error)))) {
366 HRESULT hres;
368 error->IActiveScriptError_iface.lpVtbl = &JScriptErrorVtbl;
369 error->ref = 1;
370 error->ei = *ei;
371 memset(ei, 0, sizeof(*ei));
373 hres = IActiveScriptSite_OnScriptError(ctx->site, &error->IActiveScriptError_iface);
374 IActiveScriptError_Release(&error->IActiveScriptError_iface);
375 if(hres == S_OK)
376 result = SCRIPT_E_REPORTED;
379 if(enter_notified && ctx->site)
380 IActiveScriptSite_OnLeaveScript(ctx->site);
381 reset_ei(ei);
382 return result;
385 static void clear_script_queue(JScript *This)
387 while(!list_empty(&This->queued_code))
389 bytecode_t *iter = LIST_ENTRY(list_head(&This->queued_code), bytecode_t, entry);
390 list_remove(&iter->entry);
391 if (iter->is_persistent)
392 list_add_tail(&This->persistent_code, &iter->entry);
393 else
394 release_bytecode(iter);
398 static void clear_persistent_code_list(JScript *This)
400 while(!list_empty(&This->persistent_code))
402 bytecode_t *iter = LIST_ENTRY(list_head(&This->persistent_code), bytecode_t, entry);
403 list_remove(&iter->entry);
404 release_bytecode(iter);
408 static void release_persistent_script_objs(JScript *This)
410 bytecode_t *iter;
412 LIST_FOR_EACH_ENTRY(iter, &This->persistent_code, bytecode_t, entry)
413 if(iter->named_item)
414 release_named_item_script_obj(iter->named_item);
417 static void release_named_item_list(JScript *This)
419 while(!list_empty(&This->ctx->named_items)) {
420 named_item_t *iter = LIST_ENTRY(list_head(&This->ctx->named_items), named_item_t, entry);
421 list_remove(&iter->entry);
422 release_named_item(iter);
426 static void exec_queued_code(JScript *This)
428 bytecode_t *iter;
429 jsexcept_t ei;
430 HRESULT hres = S_OK;
432 LIST_FOR_EACH_ENTRY(iter, &This->queued_code, bytecode_t, entry) {
433 enter_script(This->ctx, &ei);
434 hres = exec_source(This->ctx, EXEC_GLOBAL, iter, &iter->global_code, NULL, NULL, NULL, 0, NULL, NULL);
435 leave_script(This->ctx, hres);
436 if(FAILED(hres))
437 break;
440 clear_script_queue(This);
443 static void decrease_state(JScript *This, SCRIPTSTATE state)
445 named_item_t *item, *item_next;
447 if(This->ctx) {
448 switch(This->ctx->state) {
449 case SCRIPTSTATE_CONNECTED:
450 change_state(This, SCRIPTSTATE_DISCONNECTED);
451 if(state == SCRIPTSTATE_DISCONNECTED)
452 return;
453 /* FALLTHROUGH */
454 case SCRIPTSTATE_STARTED:
455 case SCRIPTSTATE_DISCONNECTED:
456 clear_script_queue(This);
458 if(This->ctx->state == SCRIPTSTATE_DISCONNECTED)
459 change_state(This, SCRIPTSTATE_INITIALIZED);
460 if(state == SCRIPTSTATE_INITIALIZED)
461 return;
462 /* FALLTHROUGH */
463 case SCRIPTSTATE_INITIALIZED:
464 clear_script_queue(This);
465 release_persistent_script_objs(This);
467 LIST_FOR_EACH_ENTRY_SAFE(item, item_next, &This->ctx->named_items, named_item_t, entry)
469 if(item->disp)
471 IDispatch_Release(item->disp);
472 item->disp = NULL;
474 release_named_item_script_obj(item);
475 if(!(item->flags & SCRIPTITEM_ISPERSISTENT))
477 list_remove(&item->entry);
478 release_named_item(item);
482 if(This->ctx->secmgr) {
483 IInternetHostSecurityManager_Release(This->ctx->secmgr);
484 This->ctx->secmgr = NULL;
487 if(This->ctx->site) {
488 IActiveScriptSite_Release(This->ctx->site);
489 This->ctx->site = NULL;
492 if(This->ctx->global) {
493 jsdisp_release(This->ctx->global);
494 This->ctx->global = NULL;
496 /* FALLTHROUGH */
497 case SCRIPTSTATE_UNINITIALIZED:
498 change_state(This, state);
499 break;
500 default:
501 assert(0);
504 change_state(This, state);
505 }else if(state == SCRIPTSTATE_UNINITIALIZED) {
506 if(This->site)
507 IActiveScriptSite_OnStateChange(This->site, state);
508 }else {
509 FIXME("NULL ctx\n");
512 if(state == SCRIPTSTATE_UNINITIALIZED || state == SCRIPTSTATE_CLOSED)
513 This->thread_id = 0;
515 if(This->site) {
516 IActiveScriptSite_Release(This->site);
517 This->site = NULL;
521 typedef struct {
522 IServiceProvider IServiceProvider_iface;
524 LONG ref;
526 IServiceProvider *sp;
527 } AXSite;
529 static inline AXSite *impl_from_IServiceProvider(IServiceProvider *iface)
531 return CONTAINING_RECORD(iface, AXSite, IServiceProvider_iface);
534 static HRESULT WINAPI AXSite_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
536 AXSite *This = impl_from_IServiceProvider(iface);
538 if(IsEqualGUID(&IID_IUnknown, riid)) {
539 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
540 *ppv = &This->IServiceProvider_iface;
541 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
542 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
543 *ppv = &This->IServiceProvider_iface;
544 }else {
545 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
546 *ppv = NULL;
547 return E_NOINTERFACE;
550 IUnknown_AddRef((IUnknown*)*ppv);
551 return S_OK;
554 static ULONG WINAPI AXSite_AddRef(IServiceProvider *iface)
556 AXSite *This = impl_from_IServiceProvider(iface);
557 LONG ref = InterlockedIncrement(&This->ref);
559 TRACE("(%p) ref=%d\n", This, ref);
561 return ref;
564 static ULONG WINAPI AXSite_Release(IServiceProvider *iface)
566 AXSite *This = impl_from_IServiceProvider(iface);
567 LONG ref = InterlockedDecrement(&This->ref);
569 TRACE("(%p) ref=%d\n", This, ref);
571 if(!ref)
573 if(This->sp)
574 IServiceProvider_Release(This->sp);
576 heap_free(This);
579 return ref;
582 static HRESULT WINAPI AXSite_QueryService(IServiceProvider *iface,
583 REFGUID guidService, REFIID riid, void **ppv)
585 AXSite *This = impl_from_IServiceProvider(iface);
587 TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
589 if(!This->sp)
590 return E_NOINTERFACE;
592 return IServiceProvider_QueryService(This->sp, guidService, riid, ppv);
595 static IServiceProviderVtbl AXSiteVtbl = {
596 AXSite_QueryInterface,
597 AXSite_AddRef,
598 AXSite_Release,
599 AXSite_QueryService
602 IUnknown *create_ax_site(script_ctx_t *ctx)
604 IServiceProvider *sp = NULL;
605 AXSite *ret;
606 HRESULT hres;
608 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
609 if(FAILED(hres)) {
610 TRACE("Could not get IServiceProvider iface: %08x\n", hres);
613 ret = heap_alloc(sizeof(AXSite));
614 if(!ret) {
615 IServiceProvider_Release(sp);
616 return NULL;
619 ret->IServiceProvider_iface.lpVtbl = &AXSiteVtbl;
620 ret->ref = 1;
621 ret->sp = sp;
623 return (IUnknown*)&ret->IServiceProvider_iface;
626 static inline JScript *impl_from_IActiveScript(IActiveScript *iface)
628 return CONTAINING_RECORD(iface, JScript, IActiveScript_iface);
631 static HRESULT WINAPI JScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
633 JScript *This = impl_from_IActiveScript(iface);
635 *ppv = NULL;
637 if(IsEqualGUID(riid, &IID_IUnknown)) {
638 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
639 *ppv = &This->IActiveScript_iface;
640 }else if(IsEqualGUID(riid, &IID_IActiveScript)) {
641 TRACE("(%p)->(IID_IActiveScript %p)\n", This, ppv);
642 *ppv = &This->IActiveScript_iface;
643 }else if(IsEqualGUID(riid, &IID_IActiveScriptParse)) {
644 TRACE("(%p)->(IID_IActiveScriptParse %p)\n", This, ppv);
645 *ppv = &This->IActiveScriptParse_iface;
646 }else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure)) {
647 TRACE("(%p)->(IID_IActiveScriptParseProcedure %p)\n", This, ppv);
648 *ppv = &This->IActiveScriptParseProcedure2_iface;
649 }else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure2)) {
650 TRACE("(%p)->(IID_IActiveScriptParseProcedure2 %p)\n", This, ppv);
651 *ppv = &This->IActiveScriptParseProcedure2_iface;
652 }else if(IsEqualGUID(riid, &IID_IActiveScriptProperty)) {
653 TRACE("(%p)->(IID_IActiveScriptProperty %p)\n", This, ppv);
654 *ppv = &This->IActiveScriptProperty_iface;
655 }else if(IsEqualGUID(riid, &IID_IObjectSafety)) {
656 TRACE("(%p)->(IID_IObjectSafety %p)\n", This, ppv);
657 *ppv = &This->IObjectSafety_iface;
658 }else if(IsEqualGUID(riid, &IID_IVariantChangeType)) {
659 TRACE("(%p)->(IID_IVariantChangeType %p)\n", This, ppv);
660 *ppv = &This->IVariantChangeType_iface;
663 if(*ppv) {
664 IUnknown_AddRef((IUnknown*)*ppv);
665 return S_OK;
668 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
669 return E_NOINTERFACE;
672 static ULONG WINAPI JScript_AddRef(IActiveScript *iface)
674 JScript *This = impl_from_IActiveScript(iface);
675 LONG ref = InterlockedIncrement(&This->ref);
677 TRACE("(%p) ref=%d\n", This, ref);
679 return ref;
682 static ULONG WINAPI JScript_Release(IActiveScript *iface)
684 JScript *This = impl_from_IActiveScript(iface);
685 LONG ref = InterlockedDecrement(&This->ref);
687 TRACE("(%p) ref=%d\n", iface, ref);
689 if(!ref) {
690 if(This->ctx && This->ctx->state != SCRIPTSTATE_CLOSED)
691 IActiveScript_Close(&This->IActiveScript_iface);
692 if(This->ctx) {
693 This->ctx->active_script = NULL;
694 script_release(This->ctx);
696 heap_free(This);
697 unlock_module();
700 return ref;
703 static HRESULT WINAPI JScript_SetScriptSite(IActiveScript *iface,
704 IActiveScriptSite *pass)
706 JScript *This = impl_from_IActiveScript(iface);
707 named_item_t *item;
708 LCID lcid;
709 HRESULT hres;
711 TRACE("(%p)->(%p)\n", This, pass);
713 if(!pass)
714 return E_POINTER;
716 if(This->site)
717 return E_UNEXPECTED;
719 if(InterlockedCompareExchange(&This->thread_id, GetCurrentThreadId(), 0))
720 return E_UNEXPECTED;
722 if(!This->ctx) {
723 script_ctx_t *ctx = heap_alloc_zero(sizeof(script_ctx_t));
724 if(!ctx)
725 return E_OUTOFMEMORY;
727 ctx->ref = 1;
728 ctx->state = SCRIPTSTATE_UNINITIALIZED;
729 ctx->active_script = &This->IActiveScript_iface;
730 ctx->safeopt = This->safeopt;
731 ctx->version = This->version;
732 ctx->html_mode = This->html_mode;
733 ctx->acc = jsval_undefined();
734 list_init(&ctx->named_items);
735 heap_pool_init(&ctx->tmp_heap);
737 hres = create_jscaller(ctx);
738 if(FAILED(hres)) {
739 heap_free(ctx);
740 return hres;
743 ctx->last_match = jsstr_empty();
745 ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
746 if(ctx) {
747 script_release(ctx);
748 return E_UNEXPECTED;
752 /* Retrieve new dispatches for persistent named items */
753 LIST_FOR_EACH_ENTRY(item, &This->ctx->named_items, named_item_t, entry)
755 if(!item->disp)
757 hres = retrieve_named_item_disp(pass, item);
758 if(FAILED(hres)) return hres;
761 /* For some reason, CODEONLY flag is lost in re-initialized scripts */
762 item->flags &= ~SCRIPTITEM_CODEONLY;
765 This->site = pass;
766 IActiveScriptSite_AddRef(This->site);
768 hres = IActiveScriptSite_GetLCID(This->site, &lcid);
769 if(hres == S_OK)
770 This->lcid = lcid;
772 This->ctx->lcid = This->lcid;
774 hres = init_global(This->ctx);
775 if(FAILED(hres))
776 return hres;
778 IActiveScriptSite_AddRef(This->site);
779 This->ctx->site = This->site;
781 if(This->is_initialized)
782 change_state(This, SCRIPTSTATE_INITIALIZED);
783 return S_OK;
786 static HRESULT WINAPI JScript_GetScriptSite(IActiveScript *iface, REFIID riid,
787 void **ppvObject)
789 JScript *This = impl_from_IActiveScript(iface);
790 FIXME("(%p)->()\n", This);
791 return E_NOTIMPL;
794 static HRESULT WINAPI JScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
796 JScript *This = impl_from_IActiveScript(iface);
798 TRACE("(%p)->(%d)\n", This, ss);
800 if(This->thread_id && GetCurrentThreadId() != This->thread_id)
801 return E_UNEXPECTED;
803 if(ss == SCRIPTSTATE_UNINITIALIZED) {
804 if(This->ctx && This->ctx->state == SCRIPTSTATE_CLOSED)
805 return E_UNEXPECTED;
807 decrease_state(This, SCRIPTSTATE_UNINITIALIZED);
808 list_move_tail(&This->queued_code, &This->persistent_code);
809 return S_OK;
812 if(!This->is_initialized || !This->ctx)
813 return E_UNEXPECTED;
815 switch(ss) {
816 case SCRIPTSTATE_STARTED:
817 case SCRIPTSTATE_CONNECTED: /* FIXME */
818 if(This->ctx->state == SCRIPTSTATE_CLOSED)
819 return E_UNEXPECTED;
821 exec_queued_code(This);
822 break;
823 case SCRIPTSTATE_INITIALIZED:
824 FIXME("unimplemented SCRIPTSTATE_INITIALIZED\n");
825 return S_OK;
826 default:
827 FIXME("unimplemented state %d\n", ss);
828 return E_NOTIMPL;
831 change_state(This, ss);
832 return S_OK;
835 static HRESULT WINAPI JScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
837 JScript *This = impl_from_IActiveScript(iface);
839 TRACE("(%p)->(%p)\n", This, pssState);
841 if(!pssState)
842 return E_POINTER;
844 if(This->thread_id && This->thread_id != GetCurrentThreadId())
845 return E_UNEXPECTED;
847 *pssState = This->ctx ? This->ctx->state : SCRIPTSTATE_UNINITIALIZED;
848 return S_OK;
851 static HRESULT WINAPI JScript_Close(IActiveScript *iface)
853 JScript *This = impl_from_IActiveScript(iface);
855 TRACE("(%p)->()\n", This);
857 if(This->thread_id && This->thread_id != GetCurrentThreadId())
858 return E_UNEXPECTED;
860 decrease_state(This, SCRIPTSTATE_CLOSED);
861 clear_persistent_code_list(This);
862 release_named_item_list(This);
863 return S_OK;
866 static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface,
867 LPCOLESTR pstrName, DWORD dwFlags)
869 JScript *This = impl_from_IActiveScript(iface);
870 named_item_t *item;
871 IDispatch *disp = NULL;
872 HRESULT hres;
874 TRACE("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);
876 if(This->thread_id != GetCurrentThreadId() || !This->ctx || This->ctx->state == SCRIPTSTATE_CLOSED)
877 return E_UNEXPECTED;
879 if(dwFlags & SCRIPTITEM_GLOBALMEMBERS) {
880 IUnknown *unk;
882 hres = IActiveScriptSite_GetItemInfo(This->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL);
883 if(FAILED(hres)) {
884 WARN("GetItemInfo failed: %08x\n", hres);
885 return hres;
888 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
889 IUnknown_Release(unk);
890 if(FAILED(hres)) {
891 WARN("object does not implement IDispatch\n");
892 return hres;
896 item = heap_alloc(sizeof(*item));
897 if(!item) {
898 if(disp)
899 IDispatch_Release(disp);
900 return E_OUTOFMEMORY;
903 item->ref = 1;
904 item->disp = disp;
905 item->flags = dwFlags;
906 item->script_obj = NULL;
907 item->name = heap_strdupW(pstrName);
908 if(!item->name) {
909 if(disp)
910 IDispatch_Release(disp);
911 heap_free(item);
912 return E_OUTOFMEMORY;
915 list_add_tail(&This->ctx->named_items, &item->entry);
916 return S_OK;
919 static HRESULT WINAPI JScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
920 DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
922 JScript *This = impl_from_IActiveScript(iface);
923 FIXME("(%p)->()\n", This);
924 return E_NOTIMPL;
927 static HRESULT WINAPI JScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
928 IDispatch **ppdisp)
930 JScript *This = impl_from_IActiveScript(iface);
931 jsdisp_t *script_obj;
933 TRACE("(%p)->(%s %p)\n", This, debugstr_w(pstrItemName), ppdisp);
935 if(!ppdisp)
936 return E_POINTER;
938 if(This->thread_id != GetCurrentThreadId() || !This->ctx->global) {
939 *ppdisp = NULL;
940 return E_UNEXPECTED;
943 script_obj = This->ctx->global;
944 if(pstrItemName) {
945 named_item_t *item = lookup_named_item(This->ctx, pstrItemName, 0);
946 if(!item) return E_INVALIDARG;
947 if(item->script_obj) script_obj = item->script_obj;
950 *ppdisp = to_disp(script_obj);
951 IDispatch_AddRef(*ppdisp);
952 return S_OK;
955 static HRESULT WINAPI JScript_GetCurrentScriptThreadID(IActiveScript *iface,
956 SCRIPTTHREADID *pstridThread)
958 JScript *This = impl_from_IActiveScript(iface);
959 FIXME("(%p)->()\n", This);
960 return E_NOTIMPL;
963 static HRESULT WINAPI JScript_GetScriptThreadID(IActiveScript *iface,
964 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
966 JScript *This = impl_from_IActiveScript(iface);
967 FIXME("(%p)->()\n", This);
968 return E_NOTIMPL;
971 static HRESULT WINAPI JScript_GetScriptThreadState(IActiveScript *iface,
972 SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
974 JScript *This = impl_from_IActiveScript(iface);
975 FIXME("(%p)->()\n", This);
976 return E_NOTIMPL;
979 static HRESULT WINAPI JScript_InterruptScriptThread(IActiveScript *iface,
980 SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
982 JScript *This = impl_from_IActiveScript(iface);
983 FIXME("(%p)->()\n", This);
984 return E_NOTIMPL;
987 static HRESULT WINAPI JScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
989 JScript *This = impl_from_IActiveScript(iface);
990 FIXME("(%p)->()\n", This);
991 return E_NOTIMPL;
994 static const IActiveScriptVtbl JScriptVtbl = {
995 JScript_QueryInterface,
996 JScript_AddRef,
997 JScript_Release,
998 JScript_SetScriptSite,
999 JScript_GetScriptSite,
1000 JScript_SetScriptState,
1001 JScript_GetScriptState,
1002 JScript_Close,
1003 JScript_AddNamedItem,
1004 JScript_AddTypeLib,
1005 JScript_GetScriptDispatch,
1006 JScript_GetCurrentScriptThreadID,
1007 JScript_GetScriptThreadID,
1008 JScript_GetScriptThreadState,
1009 JScript_InterruptScriptThread,
1010 JScript_Clone
1013 static inline JScript *impl_from_IActiveScriptParse(IActiveScriptParse *iface)
1015 return CONTAINING_RECORD(iface, JScript, IActiveScriptParse_iface);
1018 static HRESULT WINAPI JScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
1020 JScript *This = impl_from_IActiveScriptParse(iface);
1021 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
1024 static ULONG WINAPI JScriptParse_AddRef(IActiveScriptParse *iface)
1026 JScript *This = impl_from_IActiveScriptParse(iface);
1027 return IActiveScript_AddRef(&This->IActiveScript_iface);
1030 static ULONG WINAPI JScriptParse_Release(IActiveScriptParse *iface)
1032 JScript *This = impl_from_IActiveScriptParse(iface);
1033 return IActiveScript_Release(&This->IActiveScript_iface);
1036 static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface)
1038 JScript *This = impl_from_IActiveScriptParse(iface);
1040 TRACE("(%p)\n", This);
1042 if(This->is_initialized)
1043 return E_UNEXPECTED;
1044 This->is_initialized = TRUE;
1046 if(This->site)
1047 change_state(This, SCRIPTSTATE_INITIALIZED);
1048 return S_OK;
1051 static HRESULT WINAPI JScriptParse_AddScriptlet(IActiveScriptParse *iface,
1052 LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
1053 LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
1054 CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
1055 BSTR *pbstrName, EXCEPINFO *pexcepinfo)
1057 JScript *This = impl_from_IActiveScriptParse(iface);
1058 FIXME("(%p)->(%s %s %s %s %s %s %s %u %x %p %p)\n", This, debugstr_w(pstrDefaultName),
1059 debugstr_w(pstrCode), debugstr_w(pstrItemName), debugstr_w(pstrSubItemName),
1060 debugstr_w(pstrEventName), debugstr_w(pstrDelimiter), wine_dbgstr_longlong(dwSourceContextCookie),
1061 ulStartingLineNumber, dwFlags, pbstrName, pexcepinfo);
1062 return E_NOTIMPL;
1065 static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
1066 LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
1067 LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
1068 DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
1070 JScript *This = impl_from_IActiveScriptParse(iface);
1071 named_item_t *item = NULL;
1072 bytecode_t *code;
1073 jsexcept_t ei;
1074 HRESULT hres;
1076 TRACE("(%p)->(%s %s %p %s %s %u %x %p %p)\n", This, debugstr_w(pstrCode),
1077 debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
1078 wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLine, dwFlags, pvarResult, pexcepinfo);
1080 if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED)
1081 return E_UNEXPECTED;
1083 if(pstrItemName) {
1084 item = lookup_named_item(This->ctx, pstrItemName, 0);
1085 if(!item) {
1086 WARN("Unknown context %s\n", debugstr_w(pstrItemName));
1087 return E_INVALIDARG;
1089 if(!item->script_obj) item = NULL;
1092 enter_script(This->ctx, &ei);
1093 hres = compile_script(This->ctx, pstrCode, dwSourceContextCookie, ulStartingLine, NULL, pstrDelimiter,
1094 (dwFlags & SCRIPTTEXT_ISEXPRESSION) != 0, This->is_encode, item, &code);
1095 if(FAILED(hres))
1096 return leave_script(This->ctx, hres);
1098 if(dwFlags & SCRIPTTEXT_ISEXPRESSION) {
1099 jsval_t r;
1101 hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, 0, NULL, &r);
1102 if(SUCCEEDED(hres)) {
1103 if(pvarResult)
1104 hres = jsval_to_variant(r, pvarResult);
1105 jsval_release(r);
1108 return leave_script(This->ctx, hres);
1111 code->is_persistent = (dwFlags & SCRIPTTEXT_ISPERSISTENT) != 0;
1114 * Although pvarResult is not really used without SCRIPTTEXT_ISEXPRESSION flag, if it's not NULL,
1115 * script is executed immediately, even if it's not in started state yet.
1117 if(!pvarResult && !is_started(This->ctx)) {
1118 list_add_tail(&This->queued_code, &code->entry);
1119 }else {
1120 hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, 0, NULL, NULL);
1121 if(code->is_persistent)
1122 list_add_tail(&This->persistent_code, &code->entry);
1123 else
1124 release_bytecode(code);
1127 if(FAILED(hres = leave_script(This->ctx, hres)))
1128 return hres;
1130 if(pvarResult)
1131 V_VT(pvarResult) = VT_EMPTY;
1132 return S_OK;
1135 static const IActiveScriptParseVtbl JScriptParseVtbl = {
1136 JScriptParse_QueryInterface,
1137 JScriptParse_AddRef,
1138 JScriptParse_Release,
1139 JScriptParse_InitNew,
1140 JScriptParse_AddScriptlet,
1141 JScriptParse_ParseScriptText
1144 static inline JScript *impl_from_IActiveScriptParseProcedure2(IActiveScriptParseProcedure2 *iface)
1146 return CONTAINING_RECORD(iface, JScript, IActiveScriptParseProcedure2_iface);
1149 static HRESULT WINAPI JScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2 *iface, REFIID riid, void **ppv)
1151 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
1152 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
1155 static ULONG WINAPI JScriptParseProcedure_AddRef(IActiveScriptParseProcedure2 *iface)
1157 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
1158 return IActiveScript_AddRef(&This->IActiveScript_iface);
1161 static ULONG WINAPI JScriptParseProcedure_Release(IActiveScriptParseProcedure2 *iface)
1163 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
1164 return IActiveScript_Release(&This->IActiveScript_iface);
1167 static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2 *iface,
1168 LPCOLESTR pstrCode, LPCOLESTR pstrFormalParams, LPCOLESTR pstrProcedureName,
1169 LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter,
1170 CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
1172 JScript *This = impl_from_IActiveScriptParseProcedure2(iface);
1173 named_item_t *item = NULL;
1174 bytecode_t *code;
1175 jsdisp_t *dispex;
1176 jsexcept_t ei;
1177 HRESULT hres;
1179 TRACE("(%p)->(%s %s %s %s %p %s %s %u %x %p)\n", This, debugstr_w(pstrCode), debugstr_w(pstrFormalParams),
1180 debugstr_w(pstrProcedureName), debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
1181 wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLineNumber, dwFlags, ppdisp);
1183 if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED)
1184 return E_UNEXPECTED;
1186 if(pstrItemName) {
1187 item = lookup_named_item(This->ctx, pstrItemName, 0);
1188 if(!item) {
1189 WARN("Unknown context %s\n", debugstr_w(pstrItemName));
1190 return E_INVALIDARG;
1192 if(!item->script_obj) item = NULL;
1195 enter_script(This->ctx, &ei);
1196 hres = compile_script(This->ctx, pstrCode, dwSourceContextCookie, ulStartingLineNumber, pstrFormalParams,
1197 pstrDelimiter, FALSE, This->is_encode, item, &code);
1198 if(SUCCEEDED(hres))
1199 hres = create_source_function(This->ctx, code, &code->global_code, NULL, &dispex);
1200 release_bytecode(code);
1201 hres = leave_script(This->ctx, hres);
1202 if(FAILED(hres))
1203 return hres;
1205 *ppdisp = to_disp(dispex);
1206 return S_OK;
1209 static const IActiveScriptParseProcedure2Vtbl JScriptParseProcedureVtbl = {
1210 JScriptParseProcedure_QueryInterface,
1211 JScriptParseProcedure_AddRef,
1212 JScriptParseProcedure_Release,
1213 JScriptParseProcedure_ParseProcedureText,
1216 static inline JScript *impl_from_IActiveScriptProperty(IActiveScriptProperty *iface)
1218 return CONTAINING_RECORD(iface, JScript, IActiveScriptProperty_iface);
1221 static HRESULT WINAPI JScriptProperty_QueryInterface(IActiveScriptProperty *iface, REFIID riid, void **ppv)
1223 JScript *This = impl_from_IActiveScriptProperty(iface);
1224 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
1227 static ULONG WINAPI JScriptProperty_AddRef(IActiveScriptProperty *iface)
1229 JScript *This = impl_from_IActiveScriptProperty(iface);
1230 return IActiveScript_AddRef(&This->IActiveScript_iface);
1233 static ULONG WINAPI JScriptProperty_Release(IActiveScriptProperty *iface)
1235 JScript *This = impl_from_IActiveScriptProperty(iface);
1236 return IActiveScript_Release(&This->IActiveScript_iface);
1239 static HRESULT WINAPI JScriptProperty_GetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
1240 VARIANT *pvarIndex, VARIANT *pvarValue)
1242 JScript *This = impl_from_IActiveScriptProperty(iface);
1243 FIXME("(%p)->(%x %p %p)\n", This, dwProperty, pvarIndex, pvarValue);
1244 return E_NOTIMPL;
1247 static HRESULT WINAPI JScriptProperty_SetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
1248 VARIANT *pvarIndex, VARIANT *pvarValue)
1250 JScript *This = impl_from_IActiveScriptProperty(iface);
1252 TRACE("(%p)->(%x %s %s)\n", This, dwProperty, debugstr_variant(pvarIndex), debugstr_variant(pvarValue));
1254 if(pvarIndex)
1255 FIXME("unsupported pvarIndex\n");
1257 switch(dwProperty) {
1258 case SCRIPTPROP_INVOKEVERSIONING:
1259 if(V_VT(pvarValue) != VT_I4 || V_I4(pvarValue) < 0
1260 || (V_I4(pvarValue) > 15 && !(V_I4(pvarValue) & SCRIPTLANGUAGEVERSION_HTML))) {
1261 WARN("invalid value %s\n", debugstr_variant(pvarValue));
1262 return E_INVALIDARG;
1265 This->version = V_I4(pvarValue) & 0x1ff;
1266 This->html_mode = (V_I4(pvarValue) & SCRIPTLANGUAGEVERSION_HTML) != 0;
1267 break;
1268 default:
1269 FIXME("Unimplemented property %x\n", dwProperty);
1270 return E_NOTIMPL;
1273 return S_OK;
1276 static const IActiveScriptPropertyVtbl JScriptPropertyVtbl = {
1277 JScriptProperty_QueryInterface,
1278 JScriptProperty_AddRef,
1279 JScriptProperty_Release,
1280 JScriptProperty_GetProperty,
1281 JScriptProperty_SetProperty
1284 static inline JScript *impl_from_IObjectSafety(IObjectSafety *iface)
1286 return CONTAINING_RECORD(iface, JScript, IObjectSafety_iface);
1289 static HRESULT WINAPI JScriptSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
1291 JScript *This = impl_from_IObjectSafety(iface);
1292 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
1295 static ULONG WINAPI JScriptSafety_AddRef(IObjectSafety *iface)
1297 JScript *This = impl_from_IObjectSafety(iface);
1298 return IActiveScript_AddRef(&This->IActiveScript_iface);
1301 static ULONG WINAPI JScriptSafety_Release(IObjectSafety *iface)
1303 JScript *This = impl_from_IObjectSafety(iface);
1304 return IActiveScript_Release(&This->IActiveScript_iface);
1307 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER)
1309 static HRESULT WINAPI JScriptSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1310 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
1312 JScript *This = impl_from_IObjectSafety(iface);
1314 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
1316 if(!pdwSupportedOptions || !pdwEnabledOptions)
1317 return E_POINTER;
1319 *pdwSupportedOptions = SUPPORTED_OPTIONS;
1320 *pdwEnabledOptions = This->safeopt;
1322 return S_OK;
1325 static HRESULT WINAPI JScriptSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1326 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
1328 JScript *This = impl_from_IObjectSafety(iface);
1330 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
1332 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
1333 return E_FAIL;
1335 This->safeopt = (dwEnabledOptions & dwOptionSetMask) | (This->safeopt & ~dwOptionSetMask) | INTERFACE_USES_DISPEX;
1336 return S_OK;
1339 static const IObjectSafetyVtbl JScriptSafetyVtbl = {
1340 JScriptSafety_QueryInterface,
1341 JScriptSafety_AddRef,
1342 JScriptSafety_Release,
1343 JScriptSafety_GetInterfaceSafetyOptions,
1344 JScriptSafety_SetInterfaceSafetyOptions
1347 static inline JScript *impl_from_IVariantChangeType(IVariantChangeType *iface)
1349 return CONTAINING_RECORD(iface, JScript, IVariantChangeType_iface);
1352 static HRESULT WINAPI VariantChangeType_QueryInterface(IVariantChangeType *iface, REFIID riid, void **ppv)
1354 JScript *This = impl_from_IVariantChangeType(iface);
1355 return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
1358 static ULONG WINAPI VariantChangeType_AddRef(IVariantChangeType *iface)
1360 JScript *This = impl_from_IVariantChangeType(iface);
1361 return IActiveScript_AddRef(&This->IActiveScript_iface);
1364 static ULONG WINAPI VariantChangeType_Release(IVariantChangeType *iface)
1366 JScript *This = impl_from_IVariantChangeType(iface);
1367 return IActiveScript_Release(&This->IActiveScript_iface);
1370 static HRESULT WINAPI VariantChangeType_ChangeType(IVariantChangeType *iface, VARIANT *dst, VARIANT *src, LCID lcid, VARTYPE vt)
1372 JScript *This = impl_from_IVariantChangeType(iface);
1373 jsexcept_t ei;
1374 VARIANT res;
1375 HRESULT hres;
1377 TRACE("(%p)->(%p %s %x %s)\n", This, dst, debugstr_variant(src), lcid, debugstr_vt(vt));
1379 if(!This->ctx) {
1380 FIXME("Object uninitialized\n");
1381 return E_UNEXPECTED;
1384 enter_script(This->ctx, &ei);
1385 hres = variant_change_type(This->ctx, &res, src, vt);
1386 hres = leave_script(This->ctx, hres);
1387 if(FAILED(hres))
1388 return hres;
1390 hres = VariantClear(dst);
1391 if(FAILED(hres)) {
1392 VariantClear(&res);
1393 return hres;
1396 *dst = res;
1397 return S_OK;
1400 static const IVariantChangeTypeVtbl VariantChangeTypeVtbl = {
1401 VariantChangeType_QueryInterface,
1402 VariantChangeType_AddRef,
1403 VariantChangeType_Release,
1404 VariantChangeType_ChangeType
1407 HRESULT create_jscript_object(BOOL is_encode, REFIID riid, void **ppv)
1409 JScript *ret;
1410 HRESULT hres;
1412 ret = heap_alloc_zero(sizeof(*ret));
1413 if(!ret)
1414 return E_OUTOFMEMORY;
1416 lock_module();
1418 ret->IActiveScript_iface.lpVtbl = &JScriptVtbl;
1419 ret->IActiveScriptParse_iface.lpVtbl = &JScriptParseVtbl;
1420 ret->IActiveScriptParseProcedure2_iface.lpVtbl = &JScriptParseProcedureVtbl;
1421 ret->IActiveScriptProperty_iface.lpVtbl = &JScriptPropertyVtbl;
1422 ret->IObjectSafety_iface.lpVtbl = &JScriptSafetyVtbl;
1423 ret->IVariantChangeType_iface.lpVtbl = &VariantChangeTypeVtbl;
1424 ret->ref = 1;
1425 ret->safeopt = INTERFACE_USES_DISPEX;
1426 ret->is_encode = is_encode;
1427 list_init(&ret->persistent_code);
1428 list_init(&ret->queued_code);
1430 hres = IActiveScript_QueryInterface(&ret->IActiveScript_iface, riid, ppv);
1431 IActiveScript_Release(&ret->IActiveScript_iface);
1432 return hres;