summaryrefslogtreecommitdiff
path: root/gjs
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2017-06-24 22:28:32 -0700
committerPhilip Chimento <philip.chimento@gmail.com>2017-07-09 13:01:24 -0700
commita67a93619aa02436cc5647e6848b573f2c856631 (patch)
tree648b091a066ab70d6610590c8e867a3835aeb6d0 /gjs
parentc1525a7a48fcd109022146be657844cde2c8c9dc (diff)
downloadgjs-a67a93619aa02436cc5647e6848b573f2c856631.tar.gz
js: Allow access to modules' lexical scope
For compatibility with pre-ES6 code, we allow imported modules to access members of the lexical scope (i.e. variables defined with 'const' or 'let') as if they were properties, because that is how SpiderMonkey previously implemented 'let' and 'const'. When such properties are accessed, however, we log a warning that tells people to fix their code. Hopefully such uses will become rare and we can remove this compatibility workaround. https://bugzilla.gnome.org/show_bug.cgi?id=784196
Diffstat (limited to 'gjs')
-rw-r--r--gjs/module.cpp49
1 files changed, 48 insertions, 1 deletions
diff --git a/gjs/module.cpp b/gjs/module.cpp
index 5028d06f..6b03c967 100644
--- a/gjs/module.cpp
+++ b/gjs/module.cpp
@@ -138,6 +138,53 @@ class GjsModule {
/* JSClass operations */
+ bool
+ resolve_impl(JSContext *cx,
+ JS::HandleObject module,
+ JS::HandleId id,
+ bool *resolved)
+ {
+ JS::RootedObject lexical(cx, JS_ExtensibleLexicalEnvironment(module));
+ if (!lexical) {
+ *resolved = false;
+ return true; /* nothing imported yet */
+ }
+
+ if (!JS_HasPropertyById(cx, lexical, id, resolved))
+ return false;
+ if (!*resolved)
+ return true;
+
+ /* The property is present in the lexical environment. This should not
+ * be supported according to ES6. For compatibility with earlier GJS,
+ * we treat it as if it were a real property, but warn about it. */
+
+ GjsAutoJSChar prop_name(cx);
+ if (!gjs_get_string_id(cx, id, &prop_name))
+ return false;
+
+ g_warning("Some code accessed the property '%s' on the module '%s'. "
+ "That property was defined with 'let' or 'const' inside the "
+ "module. This was previously supported, but is not correct "
+ "according to the ES6 standard. Any symbols to be exported "
+ "from a module must be defined with 'var'. The property "
+ "access will work as previously for the time being, but "
+ "please fix your code anyway.", prop_name.get(), m_name);
+
+ JS::Rooted<JS::PropertyDescriptor> desc(cx);
+ return JS_GetPropertyDescriptorById(cx, lexical, id, &desc) &&
+ JS_DefinePropertyById(cx, module, id, desc);
+ }
+
+ static bool
+ resolve(JSContext *cx,
+ JS::HandleObject module,
+ JS::HandleId id,
+ bool *resolved)
+ {
+ return priv(module)->resolve_impl(cx, module, id, resolved);
+ }
+
static void
finalize(JSFreeOp *op,
JSObject *module)
@@ -151,7 +198,7 @@ class GjsModule {
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
- nullptr, /* resolve */
+ &GjsModule::resolve,
nullptr, /* mayResolve */
&GjsModule::finalize,
};