Open chqrlie opened 2 months ago
I'm sorta lukewarm on this. Prior experiences with homegrown (s)printf implementations have been a mixed bag.
I mean, I get the appeal but complex features need to pay for themselves and I'm not quite seeing that. Is there one killer feature in particular that made you start on this?
I'm sorta lukewarm on this. Prior experiences with homegrown (s)printf implementations have been a mixed bag.
I mean, I get the appeal but complex features need to pay for themselves and I'm not quite seeing that. Is there one killer feature in particular that made you start on this?
Hi @bnoordhuis
I understand your concerns, I have invested a hefty amount of work into this, both for pleasure (I like to hack printf
for breakfast*) and for actual goals in this project:
printf
implementations that have non standard or implementation defined behavior, not to mention obsolete implementations that lack C99 support.v8.sh
failures on my laptop (addressed in #400):
=== number-tostring-func.js
+Failure (0.5.toFixed(0)): expected <"1"> found <"0">
+Failure ((-0.5).toFixed(0)): expected <"-1"> found <"-0">
=== number-tostring-small.js
=== number-tostring.js
+Failure (0.5.toFixed(0)): expected <"1"> found <"0">
+Failure ((-0.5).toFixed(0)): expected <"-1"> found <"-0">
=== numops-fuzz-part1.js
snprintf
multiple times with varying precision settings to implement the minimum representation and the round away from zero semantics that are not supported by snprintf
portably and are difficult to emulate.fesetround()
, which may not be thread-safe for pre-C23 targets.printf
uses the current locale for floating point conversions, which may produce incorrect output if the decimal point differs from '.'
. Changing the locale is not thread safe and passing the locale dynamically is not portable. If the host application uses locales for its own purposes, QuickJS would be affected node
. My implementation of floating point conversions will help with that too.js_strtod
) should also be rewritten to ensure proper rounding in a portable fashion to all targets and remove locale dependencies. This would also avoid the copying pass to remove the _
separators.JSAtoms
, JSStrings
and possibly other objects allow for much simpler code for traces and error message construction.The implementation in the current PR still uses the library I am testing a complete version snprintf
for floating point values, butand will post that shortly. I shall also add a complete test suite with 450000 tests: qjs_printf
passes and is on average 50% faster than the C library versions on Apple and linux).
As you have noticed, Fabrice and I tried hard to avoid depending on other packages to keep the project self contained and reliable. printf
is a remaining stone is our shoes that I would like to get rid of too.
(*) Implementing printf
for breakfast is a good challenge for C experts, getting all the integer conversions right is feasible, but handling the floating point conversions correctly (and efficiently) does require time and effort :)
@chqrlie I don't have much time this week and (maybe) next week (school holidays) but I'll try to review this at the first possible opportunity.
@chqrlie I don't have much time this week and (maybe) next week (school holidays) but I'll try to review this at the first possible opportunity.
Thank you. I have not plugged js_dtoa
into this yet, so you may want to wait for a final version... I'll keep you posted.
Add custom printf version
js_snprintf
,js_printf
... to handle extra conversions:%b
and%B
%oa
and%#oa
to convertJSAtom
values%ps
to convertJSString
valuesdbuf_vprintf_fun
replaceabledbuf_printf
handlerJS_DumpString
toJS_FormatString
to convertJSSAtom
to quoted stringsJS_AtomGetStrRT
toJS_FormatAtom
to convertJSAtom
to stringsJS_AtomGetStr
to return direct string pointer for builtin atomsprint_atom
%b
,%B
andw
length modifier instd.printf
JS_ThrowTypeErrorAtom
andJS_ThrowSyntaxErrorAtom
is_lower_ascii()
andto_lower_ascii()
vsnprintf
calls indbuf_vprintf_default