[PATCH 3/5] jscript: Implement script persistence.

Gabriel Ivăncescu gabrielopcode at gmail.com
Wed Nov 6 09:28:01 CST 2019


Persistent code has to be re-executed if the script is uninitialized and
then reinitialized and restarted.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/jscript/engine.h  |  1 +
 dlls/jscript/jscript.c | 47 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index a3b598e..c7ea75a 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -186,6 +186,7 @@ typedef struct _bytecode_t {
     unsigned str_cnt;
 
     struct _bytecode_t *next;
+    struct _bytecode_t *persistent_next;
 } bytecode_t;
 
 HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,const WCHAR*,BOOL,BOOL,bytecode_t**) DECLSPEC_HIDDEN;
diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c
index 2a7c028..b059a31 100644
--- a/dlls/jscript/jscript.c
+++ b/dlls/jscript/jscript.c
@@ -62,6 +62,8 @@ typedef struct {
 
     bytecode_t *queue_head;
     bytecode_t *queue_tail;
+    bytecode_t *persistent_head;
+    bytecode_t *persistent_tail;
 } JScript;
 
 void script_release(script_ctx_t *ctx)
@@ -133,6 +135,40 @@ static void clear_script_queue(JScript *This)
     This->queue_head = This->queue_tail = NULL;
 }
 
+static void clear_persistent_scripts(JScript *This)
+{
+    bytecode_t *iter, *iter2;
+
+    if(!This->persistent_head)
+        return;
+
+    iter = This->persistent_head;
+    while(iter) {
+        iter2 = iter->persistent_next;
+        iter->persistent_next = NULL;
+        release_bytecode(iter);
+        iter = iter2;
+    }
+
+    This->persistent_head = This->persistent_tail = NULL;
+}
+
+static void queue_persistent_scripts(JScript *This)
+{
+    bytecode_t *iter;
+
+    if(!This->persistent_head)
+        return;
+
+    iter = This->queue_head = This->persistent_head;
+    This->queue_tail = This->persistent_tail;
+    while(iter) {
+        iter->next = iter->persistent_next;
+        bytecode_addref(iter);
+        iter = iter->next;
+    }
+}
+
 static void exec_queued_code(JScript *This)
 {
     bytecode_t *iter;
@@ -472,6 +508,7 @@ static HRESULT WINAPI JScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE s
             return E_UNEXPECTED;
 
         decrease_state(This, SCRIPTSTATE_UNINITIALIZED);
+        queue_persistent_scripts(This);
         return S_OK;
     }
 
@@ -524,6 +561,8 @@ static HRESULT WINAPI JScript_Close(IActiveScript *iface)
         return E_UNEXPECTED;
 
     decrease_state(This, SCRIPTSTATE_CLOSED);
+    clear_script_queue(This);
+    clear_persistent_scripts(This);
     return S_OK;
 }
 
@@ -788,6 +827,14 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
         return hres;
     }
 
+    if(dwFlags & SCRIPTTEXT_ISPERSISTENT) {
+        if(This->persistent_tail)
+            This->persistent_tail = This->persistent_tail->persistent_next = code;
+        else
+            This->persistent_head = This->persistent_tail = code;
+        bytecode_addref(code);
+    }
+
     /*
      * Although pvarResult is not really used without SCRIPTTEXT_ISEXPRESSION flag, if it's not NULL,
      * script is executed immediately, even if it's not in started state yet.
-- 
2.21.0




More information about the wine-devel mailing list