Bug 1415571: Export values of immutable variable globals; r=luke
authorBenjamin Bouvier <benj@benj.me>
Wed, 08 Nov 2017 19:39:01 +0100
changeset 444188 5bbbbcc79a5a750156eace4b70833848931ce63d
parent 444187 47fcf4a498b83104af19a8a930b7590f05156ecc
child 444189 95985f660be18466ff7d4aa1c696e73cdebc3ef8
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1415571
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1415571: Export values of immutable variable globals; r=luke MozReview-Commit-ID: DaGJMtz31kz
js/src/jit-test/tests/wasm/globals.js
js/src/wasm/WasmModule.cpp
--- a/js/src/jit-test/tests/wasm/globals.js
+++ b/js/src/jit-test/tests/wasm/globals.js
@@ -183,43 +183,46 @@ wasmFailValidateText(`(module (global (m
 wasmFailValidateText(`(module (global (mut i32) (i32.const 0)) (global i32 (get_global 0)))`, /must reference a global immutable import/);
 
 wasmFailValidateText(`(module (import "globals" "a" (global f32)) (global i32 (get_global 0)))`, /type mismatch/);
 
 function testInitExpr(type, initialValue, nextValue, coercion, assertFunc = assertEq) {
     var module = wasmEvalText(`(module
         (import "globals" "a" (global ${type}))
 
-        (global (mut ${type}) (get_global 0))
-        (global ${type} (get_global 0))
+        (global $glob_mut (mut ${type}) (get_global 0))
+        (global $glob_imm ${type} (get_global 0))
 
         (func $get0 (result ${type}) (get_global 0))
 
         (func $get1 (result ${type}) (get_global 1))
         (func $set1 (param ${type}) (set_global 1 (get_local 0)))
 
         (func $get_cst (result ${type}) (get_global 2))
 
         (export "get0" $get0)
         (export "get1" $get1)
         (export "get_cst" $get_cst)
 
         (export "set1" $set1)
+        (export "global_imm" (global $glob_imm))
     )`, {
         globals: {
             a: coercion(initialValue)
         }
     }).exports;
 
     assertFunc(module.get0(), coercion(initialValue));
     assertFunc(module.get1(), coercion(initialValue));
+    assertFunc(module.global_imm, coercion(initialValue));
 
     assertEq(module.set1(coercion(nextValue)), undefined);
     assertFunc(module.get1(), coercion(nextValue));
     assertFunc(module.get0(), coercion(initialValue));
+    assertFunc(module.global_imm, coercion(initialValue));
 
     assertFunc(module.get_cst(), coercion(initialValue));
 }
 
 testInitExpr('i32', 13, 37, x => x|0);
 testInitExpr('f32', 13.37, 0.1989, Math.fround);
 testInitExpr('f64', 13.37, 0.1989, x => +x);
 
--- a/js/src/wasm/WasmModule.cpp
+++ b/js/src/wasm/WasmModule.cpp
@@ -983,19 +983,39 @@ static bool
 GetGlobalExport(JSContext* cx, const GlobalDescVector& globals, uint32_t globalIndex,
                 const ValVector& globalImports, MutableHandleValue jsval)
 {
     const GlobalDesc& global = globals[globalIndex];
 
     // Imports are located upfront in the globals array.
     Val val;
     switch (global.kind()) {
-      case GlobalKind::Import:   val = globalImports[globalIndex]; break;
-      case GlobalKind::Variable: MOZ_CRASH("mutable variables can't be exported");
-      case GlobalKind::Constant: val = global.constantValue(); break;
+      case GlobalKind::Import: {
+        val = globalImports[globalIndex];
+        break;
+      }
+      case GlobalKind::Variable: {
+        MOZ_ASSERT(!global.isMutable(), "mutable variables can't be exported");
+        const InitExpr& init = global.initExpr();
+        switch (init.kind()) {
+          case InitExpr::Kind::Constant: {
+            val = init.val();
+            break;
+          }
+          case InitExpr::Kind::GetGlobal: {
+            val = globalImports[init.globalIndex()];
+            break;
+          }
+        }
+        break;
+      }
+      case GlobalKind::Constant: {
+        val = global.constantValue();
+        break;
+      }
     }
 
     switch (global.type()) {
       case ValType::I32: {
         jsval.set(Int32Value(val.i32()));
         return true;
       }
       case ValType::I64: {