Skip to content

Commit acb8d1e

Browse files
committed
Merge pull request #2364 from juj/musl_stdio
Musl stdio
2 parents c9823a4 + 894fdda commit acb8d1e

23 files changed

+1403
-128
lines changed

src/library.js

-75
Original file line numberDiff line numberDiff line change
@@ -2802,34 +2802,6 @@ LibraryManager.library = {
28022802
var stdin = {{{ makeGetValue(makeGlobalUse('_stdin'), '0', 'void*') }}};
28032803
return _fscanf(stdin, format, varargs);
28042804
},
2805-
sscanf__deps: ['_scanString'],
2806-
sscanf: function(s, format, varargs) {
2807-
// int sscanf(const char *restrict s, const char *restrict format, ... );
2808-
// http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html
2809-
var index = 0;
2810-
function get() { return {{{ makeGetValue('s', 'index++', 'i8') }}}; };
2811-
function unget() { index--; };
2812-
return __scanString(format, get, unget, varargs);
2813-
},
2814-
snprintf__deps: ['_formatString', 'malloc'],
2815-
snprintf: function(s, n, format, varargs) {
2816-
// int snprintf(char *restrict s, size_t n, const char *restrict format, ...);
2817-
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
2818-
var result = __formatString(format, varargs);
2819-
var limit = (n === undefined) ? result.length
2820-
: Math.min(result.length, Math.max(n - 1, 0));
2821-
if (s < 0) {
2822-
s = -s;
2823-
var buf = _malloc(limit+1);
2824-
{{{ makeSetValue('s', '0', 'buf', 'i8*') }}};
2825-
s = buf;
2826-
}
2827-
for (var i = 0; i < limit; i++) {
2828-
{{{ makeSetValue('s', 'i', 'result[i]', 'i8') }}};
2829-
}
2830-
if (limit < n || (n === undefined)) {{{ makeSetValue('s', 'i', '0', 'i8') }}};
2831-
return result.length;
2832-
},
28332805
fprintf__deps: ['fwrite', '_formatString'],
28342806
fprintf: function(stream, format, varargs) {
28352807
// int fprintf(FILE *restrict stream, const char *restrict format, ...);
@@ -2847,16 +2819,6 @@ LibraryManager.library = {
28472819
var stdout = {{{ makeGetValue(makeGlobalUse('_stdout'), '0', 'void*') }}};
28482820
return _fprintf(stdout, format, varargs);
28492821
},
2850-
sprintf__deps: ['snprintf'],
2851-
sprintf: function(s, format, varargs) {
2852-
// int sprintf(char *restrict s, const char *restrict format, ...);
2853-
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
2854-
return _snprintf(s, undefined, format, varargs);
2855-
},
2856-
asprintf__deps: ['sprintf'],
2857-
asprintf: function(s, format, varargs) {
2858-
return _sprintf(-s, format, varargs);
2859-
},
28602822
dprintf__deps: ['_formatString', 'write'],
28612823
dprintf: function(fd, format, varargs) {
28622824
var result = __formatString(format, varargs);
@@ -2868,14 +2830,10 @@ LibraryManager.library = {
28682830
#if TARGET_X86
28692831
// va_arg is just like our varargs
28702832
vfprintf: 'fprintf',
2871-
vsnprintf: 'snprintf',
28722833
vprintf: 'printf',
2873-
vsprintf: 'sprintf',
2874-
vasprintf: 'asprintf',
28752834
vdprintf: 'dprintf',
28762835
vscanf: 'scanf',
28772836
vfscanf: 'fscanf',
2878-
vsscanf: 'sscanf',
28792837
#endif
28802838

28812839
#if TARGET_ASMJS_UNKNOWN_EMSCRIPTEN
@@ -2884,22 +2842,10 @@ LibraryManager.library = {
28842842
vfprintf: function(s, f, va_arg) {
28852843
return _fprintf(s, f, {{{ makeGetValue('va_arg', 0, '*') }}});
28862844
},
2887-
vsnprintf__deps: ['snprintf'],
2888-
vsnprintf: function(s, n, format, va_arg) {
2889-
return _snprintf(s, n, format, {{{ makeGetValue('va_arg', 0, '*') }}});
2890-
},
28912845
vprintf__deps: ['printf'],
28922846
vprintf: function(format, va_arg) {
28932847
return _printf(format, {{{ makeGetValue('va_arg', 0, '*') }}});
28942848
},
2895-
vsprintf__deps: ['sprintf'],
2896-
vsprintf: function(s, format, va_arg) {
2897-
return _sprintf(s, format, {{{ makeGetValue('va_arg', 0, '*') }}});
2898-
},
2899-
vasprintf__deps: ['asprintf'],
2900-
vasprintf: function(s, format, va_arg) {
2901-
return _asprintf(s, format, {{{ makeGetValue('va_arg', 0, '*') }}});
2902-
},
29032849
vdprintf__deps: ['dprintf'],
29042850
vdprintf: function (fd, format, va_arg) {
29052851
return _dprintf(fd, format, {{{ makeGetValue('va_arg', 0, '*') }}});
@@ -2912,10 +2858,6 @@ LibraryManager.library = {
29122858
vfscanf: function(s, format, va_arg) {
29132859
return _fscanf(s, format, {{{ makeGetValue('va_arg', 0, '*') }}});
29142860
},
2915-
vsscanf__deps: ['sscanf'],
2916-
vsscanf: function(s, format, va_arg) {
2917-
return _sscanf(s, format, {{{ makeGetValue('va_arg', 0, '*') }}});
2918-
},
29192861
#endif
29202862

29212863
// ==========================================================================
@@ -4509,23 +4451,6 @@ LibraryManager.library = {
45094451
{{{ makeSetValue('intpart', 0, 'Math.floor(x)', 'float') }}};
45104452
return x - {{{ makeGetValue('intpart', 0, 'float') }}};
45114453
},
4512-
frexp: function(x, exp_addr) {
4513-
var sig = 0, exp_ = 0;
4514-
if (x !== 0) {
4515-
var sign = 1;
4516-
if (x < 0) {
4517-
x = -x;
4518-
sign = -1;
4519-
}
4520-
var raw_exp = Math.log(x)/Math.log(2);
4521-
exp_ = Math.ceil(raw_exp);
4522-
if (exp_ === raw_exp) exp_ += 1;
4523-
sig = sign*x/Math.pow(2, exp_);
4524-
}
4525-
{{{ makeSetValue('exp_addr', 0, 'exp_', 'i32') }}};
4526-
return sig;
4527-
},
4528-
frexpf: 'frexp',
45294454
finite: function(x) {
45304455
return isFinite(x);
45314456
},

src/preamble.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ var ACCEPTABLE_SAFE_HEAP_ERRORS = 0;
4141
function SAFE_HEAP_ACCESS(dest, type, store, ignore, storeValue) {
4242
//if (dest === A_NUMBER) Module.print ([dest, type, store, ignore, storeValue] + ' ' + stackTrace()); // Something like this may be useful, in debugging
4343

44-
assert(dest > 0, 'segmentation fault');
44+
if (dest <= 0) abort('segmentation fault ' + (store ? ('storing value ' + storeValue) : 'loading') + ' type ' + type + ' at address ' + dest);
4545

4646
#if USE_TYPED_ARRAYS
4747
// When using typed arrays, reads over the top of TOTAL_MEMORY will fail silently, so we must
4848
// correct that by growing TOTAL_MEMORY as needed. Without typed arrays, memory is a normal
4949
// JS array so it will work (potentially slowly, depending on the engine).
50-
assert(ignore || dest < Math.max(DYNAMICTOP, STATICTOP));
50+
if (!ignore && dest >= Math.max(DYNAMICTOP, STATICTOP)) abort('segmentation fault ' + (store ? ('storing value ' + storeValue) : 'loading') + ' type ' + type + ' at address ' + dest + '. Heap ends at address ' + Math.max(DYNAMICTOP, STATICTOP));
5151
assert(ignore || DYNAMICTOP <= TOTAL_MEMORY);
5252
#endif
5353

system/lib/libc.symbols

+11
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@
5656
W bulk_free
5757
W calloc
5858
W free
59+
T frexp
60+
T frexpf
61+
T frexpl
5962
W independent_calloc
6063
W independent_comalloc
6164
T isdigit
@@ -72,14 +75,18 @@
7275
W malloc_usable_size
7376
W mallopt
7477
W memalign
78+
T MUSL_vfprintf
7579
W posix_memalign
7680
W pvalloc
7781
W realloc
7882
W realloc_in_place
7983
T scalbn
8084
T scalbnl
85+
T memchr
8186
T memcmp
8287
T memcpy
88+
T snprintf
89+
T sprintf
8390
T strtod
8491
T strtoull
8592
T strtoll
@@ -101,3 +108,7 @@
101108
T strtold_l
102109
T tolower
103110
W valloc
111+
T vsnprintf
112+
T vsprintf
113+
T wcrtomb
114+
T wctomb

system/lib/libc/musl/src/internal/stdio_impl.h

+4
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,8 @@ int __fmodeflags(const char *);
9595
FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t);
9696
int __fclose_ca(FILE *);
9797

98+
// XXX Emscripten: musl-specific vfscanf and vfprintf live parallel to JS handwritten vfscanf and vfprintf, so musl ones are prefixed.
99+
int MUSL_vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap);
100+
int MUSL_vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap);
101+
98102
#endif

system/lib/libc/musl/src/math/frexp.c

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <math.h>
2+
#include <stdint.h>
3+
4+
double frexp(double x, int *e)
5+
{
6+
union { double d; uint64_t i; } y = { x };
7+
int ee = y.i>>52 & 0x7ff;
8+
9+
if (!ee) {
10+
if (x) {
11+
x = frexp(x*0x1p64, e);
12+
*e -= 64;
13+
} else *e = 0;
14+
return x;
15+
} else if (ee == 0x7ff) {
16+
return x;
17+
}
18+
19+
*e = ee - 0x3fe;
20+
y.i &= 0x800fffffffffffffull;
21+
y.i |= 0x3fe0000000000000ull;
22+
return y.d;
23+
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <math.h>
2+
#include <stdint.h>
3+
4+
float frexpf(float x, int *e)
5+
{
6+
union { float f; uint32_t i; } y = { x };
7+
int ee = y.i>>23 & 0xff;
8+
9+
if (!ee) {
10+
if (x) {
11+
x = frexpf(x*0x1p64, e);
12+
*e -= 64;
13+
} else *e = 0;
14+
return x;
15+
} else if (ee == 0xff) {
16+
return x;
17+
}
18+
19+
*e = ee - 0x7e;
20+
y.i &= 0x807ffffful;
21+
y.i |= 0x3f000000ul;
22+
return y.f;
23+
}
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <math.h>
2+
#include <stdint.h>
3+
#include <float.h>
4+
5+
#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
6+
7+
/* This version is for 80-bit little endian long double */
8+
9+
long double frexpl(long double x, int *e)
10+
{
11+
union { long double ld; uint16_t hw[5]; } y = { x };
12+
int ee = y.hw[4]&0x7fff;
13+
14+
if (!ee) {
15+
if (x) {
16+
x = frexpl(x*0x1p64, e);
17+
*e -= 64;
18+
} else *e = 0;
19+
return x;
20+
} else if (ee == 0x7fff) {
21+
return x;
22+
}
23+
24+
*e = ee - 0x3ffe;
25+
y.hw[4] &= 0x8000;
26+
y.hw[4] |= 0x3ffe;
27+
return y.ld;
28+
}
29+
30+
#else
31+
32+
long double frexpl(long double x, int *e)
33+
{
34+
return frexp(x, e);
35+
}
36+
37+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "stdio_impl.h"
2+
#include <string.h>
3+
4+
size_t __string_read(FILE *f, unsigned char *buf, size_t len)
5+
{
6+
char *src = f->cookie;
7+
size_t k = len+256;
8+
char *end = memchr(src, 0, k);
9+
if (end) k = end-src;
10+
if (k < len) len = k;
11+
memcpy(buf, src, len);
12+
f->rpos = (void *)(src+len);
13+
f->rend = (void *)(src+k);
14+
f->cookie = src+k;
15+
return len;
16+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#define _GNU_SOURCE
2+
#include <stdio.h>
3+
#include <stdarg.h>
4+
5+
int asprintf(char **s, const char *fmt, ...)
6+
{
7+
int ret;
8+
va_list ap;
9+
va_start(ap, fmt);
10+
ret = vasprintf(s, fmt, ap);
11+
va_end(ap);
12+
return ret;
13+
}
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include "stdio_impl.h"
2+
#include <string.h>
3+
4+
size_t __fwritex(const unsigned char *restrict s, size_t l, FILE *restrict f)
5+
{
6+
size_t i=0;
7+
8+
if (!f->wend && __towrite(f)) return 0;
9+
10+
if (l > f->wend - f->wpos) return f->write(f, s, l);
11+
12+
if (f->lbf >= 0) {
13+
/* Match /^(.*\n|)/ */
14+
for (i=l; i && s[i-1] != '\n'; i--);
15+
if (i) {
16+
if (f->write(f, s, i) < i)
17+
return i;
18+
s += i;
19+
l -= i;
20+
}
21+
}
22+
23+
memcpy(f->wpos, s, l);
24+
f->wpos += l;
25+
return l+i;
26+
}
27+
28+
// XXX Emscripten: Not used, since we are not currently using musl file IO.
29+
#if 0
30+
size_t fwrite(const void *restrict src, size_t size, size_t nmemb, FILE *restrict f)
31+
{
32+
size_t k, l = size*nmemb;
33+
if (!l) return l;
34+
FLOCK(f);
35+
k = __fwritex(src, l, f);
36+
FUNLOCK(f);
37+
return k==l ? nmemb : k/size;
38+
}
39+
#endif
40+
41+
weak_alias(fwrite, fwrite_unlocked);
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <stdio.h>
2+
#include <stdarg.h>
3+
4+
int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...)
5+
{
6+
int ret;
7+
va_list ap;
8+
va_start(ap, fmt);
9+
ret = vsnprintf(s, n, fmt, ap);
10+
va_end(ap);
11+
return ret;
12+
}
13+
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <stdio.h>
2+
#include <stdarg.h>
3+
4+
int sprintf(char *restrict s, const char *restrict fmt, ...)
5+
{
6+
int ret;
7+
va_list ap;
8+
va_start(ap, fmt);
9+
ret = vsprintf(s, fmt, ap);
10+
va_end(ap);
11+
return ret;
12+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <stdio.h>
2+
#include <stdarg.h>
3+
#include "libc.h"
4+
5+
int sscanf(const char *restrict s, const char *restrict fmt, ...)
6+
{
7+
int ret;
8+
va_list ap;
9+
va_start(ap, fmt);
10+
ret = vsscanf(s, fmt, ap);
11+
va_end(ap);
12+
return ret;
13+
}
14+
15+
weak_alias(sscanf,__isoc99_sscanf);

0 commit comments

Comments
 (0)