From 6050750d9e2bc4b5dee20a34314398834388fccd Mon Sep 17 00:00:00 2001 From: xensik Date: Sun, 17 Nov 2024 13:55:36 +0100 Subject: [PATCH] stuf --- include/xsk/arc/assembler.hpp | 10 +-- include/xsk/arc/compiler.hpp | 1 - src/arc/assembler.cpp | 126 +++++++++++++--------------------- src/arc/compiler.cpp | 31 +++------ src/arc/disassembler.cpp | 7 +- src/gsc/assembler.cpp | 4 +- 6 files changed, 68 insertions(+), 111 deletions(-) diff --git a/include/xsk/arc/assembler.hpp b/include/xsk/arc/assembler.hpp index d9305f65..4a608d8e 100644 --- a/include/xsk/arc/assembler.hpp +++ b/include/xsk/arc/assembler.hpp @@ -35,16 +35,16 @@ class assembler auto assemble_localvars(instruction const& inst) -> void; auto assemble_jump(instruction const& inst) -> void; auto assemble_switch(instruction const& inst) -> void; - auto assemble_end_switch(instruction const& inst) -> void; + auto assemble_switch_table(instruction const& inst) -> void; auto process_string(std::string const& data) -> void; auto process_function(function const& func) -> void; auto process_instruction(instruction const& inst) -> void; auto align_instruction(instruction& inst) -> void; - auto resolve_label(std::string const& name) -> i32; + auto resolve_label(std::string const& name) -> usize; auto resolve_string(std::string const& name) -> u16; - void add_stringref(std::string const& str, string_type type, u32 ref); - void add_importref(std::vector const& data, u32 ref); - void add_animref(std::vector const& data, u32 ref); + auto add_stringref(std::string const& str, string_type type, u32 ref) -> void; + auto add_importref(std::vector const& data, u32 ref) -> void; + auto add_animref(std::vector const& data, u32 ref) -> void; }; } // namespace xsk::arc diff --git a/include/xsk/arc/compiler.hpp b/include/xsk/arc/compiler.hpp index f8d29467..5d758181 100644 --- a/include/xsk/arc/compiler.hpp +++ b/include/xsk/arc/compiler.hpp @@ -69,7 +69,6 @@ class compiler auto emit_expr_const(expr_const const& exp) -> void; auto emit_expr_assign(expr_assign const& exp) -> void; auto emit_expr_clear(expr const& exp) -> void; - auto emit_expr_clear_local(expr_identifier const& exp) -> void; auto emit_expr_increment(expr_increment const& exp, bool is_stmt) -> void; auto emit_expr_decrement(expr_decrement const& exp, bool is_stmt) -> void; auto emit_expr_ternary(expr_ternary const& exp) -> void; diff --git a/src/arc/assembler.cpp b/src/arc/assembler.cpp index f1cd184c..ca93f96d 100644 --- a/src/arc/assembler.cpp +++ b/src/arc/assembler.cpp @@ -106,7 +106,7 @@ auto assembler::assemble(assembly const& data, std::string const& name) -> std:: script_.write(entry.params); script_.write(entry.flags); - for (auto const& ref : entry.refs) + for (auto ref : entry.refs) { script_.write(ref); } @@ -131,7 +131,7 @@ auto assembler::assemble(assembly const& data, std::string const& name) -> std:: script_.seek(2); } - for (auto const& ref : entry.refs) + for (auto ref : entry.refs) { script_.write(ref); } @@ -167,7 +167,7 @@ auto assembler::assemble(assembly const& data, std::string const& name) -> std:: if (ctx_->props() & props::size64) script_.seek(2); - for (auto const& ref : entry.refs) + for (auto ref : entry.refs) { script_.write(ref); } @@ -188,7 +188,7 @@ auto assembler::assemble(assembly const& data, std::string const& name) -> std:: head.flags = 0; head.name = resolve_string(name); // hash id! - auto const endpos = script_.pos(); + auto endpos = script_.pos(); script_.pos(0); script_.write(ctx_->magic()); @@ -226,7 +226,7 @@ auto assembler::assemble(assembly const& data, std::string const& name) -> std:: script_.write(head.flags); script_.pos(endpos); - auto const dev_endpos = devmap_.pos(); + auto dev_endpos = devmap_.pos(); devmap_.pos(0); devmap_.write(devmap_count_); devmap_.pos(dev_endpos); @@ -267,7 +267,7 @@ auto assembler::assemble_function(function& func) -> void export_ref entry; entry.checksum = 0; - entry.offset = func.index; + entry.offset = static_cast(func.index); entry.name = func.name; entry.params = func.params; entry.flags = func.flags; @@ -280,7 +280,7 @@ auto assembler::assemble_instruction(instruction const& inst) -> void if ((ctx_->build() & build::dev_maps) != build::prod) { - devmap_.write(script_.pos()); + devmap_.write(static_cast(script_.pos())); devmap_.write(static_cast(inst.pos.line)); devmap_.write(static_cast(inst.pos.column)); devmap_count_++; @@ -462,7 +462,7 @@ auto assembler::assemble_instruction(instruction const& inst) -> void assemble_switch(inst); break; case opcode::OP_EndSwitch: - assemble_end_switch(inst); + assemble_switch_table(inst); break; default: throw asm_error(std::format("unhandled opcode {} at index {:04X}", ctx_->opcode_name(inst.opcode), inst.index)); @@ -486,51 +486,36 @@ auto assembler::assemble_jump(instruction const& inst) -> void script_.write(static_cast(resolve_label(inst.data[0]) - inst.index - inst.size)); } -// continue from here TODO auto assembler::assemble_switch(instruction const& inst) -> void { - const i32 addr = ((resolve_label(inst.data[0]) + 4) & 0xFFFFFFFC) - inst.index - inst.size; - script_.align(4); - script_.write(addr); + script_.write(static_cast(((resolve_label(inst.data[0]) + 4) & 0xFFFFFFFC) - inst.index - inst.size)); } -auto assembler::assemble_end_switch(instruction const& inst) -> void +auto assembler::assemble_switch_table(instruction const& inst) -> void { - const auto count = std::stoul(inst.data[0]); - const auto type = static_cast(std::stoul(inst.data.back())); + auto count = std::stoul(inst.data[0]); script_.align(4); script_.write(count); for (auto i = 0u; i < count; i++) { - if (inst.data[1 + (3 * i)] == "case") + if (inst.data[1 + (4 * i)] == "case") { - if (type == switch_type::integer) - { - script_.write((std::stoi(inst.data[1 + (3 * i) + 1]) & 0xFFFFFF) + 0x800000); - } - else - { - script_.write(i + 1); - } - - const i32 addr = resolve_label(inst.data[1 + (3 * i) + 2]) - script_.pos() - 4; + auto type = static_cast(std::stoul(inst.data[1 + (4 * i) + 1])); - script_.write(addr); + script_.write((type == switch_type::integer) ? ((std::stoi(inst.data[1 + (4 * i) + 2]) & 0xFFFFFF) + 0x800000) : i + 1); + script_.write(static_cast(resolve_label(inst.data[1 + (4 * i) + 3]) - script_.pos() - 4)); } - else if (inst.data[1 + (3 * i)] == "default") + else if (inst.data[1 + (4 * i)] == "default") { script_.write(0); - - const i32 addr = resolve_label(inst.data[1 + (3 * i) + 1]) - script_.pos() - 4; - - script_.write(addr); + script_.write(static_cast(resolve_label(inst.data[1 + (4 * i) + 1]) - script_.pos() - 4)); } else { - throw asm_error(std::format("invalid switch case {}", inst.data[1 + (3 * i)])); + throw asm_error(std::format("invalid switch case {}", inst.data[1 + (4 * i)])); } } } @@ -600,17 +585,16 @@ auto assembler::process_instruction(instruction const& inst) -> void break; case opcode::OP_EndSwitch: { - const auto count = std::stoul(inst.data[0]); - const auto type = static_cast(std::stoul(inst.data.back())); + auto count = std::stoul(inst.data[0]); for (auto i = 0u; i < count; i++) { - if (inst.data[1 + (3 * i)] == "case") + if (inst.data[1 + (4 * i)] == "case") { + auto type = static_cast(std::stoul(inst.data[1 + (4 * i) + 1])); + if (type == switch_type::string) - { - process_string(inst.data[1 + (3 * i) + 1]); - } + process_string(inst.data[1 + (4 * i) + 2]); } } @@ -723,7 +707,7 @@ auto assembler::align_instruction(instruction& inst) -> void case opcode::OP_GetInteger: inst.size += script_.align(4); if (inst.data.size() == 2) - add_animref(inst.data, script_.pos()); + add_animref(inst.data, static_cast(script_.pos())); script_.seek(4); break; case opcode::OP_GetFloat: @@ -737,12 +721,12 @@ auto assembler::align_instruction(instruction& inst) -> void case opcode::OP_GetString: case opcode::OP_GetIString: inst.size += script_.align(2); - add_stringref(inst.data[0], string_type::literal, script_.pos()); + add_stringref(inst.data[0], string_type::literal, static_cast(script_.pos())); script_.seek(2); break; case opcode::OP_GetAnimation: inst.size += script_.align(4); - add_animref(inst.data, script_.pos()); + add_animref(inst.data, static_cast(script_.pos())); script_.seek(4); break; case opcode::OP_WaitTillMatch: @@ -762,7 +746,7 @@ auto assembler::align_instruction(instruction& inst) -> void for (auto i = 0u; i < inst.data.size(); i++) { inst.size += script_.align(2) + 2; - add_stringref(inst.data[i], string_type::canonical, script_.pos()); + add_stringref(inst.data[i], string_type::canonical, static_cast(script_.pos())); script_.seek(2); } @@ -779,7 +763,7 @@ auto assembler::align_instruction(instruction& inst) -> void case opcode::OP_EvalFieldVariableRef: case opcode::OP_ClearFieldVariable: inst.size += script_.align(2); - add_stringref(inst.data[0], string_type::canonical, script_.pos()); + add_stringref(inst.data[0], string_type::canonical, static_cast(script_.pos())); script_.seek(2); break; case opcode::OP_ScriptFunctionCallPointer: @@ -791,7 +775,7 @@ auto assembler::align_instruction(instruction& inst) -> void case opcode::OP_GetFunction: inst.size += script_.align(4); script_.seek(4); - add_importref(inst.data, inst.index); + add_importref(inst.data, static_cast(inst.index)); break; case opcode::OP_CallBuiltin: case opcode::OP_CallBuiltinMethod: @@ -802,7 +786,7 @@ auto assembler::align_instruction(instruction& inst) -> void script_.seek(1); inst.size += script_.align(4); script_.seek(4); - add_importref(inst.data, inst.index); + add_importref(inst.data, static_cast(inst.index)); break; case opcode::OP_JumpOnFalse: case opcode::OP_JumpOnTrue: @@ -823,17 +807,13 @@ auto assembler::align_instruction(instruction& inst) -> void inst.size += script_.align(4); script_.seek(4); - const auto count = std::stoul(inst.data[0]); - const auto type = static_cast(std::stoul(inst.data.back())); + auto count = std::stoul(inst.data[0]); for (auto i = 0u; i < count; i++) { - if (inst.data[1 + (3 * i)] == "case") + if (inst.data[1 + (4 * i)] == "case" && static_cast(std::stoul(inst.data[1 + (4 * i) + 1])) == switch_type::string) { - if (type == switch_type::string) - { - add_stringref(inst.data[1 + (3 * i) + 1], string_type::literal, script_.pos() + 2); - } + add_stringref(inst.data[1 + (3 * i) + 1], string_type::literal, static_cast(script_.pos() + 2)); } inst.size += 8; @@ -847,7 +827,7 @@ auto assembler::align_instruction(instruction& inst) -> void } } -auto assembler::resolve_label(std::string const& name) -> i32 +auto assembler::resolve_label(std::string const& name) -> usize { for (auto const& entry : func_->labels) { @@ -862,9 +842,7 @@ auto assembler::resolve_label(std::string const& name) -> i32 auto assembler::resolve_string(std::string const& name) -> u16 { - auto const itr = strpool_.find(name); - - if (itr != strpool_.end()) + if (auto const itr = strpool_.find(name); itr != strpool_.end()) { return itr->second; } @@ -872,28 +850,26 @@ auto assembler::resolve_string(std::string const& name) -> u16 throw asm_error(std::format("couldn't resolve string address of {}", name)); } -void assembler::add_stringref(std::string const& str, string_type type, u32 ref) +auto assembler::add_stringref(std::string const& str, string_type type, u32 ref) -> void { for (auto& entry : strings_) { if (entry.name == str && entry.type == static_cast(type)) { - entry.refs.push_back(ref); - return; + return entry.refs.push_back(ref); } } strings_.push_back({ str, u8(type), { ref } }); } -void assembler::add_importref(std::vector const& data, u32 ref) +auto assembler::add_importref(std::vector const& data, u32 ref) -> void { for (auto& entry : imports_) { if (entry.space == data[0] && entry.name == data[1] && entry.params == std::stoi(data[2]) && entry.flags == std::stoi(data[3])) { - entry.refs.push_back(ref); - return; + return entry.refs.push_back(ref); } } @@ -906,34 +882,24 @@ void assembler::add_importref(std::vector const& data, u32 ref) imports_.push_back(std::move(new_entry)); } -void assembler::add_animref(std::vector const& data, u32 ref) +auto assembler::add_animref(std::vector const& data, u32 ref) -> void { for (auto& entry : anims_) { - if (entry.name == data[0]) - { - if (data[1] == "-1") - { - entry.refs.push_back(ref); - } - else - { - entry.anims.push_back({ data[1], ref }); - } - return; - } + if (entry.name != data[0]) + continue; + + return (data[1] == "-1") ? entry.refs.push_back(ref) : entry.anims.push_back({ data[1], ref }); } animtree_ref new_entry; new_entry.name = data[0]; + if (data[1] == "-1") - { new_entry.refs.push_back(ref); - } else - { new_entry.anims.push_back({ data[1], ref }); - } + anims_.push_back(std::move(new_entry)); } diff --git a/src/arc/compiler.cpp b/src/arc/compiler.cpp index f21c616e..761ae46e 100644 --- a/src/arc/compiler.cpp +++ b/src/arc/compiler.cpp @@ -572,7 +572,6 @@ auto compiler::emit_stmt_switch(stmt_switch const& stm) -> void auto data = std::vector{}; data.push_back(std::format("{}", stm.body->block->list.size())); - auto type = switch_type::none; auto loc_default = std::string{}; auto has_default = false; @@ -586,25 +585,13 @@ auto compiler::emit_stmt_switch(stmt_switch const& stm) -> void if (entry->as().value->is()) { - if (type == switch_type::string) - { - throw comp_error(entry->loc(), "switch cases with different types"); - } - - type = switch_type::integer; - + data.push_back(std::format("{}", static_cast(switch_type::integer))); data.push_back(entry->as().value->as().value); data.push_back(insert_label()); } else if (entry->as().value->is()) { - if (type == switch_type::integer) - { - throw comp_error(entry->loc(), "switch cases with different types"); - } - - type = switch_type::string; - + data.push_back(std::format("{}", static_cast(switch_type::string))); data.push_back(entry->as().value->as().value); data.push_back(insert_label()); } @@ -640,8 +627,6 @@ auto compiler::emit_stmt_switch(stmt_switch const& stm) -> void data.push_back(loc_default); } - data.push_back(std::format("{}", static_cast>(type))); - insert_label(table_loc); emit_opcode(opcode::OP_EndSwitch, data); insert_label(break_loc); @@ -661,19 +646,23 @@ auto compiler::emit_stmt_default(stmt_default const& stm) -> void auto compiler::emit_stmt_break(stmt_break const& stm) -> void { - if (!can_break_ || scopes_.back().abort != scope::abort_none || scopes_.back().brk == "") + if (!can_break_ /*|| scopes_.back().abort != scope::abort_none*/ || scopes_.back().brk == "") throw comp_error(stm.loc(), "illegal break statement"); - scopes_.back().abort = scope::abort_break; + if (scopes_.back().abort == scope::abort_none) + scopes_.back().abort = scope::abort_break; + emit_opcode(opcode::OP_Jump, scopes_.back().brk); } auto compiler::emit_stmt_continue(stmt_continue const& stm) -> void { - if (!can_continue_ || scopes_.back().abort != scope::abort_none || scopes_.back().cnt == "") + if (!can_continue_ /*|| scopes_.back().abort != scope::abort_none*/ || scopes_.back().cnt == "") throw comp_error(stm.loc(), "illegal continue statement"); - scopes_.back().abort = scope::abort_continue; + if (scopes_.back().abort == scope::abort_none) + scopes_.back().abort = scope::abort_continue; + emit_opcode(opcode::OP_Jump, scopes_.back().cnt); } diff --git a/src/arc/disassembler.cpp b/src/arc/disassembler.cpp index bfb2ea26..cc3fd316 100644 --- a/src/arc/disassembler.cpp +++ b/src/arc/disassembler.cpp @@ -282,7 +282,7 @@ auto disassembler::disassemble(u8 const* data, usize data_size) -> assembly::ptr script_.seek_neg(4); } - entry->size -= end_pos - script_.pos(); + entry->size -= static_cast(end_pos - script_.pos()); } else if (script_.read() == 0) { @@ -321,7 +321,7 @@ auto disassembler::disassemble(u8 const* data, usize data_size) -> assembly::ptr auto disassembler::disassemble_function(function& func) -> void { - auto size = static_cast(func.size); + auto size = func.size; while (size > 0) { @@ -357,6 +357,9 @@ auto disassembler::disassemble_function(function& func) -> void if (ctx_->props() & props::size64) inst->size += script_.align(2); + if (inst->size > size || inst->index + inst->size != script_.pos()) + throw disasm_error("bad instruction size"); + size -= inst->size; func.instructions.push_back(std::move(inst)); diff --git a/src/gsc/assembler.cpp b/src/gsc/assembler.cpp index 6f6603f4..04f94f0a 100644 --- a/src/gsc/assembler.cpp +++ b/src/gsc/assembler.cpp @@ -519,7 +519,7 @@ auto assembler::assemble_switch_table(instruction const& inst) -> void } else { - assemble_offset(addr - index - 4); + assemble_offset(static_cast(addr - index - 4)); index += 7; } } @@ -539,7 +539,7 @@ auto assembler::assemble_switch_table(instruction const& inst) -> void { script_.write(0); stack_.write_cstr("\x01"); - assemble_offset(addr - index - 4); + assemble_offset(static_cast(addr - index - 4)); index += 7; } }