Bug 1415571: Export values of immutable variable globals; r?luke draft
authorBenjamin Bouvier <benj@benj.me>
Wed, 08 Nov 2017 19:39:01 +0100
changeset 695080 6f92358db5923f73c5de431adb3579cc02466650
parent 695079 7dbb71574255c5a02a203a4031c5902016b73e50
child 739515 9342e572eade5e8bfacc0b9a3f9894d910baa0d0
push id88333
push userbbouvier@mozilla.com
push dateWed, 08 Nov 2017 18:41:10 +0000
reviewersluke
bugs1415571
milestone58.0a1
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: {