Exemple #1
0
        public WebAssemblyExecutionContext(WebAssemblyFile file)
        {
            if (file.table != null)
            {
                InitTable(file);
            }
            if (file.global != null)
            {
                InitGlobal(file);
            }
            if (file.memory != null)
            {
                InitMemory(file);
            }
            if (file.data != null)
            {
                InitData(file);
            }
            if (file.import != null)
            {
                InitImport(file);
            }
            InitFunctions(file);
            if (file.export != null)
            {
                InitExport(file);
            }

            // TODO: InitElement(ctx);
        }
Exemple #2
0
        public WebAssemblyInterpreter(WebAssemblyFile file)
        {
            this.file = file;

            if (file.type == null)
            {
                throw new Exception("No type information!");
            }
            if (file.function == null)
            {
                throw new Exception("No type information!");
            }
            if (file.code == null)
            {
                throw new Exception("No code to execute!");
            }
            if (file.start == null)
            {
                throw new Exception("No start function!");
            }

            ctx = new WebAssemblyExecutionContext(file);

            ResolveExternalFunctions();

            uint start_func = file.start.index;

            logger.Debug($"Start function index is {start_func}. This index does {(ctx.functions.ContainsKey(start_func) ? "" : "not")} exist.");
            if (!ctx.functions.ContainsKey(start_func))
            {
                throw new Exception("Corrupt file.");
            }
        }
Exemple #3
0
        private void InitFunctions(WebAssemblyFile file)
        {
            logger.Debug("Instanciating Functions.");

            Dictionary <uint, FuncType> type_info = new Dictionary <uint, FuncType>();

            for (uint i = 0; i < (uint)file.type.entries.Length; i++)
            {
                type_info[i] = file.type.entries[i];
                logger.ConditionalTrace($"Type {i} = {file.type.entries[i]}.");
            }

            logger.ConditionalTrace($"file.function.types.Length = {file.function.types.Length} and file.code.bodies.Length = {file.code.bodies.Length}.");
            if (file.function.types.Length != file.code.bodies.Length)
            {
                throw new Exception("Invalid file");
            }

            uint import_count = (uint)functions.Count;

            logger.ConditionalTrace($"Import count = {import_count}.");

            for (uint i = 0; i < (uint)file.code.bodies.Length; i++)
            {
                uint         index = file.function.types[i];
                FunctionBody body  = file.code.bodies[i];

                uint func_indx = i + import_count;

                logger.ConditionalTrace($"Function {func_indx} = {body}.");

                functions[func_indx] = new FunctionInstance
                {
                    module       = "this",
                    is_in_module = true,
                    code         = body.code,
                    parameters   = type_info[index].param_types,
                    return_type  = type_info[index].return_type,
                };

                List <WebAssemblyType> locals_unwrapped = new List <WebAssemblyType>();

                foreach (var local in body.locals)
                {
                    locals_unwrapped.AddRange(Enumerable.Repeat(local.type, (int)local.count));
                }

                functions[func_indx].locals = locals_unwrapped.ToArray();

                logger.ConditionalTrace($"Final object = {functions[func_indx]}.");
            }

            logger.Debug("Done instanciating Functions.");
        }
Exemple #4
0
        private void InitData(WebAssemblyFile file)
        {
            logger.Debug("Instanciating Data.");

            foreach (var entry in file.data.entries)
            {
                var offset = WebAssemblyHelper.GetOffset(entry.offset);

                logger.ConditionalTrace($"Copying: {BitConverter.ToString(entry.data).Replace("-", "")} to [{offset},{offset + entry.data.Length}].");

                Array.Copy(entry.data, 0, linear_memory[entry.memory_index].memory, offset, entry.data.Length);
            }

            logger.Debug("Done instanciating Data.");
        }
Exemple #5
0
        private void InitMemory(WebAssemblyFile file)
        {
            logger.Debug("Instanciating Memory.");

            for (uint i = 0; i < (uint)file.memory.entries.Length; i++)
            {
                var limits = file.memory.entries[i].limits;

                logger.ConditionalTrace($"Instanciating MemoryInstance({limits.initial}, {limits.maximum}).");

                linear_memory[i] = new MemoryInstance(limits.initial, limits.maximum);
            }

            logger.Debug("Done instanciating Memory.");
        }
Exemple #6
0
        private void InitTable(WebAssemblyFile file)
        {
            logger.Debug("Instanciating Table.");

            for (uint i = 0; i < (uint)file.table.entries.Length; i++)
            {
                var entry = file.table.entries[i];

                logger.ConditionalTrace($"Instanciating TableInstance({entry.element_type}, {entry.limits.initial}, {entry.limits.maximum ?? 0}).");

                tables[i] = new TableInstance(entry.element_type, entry.limits.initial, entry.limits.maximum);
            }

            logger.Debug("Done instanciating Table.");
        }
Exemple #7
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.");
        }
Exemple #8
0
        private void InitExport(WebAssemblyFile file)
        {
            logger.Debug("Instanciating Export.");

            for (uint i = 0; i < (uint)file.export.entries.Length; i++)
            {
                var entry = file.export.entries[i];

                logger.ConditionalTrace($"Export is {entry.index}: {entry.kind} {entry.field_str}.");

                switch (entry.kind)
                {
                case WebAssemblyExternalKind.Function:
                    var index = entry.index;
                    functions[index].is_export = true;
                    functions[index].name      = entry.field_str;
                    break;
                }
            }

            logger.Debug("Done instanciating Export.");
        }
Exemple #9
0
        private void InitImport(WebAssemblyFile file)
        {
            logger.Debug("Instanciating Export.");

            Dictionary <uint, FuncType> type_info = new Dictionary <uint, FuncType>();

            for (uint i = 0; i < (uint)file.type.entries.Length; i++)
            {
                type_info[i] = file.type.entries[i];
                logger.ConditionalTrace($"Type {i} = {file.type.entries[i]}.");
            }

            for (uint i = 0; i < (uint)file.import.entries.Length; i++)
            {
                var entry = file.import.entries[i];

                logger.Debug($"Entry = {entry}.");

                switch (entry.kind)
                {
                case WebAssemblyExternalKind.Function:
                    uint index = (uint)entry.type;

                    functions[i] = new FunctionInstance
                    {
                        module      = entry.module_str,
                        name        = entry.field_str,
                        parameters  = type_info[index].param_types,
                        return_type = type_info[index].return_type
                    };

                    logger.ConditionalTrace($"Function {i} = {functions[i]}.");
                    break;
                }
            }

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