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

Add stdio.write import for writing a sequence of bytes to stdout #121

Closed
wants to merge 4 commits into from

Conversation

kg
Copy link
Contributor

@kg kg commented Oct 9, 2015

No description provided.

(module
(import $write "stdio" "write" (param i32 i32))

(memory 4096 4096 (segment 0 "hello, world!\0D\0A\00"))
Copy link
Member

Choose a reason for hiding this comment

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

In C/C++ code compiled to wasm, strings don't contain the "\0D", because stdout is in "text" mode, which ordinarily means that the C library translates newline into carriage-return-line-feed on Windows. However in wasm's case, the C library won't know that it's running on Windows, so it won't know that it has to do this. I think it's best if stdio.write handles this itself so that wasm programs don't have to worry about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That would make it unusable for binary data.

Copy link
Member

Choose a reason for hiding this comment

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

The alternative is to be unusable for text strings in C/C++. How about a separate function for binary data?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

write is a base primitive for writing whatever to stdout. if you want to print text, your stdlib would do any transforms like \n -> \r\n on windows.

Copy link
Member

Choose a reason for hiding this comment

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

How should the stdlib detect that is is on Windows?

Copy link
Member

Choose a reason for hiding this comment

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

What I'm actually concerned about here is that there's wasm code with a \r\n in it, which I find very concerning. I assumed you put it there because of Windows; if not, then can we just remove the \r?

Copy link
Member

Choose a reason for hiding this comment

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

IIUC this is meant to test that \r is unchanged. I strongly believe that fwrite shouldn't change the bits it's given, so the test should exist in some form. Are you suggesting the form be changed?

Copy link
Member

Choose a reason for hiding this comment

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

Would you mind making a separate test for binary output then? I saw this test as the "hello world" test that would be used as an example of what wasm code looks like. I don't want to risk anyone thinking that wasm code needs a \r to print hello world.

As you say, a separate test for binary output could test \0 and other interesting characters.

Copy link
Contributor

Choose a reason for hiding this comment

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

"write" for binary data, "print" for text?

On Fri, Oct 9, 2015 at 12:34 PM, Dan Gohman notifications@github.com
wrote:

In ml-proto/test/stdio_write.wast
#121 (comment):

@@ -0,0 +1,14 @@
+(module

  • (import $write "stdio" "write" (param i32 i32))
  • (memory 4096 4096 (segment 0 "hello, world!\0D\0A\00"))

Would you mind making a separate test for binary output then? I saw this
test as the "hello world" test that would be used as an example of what
wasm code looks like. I don't want to risk anyone thinking that wasm code
needs a \r to print hello world.

As you say, a separate test for binary output could test \0 and other
interesting characters.


Reply to this email directly or view it on GitHub
https://github.com/WebAssembly/spec/pull/121/files#r41669560.

Copy link
Member

Choose a reason for hiding this comment

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

I think separate test files is fine.

@kg
Copy link
Contributor Author

kg commented Oct 10, 2015

Welp. Looks like windows ocaml is doing line normalization. I probably need to find another way to write raw bytes to stdout.

======================================================================
FAIL: test/stdio_write.wast (__main__.RunTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./runtests.py", line 37, in <lambda>
    return lambda self : self._runTestFile(*rec)
  File "./runtests.py", line 34, in _runTestFile
    self.assertEqual(expectedText, actualText)
AssertionError: '\x89PNG\r\n\x1a\n\x00' != '\x89PNG\r\r\n\x1a\r\n\x00'

@pjuftring
Copy link
Contributor

I added the line

set_binary_mode_out stdout true;

And it seems to work, but I don't know if it does on linux.

@kg
Copy link
Contributor Author

kg commented Oct 12, 2015

Switched to print_bytes, that might disable newline conversion. Or it might not, since Bytes is initialized from char (?????)

@rossberg
Copy link
Member

I don't think print_bytes disables conversion (have you tried it?).

It's just like in the C or C++ stdlibs: newline conversion is a property of the stream, not the source. And stdout is a text stream. If you want to disable newline conversion on Windows, you need to go to binary mode. As @pjuftring pointed out, you can use set_binary_mode_out to change the mode after the fact. (Just make sure to switch it back before the function returns, so that you don't break other output to stdout.)

@kg
Copy link
Contributor Author

kg commented Oct 13, 2015

I don't think print_bytes disables conversion (have you tried it?).

Nope, I don't have access to Windows at work :-) I'll come up with a fix on my Windows machine.
Good point about the pattern match, didn't realize you could use them on lists.

@kg
Copy link
Contributor Author

kg commented Oct 13, 2015

Yeah, print_bytes doesn't disable conversion. Weird :( I'll just do set_binary_mode_out. One caveat is that you can't query the current binary mode state, so there's no way to restore it after setting it - as a result this function will trample over the output mode. I don't like that, but I can't see an alternative.

Your suggested pattern-match doesn't seem like it type-checks, at least as written. I'm not actually sure why, as it looks correct to me.

Error: This expression has type
         Eval.instance ->
         ((int32, 'a, 'b, 'c) Values.op * (int32, 'd, 'e, 'f) Values.op) list ->
         'g option
       but an expression was expected of type
         Eval.instance -> Values.value list -> 'h option
       Type (int32, 'a, 'b, 'c) Values.op * (int32, 'd, 'e, 'f) Values.op
       is not compatible with type
         Values.value = (I32.t, I64.t, F32.t, F64.t) Values.op

Should I just update the PR without using the pattern-match, or do you not want to merge without it? The pattern-match does seem like the right way to do this.

@rossberg
Copy link
Member

Ah, sorry, I keep forgetting that OCaml separates list items by semicolons. That should fix it.

…rmalized. Iterate using Int64 (since the offset and count are Int64)
@kg
Copy link
Contributor Author

kg commented Oct 13, 2015

OK, I've revised it so that it works correctly on Windows now.

Had some confusion over the fact that to disable newline normalization, you do set_binary_mode_out stdout false - the meaning of the arg is reversed.

@rossberg
Copy link
Member

lgtm

@@ -1,9 +1,50 @@
open Source
open Eval
Copy link
Member

Choose a reason for hiding this comment

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

From a readthrough, the only use of the Eval module in this file is the Eval.memory_for_module. Can this open be removed?

@rossberg
Copy link
Member

Closing, there doesn't seem to be a strong need

@rossberg rossberg closed this Feb 25, 2016
Connicpu pushed a commit to Connicpu/wasm-spec that referenced this pull request May 11, 2020
dhil pushed a commit to dhil/webassembly-spec that referenced this pull request Mar 2, 2023
…bly#121)

Included in this PR:

- Detailed core formal spec additions aiming to fully implement:
  + the "informal formal" core spec laid out by Andreas @rossberg here: WebAssembly/exception-handling#87 (comment) and
  + the core spec outlined in the [proposal overview](https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md), while removing the mention of "events" everywhere but in the binary format ,
  + prose for the above in: syntax, validation, execution, binary format, text format, and the appendix, as well as an example for throw contexts.
- Travis-ci build status icon to `README.md`. The contents of this PR get built and deployed on my fork's github page successfully, using [the howto instructions](https://github.com/WebAssembly/proposals/blob/master/howto.md#setting-up-travis-and-github-page).

Not included in this PR:

- Neither the new values representing unresolved throw contexts, nor the additional rules for the execution contexts, which we discussed in WebAssembly#87, are added here. I plan to add these separately.
- No JS API/Web API changes.

Side comments:

- In [document/core/text/types.rst](https://ioannad.github.io/exception-handling/core/text/types.html#text-refedtype): I'm not sure whether `refedtype ::= ... | event ⇒ exnref` should have `event` there or something else (perhaps `exception`?) However, since currently the only events are exceptions, this is probably not really an issue.
- The "informal formal spec" defines the administrative instruction which represents an exception package as `exnref`, i.e.,  the same name as the type. I called this administrative instruction `ref.exn` instead for two reasons;  to match the style of `ref.null` and `ref.extern`, and to avoid ambiguity in the discussions.
- I removed multi-value mentions from `README.md` because multi-value is now part of the main spec. For the same reason I didn't add "multi-value" to the list of included proposals at the top of the core spec landing page.
rossberg pushed a commit that referenced this pull request Sep 4, 2024
Fix expected result type in relaxed dot product 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.

6 participants