Skip to content
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

Adds support for qualified refs to $ion, $ion_encoding #830

Merged
merged 7 commits into from
Sep 7, 2024
Merged

Conversation

zslayton
Copy link
Contributor

@zslayton zslayton commented Sep 5, 2024

  • Modifies compiled macros to use Rc to store references to dependent macros. This allows the macro to continue referring to its dependent even if the latter is no longer directly addressable.
  • Adds support for module_name::encoding_name::parameter_name syntax and (module_name::macro_name ...) syntax. The only modules currently supported are $ion (the system module) and $ion_encoding (the active encoding module).

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

* Adds support for `module_name::encoding_name::parameter` syntax
* Adds support for `(module_name::macro_name ...)` syntax

The only modules currently supported are `$ion` (the system module)
and `$ion_encoding` the active module.

This patch also starts uses `Rc` to store macro references in the body
of a compiled macro. This allows the macro to continue referring to
its dependent even if the dependent is no longer directly addressable.
Copy link
Contributor Author

@zslayton zslayton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ PR tour 🧭

@@ -277,6 +277,15 @@ pub enum AnyEExpArgGroupKind<'top> {
Binary_1_1(BinaryEExpArgGroup<'top>),
}

impl<'top> AnyEExpArgGroupKind<'top> {
fn encoding(&self) -> &ParameterEncoding {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ Adding this method and then calling it below was a workaround for a lifetime constraint.

AnyEExpArgGroupKind::Binary_1_1(g) => g.encoding(),
}
fn encoding(&self) -> &ParameterEncoding {
self.kind.encoding()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ The callsite mentioned above.

Comment on lines +131 to +139
/// Returns the number of bytes used to encode this value's opcode. If this value was serialized
/// using a tagless encoding, returns `0`.
pub fn opcode_length(&self) -> usize {
match self.encoding {
BinaryValueEncoding::Tagged => 1,
_ => 0,
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather that setting/storing a number of opcode bytes on every value, we can derive whether an opcode byte was present. Fixes #805.

@@ -41,7 +41,7 @@ impl EncodedHeader for Header {
/// without re-parsing its header information each time.
#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) struct EncodedValue<HeaderType: EncodedHeader> {
pub(crate) encoding: ParameterEncoding,
pub(crate) encoding: BinaryValueEncoding,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ Previously, ParameterEncoding was a Copy type:

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ParameterEncoding {
/// A 'tagged' type is one whose binary encoding begins with an opcode (sometimes called a 'tag'.)
Tagged,
FlexUInt,
// TODO: tagless types, including fixed-width types and macros
}

Starting with this PR (which stubs out macro-shaped parameter support), parameters needed the ability to hold a reference to a Macro that would last as long as necessary. To achieve this, a new variant was added: MacroShaped(Rc<Macro>).

This meant that ParameterEncoding was no longer Copy. However, the only place it was used that required it to be Copy was the EncodedValue struct, which was using it as a proxy for "encoding backing this binary value". Since binary values can only be backed by value encodings (not macros), it made sense to introduce a new type for that use case.

Comment on lines -451 to +454
fn encoding(&self) -> ParameterEncoding {
fn encoding(&self) -> &ParameterEncoding {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ ParameterEncoding is no longer Copy, so accessors hand out a reference instead of a copy.

Comment on lines -437 to +438
let invoked_macro = self
.context
.macro_table()
.macro_at_address(body_invocation.invoked_macro_address)
.unwrap();
let invoked_macro = body_invocation.invoked_macro.as_ref();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ There were several places where a macro address would need to be resolved into a macro reference. These are no longer needed because the macro definitions hold an Rc.

src/lazy/expanded/template.rs Show resolved Hide resolved
Comment on lines -1006 to +981
pub fn host_macro_ref(&self) -> MacroRef<'top> {
self.context()
.macro_table()
.macro_at_address(self.host_template_address)
.unwrap()
pub fn host_macro_ref(&self) -> &'top Macro {
self.host_template.macro_ref
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ Here and below: more address lookups and unwrapping obviated by holding an actual reference.

/// A binary reader that only reads each value that it visits upon request (that is: lazily).
/// An Ion reader that only reads each value that it visits upon request (that is: lazily).
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ An incidental doc comment change to address #829.

let mut macro_table = MacroTable::new();
let mut macro_table = MacroTable::empty();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ When reading a (macro_table ...) clause, the reader no longer pre-populates the macro table with system macros.

@zslayton zslayton marked this pull request as ready for review September 5, 2024 19:42
src/lazy/expanded/compiler.rs Show resolved Hide resolved

$ion_encoding::(
(macro_table
$ion_encoding // Re-export the active encoding module's macros
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this particular case, you could also write (export double), right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes 👍

src/lazy/expanded/template.rs Show resolved Hide resolved
src/lazy/binary/raw/v1_1/value.rs Show resolved Hide resolved
@zslayton zslayton merged commit 3d6f89e into main Sep 7, 2024
33 checks passed
@zslayton zslayton deleted the qual-refs branch September 7, 2024 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants