예제 #1
0
        internal static ValueObject GetInitExpr(InitExpr init, List <GlobalInstance> initialized_globals)
        {
            if (init.expr.Length < 3)
            {
                throw new Exception("Unexpected init expression.");
            }

            uint pc = 0;

            ValueObject ret = null;

            switch (init.expr[0])
            {
            case (byte)WebAssemblyOpcode.I32_CONST:
                ret = new ValueObject(LEB128.ReadUInt32(init.expr, ref pc));
                break;

            case (byte)WebAssemblyOpcode.I64_CONST:
                ret = new ValueObject(LEB128.ReadUInt64(init.expr, ref pc));
                break;

            case (byte)WebAssemblyOpcode.F32_CONST:
                ret = new ValueObject(BitConverter.ToSingle(init.expr, (int)pc));
                break;

            case (byte)WebAssemblyOpcode.F64_CONST:
                ret = new ValueObject(BitConverter.ToDouble(init.expr, (int)pc));
                break;

            case (byte)WebAssemblyOpcode.GLOBAL_GET:
                GlobalInstance gi = initialized_globals[LEB128.ReadInt32(init.expr, ref pc)];
                if (!gi.is_mutable)
                {
                    throw new Exception("Unexpected init expression.");
                }
                ret = gi.value;
                break;

            default:
                throw new Exception("Invalid init expression. Expected only simple constant load instruction or global get.");
            }

            pc++;

            if (init.expr[pc] != (byte)WebAssemblyOpcode.END || init.expr.Length > pc)
            {
                throw new Exception("Invalid init expression.");
            }

            return(ret);
        }
예제 #2
0
        private void InitGlobal(WebAssemblyFile file)
        {
            logger.Debug("Instanciating Globals.");

            List <GlobalInstance> finalized_globals = new List <GlobalInstance>();

            for (uint i = 0; i < (uint)file.global.globals.Length; i++)
            {
                var global = file.global.globals[i];

                var value = WebAssemblyHelper.GetInitExpr(global.init, finalized_globals);

                logger.ConditionalTrace($"Instanciating GlobalInstance({global.type.mutability}, {global.type.content_type}, {value}).");

                globals[i] = new GlobalInstance(global.type.mutability, global.type.content_type, value);

                finalized_globals.Add(globals[i]);
            }

            logger.Debug("Done instanciating Globals.");
        }