summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2020-03-21 18:30:41 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2020-03-21 18:30:41 +0000
commit17b28e85c12309d60e3c45acb096b9989a7834ff (patch)
treed10a03b425d22b1c48be7356466b0420bfb36402 /content
parent313dc9b099a172914f312120f0f9d0260a3588cf (diff)
downloadnetsurf-17b28e85c12309d60e3c45acb096b9989a7834ff.tar.gz
netsurf-17b28e85c12309d60e3c45acb096b9989a7834ff.tar.bz2
JS: Split concept of JS context into heap and thread
In preparation for proper splitting of Javascript support into heaps and threads, this renames the types and corrects the no-js builds to still work. At this time no substantive change in semantics exists, and the duktape build won't work. Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'content')
-rw-r--r--content/content.h6
-rw-r--r--content/handlers/html/html.c22
-rw-r--r--content/handlers/html/html_internal.h4
-rw-r--r--content/handlers/html/html_object.c5
-rw-r--r--content/handlers/html/html_script.c24
-rw-r--r--content/handlers/javascript/js.h62
-rw-r--r--content/handlers/javascript/none/none.c19
7 files changed, 86 insertions, 56 deletions
diff --git a/content/content.h b/content/content.h
index f8f8d32f1..c2605a7f1 100644
--- a/content/content.h
+++ b/content/content.h
@@ -72,7 +72,7 @@ typedef enum {
CONTENT_MSG_REFRESH, /**< wants refresh */
CONTENT_MSG_DOWNLOAD, /**< download, not for display */
CONTENT_MSG_LINK, /**< RFC5988 link */
- CONTENT_MSG_GETCTX, /**< Javascript context */
+ CONTENT_MSG_GETTHREAD, /**< Javascript thread */
CONTENT_MSG_GETDIMS, /**< Get viewport dimensions. */
CONTENT_MSG_SCROLL, /**< Request to scroll content */
CONTENT_MSG_DRAGSAVE, /**< Allow drag saving of content */
@@ -180,9 +180,9 @@ union content_msg_data {
struct content_rfc5988_link *rfc5988_link;
/**
- * CONTENT_MSG_GETCTX - Javascript context
+ * CONTENT_MSG_GETTHREAD - Javascript context (thread)
*/
- struct jscontext **jscontext;
+ struct jsthread **jsthread;
/**
* CONTENT_MSG_GETDIMS - Get the viewport dimensions
diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index d1b810fbc..26be58d73 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -757,8 +757,8 @@ void html_finish_conversion(html_content *htmlc)
* object, but with its target set to the Document object (and
* the currentTarget set to the Window object)
*/
- if (htmlc->jscontext != NULL) {
- js_fire_event(htmlc->jscontext, "load", htmlc->document, NULL);
+ if (htmlc->jsthread != NULL) {
+ js_fire_event(htmlc->jsthread, "load", htmlc->document, NULL);
}
/* convert dom tree to box tree */
@@ -896,20 +896,20 @@ dom_default_action_DOMNodeInserted_cb(struct dom_event *evt, void *pw)
}
if (htmlc->enable_scripting) {
/* ensure javascript context is available */
- if (htmlc->jscontext == NULL) {
+ if (htmlc->jsthread == NULL) {
union content_msg_data msg_data;
- msg_data.jscontext = &htmlc->jscontext;
+ msg_data.jsthread = &htmlc->jsthread;
content_broadcast(&htmlc->base,
- CONTENT_MSG_GETCTX,
+ CONTENT_MSG_GETTHREAD,
&msg_data);
NSLOG(netsurf, INFO,
"javascript context: %p (htmlc: %p)",
- htmlc->jscontext,
+ htmlc->jsthread,
htmlc);
}
- if (htmlc->jscontext != NULL) {
- js_handle_new_element(htmlc->jscontext,
+ if (htmlc->jsthread != NULL) {
+ js_handle_new_element(htmlc->jsthread,
(dom_element *) node);
}
}
@@ -1015,8 +1015,8 @@ dom_default_action_finished_cb(struct dom_event *evt, void *pw)
{
html_content *htmlc = pw;
- if (htmlc->jscontext != NULL)
- js_event_cleanup(htmlc->jscontext, evt);
+ if (htmlc->jsthread != NULL)
+ js_event_cleanup(htmlc->jsthread, evt);
}
/* callback function selector
@@ -1136,7 +1136,7 @@ html_create_html_data(html_content *c, const http_parameter *params)
c->search_string = NULL;
c->scripts_count = 0;
c->scripts = NULL;
- c->jscontext = NULL;
+ c->jsthread = NULL;
c->enable_scripting = nsoption_bool(enable_javascript);
c->base.active = 1; /* The html content itself is active */
diff --git a/content/handlers/html/html_internal.h b/content/handlers/html/html_internal.h
index 9b363dc8b..a64078143 100644
--- a/content/handlers/html/html_internal.h
+++ b/content/handlers/html/html_internal.h
@@ -151,8 +151,8 @@ typedef struct html_content {
unsigned int scripts_count;
/** Scripts */
struct html_script *scripts;
- /** javascript context */
- struct jscontext *jscontext;
+ /** javascript thread in use */
+ struct jsthread *jsthread;
/** Number of entries in stylesheet_content. */
unsigned int stylesheet_count;
diff --git a/content/handlers/html/html_object.c b/content/handlers/html/html_object.c
index 223f5516d..3a60c47f1 100644
--- a/content/handlers/html/html_object.c
+++ b/content/handlers/html/html_object.c
@@ -340,8 +340,9 @@ html_object_callback(hlcache_handle *object,
/* Don't care about favicons that aren't on top level content */
break;
- case CONTENT_MSG_GETCTX:
- *(event->data.jscontext) = NULL;
+ case CONTENT_MSG_GETTHREAD:
+ /* Objects don't have JS threads */
+ *(event->data.jsthread) = NULL;
break;
case CONTENT_MSG_GETDIMS:
diff --git a/content/handlers/html/html_script.c b/content/handlers/html/html_script.c
index 4df5f3384..301acadd6 100644
--- a/content/handlers/html/html_script.c
+++ b/content/handlers/html/html_script.c
@@ -42,7 +42,7 @@
#include "html/html.h"
#include "html/html_internal.h"
-typedef bool (script_handler_t)(struct jscontext *jscontext, const uint8_t *data, size_t size, const char *name);
+typedef bool (script_handler_t)(struct jsthread *jsthread, const uint8_t *data, size_t size, const char *name);
static script_handler_t *select_script_handler(content_type ctype)
@@ -62,7 +62,7 @@ nserror html_script_exec(html_content *c, bool allow_defer)
script_handler_t *script_handler;
bool have_run_something = false;
- if (c->jscontext == NULL) {
+ if (c->jsthread == NULL) {
return NSERROR_BAD_PARAMETER;
}
@@ -95,7 +95,7 @@ nserror html_script_exec(html_content *c, bool allow_defer)
size_t size;
data = content_get_source_data(
s->data.handle, &size );
- script_handler(c->jscontext, data, size,
+ script_handler(c->jsthread, data, size,
nsurl_access(hlcache_handle_get_url(s->data.handle)));
have_run_something = true;
/* We have to re-acquire this here since the
@@ -319,12 +319,12 @@ convert_script_sync_cb(hlcache_handle *script,
/* attempt to execute script */
script_handler = select_script_handler(content_get_type(s->data.handle));
- if (script_handler != NULL && parent->jscontext != NULL) {
+ if (script_handler != NULL && parent->jsthread != NULL) {
/* script has a handler */
const uint8_t *data;
size_t size;
data = content_get_source_data(s->data.handle, &size );
- script_handler(parent->jscontext, data, size,
+ script_handler(parent->jsthread, data, size,
nsurl_access(hlcache_handle_get_url(s->data.handle)));
}
@@ -549,7 +549,7 @@ exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype)
lwc_string_unref(lwcmimetype);
if (script_handler != NULL) {
- script_handler(c->jscontext,
+ script_handler(c->jsthread,
(const uint8_t *)dom_string_data(script),
dom_string_byte_length(script),
"?inline script?");
@@ -575,13 +575,13 @@ html_process_script(void *ctx, dom_node *node)
/* We should only ever be here if scripting was enabled for this
* content so it's correct to make a javascript context if there
* isn't one already. */
- if (c->jscontext == NULL) {
+ if (c->jsthread == NULL) {
union content_msg_data msg_data;
- msg_data.jscontext = &c->jscontext;
- content_broadcast(&c->base, CONTENT_MSG_GETCTX, &msg_data);
- NSLOG(netsurf, INFO, "javascript context %p ", c->jscontext);
- if (c->jscontext == NULL) {
+ msg_data.jsthread = &c->jsthread;
+ content_broadcast(&c->base, CONTENT_MSG_GETTHREAD, &msg_data);
+ NSLOG(netsurf, INFO, "javascript context %p ", c->jsthread);
+ if (c->jsthread == NULL) {
/* no context and it could not be created, abort */
return DOM_HUBBUB_OK;
}
@@ -668,6 +668,6 @@ nserror html_script_free(html_content *html)
/* exported internal interface documented in html/html_internal.h */
nserror html_script_invalidate_ctx(html_content *htmlc)
{
- htmlc->jscontext = NULL;
+ htmlc->jsthread = NULL;
return NSERROR_OK;
}
diff --git a/content/handlers/javascript/js.h b/content/handlers/javascript/js.h
index 522dd9879..126cb7cfb 100644
--- a/content/handlers/javascript/js.h
+++ b/content/handlers/javascript/js.h
@@ -25,9 +25,6 @@
#include "utils/errors.h"
-typedef struct jscontext jscontext;
-typedef struct jsobject jsobject;
-
struct dom_event;
struct dom_document;
struct dom_node;
@@ -35,6 +32,27 @@ struct dom_element;
struct dom_string;
/**
+ * JavaScript interpreter heap
+ *
+ * In order to try and be moderately performant, we create a heap
+ * per browser window. This heap is shared by all browsing contexts
+ * we end up creating in that window.
+ */
+typedef struct jsheap jsheap;
+
+/**
+ * JavaScript interpreter thread
+ *
+ * When we create a browsing context itself (window+content) we have
+ * to create a JS thread to attach to the browsing context.
+ *
+ * JS threads are associated with heaps and will be destroyed when
+ * the heap is destroyed. They can be shut down manually though
+ * and should be for object lifetime safety reasons.
+ */
+typedef struct jsthread jsthread;
+
+/**
* Initialise javascript interpreter
*/
void js_initialise(void);
@@ -45,41 +63,51 @@ void js_initialise(void);
void js_finalise(void);
/**
- * Create a new javascript context.
+ * Create a new javascript heap.
*
- * There is usually one context per browsing context (browser window)
+ * There is usually one heap per browser window.
*
* \param timeout elapsed wallclock time (in seconds) before \a callback is called
- * \param jsctx Updated to the created JS context
+ * \param heap Updated to the created JS heap
* \return NSERROR_OK on success, appropriate error otherwise.
*/
-nserror js_newcontext(int timeout, jscontext **jsctx);
+nserror js_newheap(int timeout, jsheap **heap);
/**
- * Destroy a previously created context
+ * Destroy a previously created heap.
+ *
+ * \param heap The heap to destroy
*/
-void js_destroycontext(jscontext *ctx);
+void js_destroyheap(jsheap *heap);
/**
- * Create a new javascript compartment
+ * Create a new javascript thread
*
* This is called once for a page with javascript script tags on
- * it. It constructs a fresh global window object.
+ * it. It constructs a fresh global window object and prepares the JS
+ * browsing context. It's important that threads are shut down cleanly
+ * when the browsing context is going to be cleaned up.
+ *
+ * \param heap The heap to create the thread within
+ * \param win_priv The value to give to the Window constructor as the window
+ * \param doc_priv The value to give to the Document constructor as the document
+ * \param thread Updated to the created thread
+ * \return NSERROR_OK on success, appropriate error otherwise
*/
-jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv);
+nserror js_newthread(jsheap *heap, void *win_priv, void *doc_priv, jsthread **thread);
/**
* execute some javascript in a context
*/
-bool js_exec(jscontext *ctx, const uint8_t *txt, size_t txtlen, const char *name);
+bool js_exec(jsthread *thread, const uint8_t *txt, size_t txtlen, const char *name);
/**
* fire an event at a dom node
*/
-bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, struct dom_node *target);
+bool js_fire_event(jsthread *thread, const char *type, struct dom_document *doc, struct dom_node *target);
bool
-js_dom_event_add_listener(jscontext *ctx,
+js_dom_event_add_listener(jsthread *thread,
struct dom_document *document,
struct dom_node *node,
struct dom_string *event_type_dom,
@@ -94,7 +122,7 @@ js_dom_event_add_listener(jscontext *ctx,
* by the context provided. The JS implementation must then scan the element
* for on* attributes and register appropriate listeners for those handlers.
*/
-void js_handle_new_element(jscontext *ctx, struct dom_element *node);
+void js_handle_new_element(jsthread *thread, struct dom_element *node);
/**
* Handle an event propagation finished callback.
@@ -104,6 +132,6 @@ void js_handle_new_element(jscontext *ctx, struct dom_element *node);
* it may need to perform before the DOM finishes and the event may end up
* freed.
*/
-void js_event_cleanup(jscontext *ctx, struct dom_event *evt);
+void js_event_cleanup(jsthread *thread, struct dom_event *evt);
#endif /* NETSURF_JAVASCRIPT_JS_H_ */
diff --git a/content/handlers/javascript/none/none.c b/content/handlers/javascript/none/none.c
index 26b9b5300..b79d3242f 100644
--- a/content/handlers/javascript/none/none.c
+++ b/content/handlers/javascript/none/none.c
@@ -35,35 +35,36 @@ void js_finalise(void)
{
}
-nserror js_newcontext(int timeout, jscontext **jsctx)
+nserror js_newheap(int timeout, jsheap **heap)
{
- *jsctx = NULL;
+ *heap = NULL;
return NSERROR_OK;
}
-void js_destroycontext(jscontext *ctx)
+void js_destroyheap(jsheap *heap)
{
}
-jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv)
+nserror js_newthread(jsheap *heap, void *win_priv, void *doc_priv, jsthread **thread)
{
- return NULL;
+ *thread = NULL;
+ return NSERROR_NOT_IMPLEMENTED;
}
-bool js_exec(jscontext *ctx, const uint8_t *txt, size_t txtlen, const char *name)
+bool js_exec(jsthread *thread, const uint8_t *txt, size_t txtlen, const char *name)
{
return true;
}
-bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, struct dom_node *target)
+bool js_fire_event(jsthread *thread, const char *type, struct dom_document *doc, struct dom_node *target)
{
return true;
}
-void js_handle_new_element(jscontext *ctx, struct dom_element *node)
+void js_handle_new_element(jsthread *thread, struct dom_element *node)
{
}
-void js_event_cleanup(jscontext *ctx, struct dom_event *evt)
+void js_event_cleanup(jsthread *thread, struct dom_event *evt)
{
}