Exception and RPC implementation #181

Merged
sb10q merged 7 commits from exception-rpc into master 2022-02-13 10:40:13 +08:00

Should be used together with a modified version of artiq, because this PR will need the embedding map to work. Will push the changes to artiq later. (Note that for RPC with lists, we will need to change the firmware because lists are represented as &CSlice<T> in nac3 but the firmware expects CSlice<T>)

Notable changes (apart from implementing exception and RPC)

  • Class and function names will now include mod_path if it is non-empty. This is needed as exception names will be derived from class name, which should be the fully-qualified name.
  • Fixed some nasty type errors during codegen. See the changes for nac3core::codegen::concrete_type, type resolver parse_type_annotation function for details. If these were not modified when new primitives are added, some primitive types would be erroneously treated as classes, producing incorrect LLVM IR.
  • Changed the representation of strings from i8* with null terminator to CSlice<u8>.
  • Refactored codegen module, added some helper functions and rely on basic block terminator info to tell if the block is terminated (instead of propagating using return type).
  • Classes are now generated as identified types with names, instead of inline struct types. This improves the readability of the IR. However, as different identified types are treated as different types by LLVM, we need to generate each function as a separate module and link them together so LLVM will merge identified types that are structurally equivalent into one type. Hence, the name of the class type might be any one of the classes with the same layout (e.g., the exception type might be named as %Exception or %ZeroDivisionError or %IndexError, as all exception types share the same layout...).

Close issues:

Current issues:

  1. Classes extending Exception should inherit Exception directly (otherwise we cannot generate the constructor for it, we should fix this later) and are hardcoded to only accept pass as body.
  2. Not sure what is the best way to handle rpc(flags={"async"}), so I have not yet implemented async RPC for now, but it should be quite trivial to modify the codegen to handle async RPC.
  3. I did not create debug info during codegen (otherwise I have to modify a lot of code... no time for now), so the traceback will not be very readable. The name mangling rules are also quite arbitrary, may need a better way to handle this later (perhaps c++ mangling rule)
  4. Print is not supported now since we do not allow varargs. We could allow this via some hack (make print a typevar, skip type checking for it) but I haven't do it right now. For now, we could use tuples (print is a function taking 1 generic argument, which can be a tuple, and let the host handle the type...).
  5. I only added bound check for list indexing to check if the implementation is correct. We will need to add bound checks to other codegen, such as list slice and slice assignment. There is a helper function for this, so should not be too hard.
Should be used together with a modified version of artiq, because this PR will need the embedding map to work. Will push the changes to artiq later. (Note that for RPC with lists, we will need to change the firmware because lists are represented as `&CSlice<T>` in nac3 but the firmware expects `CSlice<T>`) Notable changes (apart from implementing exception and RPC) - Class and function names will now include `mod_path` if it is non-empty. This is needed as exception names will be derived from class name, which should be the fully-qualified name. - Fixed some nasty type errors during codegen. See the changes for `nac3core::codegen::concrete_type`, type resolver `parse_type_annotation` function for details. If these were not modified when new primitives are added, some primitive types would be erroneously treated as classes, producing incorrect LLVM IR. - Changed the representation of strings from `i8*` with null terminator to `CSlice<u8>`. - Refactored codegen module, added some helper functions and rely on basic block terminator info to tell if the block is terminated (instead of propagating using return type). - Classes are now generated as identified types with names, instead of inline struct types. This improves the readability of the IR. However, as different identified types are treated as different types by LLVM, we need to generate each function as a separate module and link them together so LLVM will merge identified types that are structurally equivalent into one type. Hence, the name of the class type might be any one of the classes with the same layout (e.g., the exception type might be named as `%Exception` or `%ZeroDivisionError` or `%IndexError`, as all exception types share the same layout...). Close issues: - #134 - #16 - #153 Current issues: 1. Classes extending Exception should inherit Exception directly (otherwise we cannot generate the constructor for it, we should fix this later) and are hardcoded to only accept pass as body. 2. Not sure what is the best way to handle rpc(flags={"async"}), so I have not yet implemented async RPC for now, but it should be quite trivial to modify the codegen to handle async RPC. 3. I did not create debug info during codegen (otherwise I have to modify a lot of code... no time for now), so the traceback will not be very readable. The name mangling rules are also quite arbitrary, may need a better way to handle this later (perhaps c++ mangling rule) 4. Print is not supported now since we do not allow varargs. We could allow this via some hack (make print a typevar, skip type checking for it) but I haven't do it right now. For now, we could use tuples (print is a function taking 1 generic argument, which can be a tuple, and let the host handle the type...). 5. I only added bound check for list indexing to check if the implementation is correct. We will need to add bound checks to other codegen, such as list slice and slice assignment. There is a helper function for this, so should not be too hard.
pca006132 added 1 commit 2022-02-12 21:49:48 +08:00
050c862c1a nac3core: function codegen callback changes
Added code generator argument to the callback, so it would be easier to
write complicated codegen with that callback. To prepare for RPC
codegen.
pca006132 force-pushed exception-rpc from 5e72c2d45d to aefd10c312 2022-02-12 22:14:44 +08:00 Compare
pca006132 force-pushed exception-rpc from aefd10c312 to b18626b149 2022-02-12 22:50:44 +08:00 Compare

Changes for artiq: f23b7a6154

Changes for artiq: https://github.com/pca006132/artiq/commit/f23b7a615421f1b7545b48c984aa5a6d2e61f1be
sb10q merged commit b18626b149 into master 2022-02-13 10:40:13 +08:00
sb10q deleted branch exception-rpc 2022-02-13 10:40:14 +08:00
Sign in to join this conversation.
No reviewers
No Milestone
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: M-Labs/nac3#181
There is no content yet.