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

js: fix libyaml bindings #7918

Merged
merged 1 commit into from May 31, 2023
Merged

js: fix libyaml bindings #7918

merged 1 commit into from May 31, 2023

Conversation

tpetr
Copy link
Collaborator

@tpetr tpetr commented May 30, 2023

This PR fixes memory alignment issues that was preventing YAML parsing from working properly. TL;DR: ocaml-yaml uses ocaml-ctypes to generate bindings for the libyaml library. Since this is done at compile time, the memory offsets are calculated based off of the build machine (64-bit address space --> 8 byte pointer size). WebAssembly, however, is 32-bit (4 bytes), and this mismatch prevented us from interfacing with the library properly.

To fix, we override the memory offsets in JavaScript (exploiting its inherent mutability) at startup. This is a little weird, is much faster than figuring out how to cross-compile ocaml-yaml against a 32-bit architecture.

There is a weird off-by-one issue with the index of the end token in Yaml_to_generic, but I'll fix in a separate PR if it proves to be an issue.

test plan:

  • make test
  • confirm js/examples/yaml.html works properly

@tpetr tpetr requested a review from aryx May 30, 2023 15:39
@aryx
Copy link
Collaborator

aryx commented May 30, 2023

Could be worth asking on discuss.ocaml.org if there's an easier way to fix the issue.

Copy link
Collaborator

@aryx aryx left a comment

Choose a reason for hiding this comment

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

Lots of magic constants and hardcoded array indexes ...
Would be better to document those at least.


let fix_libyaml_field_offsets_for_wasm () =
(* mark *)
override_yaml_ctypes_field_offset Yaml_types.M.Mark.line 4;
Copy link
Collaborator

Choose a reason for hiding this comment

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

How did you end up with all those magic constants below?
you disassembled the resulting WASM?
If tomorrow the bus hit you, how someone else can update this code if say the libyaml C library changes a little bit?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yep, when I was investigating this I created a macro that I used to print the offset of every struct field. I'll restructure and add more comments to make it clearer what's going on here.

@tpetr
Copy link
Collaborator Author

tpetr commented May 30, 2023

Could be worth asking on discuss.ocaml.org if there's an easier way to fix the issue.

Good idea, if folks have a cleaner solution I'll apply it in another PR 👍

edit: posted question here: https://discuss.ocaml.org/t/using-ocaml-ctypes-with-webassembly/12279

@aryx aryx merged commit 6e0ed7a into develop May 31, 2023
40 checks passed
@aryx aryx deleted the tom/fix-yaml2 branch May 31, 2023 07:06
(* event *)
override_yaml_ctypes_field_offset Yaml_types.M.Event.data 4;
override_yaml_ctypes_field_offset Yaml_types.M.Event.start_mark 32;
override_yaml_ctypes_field_offset Yaml_types.M.Event.start_mark 44;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

argh, typo

tpetr added a commit that referenced this pull request Jun 5, 2023
YAML parsing was fixed in
#7918 and
#7931, but I didn't catch
that node start/end positions were incorrect. This was because in
`ctypes_read()` we were returning a JS int when we should have been
returning `UInt32` instead.

test plan:
- confirmed locally that the playground works properly w/ a yaml pattern
- added unit test to confirm yaml check works and returns correct
positions
- `dune build && make test` succeeded
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants