-
-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(compiler)!: Refactor enum constructors #1211
Conversation
149f1df
to
2c0dd5b
Compare
let assertion_error_ident = Ident.create_persistent("AssertionError"); | ||
let assertion_error_closure_ident = | ||
Ident.create_persistent("GRAIN$EXPORT$AssertionError"); | ||
let index_out_of_bounds_ident = | ||
Ident.create_persistent("GRAIN$EXPORT$IndexOutOfBounds"); | ||
let index_non_integer_ident = | ||
Ident.create_persistent("GRAIN$EXPORT$IndexNonInteger"); | ||
let match_failure_ident = | ||
Ident.create_persistent("GRAIN$EXPORT$MatchFailure"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no identifiers or closures for variants anymore.
@@ -90,6 +81,7 @@ let console_mod = "console"; | |||
let tracepoint_ident = Ident.create_persistent("tracepoint"); | |||
|
|||
let grain_main = "_gmain"; | |||
let grain_type_metadata = "_gtype_metadata"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type metadata is now explicitly provided by a special type metadata function in the module. This allows modules to choose to define only types but still have type information loaded.
| Runtime_errors.AssertionError => ( | ||
assertion_error_closure_ident, | ||
Some(get_wasm_imported_name(exception_mod, assertion_error_ident)), | ||
/** Heap allocations. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of this has changed, it's just moved higher so we can do allocations for exceptions (which was previously just calling a function).
@@ -2484,6 +2388,9 @@ let compile_prim1 = (wasm_mod, env, p1, arg, loc): Expression.t => { | |||
Expression.Unreachable.make(wasm_mod), | |||
], | |||
) | |||
| Assert => failwith("Unreachable case; should never get here: Assert") | |||
| BuiltinId => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This BuiltinId
will be how print
will be able to know about built-in types.
|
||
let grain_main = "_gmain"; | ||
let grain_start = "_start"; | ||
let hard_dependencies: Hashtbl.t(string, unit) = Hashtbl.create(10); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hard dependencies are ones that require code to be loaded from the module, whereas soft dependencies just require type information be loaded.
@@ -301,17 +285,25 @@ let rec globalize_names = (~function_names, ~global_names, ~label_names, expr) = | |||
}; | |||
|
|||
let table_offset = ref(0); | |||
let module_id = ref(0); | |||
let module_id = ref(Comp_utils.encoded_int32(0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a really sad bug that took away a week of my life.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain it a bit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As defined in the data representations doc, module IDs are always tagged and thus GC-able. Except during linking, the linker assigned non-tagged IDS 🤦♂️
This wasn't a problem before because the IDs were treated by the runtime as untagged, but some updates while working on this PR caused them to be treated as regular values and made the bug show up.
let dependencies = | ||
Topo.fold((dep, acc) => [dep, ...acc], dependency_graph, []); | ||
|
||
let dependencies = Module_resolution.get_dependencies(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gives us the full dependency graph, which includes files that might not contain necessary code.
@@ -21,12 +21,11 @@ open Path; | |||
open Types; | |||
open Btype; | |||
|
|||
let builtin_idents = ref([]); | |||
let builtin_decls = ref([]); | |||
let builtin_idents = Hashtbl.create(64); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hash lets us look these up quickly versus having to traverse the list.
@@ -46,42 +46,33 @@ enum StringList { | |||
primitive _RUNTIME_TYPE_METADATA_PTR: WasmI32 = "@heap.type_metadata" | |||
|
|||
@unsafe | |||
let findTypeMetadata = (moduleId, typeId) => { | |||
let findTypeMetadata = typeId => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is now quite a bit less efficient since it traverses all type information. It should be converted to something faster like a binary tree or a hash, though it's tricky to implement because the metadata itself lives in runtime land where arbitrary allocations are not available. Regardless, I felt that optimization didn't need to be included in this PR and could come separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comments inline, they helped a ton! I had one question about the parser (and I'll probably spend a little more time looking at snapshots).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a good read through this - nice to see list constructors cleaned up as well and looks like some nice changes as well as a deep bug fixed. Really nice work!
Hopefully with the new code owner rules I can approve this releasing it as a lot of the changes are beyond my current comprehension but I liked the changes I did understand and the code changes read well.
Note to self: need to update |
Signed-off-by: Itay Dafna <i.b.dafna@gmail.com>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love this!
Signed-off-by: Itay Dafna i.b.dafna@gmail.com
Closes #1021
Closes #1502
This PR changes how enum variant constructors work in Grain, making individual variants handled separately from functions. This change allows us to build variant types into the language rather than just the standard library, which will allow us to provide better error messages, allow for disambiguation of variants from multiple types with the same name, and open up opportunities for features like optional arguments. The tradeoff is that the names of variant constructors are no longer functions, but this feature was only seldom used (only appearing once in Grain's entire standard library). Wrapper functions can be used to provide the same functionality.
Before:
After: