Phasor 3.3.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
NativeRuntime_com.cpp
Go to the documentation of this file.
2
6
7#include <oleauto.h>
8#include <string>
9#include <unordered_map>
10#include <functional>
11
12namespace
13{
14 std::string wideToUtf8(LPCOLESTR text)
15 {
16 if (!text)
17 return {};
18
19 int required = WideCharToMultiByte(CP_UTF8, 0, text, -1, nullptr, 0, nullptr, nullptr);
20 if (required <= 1)
21 return {};
22
23 std::string out(static_cast<size_t>(required - 1), '\0');
24 WideCharToMultiByte(CP_UTF8, 0, text, -1, out.data(), required, nullptr, nullptr);
25 return out;
26 }
27}
28
29HRESULT __stdcall PhasorScriptEngine::QueryInterface(REFIID riid, void** ppv)
30{
31 if (!ppv)
32 return E_POINTER;
33
34 *ppv = nullptr;
35
36 if (riid == IID_IUnknown || riid == IID_IActiveScript)
37 {
38 *ppv = static_cast<IActiveScript*>(this);
39 }
40 else if (riid == IID_IActiveScriptParse)
41 {
42 *ppv = static_cast<IActiveScriptParse*>(this);
43 }
44 else
45 {
46 return E_NOINTERFACE;
47 }
48
49 AddRef();
50 return S_OK;
51}
52
54{
55 return ++refCount;
56}
57
59{
60 long r = --refCount;
61 if (r == 0)
62 delete this;
63 return r;
64}
65
66HRESULT __stdcall PhasorScriptEngine::SetScriptSite(IActiveScriptSite* pSite)
67{
68 if (pSite)
69 pSite->AddRef();
70
71 if (site)
72 site->Release();
73
74 site = pSite;
75 return S_OK;
76}
77
78HRESULT __stdcall PhasorScriptEngine::GetScriptSite(REFIID riid, void** ppvObject)
79{
80 if (!ppvObject)
81 return E_POINTER;
82
83 *ppvObject = nullptr;
84
85 if (!site)
86 return E_FAIL;
87
88 return site->QueryInterface(riid, ppvObject);
89}
90
91HRESULT __stdcall PhasorScriptEngine::SetScriptState(SCRIPTSTATE st)
92{
93 state = st;
94 return S_OK;
95}
96
97HRESULT __stdcall PhasorScriptEngine::GetScriptState(SCRIPTSTATE* pss)
98{
99 if (!pss)
100 return E_POINTER;
101
102 *pss = state;
103 return S_OK;
104}
105
106HRESULT __stdcall PhasorScriptEngine::Close()
107{
108 if (site)
109 {
110 site->Release();
111 site = nullptr;
112 }
113
114 vm.reset(true, true, true);
115 state = SCRIPTSTATE_CLOSED;
116 return S_OK;
117}
118
119HRESULT __stdcall PhasorScriptEngine::AddNamedItem(LPCOLESTR, DWORD)
120{
121 return E_NOTIMPL;
122}
123
124HRESULT __stdcall PhasorScriptEngine::AddTypeLib(REFGUID, DWORD, DWORD, DWORD)
125{
126 return E_NOTIMPL;
127}
128
129HRESULT __stdcall PhasorScriptEngine::GetScriptDispatch(LPCOLESTR, IDispatch** ppdisp)
130{
131 if (!ppdisp)
132 return E_POINTER;
133
134 *ppdisp = nullptr;
135 return E_NOTIMPL;
136}
137
138HRESULT __stdcall PhasorScriptEngine::GetCurrentScriptThreadID(SCRIPTTHREADID* pstidThread)
139{
140 if (!pstidThread)
141 return E_POINTER;
142
143 *pstidThread = SCRIPTTHREADID_BASE;
144 return S_OK;
145}
146
147HRESULT __stdcall PhasorScriptEngine::GetScriptThreadID(DWORD, SCRIPTTHREADID* pstidThread)
148{
149 if (!pstidThread)
150 return E_POINTER;
151
152 *pstidThread = SCRIPTTHREADID_BASE;
153 return S_OK;
154}
155
156HRESULT __stdcall PhasorScriptEngine::GetScriptThreadState(SCRIPTTHREADID, SCRIPTTHREADSTATE* pstsState)
157{
158 if (!pstsState)
159 return E_POINTER;
160
161 *pstsState = SCRIPTTHREADSTATE_NOTINSCRIPT;
162 return S_OK;
163}
164
165HRESULT __stdcall PhasorScriptEngine::InterruptScriptThread(SCRIPTTHREADID, const EXCEPINFO*, DWORD)
166{
167 return E_NOTIMPL;
168}
169
170HRESULT __stdcall PhasorScriptEngine::Clone(IActiveScript** ppscript)
171{
172 if (ppscript)
173 *ppscript = nullptr;
174 return E_NOTIMPL;
175}
176
178{
179 vm.reset(true, true, true);
181 state = SCRIPTSTATE_INITIALIZED;
182 return S_OK;
183}
184
186 LPCOLESTR,
187 LPCOLESTR,
188 LPCOLESTR,
189 LPCOLESTR,
190 LPCOLESTR,
191 LPCOLESTR,
192#if defined(_WIN64)
193 DWORDLONG,
194#else
195 DWORD,
196#endif
197 ULONG,
198 DWORD,
199 BSTR* pbstrName,
200 EXCEPINFO*)
201{
202 if (pbstrName)
203 *pbstrName = nullptr;
204
205 return E_NOTIMPL;
206}
207
209 LPCOLESTR code,
210 LPCOLESTR,
211 IUnknown*,
212 LPCOLESTR,
213#if defined(_WIN64)
214 DWORDLONG,
215#else
216 DWORD,
217#endif
218 ULONG,
219 DWORD,
220 VARIANT* result,
221 EXCEPINFO* ex)
222{
223 if (!code)
224 return E_POINTER;
225
226 if (result)
227 VariantInit(result);
228
229 if (ex)
230 ZeroMemory(ex, sizeof(*ex));
231
232 try
233 {
234 std::string src = wideToUtf8(code);
235 Phasor::Frontend::runScript(src.c_str(), &vm, "", false);
236 return S_OK;
237 }
238 catch (...)
239 {
240 return E_FAIL;
241 }
242}
243
244class ClassFactory final : public IClassFactory
245{
246 long refCount = 1;
247
248public:
249 HRESULT __stdcall QueryInterface(REFIID riid, void** ppv) override
250 {
251 if (!ppv)
252 return E_POINTER;
253
254 *ppv = nullptr;
255
256 if (riid == IID_IUnknown || riid == IID_IClassFactory)
257 {
258 *ppv = static_cast<IClassFactory*>(this);
259 AddRef();
260 return S_OK;
261 }
262
263 return E_NOINTERFACE;
264 }
265
266 ULONG __stdcall AddRef() override
267 {
268 return ++refCount;
269 }
270
271 ULONG __stdcall Release() override
272 {
273 long r = --refCount;
274 if (r == 0)
275 delete this;
276 return r;
277 }
278
279 HRESULT __stdcall CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv) override
280 {
281 if (!ppv)
282 return E_POINTER;
283
284 *ppv = nullptr;
285
286 if (pUnkOuter)
287 return CLASS_E_NOAGGREGATION;
288
289 auto* engine = new PhasorScriptEngine();
290 HRESULT hr = engine->QueryInterface(riid, ppv);
291 engine->Release();
292 return hr;
293 }
294
295 HRESULT __stdcall LockServer(BOOL) override
296 {
297 return S_OK;
298 }
299};
300
301#if defined(__clang__)
302#pragma clang diagnostic push
303#pragma clang diagnostic ignored "-Wdll-attribute-on-redeclaration"
304#endif
305
306#if defined(_MSC_VER) && !defined(__clang__)
307 #if defined(_M_IX86)
308 #pragma comment(linker, "/EXPORT:DllGetClassObject=_DllGetClassObject@12,PRIVATE")
309 #pragma comment(linker, "/EXPORT:DllCanUnloadNow=_DllCanUnloadNow@0,PRIVATE")
310 #else
311 #pragma comment(linker, "/EXPORT:DllGetClassObject,PRIVATE")
312 #pragma comment(linker, "/EXPORT:DllCanUnloadNow,PRIVATE")
313 #endif
314 #define PHASOR_COM_EXPORT
315#else
316 #define PHASOR_COM_EXPORT __declspec(dllexport)
317#endif
318
319extern "C"
321HRESULT __stdcall DllGetClassObject(
322 REFCLSID rclsid,
323 REFIID riid,
324 void** ppv)
325{
326 if (!ppv)
327 return E_POINTER;
328
329 *ppv = nullptr;
330
331 if (!IsEqualCLSID(rclsid, CLSID_PhasorEngine))
332 return CLASS_E_CLASSNOTAVAILABLE;
333
334 auto* factory = new ClassFactory();
335 HRESULT hr = factory->QueryInterface(riid, ppv);
336 factory->Release();
337 return hr;
338}
339
340extern "C"
342HRESULT __stdcall DllCanUnloadNow()
343{
344 return S_OK;
345}
346
347#if defined(__clang__)
348#pragma clang diagnostic pop
349#endif
#define PHASOR_COM_EXPORT
PHASOR_COM_EXPORT HRESULT __stdcall DllCanUnloadNow()
PHASOR_COM_EXPORT HRESULT __stdcall DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
static const GUID CLSID_PhasorEngine
ULONG __stdcall AddRef() override
HRESULT __stdcall QueryInterface(REFIID riid, void **ppv) override
HRESULT __stdcall CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv) override
ULONG __stdcall Release() override
HRESULT __stdcall LockServer(BOOL) override
ULONG __stdcall Release() override
HRESULT __stdcall QueryInterface(REFIID riid, void **ppv) override
HRESULT __stdcall AddTypeLib(REFGUID rguidTypeLib, DWORD dwMajor, DWORD dwMinor, DWORD dwFlags) override
HRESULT __stdcall GetScriptThreadState(SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState) override
HRESULT __stdcall InterruptScriptThread(SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags) override
HRESULT __stdcall GetScriptThreadID(DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread) override
HRESULT __stdcall InitNew() override
HRESULT __stdcall AddScriptlet(LPCOLESTR defaultName, LPCOLESTR code, LPCOLESTR itemName, LPCOLESTR subItemName, LPCOLESTR eventName, LPCOLESTR delimiter, DWORD sourceContextCookie, ULONG startingLine, DWORD flags, BSTR *pbstrName, EXCEPINFO *pexcepinfo) override
HRESULT __stdcall GetCurrentScriptThreadID(SCRIPTTHREADID *pstidThread) override
HRESULT __stdcall ParseScriptText(LPCOLESTR code, LPCOLESTR itemName, IUnknown *context, LPCOLESTR delimiter, DWORD sourceContextCookie, ULONG startingLine, DWORD flags, VARIANT *result, EXCEPINFO *ex) override
HRESULT __stdcall SetScriptState(SCRIPTSTATE state) override
HRESULT __stdcall Close() override
HRESULT __stdcall Clone(IActiveScript **ppscript) override
HRESULT __stdcall GetScriptDispatch(LPCOLESTR name, IDispatch **ppdisp) override
HRESULT __stdcall SetScriptSite(IActiveScriptSite *pSite) override
HRESULT __stdcall AddNamedItem(LPCOLESTR name, DWORD flags) override
IActiveScriptSite * site
HRESULT __stdcall GetScriptSite(REFIID riid, void **ppvObject) override
ULONG __stdcall AddRef() override
HRESULT __stdcall GetScriptState(SCRIPTSTATE *pss) override
static void registerFunctions(VM &vm)
Definition StdLib.hpp:35
int runScript(const std::string &source, VM *vm, const std::filesystem::path &path="", bool verbose=false)
Run a script.
Definition Frontend.cpp:17