The following files and functions were ported: - jit.c - codegen.c - _jit functions in instructions*.c and misc_instr.c - generate_{analyzer,jit}.js (produces Rust code) - jit_* from cpu.c And the following data structures: - hot_code_addresses - wasm_table_index_free_list - entry_points - jit_cache_array - page_first_jit_cache_entry Other miscellaneous changes: - Page is an abstract type - Addresses, locals and bitflags are unsigned - Make the number of entry points a growable type - Avoid use of global state wherever possible - Delete string packing - Make CachedStateFlags abstract - Make AnalysisType product type - Make BasicBlockType product type - Restore opcode assertion - Set opt-level=2 in debug mode (for test performance) - Delete JIT_ALWAYS instrumentation (now possible via api) - Refactor generate_analyzer.js - Refactor generate_jit.js
89 lines
2.3 KiB
JavaScript
89 lines
2.3 KiB
JavaScript
"use strict";
|
|
|
|
function repeat(s, n)
|
|
{
|
|
let out = "";
|
|
for(let i = 0; i < n; i++) out += s;
|
|
return out;
|
|
}
|
|
|
|
function indent(lines, how_much)
|
|
{
|
|
return lines.map(line => repeat(" ", how_much) + line);
|
|
}
|
|
|
|
function print_syntax_tree(statements)
|
|
{
|
|
let code = [];
|
|
|
|
for(let statement of statements)
|
|
{
|
|
if(typeof statement === "string")
|
|
{
|
|
code.push(statement);
|
|
}
|
|
else if(statement.type === "switch")
|
|
{
|
|
console.assert(statement.condition);
|
|
|
|
const cases = [];
|
|
|
|
for(let case_ of statement.cases)
|
|
{
|
|
console.assert(case_.conditions.length >= 1);
|
|
|
|
cases.push(case_.conditions.join(" | ") + " => {");
|
|
cases.push.apply(cases, indent(print_syntax_tree(case_.body), 4));
|
|
cases.push(`},`);
|
|
}
|
|
|
|
if(statement.default_case)
|
|
{
|
|
cases.push(`_ => {`);
|
|
cases.push.apply(cases, indent(print_syntax_tree(statement.default_case.body), 4));
|
|
cases.push(`}`);
|
|
}
|
|
|
|
code.push(`match ${statement.condition} {`);
|
|
code.push.apply(code, indent(cases, 4));
|
|
code.push(`}`);
|
|
}
|
|
else if(statement.type === "if-else")
|
|
{
|
|
console.assert(statement.if_blocks.length >= 1);
|
|
|
|
let first_if_block = statement.if_blocks[0];
|
|
|
|
code.push(`if ${first_if_block.condition} {`);
|
|
code.push.apply(code, indent(print_syntax_tree(first_if_block.body), 4));
|
|
code.push(`}`);
|
|
|
|
for(let i = 1; i < statement.if_blocks.length; i++)
|
|
{
|
|
let if_block = statement.if_blocks[i];
|
|
|
|
code.push(`else if ${if_block.condition} {`);
|
|
code.push.apply(code, indent(print_syntax_tree(if_block.body), 4));
|
|
code.push(`}`);
|
|
}
|
|
|
|
if(statement.else_block)
|
|
{
|
|
code.push(`else {`);
|
|
code.push.apply(code, indent(print_syntax_tree(statement.else_block.body), 4));
|
|
code.push(`}`);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
console.assert(false, "Unexpected type: " + statement.type, "In:", statement);
|
|
}
|
|
}
|
|
|
|
return code;
|
|
}
|
|
|
|
module.exports = {
|
|
print_syntax_tree,
|
|
};
|