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

Write integer of_string from scratch #283

Merged
merged 6 commits into from
Jun 21, 2016
Merged

Conversation

pjuftring
Copy link
Contributor

While #265 did the job of supporting unsigned integers, it certainly was
no nice implementation. This version adds the same features, i.e.
allowing signed integers (as defined in the lexer) and larger unsigned
values, but is actually written from scratch and doesn't rely on the
builtin of_string anymore. This PR should close #225 if it is accepted.

While WebAssembly#265 did the job of supporting unsigned integers, it certainly was
no nice implementation. This version adds the same features, i.e.
allowing signed integers (as defined in the lexer) and larger unsigned
values, but is actually written from scratch and doesn't rely on the
builtin of_string anymore. This PR should close WebAssembly#225 if it is accepted.
@rossberg
Copy link
Member

rossberg commented May 3, 2016

Hm, this code seems to cause assertion failures on invalid input. That should never happen. Can you change it to raise normal exceptions, preferably the same as the original?

Additional nit: there are plenty of redundant parens in the code.

@pjuftring
Copy link
Contributor Author

I removed all redundent parentheses, that I could find, and added a "try" to catch my asserts.

@rossberg
Copy link
Member

rossberg commented May 4, 2016

Please do not use assertions like this. Assertions are intended for checking invariants (pre/post-conditions) and thus the internal consistency of code, not for checking the validity of input data. An assertion failure is supposed to signal a program bug.

Also, please do never write catch-all try handlers. That is a guarantee for unintentionally masking unrelated errors. Only match the exceptions you expect to get and intend to handle.

@pjuftring
Copy link
Contributor Author

Oh, sorry, I didn't know that. I hope, that I solved it correctly.

let of_string = Rep.of_string
(* This implementation allows leading signs and unsigned values *)
let of_string x =
let len = String.length x in
Copy link
Member

Choose a reason for hiding this comment

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

Hint: let open Rep in allows to omit the repeated module prefix.

@rossberg
Copy link
Member

Thanks! I left a few comments. Also, it would be good to have a few additional tests, especially for boundary conditions.

@pjuftring
Copy link
Contributor Author

I addressed the comments, but there's some stuff I'm not sure about:

  • Did I move the right helper functions out of of_int?
  • Do I raise the correct exceptions in my helper functions?
  • How can I test the bounds of my implementation sufficently, when I can't catch lexer-errors within the test-file?

else failwith "unexpected digit"

let neg_safe x =
if lt_s (sub x Rep.one) Rep.minus_one then raise Numerics.IntegerOverflow;
Copy link
Member

Choose a reason for hiding this comment

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

Since this is called only once, I'd just inline it. And just use failwith, too.

@rossberg
Copy link
Member

Thanks, looks pretty good now, just a few nits left.

As for testing, you can write test files named xyz.fail.wast, which the runner expects to fail. If you also want to check the specific error output then you have to create associated expected-output files (though that's perhaps overkill in this case).

if '0' <= c && '9' >= c then 0x30
else if 'a' <= c && 'f' >= c then 0x61 - 10
else if 'A' <= c && 'F' >= c then 0x41 - 10
else failwith "unexpected digit"
Copy link

Choose a reason for hiding this comment

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

fwiw, I find the following easier to read :

let parse_hexdigit = function
  | '0' .. '9' as c ->  Char.code c - Char.code '0'
  | 'a' .. 'f' as c ->  0xa + Char.code c - Char.code 'a' 
  | 'A' .. 'F' as c ->  0xa + Char.code c - Char.code 'A'
  | _                  ->  failwith "unexpected digit"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think, this is a lot prettier than my version @rossberg-chromium shall I copy this?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, looks good.

@pjuftring
Copy link
Contributor Author

I added some tests and hoisted parse_decdigit and require.

@@ -250,7 +249,12 @@ struct
in
match x.[0] with
| '+' -> parse_int 1
| '-' -> neg_safe (parse_int 1)
| '-' ->
begin
Copy link
Member

Choose a reason for hiding this comment

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

Nit: you don't need the begin/end here

@rossberg
Copy link
Member

Thanks! LGTM modulo a last couple of nits

@rossberg rossberg merged commit 3497686 into WebAssembly:master Jun 21, 2016
ngzhian added a commit to ngzhian/spec that referenced this pull request Nov 4, 2021
Decided to cheat a little bit, and squeeze v8x16.swizzle into the i8x16
ast node, so that we don't have to create a new v8x16 data type.
Semantically it means the same thing, v8x16 is called that way since it
doesn't treat the underlying data as any particular type, so treating it
as int will work too.
dhil pushed a commit to dhil/webassembly-spec that referenced this pull request Oct 3, 2023
rossberg added a commit that referenced this pull request Feb 28, 2024
* Reintroduce exnref

* Fix type_of

* Simplify parser

* Implement 1b

* Change opcodes for catch/catch_all to avoid conflict

* Put catch clauses first

* Remove obsolete Delegating cases

* Change exn type opcode to -0x17

* Switch to B' variant

* [interpreter] Add boilerplate for ref.exn result patterns

* [ci] Deactivate node run, since it can't handle try_table yet

* Try -> TryTable in AST

* [spec] Update spec for option B' (#283)

* Deactivate Bikeshed

* [spec/tests] Specification of legacy exceptions + tests (#284)

* [legacy] Create specification doc for legacy exception handling

* [test] Create infra for legacy tests
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.

ml-proto does not accept the full range of unsigned i32 or i64 constants
3 participants