Woot! Hello world.

7,268 views
Skip to first unread message

Mike Acton

unread,
May 6, 2012, 5:32:59 AM5/6/12
to native-cli...@googlegroups.com
In my quixotic quest to make porting stuff to NaCl more straightforward and the API (or app's use of it) more sensible, I decided to begin at the beginning.

I wanted to get this to work:
#include <stdio.h>

int main( int argc, char** argv )
{
  printf("Hello, World!\n");
  return (0);
}

Surely, that couldn't be asking too much? 

We'll here you go. It's not much to look at but I have to say that I'm pretty excited to see it! :)

Inline image 1

So what had do be done?
  • main() is already taken by NaCl, so after the file is compiled objcopy is used to rename main to something else.
  • I made a quick library (nativeblue) that does the work (hello.c just links with this)
    • it provides all the entry points that the NaCl SDK needs.
    • it spawns a "main" thread and in that thread's entry point calls the renamed main function.
    • write() is wrapped. (a la /naclports/src/experimental/libav/photo/)
    • write() copies fd+buffer to a queue to be processed later; write can be called from whatever thread.
    • Note: printf eventually calls write with fileno(stdout).
    • In the render loop in the NaCl main thread, anything in that write queue is flushed out and sent to the browser using MessagingPost
  • I borrowed hterm from the hterm/ssh project: http://git.chromium.org/gitweb/?p=chromiumos/platform/assets.git;a=blob;f=chromeapps/hterm/doc/faq.txt;h=f0d3007f9fc54c7331f68293b7fae5f5b71214ff;hb=HEAD
  • finally, javascript recieves the message and if the dev in the message is "/dev/stdout" (which fileno(stdout) is changed to) it's sent to the terminal output.
Lots of work left to make it more generally useful, cleanup, etc. But definitely takes me the first big step to porting normal "headless" apps and perhaps using the same source both client and server side.

If you want to check it out: https://github.com/macton/nativecolors
And you can see that hello.c is exactly what you'd expect: https://github.com/macton/nativecolors/blob/master/examples/hello_nativeblue_hterm/hello.c

Mike.

image.png

Mihai Tudorache

unread,
May 6, 2012, 4:20:27 PM5/6/12
to native-cli...@googlegroups.com
This is great stuff! Keep it up! 


Mike.

--
You received this message because you are subscribed to the Google Groups "Native-Client-Discuss" group.
To post to this group, send email to native-cli...@googlegroups.com.
To unsubscribe from this group, send email to native-client-di...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/native-client-discuss?hl=en.

image.png

Mark Seaborn

unread,
May 6, 2012, 4:37:42 PM5/6/12
to native-cli...@googlegroups.com
On 6 May 2012 02:32, Mike Acton <mac...@gmail.com> wrote:
  • main() is already taken by NaCl, so after the file is compiled objcopy is used to rename main to something else.

main() isn't reserved by NaCl, by the way.  In the SDK, main() is just a convenience function that calls PpapiPluginMain() (see src/untrusted/irt_stub/plugin_main_irt.c in the NaCl source tree).  If you provide your own main(), it will just override the version that is provided by libppapi.a/libppapi.so.

Mark

Mike Acton

unread,
May 6, 2012, 4:54:33 PM5/6/12
to native-cli...@googlegroups.com
main() isn't reserved by NaCl, by the way.  In the SDK, main() is just a convenience function that calls PpapiPluginMain() (see src/untrusted/irt_stub/plugin_main_irt.c in the NaCl source tree).  If you provide your own main(), it will just override the version that is provided by libppapi.a/libppapi.so.


I didn't dig into it too much, but I initially just tried to override main() and it caused the plugin to crash. It worked fine if I wrapped it and called the "real main" when I wasn't intentionally calling it. So it's getting called somewhere directly. But good to know that there *should* be a way I can do it. I'll have to take a look at that source, thanks!

Mike.

Victor Khimenko

unread,
May 6, 2012, 5:06:05 PM5/6/12
to native-cli...@googlegroups.com
On Mon, May 7, 2012 at 12:54 AM, Mike Acton <mac...@gmail.com> wrote:
main() isn't reserved by NaCl, by the way.  In the SDK, main() is just a convenience function that calls PpapiPluginMain() (see src/untrusted/irt_stub/plugin_main_irt.c in the NaCl source tree).  If you provide your own main(), it will just override the version that is provided by libppapi.a/libppapi.so.

I didn't dig into it too much, but I initially just tried to override main() and it caused the plugin to crash.

If you override main and don't initialize PPAPI in your version then plugin just never finishes the initialization and browser decides at some point that it's broken. You must call PpapiPluginMain() explicitly if you override main().

Mike Acton

unread,
May 6, 2012, 5:11:12 PM5/6/12
to native-cli...@googlegroups.com
You must call PpapiPluginMain() explicitly if you override main().

Ah, I get it. Then there's no real benefit to me doing it that way here. That will put main() in the wrong thread (in the NaCl thread which is definitely *not* where it should be) and I'd still have to change the source in hello world to call PpapiPluginMain(). But it's good information, maybe another way to make use of that. Thanks, dude. :)

Mike.

Mike Acton

unread,
May 6, 2012, 5:23:36 PM5/6/12
to native-cli...@googlegroups.com
That will put main() in the wrong thread...

Actually that's a question: Will the PPAPI callbacks, functions, etc. happen/work in whatever thread PpapiPluginMain() is called from? Or is there some other reason it has to be in the "main" thread?

Victor Khimenko

unread,
May 7, 2012, 2:52:11 AM5/7/12
to native-cli...@googlegroups.com
On Mon, May 7, 2012 at 1:23 AM, Mike Acton <mac...@gmail.com> wrote:
That will put main() in the wrong thread...

Actually that's a question: Will the PPAPI callbacks, functions, etc. happen/work in whatever thread PpapiPluginMain() is called from? Or is there some other reason it has to be in the "main" thread?

No other reason except for convenience. It was easier to only support PpapiPluginMain() on main thread and, really, what the ability to call it on other threads will buy us?

Landroid

unread,
May 7, 2012, 6:12:54 AM5/7/12
to native-cli...@googlegroups.com
so basically you made an online C compiler that runs on google chrome?

Landroid

unread,
May 7, 2012, 6:16:18 AM5/7/12
to native-cli...@googlegroups.com

why was my comment deleted?, i just wanted to know what your app does!

On Sunday, 6 May 2012 10:32:59 UTC+1, Mike Acton wrote:

Mike Acton

unread,
May 8, 2012, 1:36:00 AM5/8/12
to native-cli...@googlegroups.com
so basically you made an online C compiler that runs on google chrome?

It's not clear what you're asking. 

If you're asking "What is Native Client?" 

If you're asking about the app that runs the compiler "in" the browser? (Which it's really not, it's on the server)

If you're asking about this particular thread:
  • It's really about a specific way of writing code - which is to say, a more standard approach rather than the more slightly obtuse NaCl SDK setup.

Mike. 


Mike Acton

unread,
May 8, 2012, 1:46:21 AM5/8/12
to native-cli...@googlegroups.com
No other reason except for convenience. It was easier to only support PpapiPluginMain() on main thread and, really, what the ability to call it on other threads will buy us?

Who's convenience? When you say buy "us," to whom are you referring?

Mike Acton

unread,
May 10, 2012, 5:56:29 AM5/10/12
to native-cli...@googlegroups.com
Bonus: Since I have both a main loop and stdout being redirected to hterm, some things become much easier.

Hterm accepts (x-term) ansi escape codes, so I started a port of pdcurses that just uses those. The demos for pdcurses then just compile straight out of the box. No changes to the actual app source necessary:

Inline image 1

Animates and everything. ;)

It's a *super* rough start to the pdcurses port, but really cool to see the demo apps work without any changes to their source

There's not much to it yet, but if you're interested: https://github.com/macton/nativecolors/tree/master/pdcurses-3.4

This is the most awesomely backward setup ever. It's native code essentially running on a javascript OS kernel. ;)

Mike.


image.png

Mark Seaborn

unread,
May 10, 2012, 11:32:49 AM5/10/12
to native-cli...@googlegroups.com
On 6 May 2012 14:23, Mike Acton <mac...@gmail.com> wrote:
That will put main() in the wrong thread...

Actually that's a question: Will the PPAPI callbacks, functions, etc. happen/work in whatever thread PpapiPluginMain() is called from?

I think PpapiPluginMain() will work in whatever thread it is called from, as long as it is only called once.  This thread will become the "PPAPI main thread".

But yes, PPAPI callbacks will happen in whatever thread PpapiPluginMain() is called on.  Certainly, PpapiPluginMain() will not create any new threads to run PPAPI callbacks on.  The ABI requires this because of how Thread Local Storage is set up.  The user code's TLS is set up by the user code's threading library, and the IRT library (provided as part of Chromium but running as untrusted code) does not know how to set up TLS on the user code's behalf.  (There is one exception, which is the audio thread for PPB_Audio.  User code passes pointers to its pthread_create()/pthread_join() functions to the IRT, and these are for creating audio threads for PPB_Audio only.)

Cheers,
Mark

Mike Acton

unread,
May 11, 2012, 3:38:02 AM5/11/12
to native-cli...@googlegroups.com
I think PpapiPluginMain() will work in whatever thread it is called from, as long as it is only called once.  This thread will become the "PPAPI main thread".

Good to know. Thanks, Mark.

Now for a demo!
Run the demo yourself (Chrome 19+):

Still got a *few* more functions to fill in before curses is totally ready, though. ;)

Inline image 1

image.png
Reply all
Reply to author
Forward
0 new messages