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); }
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."); }