diff --git a/external/pegmatite b/external/pegmatite index 726cad86f..42fd31fcf 160000 --- a/external/pegmatite +++ b/external/pegmatite @@ -1 +1 @@ -Subproject commit 726cad86f8d822f762099962cf2601936791eec7 +Subproject commit 42fd31fcfc4c3ad8225c40c6e88b4174711ffe98 diff --git a/src/compiler/codegen/codegen.cc b/src/compiler/codegen/codegen.cc index 70ca364f2..d373fe300 100644 --- a/src/compiler/codegen/codegen.cc +++ b/src/compiler/codegen/codegen.cc @@ -92,6 +92,15 @@ namespace verona::compiler return std::make_pair(class_item, method_item); } + /** + * Writes the magic numbers to the bytecode + * @param code Generator to which the bytes should be emitted + */ + void write_magic_number(Generator& code) + { + code.u32(bytecode::MAGIC_NUMBER); + } + std::vector codegen( Context& context, const Program& program, const AnalysisResults& analysis) { @@ -100,7 +109,9 @@ namespace verona::compiler return {}; std::vector code; + Generator gen(code); + write_magic_number(gen); Reachability reachability = compute_reachability( context, program, gen, entry->first, entry->second, analysis); diff --git a/src/interpreter/bytecode.h b/src/interpreter/bytecode.h index 7c97930d1..5815a556d 100644 --- a/src/interpreter/bytecode.h +++ b/src/interpreter/bytecode.h @@ -13,6 +13,7 @@ * Bytecode has the following layout: * * Program header: + * - 32-bit verona magic number, equal to the MAGIC_NUMBER constant * - 32-bit number of descriptors, followed by that many descriptors (see below) * - 32-bit descriptor index of Main class * - 32-bit selector index of main method @@ -131,6 +132,8 @@ namespace verona::bytecode uint32_t size; }; + constexpr static uint32_t MAGIC_NUMBER = 0xF38932C3; + /** * Type-safe wrapper for register indices, helps avoid implicit conversion * from/to integers. diff --git a/src/interpreter/code.h b/src/interpreter/code.h index 16051ac1d..2472280b7 100644 --- a/src/interpreter/code.h +++ b/src/interpreter/code.h @@ -86,10 +86,12 @@ namespace verona::interpreter { return load(ip); } - uint16_t u32(size_t& ip) const + + uint32_t u32(size_t& ip) const { return load(ip); } + uint64_t u64(size_t& ip) const { return load(ip); @@ -137,6 +139,8 @@ namespace verona::interpreter { size_t ip = 0; + check_verona_nums(ip); + uint32_t descriptors_count = u32(ip); for (uint32_t i = 0; i < descriptors_count; i++) { @@ -190,6 +194,15 @@ namespace verona::interpreter SpecialDescriptors special_descriptors_; + void check_verona_nums(size_t& ip) + { + uint32_t nums = u32(ip); + if (nums != bytecode::MAGIC_NUMBER) + { + throw std::logic_error{"Invalid magic number, not recognized"}; + } + } + std::unique_ptr load_descriptor(size_t& ip) { std::string_view name = str(ip);