[wasm] Revert back to eval in wasm InvokeJS with modularization support . (#61212)
authorMarek Fišera <mara@neptuo.com>
Fri, 5 Nov 2021 14:02:45 +0000 (15:02 +0100)
committerGitHub <noreply@github.com>
Fri, 5 Nov 2021 14:02:45 +0000 (15:02 +0100)
Revert back  to eval in wasm InvokeJS with modularization support .

Wrap code to evaluate in a function with MONO, BINDING, INTERNAL
and module as local variables.

Added tests for running js expressions (successful, null, undefined, global scope separation)

Co-authored-by: Pavel Savara <pavelsavara@microsoft.com>
src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs
src/mono/wasm/runtime/method-calls.ts

index 101ce90..fb52d1d 100644 (file)
@@ -871,5 +871,33 @@ namespace System.Runtime.InteropServices.JavaScript.Tests
             Assert.Equal("s: 1 length: 1", HelperMarshal._stringResource);
             Assert.Equal("1", HelperMarshal._stringResource2);
         }
+
+        [Fact]
+        public static void InvokeJSExpression()
+        {
+            var result = Runtime.InvokeJS(@"1 + 2");
+            Assert.Equal("3", result);
+        }
+
+        [Fact]
+        public static void InvokeJSNullExpression()
+        {
+            var result = Runtime.InvokeJS(@"null");
+            Assert.Null(result);
+        }
+
+        [Fact]
+        public static void InvokeJSUndefinedExpression()
+        {
+            var result = Runtime.InvokeJS(@"undefined");
+            Assert.Null(result);
+        }
+
+        [Fact]
+        public static void InvokeJSNotInGlobalScope()
+        {
+            var result = Runtime.InvokeJS(@"var test_local_variable_name = 5; globalThis.test_local_variable_name");
+            Assert.Null(result);
+        }
     }
 }
index a2dd26d..3567fc8 100644 (file)
@@ -541,21 +541,18 @@ export function mono_wasm_invoke_js(code: MonoString, is_exception: Int32Ptr): M
     if (code === MonoStringNull)
         return MonoStringNull;
 
-    const js_code = conv_string(code);
+    const js_code = conv_string(code)!;
 
     try {
-        const closure = {
-            Module, MONO, BINDING, INTERNAL
+        const closedEval = function (Module: EmscriptenModule, MONO: any, BINDING: any, INTERNAL: any, code: string) {
+            return eval(code);
         };
-        const fn_body_template = `const {Module, MONO, BINDING, INTERNAL} = __closure; const __fn = function(){ ${js_code} }; return __fn.call(__closure);`;
-        const fn_defn = new Function("__closure", fn_body_template);
-        const res = fn_defn(closure);
+        const res = closedEval(Module, MONO, BINDING, INTERNAL, js_code);
         Module.setValue(is_exception, 0, "i32");
         if (typeof res === "undefined" || res === null)
             return MonoStringNull;
-        if (typeof res !== "string")
-            return wrap_error(is_exception, `Return type of InvokeJS is string. Can't marshal response of type ${typeof res}.`);
-        return js_string_to_mono_string(res);
+
+        return js_string_to_mono_string(res.toString());
     } catch (ex) {
         return wrap_error(is_exception, ex);
     }