Commit faad86d7 authored by Will Hilton's avatar Will Hilton

Implemented `putchar` and `putbuffer`.

parent 093624e2
function (o) {
if (o.OpenMP.id === 0) {
// This runs in about 550ms on my machine.
// Interestingly, I get the same performance buffering "manually" like this,
// as I do by leaving stdout buffering enabled in the C layer and running
// the `stdout-unbuffered` demo. Using both C buffering and manual buffering
// doesn't provide any noticeable speedup either.
//
// So why add the complexity of buffering at the C layer if buffering in
// the JS layer is equally performant? For now then I'm disabling buffering
// in the C layer. Moving output buffering into the JS layer allows you the
// developer more flexibility and power to tweak the heck out of it for performance.
// And more importantly, your output is actually output when you put it out!
// None of this "Oh, well if you were serious, you need to add process.stdout.flush()
// after your console.log" which causes beginners so much pain.
//
// Buffering is an optimization. Do it when writing becomes a bottleneck, not
// by default on fricking everything.
var c;
var chars = []
for (var i = 0x20; i < 0x7E; i++) {
for (var n = 0; n < 10000; n++) {
chars.push(i)
}
o.modules.putbuffer(new Uint8Array(chars))
chars = []
}
}
}
function (o) {
if (o.OpenMP.id === 0) {
// On my system, this takes 18.0 seconds to run!
// This is because by default we are not buffering output.
// See `stdout-buffered` example next.
var c;
for (var i = 0x20; i < 0x7E; i++) {
for (var n = 0; n < 10000; n++) {
o.modules.putchar(i)
}
}
}
}
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "duktape/duktape.h"
#include "c_putbuffer.h"
duk_size_t c_putbuffer (duk_context *ctx) {
char * buffer;
duk_size_t length;
buffer = duk_require_buffer_data(ctx, 0, &length);
size_t written = fwrite(buffer, sizeof(char), length, stdout);
if (written != length) {
if (feof(stdout)) {
duk_push_error_object(ctx, errno, "EOF");
return 1;
}
if (ferror(stdout)) {
if (errno == EWOULDBLOCK) {
duk_push_undefined(ctx);
return 1;
}
duk_push_error_object(ctx, errno, strerror(errno));
clearerr(stdout);
return duk_throw(ctx);
}
return duk_error(ctx, 999, "Unhandled situation in c_putbuffer.");
}
duk_push_int(ctx, written);
return 1;
}
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "duktape/duktape.h"
#include "c_putchar.h"
int c_putchar (duk_context *ctx) {
int c = duk_require_int(ctx, 0);
if (fputc(c, stdout) != EOF) {
duk_push_int(ctx, c);
return 1;
}
if (feof(stdout)) {
duk_push_error_object(ctx, errno, "EOF");
return 1;
}
if (ferror(stdout)) {
if (errno == EWOULDBLOCK) {
duk_push_undefined(ctx);
return 1;
}
duk_push_error_object(ctx, errno, strerror(errno));
clearerr(stdout);
return duk_throw(ctx);
}
return duk_error(ctx, 999, "Unhandled situation in c_putchar.");
}
......@@ -37,6 +37,8 @@ int main(int argc, char *argv[] /* char *environ[] */) {
#ifdef UNIX
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
flags = fcntl(STDOUT_FILENO, F_GETFL, 0);
fcntl(STDOUT_FILENO, F_SETFL, flags | O_NONBLOCK);
#endif
if (argc < 2) {
......@@ -97,6 +99,10 @@ int main(int argc, char *argv[] /* char *environ[] */) {
duk_put_prop_string(ctx, -2, "sleep");
duk_push_c_function(ctx, c_getchar, 0);
duk_put_prop_string(ctx, -2, "getchar");
duk_push_c_function(ctx, c_putchar, 1);
duk_put_prop_string(ctx, -2, "putchar");
duk_push_c_function(ctx, c_putbuffer, 1);
duk_put_prop_string(ctx, -2, "putbuffer");
app_push_netLib(ctx);
duk_put_prop_string(ctx, -2, "netLib");
duk_put_prop_string(ctx, -2, "modules");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment