Bug 1248598 part 1 - Some code changes required for the i64.const instruction. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 18 Feb 2016 14:19:21 +0100
changeset 331896 b34a59d6ffe8af9449bcac1eb660f86279d80ad7
parent 331895 2da9867fc1d2c83dd8be224dd606034772ecde16
child 331897 1354c6e4ac2fd1af0126a9354cb99fd73e8c14dc
push id11113
push userrjesup@wgate.com
push dateThu, 18 Feb 2016 19:00:12 +0000
reviewersluke
bugs1248598
milestone47.0a1
Bug 1248598 part 1 - Some code changes required for the i64.const instruction. r=luke
js/src/asmjs/WasmBinary.h
js/src/asmjs/WasmIonCompile.cpp
js/src/asmjs/WasmText.cpp
--- a/js/src/asmjs/WasmBinary.h
+++ b/js/src/asmjs/WasmBinary.h
@@ -699,29 +699,39 @@ class Decoder
         return uncheckedRead<uint32_t>();
     }
     float uncheckedReadFixedF32() {
         return uncheckedRead<float>();
     }
     double uncheckedReadFixedF64() {
         return uncheckedRead<double>();
     }
-    uint32_t uncheckedReadVarU32() {
-        uint32_t decoded = 0;
+    template <typename UInt>
+    UInt uncheckedReadVarU() {
+        static const unsigned numBits = sizeof(UInt) * CHAR_BIT;
+        static const unsigned remainderBits = numBits % 7;
+        static const unsigned numBitsInSevens = numBits - remainderBits;
+        UInt decoded = 0;
         uint32_t shift = 0;
         do {
             uint8_t byte = *cur_++;
             if (!(byte & 0x80))
-                return decoded | (uint32_t(byte) << shift);
-            decoded |= uint32_t(byte & 0x7f) << shift;
+                return decoded | (UInt(byte) << shift);
+            decoded |= UInt(byte & 0x7f) << shift;
             shift += 7;
-        } while (shift != 28);
+        } while (shift != numBitsInSevens);
         uint8_t byte = *cur_++;
         MOZ_ASSERT(!(byte & 0xf0));
-        return decoded | (uint32_t(byte) << 28);
+        return decoded | (UInt(byte) << numBitsInSevens);
+    }
+    uint32_t uncheckedReadVarU32() {
+        return uncheckedReadVarU<uint32_t>();
+    }
+    uint64_t uncheckedReadVarU64() {
+        return uncheckedReadVarU<uint64_t>();
     }
     Expr uncheckedReadExpr() {
         return uncheckedReadEnum<Expr>();
     }
     Expr uncheckedPeekExpr() {
         const uint8_t* before = cur_;
         Expr ret = uncheckedReadEnum<Expr>();
         cur_ = before;
--- a/js/src/asmjs/WasmIonCompile.cpp
+++ b/js/src/asmjs/WasmIonCompile.cpp
@@ -193,16 +193,25 @@ class FunctionCompiler
     {
         if (inDeadCode())
             return nullptr;
         MConstant* constant = MConstant::NewAsmJS(alloc(), v, type);
         curBlock_->add(constant);
         return constant;
     }
 
+    MDefinition* constant(int64_t i)
+    {
+        if (inDeadCode())
+            return nullptr;
+        MConstant* constant = MConstant::NewInt64(alloc(), i);
+        curBlock_->add(constant);
+        return constant;
+    }
+
     template <class T>
     MDefinition* unary(MDefinition* op)
     {
         if (inDeadCode())
             return nullptr;
         T* ins = T::NewAsmJS(alloc(), op);
         curBlock_->add(ins);
         return ins;
@@ -1209,16 +1218,17 @@ class FunctionCompiler
     // Provides unique identifiers for internal uses in the control flow stacks;
     // these ids have to grow monotonically.
     unsigned nextId() { return nextId_++; }
 
     /************************************************************ DECODING ***/
 
     uint8_t        readU8()       { return decoder_.uncheckedReadFixedU8(); }
     uint32_t       readVarU32()   { return decoder_.uncheckedReadVarU32(); }
+    uint64_t       readVarU64()   { return decoder_.uncheckedReadVarU64(); }
     float          readF32()      { return decoder_.uncheckedReadFixedF32(); }
     double         readF64()      { return decoder_.uncheckedReadFixedF64(); }
     Expr           readExpr()     { return decoder_.uncheckedReadExpr(); }
     Expr           peakExpr()     { return decoder_.uncheckedPeekExpr(); }
 
     SimdConstant readI32X4() {
         Val::I32x4 i32x4;
         JS_ALWAYS_TRUE(decoder_.readFixedI32x4(&i32x4));
@@ -1339,17 +1349,19 @@ EmitLiteral(FunctionCompiler& f, ExprTyp
 {
     switch (type) {
       case ExprType::I32: {
         int32_t val = f.readVarU32();
         *def = f.constant(Int32Value(val), MIRType_Int32);
         return true;
       }
       case ExprType::I64: {
-        MOZ_CRASH("int64");
+        int64_t val = f.readVarU64();
+        *def = f.constant(val);
+        return true;
       }
       case ExprType::F32: {
         float val = f.readF32();
         *def = f.constant(Float32Value(val), MIRType_Float32);
         return true;
       }
       case ExprType::F64: {
         double val = f.readF64();
@@ -2803,16 +2815,19 @@ EmitExpr(FunctionCompiler& f, ExprType t
       case Expr::I32AtomicsExchange:
         return EmitAtomicsExchange(f, def);
       case Expr::I32AtomicsLoad:
         return EmitAtomicsLoad(f, def);
       case Expr::I32AtomicsStore:
         return EmitAtomicsStore(f, def);
       case Expr::I32AtomicsBinOp:
         return EmitAtomicsBinOp(f, def);
+      // I64
+      case Expr::I64Const:
+        return EmitLiteral(f, ExprType::I64, def);
       // F32
       case Expr::F32Const:
         return EmitLiteral(f, ExprType::F32, def);
       case Expr::F32Add:
         return EmitAddOrSub(f, ExprType::F32, IsAdd(true), def);
       case Expr::F32Sub:
         return EmitAddOrSub(f, ExprType::F32, IsAdd(false), def);
       case Expr::F32Mul:
@@ -2924,17 +2939,16 @@ EmitExpr(FunctionCompiler& f, ExprType t
       case Expr::I32Popcnt:
       case Expr::F32CopySign:
       case Expr::F32Trunc:
       case Expr::F32Nearest:
       case Expr::F64CopySign:
       case Expr::F64Nearest:
       case Expr::F64Trunc:
       case Expr::I32WrapI64:
-      case Expr::I64Const:
       case Expr::I64ExtendSI32:
       case Expr::I64ExtendUI32:
       case Expr::I64TruncSF32:
       case Expr::I64TruncSF64:
       case Expr::I64TruncUF32:
       case Expr::I64TruncUF64:
       case Expr::F32ConvertSI64:
       case Expr::F32ConvertUI64:
--- a/js/src/asmjs/WasmText.cpp
+++ b/js/src/asmjs/WasmText.cpp
@@ -2069,17 +2069,17 @@ ParseConst(WasmParseContext& c, WasmToke
           default:
             break;
         }
         break;
       }
       case ValType::I64: {
         switch (val.kind()) {
           case WasmToken::Index:
-            return new(c.lifo) WasmAstConst(Val(val.index()));
+            return new(c.lifo) WasmAstConst(Val(uint64_t(val.index())));
           case WasmToken::UnsignedInteger:
             return new(c.lifo) WasmAstConst(Val(val.uint()));
           case WasmToken::SignedInteger:
             return new(c.lifo) WasmAstConst(Val(uint64_t(val.sint())));
           default:
             break;
         }
         break;