Liu Song’s Projects


~/Projects/quickjs

git clone https://code.lsong.org/quickjs

Commit

Commit
0e8fffd4de4a10f498f46cd0e99f53da6a523542
Author
bellard <6490144+[email protected]>
Date
2020-09-06 18:57:11 +0200 +0200
Diffstat
 Changelog | 12 
 Makefile | 41 
 TODO | 5 
 VERSION | 2 
 doc/jsbignum.html | 774 ++-----
 doc/jsbignum.texi | 592 +---
 doc/quickjs.html | 15 
 doc/quickjs.texi | 8 
 examples/pi_bigdecimal.js | 17 
 libbf.c | 1470 ++++++++-----
 libbf.h | 131 
 qjs.c | 27 
 qjsc.c | 27 
 qjscalc.js | 1789 +++++++++------
 quickjs-atom.h | 26 
 quickjs-libc.c | 16 
 quickjs-opcode.h | 4 
 quickjs.c | 4164 ++++++++++++++++++++++---------------
 quickjs.h | 16 
 repl.js | 39 
 test262_errors.txt | 13 
 tests/test_bignum.js | 177 +
 tests/test_op_overloading.js | 207 +
 tests/test_qjscalc.js | 23 

2020-01-19 release


diff --git a/Changelog b/Changelog
index 73b125005d6e94a5663af39830e6335397002292..637dce18aa2c4af0ada572c65a7d4a38ae2ba759 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,15 @@
+2020-01-19:
+
+- keep CONFIG_BIGNUM in the makefile
+- added os.chdir()
+- qjs: added -I option
+- more memory checks in the bignum operations
+- modified operator overloading semantics to be closer to the TC39
+  proposal
+- suppressed "use bigint" mode. Simplified "use math" mode
+- BigDecimal: changed suffix from 'd' to 'm'
+- misc bug fixes
+
 2020-01-05:
 
 - always compile the bignum code. Added '--bignum' option to qjs.




diff --git a/Makefile b/Makefile
index e402d6b4c7af61712975b6c60a99bd4a2e476406..88e605b33e54cf8f9d6491e1910b75c33ab122af 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 #
 # QuickJS Javascript Engine
 # 
-# Copyright (c) 2017-2019 Fabrice Bellard
+# Copyright (c) 2017-2020 Fabrice Bellard
-# Copyright (c) 2017-2019 Charlie Gordon
+# Copyright (c) 2017-2020 Charlie Gordon
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
@@ -48,6 +48,9 @@ #CONFIG_PROFILE=y
 # use address sanitizer
 #CONFIG_ASAN=y
 # QuickJS Javascript Engine
+LDFLAGS+=-fsanitize=address
+CONFIG_BIGNUM=y
+# QuickJS Javascript Engine
 #
 OBJDIR=.obj
 
@@ -95,6 +98,9 @@ ifdef CONFIG_WERROR
 CFLAGS+=-Werror
 endif
 DEFINES:=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION)\"
+ifdef CONFIG_BIGNUM
+DEFINES+=-DCONFIG_BIGNUM
+endif
 CFLAGS+=$(DEFINES)
 CFLAGS_DEBUG=$(CFLAGS) -O0
 CFLAGS_SMALL=$(CFLAGS) -Os
@@ -154,12 +160,16 @@ endif
 
 all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS)
 
+QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o
+# QuickJS Javascript Engine
 #
+QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS)
+ifdef CONFIG_BIGNUM
+#CONFIG_WERROR=y
 #
-# in the Software without restriction, including without limitation the rights
+#CONFIG_WERROR=y
 # QuickJS Javascript Engine
-#
-QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(OBJDIR)/qjscalc.o $(QJS_LIB_OBJS)
+endif
 
 LIBS=-lm
 ifndef CONFIG_WIN32
@@ -219,7 +229,7 @@ libquickjs.a: $(patsubst %.o, %.nolto.o, $(QJS_LIB_OBJS))
 	$(AR) rcs $@ $^
 endif # CONFIG_LTO
 
-repl.c: $(QJSC) repl.js 
+repl.c: $(QJSC) repl.js
 	$(QJSC) -c -o $@ -m repl.js
 
 qjscalc.c: $(QJSC) qjscalc.js
@@ -305,8 +315,12 @@ # example of static JS compilation
 HELLO_SRCS=examples/hello.js
 HELLO_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
            -fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
+           -fno-date -fno-module-loader
 # QuickJS Javascript Engine
-#
+LDEXPORT=-rdynamic
+# 
+# Copyright (c) 2017-2019 Charlie Gordon
+endif
 
 hello.c: $(QJSC) $(HELLO_SRCS)
 	$(QJSC) -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS)
@@ -378,12 +392,21 @@ 	./qjs tests/test_loop.js
 	./qjs tests/test_std.js
 ifndef CONFIG_DARWIN
 # QuickJS Javascript Engine
+LDEXPORT=-rdynamic
+# QuickJS Javascript Engine
   CROSS_PREFIX=
+else
+	./qjs tests/test_bjson.js
+endif
 	./qjs examples/test_point.js
 endif
 # QuickJS Javascript Engine
+LDEXPORT=-rdynamic
+	./qjs --bignum tests/test_op_overloading.js
+# QuickJS Javascript Engine
 ifdef CONFIG_CLANG
 	./qjs --qjscalc tests/test_qjscalc.js
+endif
 ifdef CONFIG_M32
 	./qjs32 tests/test_closure.js
 	./qjs32 tests/test_op.js
@@ -391,8 +414,12 @@ 	./qjs32 tests/test_builtin.js
 	./qjs32 tests/test_loop.js
 	./qjs32 tests/test_std.js
 # QuickJS Javascript Engine
+LDEXPORT=-rdynamic
+	./qjs32 --bignum tests/test_op_overloading.js
+# QuickJS Javascript Engine
   CFLAGS += -Wundef -Wuninitialized
 	./qjs32 --qjscalc tests/test_qjscalc.js
+endif
 endif
 
 stats: qjs qjs32




diff --git a/TODO b/TODO
index dbb461256c260a66337439f27952f633993fc689..33a9b9ddf6e7e6621394474d10922b33f666d4e2 100644
--- a/TODO
+++ b/TODO
@@ -74,7 +74,6 @@ Test262o:   0/11262 errors, 463 excluded
 Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
 
 - use JSHoistedDef only for global variables (JSHoistedDef.var_name != JS_ATOM_NULL)
-Misc:
+- unify coding style and naming conventions
 - use JSHoistedDef only for global variables (JSHoistedDef.var_name != JS_ATOM_NULL)
-- use custom printf to avoid C library compatibility issues
-test262 commit: 19fd4bea797646ae9bbfc9d325f14052ca370b54
+- use names from the ECMA spec in library implementation




diff --git a/VERSION b/VERSION
index 242aa927f46b0d5604ff84df3ee05f02c2441f50..ceac5568949598644d806d1022ca31827bb93d47 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2020-01-05
+2020-01-19




diff --git a/doc/jsbignum.html b/doc/jsbignum.html
index c60dc4541cf46e62a469d74062d069b57d7baf63..096dc04235cf8cf7bee7081c27f2fb12a7c04023 100644
--- a/doc/jsbignum.html
+++ b/doc/jsbignum.html
@@ -1,7 +1,8 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
-<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
+<!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
 <head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>Javascript Bignum Extensions</title>
 
 <meta name="description" content="Javascript Bignum Extensions">
@@ -9,7 +10,6 @@ 
 <meta name="resource-type" content="document">
 <meta name="distribution" content="global">
 <meta name="Generator" content="makeinfo">
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <link href="#SEC_Contents" rel="contents" title="Table of Contents">
 <style type="text/css">
 <!--
@@ -52,566 +52,171 @@
 <div class="contents">
 <ul class="no-bullet">
 <li><a name="toc-Introduction" href="#Introduction">1 Introduction</a></li>
-<li><a name="toc-Operator-overloading" href="#Operator-overloading">2 Operator overloading</a>
-<ul class="no-bullet">
-  <li><a name="toc-Introduction-1" href="#Introduction-1">2.1 Introduction</a></li>
-  <li><a name="toc-Builtin-Object-changes" href="#Builtin-Object-changes">2.2 Builtin Object changes</a>
-  <ul class="no-bullet">
-    <li><a name="toc-Symbol-constructor" href="#Symbol-constructor">2.2.1 <code>Symbol</code> constructor</a></li>
-  </ul></li>
-<title>Javascript Bignum Extensions</title>
 
 <title>Javascript Bignum Extensions</title>
-<meta name="description" content="Javascript Bignum Extensions">
-<head>
 <meta name="keywords" content="Javascript Bignum Extensions">
-  <li><a name="toc-Introduction-2" href="#Introduction-2">3.1 Introduction</a></li>
+
   <li><a name="toc-Changes-that-introduce-incompatibilities-with-Javascript" href="#Changes-that-introduce-incompatibilities-with-Javascript">3.2 Changes that introduce incompatibilities with Javascript</a>
-  <ul class="no-bullet">
 
 
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-  </ul></li>
-  <li><a name="toc-Operators" href="#Operators">3.3 Operators</a>
-  <ul class="no-bullet">
-    <li><a name="toc-Arithmetic-operators" href="#Arithmetic-operators">3.3.1 Arithmetic operators</a></li>
-
 <head>
-    <li><a name="toc-Relational-operators" href="#Relational-operators">3.3.3 Relational operators</a></li>
-  </ul></li>
+<meta name="keywords" content="Javascript Bignum Extensions">
   <li><a name="toc-Number-literals" href="#Number-literals">3.4 Number literals</a></li>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-
 <meta name="description" content="Javascript Bignum Extensions">
 <title>Javascript Bignum Extensions</title>
-<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
 
-<meta name="keywords" content="Javascript Bignum Extensions">
 
-<meta name="resource-type" content="document">
-    <li><a name="toc-Number-constructor" href="#Number-constructor">3.5.3 <code>Number</code> constructor</a></li>
-    <li><a name="toc-Number_002eprototype" href="#Number_002eprototype">3.5.4 <code>Number.prototype</code></a></li>
-<meta name="description" content="Javascript Bignum Extensions">
 <html>
-  </ul></li>
-</ul></li>
 <meta name="description" content="Javascript Bignum Extensions">
-<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
-<ul class="no-bullet">
 <meta name="description" content="Javascript Bignum Extensions">
-<head>
-  <li><a name="toc-Floating-point-rounding" href="#Floating-point-rounding">4.2 Floating point rounding</a></li>
-<meta name="description" content="Javascript Bignum Extensions">
 
-  <li><a name="toc-BigFloat-literals" href="#BigFloat-literals">4.4 BigFloat literals</a></li>
-  <li><a name="toc-Builtin-Object-changes-2" href="#Builtin-Object-changes-2">4.5 Builtin Object changes</a>
+    <li><a name="toc-Arithmetic-operators" href="#Arithmetic-operators">3.3.1 Arithmetic operators</a></li>
   <ul class="no-bullet">
     <li><a name="toc-BigFloat-function" href="#BigFloat-function">4.5.1 <code>BigFloat</code> function</a></li>
     <li><a name="toc-BigFloat_002eprototype" href="#BigFloat_002eprototype">4.5.2 <code>BigFloat.prototype</code></a></li>
     <li><a name="toc-BigFloatEnv-constructor" href="#BigFloatEnv-constructor">4.5.3 <code>BigFloatEnv</code> constructor</a></li>
-    <li><a name="toc-Math-object-1" href="#Math-object-1">4.5.4 <code>Math</code> object</a></li>
   </ul></li>
 </ul></li>
-<li><a name="toc-Math-mode" href="#Math-mode">5 Math mode</a>
+  <li><a name="toc-Number-literals" href="#Number-literals">3.4 Number literals</a></li>
 <head>
-<meta name="keywords" content="Javascript Bignum Extensions">
-<meta name="keywords" content="Javascript Bignum Extensions">
 <head>
 <meta name="keywords" content="Javascript Bignum Extensions">
-<title>Javascript Bignum Extensions</title>
-  <ul class="no-bullet">
-<meta name="keywords" content="Javascript Bignum Extensions">
+
 
-<title>Javascript Bignum Extensions</title>
 <title>Javascript Bignum Extensions</title>
-  <li><a name="toc-Remaining-issues" href="#Remaining-issues">5.3 Remaining issues</a></li>
-<title>Javascript Bignum Extensions</title>
 
 
-</ul>
-</div>
 
 
-<a name="Introduction"></a>
-<h2 class="chapter">1 Introduction</h2>
 
-<p>The Bignum extensions add the following features to the Javascript
+<meta name="description" content="Javascript Bignum Extensions">
-<meta name="resource-type" content="document">
+<title>Javascript Bignum Extensions</title>
 <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
-</p>
-<ul>
-<meta name="resource-type" content="document">
 
-to support new types such as complex numbers, fractions or matrices.
 
-<meta name="resource-type" content="document">
 <meta name="keywords" content="Javascript Bignum Extensions">
 
-</li><li> Arbitrarily large floating point numbers (<code>BigFloat</code>) in base 2 using the IEEE 754 semantics.
 
-</li><li> Optional <code>math</code> mode which modifies the semantics of the division, modulo and power operator. The division and power operator return a fraction with integer operands and the modulo operator is defined as the Euclidian remainder.
-
-</li></ul>
-
-<p>The extensions are independent from each other except the <code>math</code>
-mode which relies on the bigint mode and the operator overloading.
 <meta name="resource-type" content="document">
-<head>
-<a name="Operator-overloading"></a>
-<h2 class="chapter">2 Operator overloading</h2>
 
-<a name="Introduction-1"></a>
-<meta name="distribution" content="global">
 <meta name="description" content="Javascript Bignum Extensions">
-
-<p>If the operands of an operator have at least one object type, a custom
-operator method is searched before doing the legacy Javascript
-<meta name="Generator" content="makeinfo">
-</p>
-<p>For unary operators, the custom function is looked up in the object
-and has the following name:
-</p>
-<dl compact="compact">
-<dt><code>unary +</code></dt>
-<meta name="Generator" content="makeinfo">
 <title>Javascript Bignum Extensions</title>
-</p>
-</dd>
-<dt><code>unary -</code></dt>
-<dd><p><code>Symbol.operatorNeg</code>
-</p>
-</dd>
-<dt><code>++</code></dt>
-<dd><p><code>Symbol.operatorInc</code>
-</p>
-</dd>
-<dt><code>--</code></dt>
-<dd><p><code>Symbol.operatorDec</code>
-</p>
-</dd>
-<dt><code>~</code></dt>
-<dd><p><code>Symbol.operatorNot</code>
-</p>
-</dd>
+<title>Javascript Bignum Extensions</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>Javascript Bignum Extensions</title>
 
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 
-</p>
-<ul>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <meta name="description" content="Javascript Bignum Extensions">
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-pre.format {font-family: inherit}
 
-</li><li> Otherwise, the property <code>Symbol.operatorOrder</code> is looked up in both
-constructors and converted to <code>Int32</code>. The operator is then
-looked in the constructor with the larger <code>Symbol.operatorOrder</code>
-value. A <code>TypeError</code> is raised if both constructors have the same
+</ul>
-<code>Symbol.operatorOrder</code> value.
-
-</li></ul>
-
-<p>The operator is looked up with the following name:
-</p>
-<dl compact="compact">
-<dt><code>+</code></dt>
-<dd><p><code>Symbol.operatorAdd</code>
-</p>
-</dd>
-<dt><code>-</code></dt>
-<link href="#SEC_Contents" rel="contents" title="Table of Contents">
 <meta name="keywords" content="Javascript Bignum Extensions">
 <meta name="resource-type" content="document">
-<head>
-<meta name="Generator" content="makeinfo">
 
-<dt><code>*</code></dt>
-<dd><p><code>Symbol.operatorMul</code>
-</p>
-<meta name="Generator" content="makeinfo">
 
-<dt><code>/</code></dt>
-<dd><p><code>Symbol.operatorDiv</code>
 <meta name="resource-type" content="document">
-<head>
-</dd>
-<dt><code>%</code></dt>
-<dd><p><code>Symbol.operatorMod</code>
 <meta name="resource-type" content="document">
-<head>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-
-<dt><code>% (math mode)</code></dt>
-<style type="text/css">
 
 <meta name="resource-type" content="document">
-<head>
-</dd>
-<dt><code>**</code></dt>
-<dd><p><code>Symbol.operatorPow</code>
-</p>
-</dd>
-<dt><code>|</code></dt>
-<dd><p><code>Symbol.operatorOr</code>
-</p>
-</dd>
-<dt><code>^</code></dt>
-<!--
 <html>
 <meta name="resource-type" content="document">
-<head>
-</dd>
-<!--
 <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
-<dd><p><code>Symbol.operatorAnd</code>
 </p>
-</dd>
-<dt><code>&lt;&lt;</code></dt>
-<dd><p><code>Symbol.operatorShl</code>
 <meta name="resource-type" content="document">
-<head>
-</dd>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <title>Javascript Bignum Extensions</title>
-<meta name="description" content="Javascript Bignum Extensions">
-<dd><p><code>Symbol.operatorShr</code>
-</p>
-<meta name="Generator" content="makeinfo">
 
+    <li><a name="toc-Math-object" href="#Math-object">3.5.5 <code>Math</code> object</a></li>
-<dt><code>&lt;</code></dt>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
 <meta name="resource-type" content="document">
-<head>
-</dd>
-<dt><code>&gt;</code></dt>
-<dd><p><code>Symbol.operatorCmpLT</code>, operands swapped
 <meta name="resource-type" content="document">
-<head>
-<meta name="Generator" content="makeinfo">
 
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
+<meta name="description" content="Javascript Bignum Extensions">
 <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
+<meta name="description" content="Javascript Bignum Extensions">
 <head>
-</p>
-<meta name="Generator" content="makeinfo">
 
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
+<meta name="description" content="Javascript Bignum Extensions">
 <title>Javascript Bignum Extensions</title>
-<dd><p><code>Symbol.operatorCmpLE</code>, operands swapped
-</p>
-</dd>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
   <li><a name="toc-Builtin-Object-changes-1" href="#Builtin-Object-changes-1">3.5 Builtin Object changes</a>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
-<meta name="keywords" content="Javascript Bignum Extensions">
-</p>
-<meta name="Generator" content="makeinfo">
 
-</dl>
-
-<p>The return value of <code>Symbol.operatorCmpLT</code>, <code>Symbol.operatorCmpLE</code> and
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <meta name="description" content="Javascript Bignum Extensions">
-</p>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <meta name="description" content="Javascript Bignum Extensions">
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<h3 class="section">2.2 Builtin Object changes</h3>
 
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<li><a name="toc-Arbitrarily-large-floating-point-numbers" href="#Arbitrarily-large-floating-point-numbers">4 Arbitrarily large floating point numbers</a>
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-  <li><a name="toc-Introduction-3" href="#Introduction-3">4.1 Introduction</a></li>
 
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-  <li><a name="toc-Floating-point-rounding" href="#Floating-point-rounding">4.2 Floating point rounding</a></li>
-</p><dl compact="compact">
-<dt><code>operatorOrder</code></dt>
-<dt><code>operatorAdd</code></dt>
-<dt><code>operatorSub</code></dt>
-blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
-<dt><code>operatorDiv</code></dt>
-blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
 <html>
-<dt><code>operatorPow</code></dt>
-<dt><code>operatorShl</code></dt>
-<dt><code>operatorShr</code></dt>
-blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
 
-blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
 <meta name="description" content="Javascript Bignum Extensions">
-blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
 <meta name="keywords" content="Javascript Bignum Extensions">
-blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
 <meta name="resource-type" content="document">
+<head>
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<meta name="resource-type" content="document">
-<dt><code>operatorCmpEQ</code></dt>
-<dt><code>operatorPlus</code></dt>
-<dt><code>operatorNeg</code></dt>
-blockquote.smallquotation {font-size: smaller}
 <head>
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<ul>
-<dt><code>operatorDec</code></dt>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>Javascript Bignum Extensions</title>
 
 
-blockquote.smallquotation {font-size: smaller}
 <meta name="description" content="Javascript Bignum Extensions">
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <meta name="resource-type" content="document">
-<meta name="keywords" content="Javascript Bignum Extensions">
 
-<a name="Introduction-2"></a>
-div.display {margin-left: 3.2em}
+<meta name="keywords" content="Javascript Bignum Extensions">
 
-<p>The bigint mode is enabled with the <code>&quot;use bigint&quot;</code> directive. It
-propagates the same way as the strict mode. In bigint mode, all
-integers are considered as <code>bigint</code> (arbitrarily large integer,
-similar to the TC39 BigInt
-proposal<a name="DOCF2" href="#FOOT2"><sup>2</sup></a>)
-instead of <code>number</code> (floating point number). In order to be able
-to exchange data between standard and bigint modes, numbers are
-div.display {margin-left: 3.2em}
 <meta name="keywords" content="Javascript Bignum Extensions">
-</p>
-<ul>
-<li> Small integer (SmallInt): 32 bit integer<a name="DOCF3" href="#FOOT3"><sup>3</sup></a>.
-
-</li><li> Big integer (BigInt): arbitrarily large integer.
-
-div.example {margin-left: 3.2em}
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
-</li></ul>
-
-<p>In standard mode, the semantics of each operation is modified so that
-when it returns a <code>number</code>, it is either of SmallInt or
-Float. But the difference between SmallInt and Float is not observable
-in standard mode.
-</p>
-<p>In bigint mode, each operation behaves differently whether its
-operands are integer or float. The difference between SmallInt and
-div.example {margin-left: 3.2em}
 <meta name="keywords" content="Javascript Bignum Extensions">
-</p>
 <html>
-blockquote.smallquotation {font-size: smaller}
-</p>
-<table>
-<thead><tr><th width="30%">Internal type</th><th width="30%">Observable type<br> (standard mode)</th><th width="30%">Observable type<br> (bigint mode)</th></tr></thead>
-<tr><td width="30%">SmallInt</td><td width="30%">number</td><td width="30%">bigint</td></tr>
-<tr><td width="30%">BigInt</td><td width="30%">bigint</td><td width="30%">bigint</td></tr>
-<tr><td width="30%">Float</td><td width="30%">number</td><td width="30%">number</td></tr>
-</table>
 
-<a name="Changes-that-introduce-incompatibilities-with-Javascript"></a>
-<h3 class="section">3.2 Changes that introduce incompatibilities with Javascript</h3>
-
-div.lisp {margin-left: 3.2em}
 <meta name="keywords" content="Javascript Bignum Extensions">
-<h4 class="subsection">3.2.1 Standard mode</h4>
-
-<html>
 <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
 </p>
-<a name="Bigint-mode"></a>
-<h4 class="subsection">3.2.2 Bigint mode</h4>
 
-<p>The following changes are visible:
-</p>
-<ul>
-<li> Integer and Float are different types. Constants are typed. For example: <code>typeof 1.0 === &quot;number&quot;</code> and <code>typeof 1 === &quot;bigint&quot;</code>. Another consequence is that <code>1.0 === 1</code> is false.
-
-</li><li> The range of integers is unlimited. In standard mode: <code>2**53 + 1 === 2**53</code>. This is no longer true with the bignum extensions.
-
-</li><li> Binary bitwise operators do not truncate to 32 bits i.e. <code>0x800000000 | 1 === 0x800000001</code> while it gives <code>1</code> in standard mode.
-
-</li><li> Bitwise shift operators do not truncate to 32 bits and do not mask the shift count with <code>0x1f</code> i.e. <code>1 &lt;&lt; 32 === 4294967296</code> while it gives <code>1</code> in standard mode. However, the <code>&gt;&gt;&gt;</code> operator (unsigned right shift) which is useless with bignums keeps its standard mode behavior<a name="DOCF4" href="#FOOT4"><sup>4</sup></a>.
-
-div.smalldisplay {margin-left: 3.2em}
 <meta name="keywords" content="Javascript Bignum Extensions">
-
-</li><li> The <code>ToPrimitive</code> abstract operation is called with the <code>&quot;integer&quot;</code> preferred type when an integer is required (e.g. for bitwise binary or shift operations).
-
-</li><li> The prototype of integers is no longer <code>Number.prototype</code>. Instead<br> <code>Object.getPrototypeOf(1) === BigInt.prototype</code>. The prototype of floats remains Number.prototype.
-
-</li><li> If the TC39 BigInt proposal is supported, there is no observable difference between integers and <code>bigint</code>s.
-
-</li></ul>
-
-<a name="Operators"></a>
-<h3 class="section">3.3 Operators</h3>
-
-div.smallexample {margin-left: 3.2em}
 <head>
-<h4 class="subsection">3.3.1 Arithmetic operators</h4>
-
-<p>The operands are converted to number values as in normal
-Javascript. Then the general case is that an Integer is returned if
-both operands are Integer. Otherwise, a float is returned.
 </p>
-div.smallexample {margin-left: 3.2em}
 <meta name="resource-type" content="document">
-<html>
 <title>Javascript Bignum Extensions</title>
-</p>
-<p>The binary operator <code>%</code> returns the truncated remainder of the
-division. When the result is an Integer type, a dividend of zero yields a
-RangeError exception.
-</p>
-<p>The binary operator <code>%</code> in math mode returns the Euclidian
-remainder of the division i.e. it is always positive. 
-</p>
-div.smalllisp {margin-left: 3.2em}
 
-</p>
-<p>The binary operator <code>/</code> in math mode returns a float if one of
-div.smalllisp {margin-left: 3.2em}
 <meta name="keywords" content="Javascript Bignum Extensions">
-<html>
 <title>Javascript Bignum Extensions</title>
-<meta name="resource-type" content="document">
-</p>
-<html>
 
-are Float. If <em>a</em> and <em>b</em> are integers:
-</p><ul>
-<li> <em>b &lt; 0</em> returns a Float in bigint mode. In math mode, <code>BigInt[Symbol.operatorPow]</code> is invoked.
-
-</li><li> <em>b &gt;= 0</em> returns an integer.
-</li></ul>
-
-<p>The unary <code>-</code> and unary <code>+</code> return the same type as their
-operand. They performs no floating point rounding when the result is a
-float.
-</p>
-<html>
     <li><a name="toc-BigInt-function" href="#BigInt-function">3.5.1 <code>BigInt</code> function</a></li>
-<html>
 
-<meta name="resource-type" content="document">
-</p>
-<p>In standard mode:
-</p>
-<p>If the operator returns an Integer and that the result fits a
-SmallInt, it is converted to SmallInt. Otherwise, the Integer is
-converted to a Float.
-</p>
-<p>In bigint mode:
-</p>
-<p>If the operator returns an Integer and that the result fits a
-SmallInt, it is converted to SmallInt. Otherwise it is a BigInt.
-</p>
-pre.display {font-family: inherit}
 
-<h4 class="subsection">3.3.2 Logical operators</h4>
 
-<p>In standard mode:
-</p>
-pre.display {font-family: inherit}
 <meta name="keywords" content="Javascript Bignum Extensions">
-<html>
 <meta name="description" content="Javascript Bignum Extensions">
-<meta name="resource-type" content="document">
-</p>
-<p>In bigint mode:
-</p>
-<p>The operands are converted to integer values. The floating point
+
-values are converted to integer by rounding them to zero.
-</p>
-<p>The logical operators are defined assuming the integers are
-represented in two complement notation.
-</p>
-<p>For <code>&lt;&lt;</code> and <code>&lt;&lt;</code>, the shift can be positive or negative. So
-<code>a &lt;&lt; b</code> is defined as <em>\lfloor a/2^{-b} \rfloor</em> and
-pre.format {font-family: inherit}
 
-</p>
-<html>
 <meta name="keywords" content="Javascript Bignum Extensions">
-<meta name="description" content="Javascript Bignum Extensions">
-<html>
 <meta name="keywords" content="Javascript Bignum Extensions">
-<meta name="keywords" content="Javascript Bignum Extensions">
-</p>
-<p>If the result fits a SmallInt it is converted to a SmallInt. Otherwise
-it is a BigInt.
-</p>
-<a name="Relational-operators"></a>
-<h4 class="subsection">3.3.3 Relational operators</h4>
 
-<p>The relational operators &lt;, &lt;=, &gt;, &gt;=, ==, != work as expected with
-integers and floating point numbers (e.g. <code>1.0 == 1</code> is true).
-</p>
-<p>The strict equality operators === and !== have the usual Javascript
-pre.menu-comment {font-family: serif}
 
-=== 1</code> is false.
-</p>
-pre.menu-comment {font-family: serif}
 <meta name="keywords" content="Javascript Bignum Extensions">
-pre.menu-comment {font-family: serif}
 <meta name="resource-type" content="document">
 
-<p>Number literals in bigint mode have a slightly different behavior than
-pre.menu-preformatted {font-family: serif}
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-</p>
-<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
-<html>
-<li> A number literal without a decimal point or an exponent is considered
-as an Integer. Otherwise it is a Float.
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
-</li><li> Hexadecimal, octal or binary floating point literals are accepted with
-pre.menu-preformatted {font-family: serif}
 
-<code>p</code> letter assuming a base 2. The same convention is used by
-C99. Example: <code>0x1p3</code> is the same as <code>8.0</code>.
-
-pre.menu-preformatted {font-family: serif}
 <meta name="resource-type" content="document">
-
-pre.smalldisplay {font-family: inherit; font-size: smaller}
-<h3 class="section">3.5 Builtin Object changes</h3>
 
-<a name="BigInt-function"></a>
-<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
+<meta name="resource-type" content="document">
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
 
-<p>The <code>BigInt</code> function cannot be invoked as a constructor. When
-invoked as a function, it converts its first parameter to an
-pre.smalldisplay {font-family: inherit; font-size: smaller}
 
-truncated to an integer with infinite precision.
 <meta name="resource-type" content="document">
-<head>
-<p><code>BigInt</code> properties:
-</p>
-<dl compact="compact">
-<dt><code>asIntN(bits, a)</code></dt>
-<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
 <html>
-otherwise <em>b-2^{bits}</em>.
 </p>
 <meta name="Generator" content="makeinfo">
-
 <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
-div.lisp {margin-left: 3.2em}
-<dd><p>Return <em>a \pmod{2^{bits}}</em>.
-</p>
-</dd>
 <dt><code>tdiv(a, b)</code></dt>
 <dd><p>Return <em>trunc(a/b)</em>. <code>b = 0</code> raises a RangeError
 exception.
@@ -650,77 +263,14 @@ 

</dd> </dl> -<a name="BigInt_002eprototype"></a> -<h4 class="subsection">3.5.2 <code>BigInt.prototype</code></h4> -<p>It is a normal object. <meta name="resource-type" content="document"> -<head> <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> - </ul></li> -<h4 class="subsection">3.5.3 <code>Number</code> constructor</h4> -<p>The number constructor returns its argument rounded to a Float using -the global floating point environment. In bigint mode, the Number -constructor returns a Float. In standard mode, it returns a SmallInt -if the value fits it, otherwise a Float. </p> -<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<h4 class="subsection">3.5.4 <code>Number.prototype</code></h4> - -<p>The following properties are modified: -</p> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<link href="#SEC_Contents" rel="contents" title="Table of Contents"> -<dt><code>toString(radix)</code></dt> -<dd> -<p>In bigint mode, integers are converted to the specified radix with -infinite precision. -</p> -</dd> -<dt><code>toPrecision(p)</code></dt> -<dt><code>toFixed(p)</code></dt> -span.sansserif {font-family: sans-serif; font-weight: normal} -<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> -<title>Javascript Bignum Extensions</title> -<p>In bigint mode, integers are accepted and converted to string with -infinite precision. -</p> -</dd> -<dt><code>parseInt(string, radix)</code></dt> -<dd> -<p>In bigint mode, an integer is returned and the conversion is done with -infinite precision. -</p> -</dd> -</dl> - -<a name="Math-object"></a> -<h4 class="subsection">3.5.5 <code>Math</code> object</h4> - -<p>The following properties are modified: -</p> -<dl compact="compact"> -<dt><code>abs(x)</code></dt> -<dd><p>Absolute value. Return an integer if <code>x</code> is an Integer. Otherwise -return a Float. No rounding is performed. -</p> -</dd> -<dt><code>min(a, b)</code></dt> -<dt><code>max(a, b)</code></dt> -<dd><p>No rounding is performed. The returned type is the same one as the -minimum (resp. maximum) value. -</p> -</dd> -</dl> - -<a name="Arbitrarily-large-floating-point-numbers"></a> -<h2 class="chapter">4 Arbitrarily large floating point numbers</h2> - -<a name="Introduction-3"></a> <h3 class="section">4.1 Introduction</h3> <p>This extension adds the <code>BigFloat</code> primitive type. The @@ -743,8 +293,8 @@

If no floating point environment is provided, the global floating point environment is used. </p> <p>The rounding mode of the global floating point environment is always -<code>RNDN</code> (&ldquo;round to nearest with ties to even&rdquo;)<a name="DOCF5" href="#FOOT5"><sup>5</sup></a>. The status flags of the global environment cannot be +<code>RNDN</code> (&ldquo;round to nearest with ties to even&rdquo;)<a name="DOCF1" href="#FOOT1"><sup>1</sup></a>. The status flags of the global environment cannot be -read<a name="DOCF6" href="#FOOT6"><sup>6</sup></a>. The precision of the global environment is +read<a name="DOCF2" href="#FOOT2"><sup>2</sup></a>. The precision of the global environment is <code>BigFloatEnv.prec</code>. The number of exponent bits of the global environment is <code>BigFloatEnv.expBits</code>. If <code>BigFloatEnv.expBits</code> is strictly smaller than the maximum allowed number of exponent bits @@ -761,8 +311,9 @@ when calling a function (see BigFloatEnv.setPrec). Hence a function can change the global floating point environment for its callees but not for its caller. </p> +<html> <head> -blockquote.smallindentedblock {margin-right: 0em; font-size: smaller} +<html> <h3 class="section">4.3 Operators</h3> <p>The builtin operators are extended so that a BigFloat is returned if @@ -785,9 +336,9 @@ <p>BigFloat literals are floating point numbers with a trailing <code>l</code> suffix. BigFloat literals have an infinite precision. They are rounded according to the global floating point environment when they are -evaluated.<a name="DOCF7" href="#FOOT7"><sup>7</sup></a> +evaluated.<a name="DOCF3" href="#FOOT3"><sup>3</sup></a> </p> -<a name="Builtin-Object-changes-2"></a> +<a name="Builtin-Object-changes"></a> <h3 class="section">4.5 Builtin Object changes</h3> <a name="BigFloat-function"></a> @@ -855,6 +406,10 @@

trunc(x)
<dd><p>Round to an integer. No additional rounding is performed. </p> </dd> +<dt><code>abs(x)</code></dt> +<dd><p>Return the absolute value of x. No additional rounding is performed. +</p> +</dd> <dt><code>fmod(x, y[, e])</code></dt> <dt><code>remainder(x, y[, e])</code></dt> <dd><p>Floating point remainder. The quotient is truncated to zero (fmod) or @@ -889,6 +444,10 @@ <p>The following properties are modified: </p> <dl compact="compact"> +<dt><code>valueOf()</code></dt> +<dd><p>Return the bigfloat primitive value corresponding to <code>this</code>. +</p> +</dd> <dt><code>toString(radix)</code></dt> <dd> <p>For floating point numbers: @@ -903,19 +462,21 @@ the global precision and round to nearest gives the same number. </li></ul> -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> + <li><a name="toc-Number-constructor" href="#Number-constructor">3.5.3 <code>Number</code> constructor</a></li> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> - -<title>Javascript Bignum Extensions</title> +16 with a binary exponent and <code>@</code> for the other bases. +</p> <meta name="Generator" content="makeinfo"> + -<dt><code>toFixed(p[, rnd_mode])</code></dt> +<dt><code>toPrecision(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)</code></dt> +<dt><code>toFixed(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)</code></dt> + <li><a name="toc-Number-constructor" href="#Number-constructor">3.5.3 <code>Number</code> constructor</a></li> <title>Javascript Bignum Extensions</title> -<link href="#SEC_Contents" rel="contents" title="Table of Contents"> <dd><p>Same semantics as the corresponding <code>Number</code> functions with BigFloats. There is no limit on the accepted precision <code>p</code>. The - <li><a name="toc-Introduction-1" href="#Introduction-1">2.1 Introduction</a></li> + <li><a name="toc-Number-constructor" href="#Number-constructor">3.5.3 <code>Number</code> constructor</a></li> - <li><a name="toc-Introduction-1" href="#Introduction-1">2.1 Introduction</a></li> + <li><a name="toc-Number-constructor" href="#Number-constructor">3.5.3 <code>Number</code> constructor</a></li> <meta name="description" content="Javascript Bignum Extensions"> </p> </dd> @@ -954,7 +515,7 @@

<dl compact="compact"> <dt><code>prec</code></dt> <dd><p>Getter. Return the precision in bits of the global floating point - <ul class="no-bullet"> + <li><a name="toc-Number-constructor" href="#Number-constructor">3.5.3 <code>Number</code> constructor</a></li> <meta name="keywords" content="Javascript Bignum Extensions"> </p> </dd> @@ -962,7 +523,7 @@
expBits
<dd><p>Getter. Return the exponent size in bits of the global floating point environment assuming an IEEE 754 representation. If <code>expBits &lt; expBitsMax</code>, then subnormal numbers are supported. The initial value -is <code>11</code>. +is <code>15</code>. </p> </dd> <dt><code>setPrec(f, p[, e])</code></dt> @@ -971,9 +532,7 @@ and the exponent size to e then call the function <code>f</code>. Then the Float precision and exponent size are reset to their precious value and the return value of <code>f</code> is returned (or an exception is raised if <code>f</code> raised an exception). If <code>e</code> - </ul></li> + <li><a name="toc-Number_002eprototype" href="#Number_002eprototype">3.5.4 <code>Number.prototype</code></a></li> -must be &gt;= 53 and <code>e</code> must be &gt;= 11 so that the global precision -is at least equivalent to the IEEE 754 64 bit doubles. </p> </dd> <dt><code>precMin</code></dt> @@ -981,7 +540,7 @@

Read-only integer. Return the minimum allowed precision. Must be at least 2. </p> </dd> <dt><code>precMax</code></dt> -<dd><p>Read-only integer. Return the maximum allowed precision. Must be at least 53. +<dd><p>Read-only integer. Return the maximum allowed precision. Must be at least 113. </p> </dd> <dt><code>expBitsMin</code></dt> @@ -991,7 +550,7 @@

</dd> <dt><code>expBitsMax</code></dt> <dd><p>Read-only integer. Return the maximum allowed exponent size in -</ul></li> + <li><a name="toc-Number_002eprototype" href="#Number_002eprototype">3.5.4 <code>Number.prototype</code></a></li> <html> </p> </dd> @@ -1015,16 +574,16 @@
RNDNA
<dd><p>Read-only integer. Round to nearest, with ties away from zero rounding mode. </p> </dd> -<title>Javascript Bignum Extensions</title> <meta name="description" content="Javascript Bignum Extensions"> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> -<title>Javascript Bignum Extensions</title> <meta name="description" content="Javascript Bignum Extensions"> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <head> </p> </dd> -<title>Javascript Bignum Extensions</title> <meta name="description" content="Javascript Bignum Extensions"> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <title>Javascript Bignum Extensions</title> <dd><p>Read-only integer. Faithful rounding mode. The result is non-deterministically rounded to -Infinity or +Infinity. This rounding @@ -1069,179 +628,300 @@

</dd> </dl> -<title>Javascript Bignum Extensions</title> +<a name="BigDecimal"></a> +<h2 class="chapter">5 BigDecimal</h2> + +<p>This extension adds the <code>BigDecimal</code> primitive type. The +<code>BigDecimal</code> type represents floating point numbers in base +10. It is inspired from the proposal available at +<a href="https://github.com/littledan/proposal-bigdecimal">https://github.com/littledan/proposal-bigdecimal</a>. <meta name="resource-type" content="document"> +<head> <meta name="description" content="Javascript Bignum Extensions"> +div.example {margin-left: 3.2em} +finite. There is no concept of <code>-0</code>, <code>Infinity</code> or +<code>NaN</code>. By default, all the computations are done with infinite <title>Javascript Bignum Extensions</title> + <meta name="resource-type" content="document"> +<head> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="keywords" content="Javascript Bignum Extensions"> +<h3 class="section">5.1 Operators</h3> -<p>The following properties are modified: +<p>The following builtin operators support BigDecimal: </p> <dl compact="compact"> +<dt><code>+</code></dt> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> span.sansserif {font-family: sans-serif; font-weight: normal} - - <li><a name="toc-Changes-that-introduce-incompatibilities-with-Javascript" href="#Changes-that-introduce-incompatibilities-with-Javascript">3.2 Changes that introduce incompatibilities with Javascript</a> +<link href="#SEC_Contents" rel="contents" title="Table of Contents"> <meta name="resource-type" content="document"> + <li><a name="toc-Math-object" href="#Math-object">3.5.5 <code>Math</code> object</a></li> +<title>Javascript Bignum Extensions</title> + +</p></dd> +<dt><code>%</code></dt> +<dd><p>Both operands must be BigDecimal. The result is computed with infinite +precision. A range error is throws in case of division by zero. </p> </dd> -<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +<dt><code>/</code></dt> <meta name="description" content="Javascript Bignum Extensions"> +<html> <meta name="resource-type" content="document"> +<meta name="description" content="Javascript Bignum Extensions"> <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> -<meta name="keywords" content="Javascript Bignum Extensions"> - <li><a name="toc-Standard-mode" href="#Standard-mode">3.2.1 Standard mode</a></li> +<li><a name="toc-Arbitrarily-large-floating-point-numbers" href="#Arbitrarily-large-floating-point-numbers">4 Arbitrarily large floating point numbers</a> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +</p> +<meta name="Generator" content="makeinfo"> +<dt><code>**</code></dt> +<li><a name="toc-Arbitrarily-large-floating-point-numbers" href="#Arbitrarily-large-floating-point-numbers">4 Arbitrarily large floating point numbers</a> <html> +integer. The result is computed with infinite precision. +</p> +<meta name="Generator" content="makeinfo"> +<meta name="description" content="Javascript Bignum Extensions"> <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +<head> +<dd><p>When one of the operand is a BigDecimal, return true if both operands +are a BigDecimal and if they are equal. </p> </dd> +<dt><code>==</code></dt> +<dt><code>!=</code></dt> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<html> + <li><a name="toc-Arithmetic-operators" href="#Arithmetic-operators">3.3.1 Arithmetic operators</a></li> +a.summary-letter {text-decoration: none} <title>Javascript Bignum Extensions</title> +<dt><code>&lt;</code></dt> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +<title>Javascript Bignum Extensions</title> +<p>Numerical comparison. When one of the operand is not a BigDecimal, it is + <li><a name="toc-Introduction-3" href="#Introduction-3">4.1 Introduction</a></li> +<meta name="description" content="Javascript Bignum Extensions"> <head> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +Number value. +</p> +<meta name="Generator" content="makeinfo"> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Javascript Bignum Extensions</title> +<a name="BigDecimal-literals"></a> +<h3 class="section">5.2 BigDecimal literals</h3> +<p>BigDecimal literals are decimal floating point numbers with a trailing + <li><a name="toc-Introduction-3" href="#Introduction-3">4.1 Introduction</a></li> - +</p> +pre.smalldisplay {font-family: inherit; font-size: smaller} + <li><a name="toc-Introduction-3" href="#Introduction-3">4.1 Introduction</a></li> <meta name="description" content="Javascript Bignum Extensions"> - <li><a name="toc-Standard-mode" href="#Standard-mode">3.2.1 Standard mode</a></li> + <li><a name="toc-Introduction-3" href="#Introduction-3">4.1 Introduction</a></li> <meta name="keywords" content="Javascript Bignum Extensions"> - <li><a name="toc-Standard-mode" href="#Standard-mode">3.2.1 Standard mode</a></li> + <li><a name="toc-Introduction-3" href="#Introduction-3">4.1 Introduction</a></li> <meta name="resource-type" content="document"> -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> + <li><a name="toc-Floating-point-rounding" href="#Floating-point-rounding">4.2 Floating point rounding</a></li> - <li><a name="toc-Bigint-mode" href="#Bigint-mode">3.2.2 Bigint mode</a></li> + <li><a name="toc-Floating-point-rounding" href="#Floating-point-rounding">4.2 Floating point rounding</a></li> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> - <li><a name="toc-Bigint-mode" href="#Bigint-mode">3.2.2 Bigint mode</a></li> + <li><a name="toc-Floating-point-rounding" href="#Floating-point-rounding">4.2 Floating point rounding</a></li> <html> +BigDecimal. </p> +<a name="Properties-of-the-BigDecimal-object"></a> +<h4 class="subsection">5.3.2 Properties of the <code>BigDecimal</code> object</h4> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <link href="#SEC_Contents" rel="contents" title="Table of Contents"> - +<dt><code>add(a, b[, e])</code></dt> +<div class="contents"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <head> + <li><a name="toc-Math-object" href="#Math-object">3.5.5 <code>Math</code> object</a></li> -<meta name="resource-type" content="document"> +<dt><code>div(a, b[, e])</code></dt> +<dt><code>mod(a, b[, e])</code></dt> +<dt><code>sqrt(a, e)</code></dt> +<dt><code>round(a, e)</code></dt> +<div class="contents"> <head> + <li><a name="toc-Floating-point-rounding" href="#Floating-point-rounding">4.2 Floating point rounding</a></li> <meta name="resource-type" content="document"> -<title>Javascript Bignum Extensions</title> +<meta name="description" content="Javascript Bignum Extensions"> -<!-- +<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +<meta name="description" content="Javascript Bignum Extensions"> +</p> +<meta name="description" content="Javascript Bignum Extensions"> <li><a name="toc-Bigint-mode" href="#Bigint-mode">3.2.2 Bigint mode</a></li> +division by zero or if the result cannot be represented with infinite +<meta name="description" content="Javascript Bignum Extensions"> +<html> +</p> +<meta name="description" content="Javascript Bignum Extensions"> +<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +<meta name="description" content="Javascript Bignum Extensions"> -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<head> +</p> <meta name="description" content="Javascript Bignum Extensions"> + <li><a name="toc-Relational-operators" href="#Relational-operators">3.3.3 Relational operators</a></li> + <li><a name="toc-Operators-1" href="#Operators-1">4.3 Operators</a></li> +<meta name="description" content="Javascript Bignum Extensions"> -blockquote.smallindentedblock {margin-right: 0em; font-size: smaller} +<meta name="description" content="Javascript Bignum Extensions"> +<meta name="description" content="Javascript Bignum Extensions"> +<meta name="keywords" content="Javascript Bignum Extensions"> +<meta name="description" content="Javascript Bignum Extensions"> +<meta name="resource-type" content="document"> +be present to specify respectively the number of significant digits + <li><a name="toc-BigFloat-literals" href="#BigFloat-literals">4.4 BigFloat literals</a></li> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +be &gt;= 0). <meta name="resource-type" content="document"> +<head> +<meta name="Generator" content="makeinfo"> - +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> +<title>Javascript Bignum Extensions</title> +<a name="Properties-of-the-BigDecimal_002eprototype-object"></a> +<h4 class="subsection">5.3.3 Properties of the <code>BigDecimal.prototype</code> object</h4> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +</li><li> Arbitrarily large floating point numbers (<code>BigFloat</code>) in base 2 using the IEEE 754 semantics. +<dd><p>Return the bigdecimal primitive value corresponding to <code>this</code>. +</p> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> + <li><a name="toc-BigFloat-literals" href="#BigFloat-literals">4.4 BigFloat literals</a></li> -div.lisp {margin-left: 3.2em} +<dd><p>Convert <code>this</code> to a string with infinite precision in base 10. +</p> +<meta name="Generator" content="makeinfo"> +<dt><code>toPrecision(p, rnd_mode = &quot;half-up&quot;)</code></dt> +<dt><code>toFixed(p, rnd_mode = &quot;half-up&quot;)</code></dt> +<dt><code>toExponential(p, rnd_mode = &quot;half-up&quot;)</code></dt> +<dd><p>Convert the BigDecimal <code>this</code> to string with the specified + <li><a name="toc-Builtin-Object-changes-2" href="#Builtin-Object-changes-2">4.5 Builtin Object changes</a> <html> + <li><a name="toc-Builtin-Object-changes-2" href="#Builtin-Object-changes-2">4.5 Builtin Object changes</a> <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +specified. <code>toPrecision</code> outputs either in decimal fixed notation +or in decimal exponential notation with a <code>p</code> digits of + <li><a name="toc-Builtin-Object-changes-2" href="#Builtin-Object-changes-2">4.5 Builtin Object changes</a> - <li><a name="toc-Operators" href="#Operators">3.3 Operators</a> +notation with <code>p</code> digits after the decimal point. <code>toFixed</code> +outputs in decimal notation with <code>p</code> digits after the decimal +point. +<meta name="resource-type" content="document"> <head> +<meta name="Generator" content="makeinfo"> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> div.smalllisp {margin-left: 3.2em} -kbd {font-style: oblique} +<head> -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <meta name="description" content="Javascript Bignum Extensions"> +<a name="Introduction"></a> -<html> +<meta name="keywords" content="Javascript Bignum Extensions"> <meta name="description" content="Javascript Bignum Extensions"> +<h2 class="chapter">1 Introduction</h2> -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> + <li><a name="toc-BigFloat-function" href="#BigFloat-function">4.5.1 <code>BigFloat</code> function</a></li> <html> +are available by default. In order to minimize the number of changes +in the Javascript semantics, integers are represented either as Number + <li><a name="toc-BigFloat-function" href="#BigFloat-function">4.5.1 <code>BigFloat</code> function</a></li> <title>Javascript Bignum Extensions</title> + <li><a name="toc-BigFloat-function" href="#BigFloat-function">4.5.1 <code>BigFloat</code> function</a></li> - <li><a name="toc-Operators" href="#Operators">3.3 Operators</a> +</p> +<p>The following changes are made to the Javascript semantics: +</p> +<ul> + <li><a name="toc-BigFloat-function" href="#BigFloat-function">4.5.1 <code>BigFloat</code> function</a></li> <meta name="keywords" content="Javascript Bignum Extensions"> -<html> + <li><a name="toc-BigFloat-function" href="#BigFloat-function">4.5.1 <code>BigFloat</code> function</a></li> <meta name="resource-type" content="document"> -<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +<meta name="keywords" content="Javascript Bignum Extensions"> -<html> -<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +<meta name="keywords" content="Javascript Bignum Extensions"> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +<meta name="keywords" content="Javascript Bignum Extensions"> -<meta name="resource-type" content="document"> +<html> -<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> + -pre.smallexample {font-size: smaller} +</li><li> The logical xor operator is still available with the <code>^^</code> operator. -<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> + <li><a name="toc-BigFloat_002eprototype" href="#BigFloat_002eprototype">4.5.2 <code>BigFloat.prototype</code></a></li> <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> - <li><a name="toc-Arithmetic-operators" href="#Arithmetic-operators">3.3.1 Arithmetic operators</a></li> + <li><a name="toc-BigFloat_002eprototype" href="#BigFloat_002eprototype">4.5.2 <code>BigFloat.prototype</code></a></li> <head> -<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> + <li><a name="toc-BigFloat_002eprototype" href="#BigFloat_002eprototype">4.5.2 <code>BigFloat.prototype</code></a></li> <title>Javascript Bignum Extensions</title> -span.roman {font-family: initial; font-weight: normal} +</li></ul> -span.nolinebreak {white-space: nowrap} <li><a name="toc-Arithmetic-operators" href="#Arithmetic-operators">3.3.1 Arithmetic operators</a></li> -<meta name="description" content="Javascript Bignum Extensions"> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <li><a name="toc-Arithmetic-operators" href="#Arithmetic-operators">3.3.1 Arithmetic operators</a></li> -<meta name="keywords" content="Javascript Bignum Extensions"> +<html> <li><a name="toc-Arithmetic-operators" href="#Arithmetic-operators">3.3.1 Arithmetic operators</a></li> -<meta name="resource-type" content="document"> +<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> -</style> +<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> <head> -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <p>The rationale is that the rounding mode changes must always be explicit.</p> -<a name="SEC_Contents"></a> +span.roman {font-family: initial; font-weight: normal} <p>The rationale is to avoid side effects for the built-in operators.</p> -<ul class="no-bullet"> +span.sansserif {font-family: sans-serif; font-weight: normal} <p>Base 10 floating point literals cannot usually be exactly represented as base 2 floating point number. In order to ensure that the literal is represented accurately with the current precision, it must be evaluated at runtime.</p> -<title>Javascript Bignum Extensions</title> <!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +<meta name="resource-type" content="document"> <p>Could be removed in case a deterministic behavior for floating point operations is required.</p> </div> <hr> diff --git a/doc/jsbignum.pdf b/doc/jsbignum.pdf index 16a0a35d374493f79c148c97211c68f74343da10..09d414251b729c5b4cddbd3149a7f6fb4cd55e8d 100644 Binary files a/doc/jsbignum.pdf and b/doc/jsbignum.pdf differ diff --git a/doc/jsbignum.texi b/doc/jsbignum.texi index 8b69eb2b377fec0b5e9346015d0f593ca92bbbd5..70455ec1c24abb3659d248f16950f01cc08cf2e3 100644 --- a/doc/jsbignum.texi +++ b/doc/jsbignum.texi @@ -10,14 +10,16 @@ @afourpaper @sp 7 @center @titlefont{Javascript Bignum Extensions} @sp 3 +@headings double \input texinfo -\input texinfo +@end iftex @sp 3 @center Author: Fabrice Bellard @end titlepage +@headings double \input texinfo -@afourpaper +@titlepage @settitle Javascript Bignum Extensions @contents @@ -29,396 +31,86 @@ language while being 100% backward compatible: @itemize -@item Overloading of the standard operators -to support new types such as complex numbers, fractions or matrices. - -@item Bigint mode where arbitrarily large integers are available by default (no @code{n} suffix is necessary as in the TC39 BigInt proposal@footnote{@url{https://tc39.github.io/proposal-bigint/}}). - -@item Arbitrarily large floating point numbers (@code{BigFloat}) in base 2 using the IEEE 754 semantics. - - @headings double - -@end itemize - -The extensions are independent from each other except the @code{math} -mode which relies on the bigint mode and the operator overloading. - -@chapter Operator overloading - -@section Introduction - -@iftex \input texinfo -operator method is searched before doing the legacy Javascript -@code{ToNumber} conversion. - -For unary operators, the custom function is looked up in the object -and has the following name: - -@table @code -@item unary + -@iftex @sp 7 -@item unary - -@code{Symbol.operatorNeg} @afourpaper -\input texinfo -@code{Symbol.operatorInc} -@item -- -@code{Symbol.operatorDec} - -@item ~ -@code{Symbol.operatorNot} - -@end table - -For binary operators: - -@itemize - -@item -If both operands have the same constructor function, then the operator is looked up in the constructor. - -@afourpaper @center @titlefont{Javascript Bignum Extensions} Otherwise, the property @code{Symbol.operatorOrder} is looked up in both -constructors and converted to @code{Int32}. The operator is then -looked in the constructor with the larger @code{Symbol.operatorOrder} -value. A @code{TypeError} is raised if both constructors have the same -@code{Symbol.operatorOrder} value. - -@end itemize @headings double -@titlepage -@table @code -@item + -@code{Symbol.operatorAdd} - -@item - -@end iftex \input texinfo - -@item * -@code{Symbol.operatorMul} - -@item / -@end iftex @headings double -@item % -@code{Symbol.operatorMod} -@item % (math mode) -@code{Symbol.operatorMathMod} - -@item ** -@code{Symbol.operatorPow} - -@item | -@code{Symbol.operatorOr} - -@item ^ -@titlepage @headings double -@item & -@code{Symbol.operatorAnd} - -@item << -@code{Symbol.operatorShl} - -@item >> -@code{Symbol.operatorShr} - -@item < -@sp 7 @iftex -@item > -@code{Symbol.operatorCmpLT}, operands swapped -@sp 7 @end iftex -@code{Symbol.operatorCmpLE} -@item >= -@code{Symbol.operatorCmpLE}, operands swapped -@item ==, != -@code{Symbol.operatorCmpEQ} - -@afourpaper @titlepage - -The return value of @code{Symbol.operatorCmpLT}, @code{Symbol.operatorCmpLE} and -@code{Symbol.operatorCmpEQ} is converted to @code{Boolean}. +@headings double -@center @titlefont{Javascript Bignum Extensions} @afourpaper -@subsection @code{Symbol} constructor @center @titlefont{Javascript Bignum Extensions} -@end iftex -@table @code -@item operatorOrder -@item operatorAdd -@item operatorSub -@item operatorMul -@item operatorDiv -@sp 3 -@item operatorPow -@item operatorShl -@sp 3 @headings double -@item operatorAnd -@item operatorOr -@item operatorXor -@item operatorCmpLT -@item operatorCmpLE -@item operatorCmpEQ -@center Version 2018-06-16 -@item operatorNeg -@item operatorNot -@center Version 2018-06-16 @headings double -@item operatorDec -@end table - - -@chapter The BigInt Mode - -@section Introduction - -The bigint mode is enabled with the @code{"use bigint"} directive. It -propagates the same way as the strict mode. In bigint mode, all -integers are considered as @code{bigint} (arbitrarily large integer, -similar to the TC39 BigInt -proposal@footnote{@url{https://tc39.github.io/proposal-bigint/}}) -instead of @code{number} (floating point number). In order to be able -to exchange data between standard and bigint modes, numbers are -@center Author: Fabrice Bellard @headings double - -@itemize - -\input texinfo @end itemize - -\input texinfo +@headings double The extensions are independent from each other except the @code{math} - -\input texinfo +@headings double mode which relies on the bigint mode and the operator overloading. - -@end itemize - -\input texinfo +@headings double @chapter Operator overloading -when it returns a @code{number}, it is either of SmallInt or -Float. But the difference between SmallInt and Float is not observable -@end titlepage - -In bigint mode, each operation behaves differently whether its -operands are integer or float. The difference between SmallInt and -@end titlepage @headings double - -\input texinfo @iftex -@end iftex - -@multitable @columnfractions .3 .3 .3 -@headitem Internal type @tab Observable type@* (standard mode) @tab Observable type@* (bigint mode) -@item SmallInt @tab number @tab bigint -@setfilename spec.info -@item Float @tab number @tab number -@end multitable - -@section Changes that introduce incompatibilities with Javascript - -@subsection Standard mode - -There is no incompatibility with Javascript. - -@subsection Bigint mode - -The following changes are visible: @itemize -@item Integer and Float are different types. Constants are typed. For example: @code{typeof 1.0 === "number"} and @code{typeof 1 === "bigint"}. Another consequence is that @code{1.0 === 1} is false. - -@item The range of integers is unlimited. In standard mode: @code{2**53 + 1 === 2**53}. This is no longer true with the bignum extensions. - -@item Binary bitwise operators do not truncate to 32 bits i.e. @code{0x800000000 | 1 === 0x800000001} while it gives @code{1} in standard mode. - -@item Bitwise shift operators do not truncate to 32 bits and do not mask the shift count with @code{0x1f} i.e. @code{1 << 32 === 4294967296} while it gives @code{1} in standard mode. However, the @code{>>>} operator (unsigned right shift) which is useless with bignums keeps its standard mode behavior@footnote{The unsigned right right operator could be removed in bigint mode.}. - -@item Operators with integer operands never return the minus zero floating point value as result. Hence @code{Object.is(0, -0) === true}. Use @code{-0.0} to create a minus zero floating point value. - -\input texinfo constructors and converted to @code{Int32}. The operator is then - \input texinfo -looked in the constructor with the larger @code{Symbol.operatorOrder} -\input texinfo @headings double -@headings double +@iftex -@end iftex - -\input texinfo @headings double -@end iftex +@code{ToNumber} conversion. -\input texinfo @headings double -@titlepage - -The operands are converted to number values as in normal -Javascript. Then the general case is that an Integer is returned if -both operands are Integer. Otherwise, a float is returned. - -The @code{+} operator also accepts strings as input and behaves like -standard Javascript in this case. - -@contents @iftex -@contents @afourpaper -RangeError exception. -The binary operator @code{%} in math mode returns the Euclidian -remainder of the division i.e. it is always positive. - -The binary operator @code{/} returns a float. - -The binary operator @code{/} in math mode returns a float if one of -the operands is float. Otherwise, @code{BigInt[Symbol.operatorDiv]} is -invoked. - -The returned type of @code{a ** b} is Float if @math{a} or @math{b} -are Float. If @math{a} and @math{b} are integers: -@itemize -@item @math{b < 0} returns a Float in bigint mode. In math mode, @code{BigInt[Symbol.operatorPow]} is invoked. - -@chapter Introduction @headings double -@end itemize - -The unary @code{-} and unary @code{+} return the same type as their -operand. They performs no floating point rounding when the result is a -float. - -The unary operators @code{++} and @code{--} return the same type as -their operand. - -In standard mode: - -If the operator returns an Integer and that the result fits a -The Bignum extensions add the following features to the Javascript @iftex -converted to a Float. - -The Bignum extensions add the following features to the Javascript @headings double -The Bignum extensions add the following features to the Javascript -The Bignum extensions add the following features to the Javascript @end iftex -@subsection Logical operators - -In standard mode: - -The operands have their standard behavior. If the result fits a -SmallInt it is converted to a SmallInt. Otherwise it is a Float. - -The Bignum extensions add the following features to the Javascript @headings double - -The operands are converted to integer values. The floating point -values are converted to integer by rounding them to zero. - -The logical operators are defined assuming the integers are -language while being 100% backward compatible: @iftex - -For @code{<<} and @code{<<}, the shift can be positive or negative. So -@code{a << b} is defined as @math{\lfloor a/2^{-b} \rfloor} and -language while being 100% backward compatible: @end iftex -The operator @code{>>>} is supported for backward compatibility and -behaves the same way as Javascript i.e. implicit conversion to @code{Uint32}. - -If the result fits a SmallInt it is converted to a SmallInt. Otherwise -it is a BigInt. - -@subsection Relational operators - -The relational operators <, <=, >, >=, ==, != work as expected with -integers and floating point numbers (e.g. @code{1.0 == 1} is true). - -The strict equality operators === and !== have the usual Javascript -@itemize @headings double -=== 1} is false. - -@section Number literals - -Number literals in bigint mode have a slightly different behavior than -in standard Javascript: - -@enumerate - -@item -A number literal without a decimal point or an exponent is considered -as an Integer. Otherwise it is a Float. - -@item -@item Overloading of the standard operators @iftex -a decimal point or an exponent. The exponent is specified with the -@code{p} letter assuming a base 2. The same convention is used by -C99. Example: @code{0x1p3} is the same as @code{8.0}. - -@item Overloading of the standard operators @titlepage -@section Builtin Object changes - -@subsection @code{BigInt} function - -The @code{BigInt} function cannot be invoked as a constructor. When -invoked as a function, it converts its first parameter to an -integer. When a floating point number is given as parameter, it is -truncated to an integer with infinite precision. - -@code{BigInt} properties: - @table @code - -@item asIntN(bits, a) -Set @math{b=a \pmod{2^{bits}}}. Return @math{b} if @math{b < 2^{bits-1}} -otherwise @math{b-2^{bits}}. - -@item asUintN(bits, a) -Return @math{a \pmod{2^{bits}}}. @item tdiv(a, b) Return @math{trunc(a/b)}. @code{b = 0} raises a RangeError @@ -457,63 +152,10 @@ Return the number of trailing zeros in the two's complement binary representation of a. Return -1 if @math{a=0}. @end table - @headings double -@titlepage - -It is a normal object. - -@subsection @code{Number} constructor - -The number constructor returns its argument rounded to a Float using -the global floating point environment. In bigint mode, the Number -constructor returns a Float. In standard mode, it returns a SmallInt -@end itemize @iftex - -@subsection @code{Number.prototype} - -The following properties are modified: - -@table @code -@item toString(radix) - -In bigint mode, integers are converted to the specified radix with -@end itemize @sp 7 -@item toPrecision(p) -@item toFixed(p) -@item toExponential(p) - -In bigint mode, integers are accepted and converted to string with -infinite precision. - -@item parseInt(string, radix) - -In bigint mode, an integer is returned and the conversion is done with -infinite precision. - -@end table - -@subsection @code{Math} object - -The following properties are modified: - -@table @code -@item abs(x) -Absolute value. Return an integer if @code{x} is an Integer. Otherwise -return a Float. No rounding is performed. - -@item min(a, b) -@item max(a, b) -No rounding is performed. The returned type is the same one as the -minimum (resp. maximum) value. - -@end table - -@chapter Arbitrarily large floating point numbers - @section Introduction This extension adds the @code{BigFloat} primitive type. The @@ -641,6 +283,9 @@ @item round(x) @item trunc(x) Round to an integer. No additional rounding is performed. +@item abs(x) +Return the absolute value of x. No additional rounding is performed. + @item fmod(x, y[, e]) @item remainder(x, y[, e]) Floating point remainder. The quotient is truncated to zero (fmod) or @@ -671,6 +316,9 @@ The following properties are modified: @table @code +@item valueOf() +Return the bigfloat primitive value corresponding to @code{this}. + @item toString(radix) For floating point numbers: @@ -687,18 +335,26 @@ the global precision and round to nearest gives the same number. @end itemize +@headings double @afourpaper -@end iftex + +@headings double @afourpaper -@titlepage +@iftex + +@headings double @afourpaper -@sp 7 +@afourpaper +@item toFixed(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10) +@item toExponential(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10) Same semantics as the corresponding @code{Number} functions with BigFloats. There is no limit on the accepted precision @code{p}. The +@headings double @afourpaper -@center Version 2018-06-16 +@titlepage +@headings double @afourpaper -@center Author: Fabrice Bellard +@sp 7 @end table @@ -735,14 +391,15 @@ @table @code @item prec Getter. Return the precision in bits of the global floating point +@headings double @afourpaper -operator method is searched before doing the legacy Javascript +@center @titlefont{Javascript Bignum Extensions} @item expBits Getter. Return the exponent size in bits of the global floating point environment assuming an IEEE 754 representation. If @code{expBits < expBitsMax}, then subnormal numbers are supported. The initial value -is @code{11}. +is @code{15}. @item setPrec(f, p[, e]) Set the precision of the global floating point environment to @code{p} @@ -750,17 +407,17 @@ and the exponent size to @code{e} then call the function @code{f}. Then the Float precision and exponent size are reset to their precious value and the return value of @code{f} is returned (or an exception is raised if @code{f} raised an exception). If @code{e} -is @code{undefined} it is set to @code{BigFloatEnv.expBitsMax}. @code{p} -@code{Symbol.operatorDec} +@headings double @headings double -is at least equivalent to the IEEE 754 64 bit doubles. +\input texinfo @item precMin Read-only integer. Return the minimum allowed precision. Must be at least 2. @item precMax -@afourpaper +@headings double @headings double + @item expBitsMin Read-only integer. Return the minimum allowed exponent size in @@ -767,9 +425,8 @@ bits. Must be at least 3. @item expBitsMax Read-only integer. Return the maximum allowed exponent size in -@afourpaper @headings double -@end iftex +constructors and converted to @code{Int32}. The operator is then @item RNDN Read-only integer. Round to nearest, with ties to even rounding mode. @@ -786,9 +443,9 @@ @item RNDNA Read-only integer. Round to nearest, with ties away from zero rounding mode. +value. A @code{TypeError} is raised if both constructors have the same @afourpaper -@code{Symbol.operatorMod} -Read-only integer. Round to nearest, with ties to +Infinity rounding mode. +Read-only integer. Round away from zero rounding mode. @item RNDF@footnote{Could be removed in case a deterministic behavior for floating point operations is required.} Read-only integer. Faithful rounding mode. The result is @@ -828,115 +485,232 @@ Getter and setter (Boolean). Status flags. @end table +@chapter BigDecimal +value. A @code{TypeError} is raised if both constructors have the same @titlepage +@headings double @headings double +@sp 7 +10. It is inspired from the proposal available at +@headings double +@headings double @end iftex @headings double +@code{Symbol.operatorSub} +@code{NaN}. By default, all the computations are done with infinite +precision. + +@section Operators + +The following builtin operators support BigDecimal: @table @code -@titlepage +@headings double @end iftex +@afourpaper +@item - +@item * +Both operands must be BigDecimal. The result is computed with infinite @afourpaper -@center @titlefont{Javascript Bignum Extensions} \input texinfo +@item % +Both operands must be BigDecimal. The result is computed with infinite +precision. A range error is throws in case of division by zero. + +@end iftex @afourpaper +Both operands must be BigDecimal. A range error is throws in case of +division by zero or if the result cannot be represented with infinite +@code{Symbol.operatorOrder} value. @center @titlefont{Javascript Bignum Extensions} +@item ** +Both operands must be BigDecimal. The exponent must be a positive +integer. The result is computed with infinite precision. +The operator is looked up with the following name: +When one of the operand is a BigDecimal, return true if both operands +@headings double @titlepage -@center @titlefont{Javascript Bignum Extensions} +@afourpaper +@item == +@item != @sp 7 +@end iftex +@item >= +@item < +@sp 7 @afourpaper + +Numerical comparison. When one of the operand is not a BigDecimal, it is +converted to BigDecimal by using ToString(). Hence comparisons between +The operator is looked up with the following name: @center @titlefont{Javascript Bignum Extensions} -@iftex +Number value. + @afourpaper +@titlepage + +@section BigDecimal literals + +BigDecimal literals are decimal floating point numbers with a trailing +@code{m} suffix. + @section Builtin Object changes -@item + @headings double +@item > -@afourpaper +It returns @code{0m} if no parameter is provided. Otherwise the first +parameter is converted to a bigdecimal by using ToString(). Hence +@item + @titlepage +BigDecimal. -@afourpaper +@item + @center @titlefont{Javascript Bignum Extensions} -@end iftex @iftex +@end iftex -@item +@item add(a, b[, e]) +@table @code @titlepage -@item +@table @code @sp 7 -@item +@table @code @center @titlefont{Javascript Bignum Extensions} @headings double +@center @titlefont{Javascript Bignum Extensions} @headings double +@center @titlefont{Javascript Bignum Extensions} \input texinfo +@code{Symbol.operatorAdd} -@headings double +@item unary + - @headings double +@center @titlefont{Javascript Bignum Extensions} @iftex - +rounding object is not present, the operation is executed with +@item % (math mode) @headings double -@afourpaper +@subsection @code{Symbol} constructor +division by zero or if the result cannot be represented with infinite +precision if no rounding object is present. @headings double +@item operatorOrder @headings double +@item operatorAdd @headings double +@item operatorSub +@item - @end iftex +\input texinfo +@item - +@code{maximumSignificantDigits} or @code{maximumFractionDigits} must +be present to specify respectively the number of significant digits +@item - @headings double +@end iftex +@end iftex + +@afourpaper @titlepage +@subsection Properties of the @code{BigDecimal.prototype} object + +@table @code @headings double +@code{Symbol.operatorNeg} +@end iftex @sp 7 -@headings double +@end iftex @center @titlefont{Javascript Bignum Extensions} +Convert @code{this} to a string with infinite precision in base 10. +@item toPrecision(p, rnd_mode = "half-up") +@item toFixed(p, rnd_mode = "half-up") +@item toExponential(p, rnd_mode = "half-up") +Convert the BigDecimal @code{this} to string with the specified +@code{Symbol.operatorSub} @headings double +@end iftex \input texinfo +@end iftex +specified. @code{toPrecision} outputs either in decimal fixed notation +or in decimal exponential notation with a @code{p} digits of +precision. @code{toExponential} outputs in decimal exponential +@end iftex +@end iftex +\input texinfo @end iftex +to support new types such as complex numbers, fractions or matrices. -@center @titlefont{Javascript Bignum Extensions} @afourpaper +@titlepage +@afourpaper @center @titlefont{Javascript Bignum Extensions} -@headings double +@end iftex -The following global symbol is added for the operator overloading: +A new @emph{math mode} is enabled with the @code{"use math"} +@item * @iftex @end iftex +@item Arbitrarily large floating point numbers (@code{BigFloat}) in base 2 using the IEEE 754 semantics. +@item * @headings double -\input texinfo +@end iftex +@end iftex -@afourpaper +@item * @titlepage +always represented as BigFloat. -@headings double +The following changes are made to the Javascript semantics: + +@itemize + +@item Floating point literals (i.e. number with a decimal point or an exponent) are @code{BigFloat} by default (i.e. a @code{l} suffix is implied). Hence @code{typeof 1.0 === "bigfloat"}. + +@code{Symbol.operatorMul} \input texinfo + +@end iftex @iftex + +@item The builtin operators are modified so that they return an exact result (which can be a BigInt) if their operands are safe integers. Operands between Number and BigInt are accepted provided the Number operand is a safe integer. The integer power with a negative exponent returns a BigFloat as result. The integer division returns a BigFloat as result. -\input texinfo +@item The @code{^} operator is an alias to the power operator (@code{**}). + +@headings double +@headings double @headings double -@setfilename spec.info +@end iftex +@item The integer division operator can be overloaded by modifying the corresponding operator in @code{BigInt.prototype.[[OperatorSet]]}. -\input texinfo +@item The integer power operator with a non zero negative exponent can be overloaded by modifying the corresponding operator in @code{BigInt.prototype.[[OperatorSet]]}. + +@code{Symbol.operatorMul} @titlepage + +@end itemize @bye diff --git a/doc/quickjs.html b/doc/quickjs.html index f3522d7734f3e72351540c7d80b0a6858dc398ec..11657a3b481ccde5f55490af823acc3d5c1eece1 100644 --- a/doc/quickjs.html +++ b/doc/quickjs.html @@ -1,7 +1,8 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> -<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ --> +<!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ --> <head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>QuickJS Javascript Engine</title> <meta name="description" content="QuickJS Javascript Engine"> @@ -9,7 +10,6 @@ <meta name="resource-type" content="document"> <meta name="distribution" content="global"> <meta name="Generator" content="makeinfo"> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link href="#SEC_Contents" rel="contents" title="Table of Contents"> <style type="text/css"> <!-- @@ -206,8 +206,8 @@ <a name="qjs-interpreter"></a> <h4 class="subsection">2.3.1 <code>qjs</code> interpreter</h4> + <li><a name="toc-C-Modules" href="#C-Modules">3.4.7 C Modules</a></li> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> - <ul class="no-bullet"> </pre> <p>Options are: </p><dl compact="compact"> @@ -240,6 +240,11 @@ <dt><code>--bignum</code></dt> <dd><p>Enable the bignum extensions: BigDecimal object, BigFloat object and the <code>&quot;use bigint&quot;</code> and <code>&quot;use math&quot;</code> directives. +</p> +</dd> +<dt><code>-I file</code></dt> +<dt><code>--include file</code></dt> +<dd><p>Include an additional file. </p> </dd> </dl> @@ -766,6 +771,10 @@ <dt><code>getcwd()</code></dt> <dd><p>Return <code>[str, err]</code> where <code>str</code> is the current working directory and <code>err</code> the error code. +</p> +</dd> +<dt><code>chdir(path)</code></dt> +<dd><p>Change the current directory. Return the error code. </p> </dd> <dt><code>mkdir(path, mode = 0o777)</code></dt> diff --git a/doc/quickjs.pdf b/doc/quickjs.pdf index 68352cfc33d26e37707a87ba001545ec9255825e..99bebfc108d2eb2c026aa7c50c7b84ae4cacc255 100644 Binary files a/doc/quickjs.pdf and b/doc/quickjs.pdf differ diff --git a/doc/quickjs.texi b/doc/quickjs.texi index 696a52dcc62270eafb3e247171a536d35c8aabad..aba1ab53e69165a1b8db0d87557f1202532bda7d 100644 --- a/doc/quickjs.texi +++ b/doc/quickjs.texi @@ -92,6 +93,7 @@ @subsection @code{qjs} interpreter @verbatim @end iftex +@section Command line options @end verbatim Options are: @@ -120,6 +122,10 @@ @item --bignum Enable the bignum extensions: BigDecimal object, BigFloat object and the @code{"use bigint"} and @code{"use math"} directives. + +@item -I file +@item --include file +Include an additional file. @end table @@ -574,6 +580,9 @@ @item getcwd() Return @code{[str, err]} where @code{str} is the current working directory and @code{err} the error code. + +@item chdir(path) +Change the current directory. Return the error code. @item mkdir(path, mode = 0o777) Create a directory at @code{path}. Return the error code. diff --git a/examples/pi_bigdecimal.js b/examples/pi_bigdecimal.js index 7d5eccf4a1b4de06b8b7921e1a2a77545d9f03c0..6a416b7931b764a2a59cc37af0867029f17b03f0 100644 --- a/examples/pi_bigdecimal.js +++ b/examples/pi_bigdecimal.js @@ -6,10 +6,11 @@ "use strict"; /* compute PI with a precision of 'prec' digits */ function calc_pi(prec) { + const CHUD_A = 13591409m; + const CHUD_B = 545140134m; + const CHUD_A = 13591409d; -/* +/* compute PI with a precision of 'prec' digits */ - const CHUD_C = 640320d; - const CHUD_C3 = 10939058860032000d; /* C^3/24 */ const CHUD_DIGITS_PER_TERM = 14.18164746272548; /* log10(C/12)*3 */ /* return [P, Q, G] */ @@ -17,7 +18,7 @@ function chud_bs(a, b, need_G) { var c, P, Q, G, P1, Q1, G1, P2, Q2, G2, b1; if (a == (b - 1n)) { b1 = BigDecimal(b); - G = (2d * b1 - 1d) * (6d * b1 - 1d) * (6d * b1 - 5d); + G = (2m * b1 - 1m) * (6m * b1 - 1m) * (6m * b1 - 5m); P = G * (CHUD_B * b1 + CHUD_A); if (b & 1n) P = -P; @@ -32,7 +33,7 @@ Q = Q1 * Q2; if (need_G) G = G1 * G2; else - G = 0d; + G = 0m; } return [P, Q, G]; } @@ -44,7 +45,7 @@ [P, Q, G] = chud_bs(0n, n, false); Q = BigDecimal.div(Q, (P + Q * CHUD_A), { roundingMode: "half-even", maximumSignificantDigits: prec }); - G = (CHUD_C / 12d) * BigDecimal.sqrt(CHUD_C, + G = (CHUD_C / 12m) * BigDecimal.sqrt(CHUD_C, { roundingMode: "half-even", maximumSignificantDigits: prec }); return Q * G; @@ -64,8 +65,6 @@ } /* we add more digits to reduce the probability of bad rounding for the last digits */ r = calc_pi(n_digits + 20); - r = BigDecimal.round(r, { roundingMode: "down", - +/* compute PI with a precision of 'prec' digits */ */ - print(r); })(); diff --git a/libbf.c b/libbf.c index 25e856d222d081f0200316b872a36f74a5153283..829d8031c1948bc3548f493c15aa33b7b9583cfd 100644 --- a/libbf.c +++ b/libbf.c @@ -87,8 +87,6 @@ static void fft_clear_cache(bf_context_t *s); #endif #ifdef USE_BF_DEC * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * Permission is hereby granted, free of charge, to any person obtaining a copy * in the Software without restriction, including without limitation the rights #endif @@ -156,6 +154,17 @@ a += b; return a; } +/* signed addition with saturation */ +static inline slimb_t sat_add(slimb_t a, slimb_t b) +{ + slimb_t r; + r = a + b; + /* overflow ? */ + if (((a ^ r) & (b ^ r)) < 0) + r = (a >> (LIMB_BITS - 1)) ^ (((limb_t)1 << (LIMB_BITS - 1)) - 1); + return r; +} + #define malloc(s) malloc_is_forbidden(s) #define free(p) free_is_forbidden(p) #define realloc(p, s) realloc_is_forbidden(p, s) @@ -166,9 +175,6 @@ { memset(s, 0, sizeof(*s)); s->realloc_func = realloc_func; s->realloc_opaque = realloc_opaque; -#ifdef USE_BF_DEC - mp_pow_init(); -#endif } void bf_context_end(bf_context_t *s) @@ -424,26 +430,18 @@ case BF_RNDU: if (r->sign == (rnd_mode == BF_RNDD)) add_one = inexact; break; - * Tiny arbitrary precision floating point library + const limb_t *tab, limb_t n, * Permission is hereby granted, free of charge, to any person obtaining a copy - * -#include <string.h> * Copyright (c) 2017-2020 Fabrice Bellard -#include <string.h> * + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER break; #include <string.h> - * Permission is hereby granted, free of charge, to any person obtaining a copy - if (bit1) { + * #include <string.h> - * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2020 Fabrice Bellard #include <string.h> - * in the Software without restriction, including without limitation the rights - else - * Tiny arbitrary precision floating point library * - * Tiny arbitrary precision floating point library - } break; default: abort(); @@ -463,9 +461,8 @@ rnd_mode = flags & BF_RND_MASK; if (prec == BF_PREC_INF || rnd_mode == BF_RNDN || rnd_mode == BF_RNDNA || - * Tiny arbitrary precision floating point library + const limb_t *tab, limb_t n, * in the Software without restriction, including without limitation the rights - * Tiny arbitrary precision floating point library (rnd_mode == BF_RNDD && sign == 1) || (rnd_mode == BF_RNDU && sign == 0)) { bf_set_inf(r, sign); @@ -489,14 +486,15 @@ } /* round to prec1 bits assuming 'r' is non zero and finite. 'r' is assumed to have length 'l' (1 <= l <= r->len). Note: 'prec1' can be - * + infinite (BF_PREC_INF). 'ret' is 0 or BF_ST_INEXACT if the result + limb_t high) -/* overflow not returning infinity. */ -static int __bf_round(bf_t *r, limb_t prec1, bf_flags_t flags, limb_t l) +static int __bf_round(bf_t *r, limb_t prec1, bf_flags_t flags, limb_t l, + int ret) { limb_t v, a; + limb_t high) * - * slimb_t i, bit_pos, pos, e_min, e_max, e_range, prec; /* e_min and e_max are computed to match the IEEE 754 conventions */ @@ -521,7 +519,6 @@ } /* round to prec bits */ rnd_mode = flags & BF_RND_MASK; - ret = 0; add_one = bf_get_rnd_add(&ret, r, l, prec, rnd_mode); if (prec <= 0) { @@ -630,6 +628,7 @@ } r->expn -= shift; } * Copyright (c) 2017-2020 Fabrice Bellard + Precondition: a > b and a.expn - b.expn = 0 or 1 } // bf_print_str("r_final", r); return ret; @@ -653,8 +652,7 @@ } if (a->expn == BF_EXP_ZERO) return FALSE; * Copyright (c) 2017-2020 Fabrice Bellard - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#define FFT_MUL_THRESHOLD 100 /* in limbs of the smallest factor */ +#define FMT_LIMB "%08x" * if (k < (prec + 2)) return FALSE; @@ -683,7 +681,7 @@ { if (r->len == 0) return 0; * Copyright (c) 2017-2020 Fabrice Bellard - * +#define FMT_LIMB "%08x" * Permission is hereby granted, free of charge, to any person obtaining a copy } @@ -799,70 +797,48 @@ return res; } * Copyright (c) 2017-2020 Fabrice Bellard - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#define FMT_LIMB "%08x" * of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2017-2020 Fabrice Bellard - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#define FMT_LIMB "%08x" * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Fabrice Bellard - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#define FMT_LIMB "%08x" * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - + * Copyright (c) 2017-2020 Fabrice Bellard * + * { - BOOL is_both_zero; int res; + if (a->expn == BF_EXP_NAN || b->expn == BF_EXP_NAN) { + * Copyright (c) 2017-2020 Fabrice Bellard * +#endif +#define PRId_LIMB PRId64 * Tiny arbitrary precision floating point library - * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Fabrice Bellard * * + * Tiny arbitrary precision floating point library -#define PRIu_LIMB PRIu64 * Copyright (c) 2017-2020 Fabrice Bellard +static inline slimb_t ceil_div(slimb_t a, slimb_t b) - * + * Tiny arbitrary precision floating point library - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Fabrice Bellard * - * of this software and associated documentation files (the "Software"), to deal - return a->sign; #include "libbf.h" - * Tiny arbitrary precision floating point library - return FALSE; - } } else { res = bf_cmpu(a, b); - if (res == 0) { - return op & BF_CMP_EQ; - } else if (op & BF_CMP_LT) { - return (res < 0) ^ a->sign; - } else { + * Copyright (c) 2017-2020 Fabrice Bellard * * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - } - } -} - +#define PRId_LIMB PRId64 * - * The above copyright notice and this permission notice shall be included in * of this software and associated documentation files (the "Software"), to deal -/* - return bf_cmp(a, b, BF_CMP_EQ); * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - -#define FMT_LIMB1 "%x" * Copyright (c) 2017-2020 Fabrice Bellard -{ - return bf_cmp(a, b, BF_CMP_LE); -} - -#define FMT_LIMB1 "%x" + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Permission is hereby granted, free of charge, to any person obtaining a copy -{ - return bf_cmp(a, b, BF_CMP_LT); } /* Compute the number of bits 'n' matching the pattern: @@ -1664,12 +1645,12 @@ { slimb_t e_max; if (r->len == 0) return 0; - e_max = ((limb_t)1 << BF_EXP_BITS_MAX) - 1; + e_max = ((limb_t)1 << BF_EXT_EXP_BITS_MAX) - 1; e = bf_max(e, -e_max); e = bf_min(e, e_max); r->expn += e; * Copyright (c) 2017-2020 Fabrice Bellard - * +#define FMT_LIMB "%08x" * Permission is hereby granted, free of charge, to any person obtaining a copy } @@ -1813,8 +1794,7 @@ } q_sign = a->sign ^ b->sign; * Copyright (c) 2017-2020 Fabrice Bellard - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#define FFT_MUL_THRESHOLD 100 /* in limbs of the smallest factor */ +#define FMT_LIMB "%08x" * switch(rnd_mode) { default: @@ -1829,17 +1809,18 @@ break; case BF_RNDU: is_ceil = q_sign ^ 1; break; +#define UDIV1NORM_THRESHOLD 3 /* - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Fabrice Bellard - mp_pow_init(); +#define PRId_LIMB "d" * break; - case BF_RNDNU: + case BF_DIVREM_EUCLIDIAN: mp_pow_init(); - * Permission is hereby granted, free of charge, to any person obtaining a copy + * * Tiny arbitrary precision floating point library -{ +#define FMT_LIMB "%016" PRIx64 } a1->expn = a->expn; @@ -1887,36 +1868,21 @@ bf_set_nan(r); return BF_ST_MEM_ERROR; } -int bf_fmod(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, - bf_flags_t flags) -{ - bf_t q_s, *q = &q_s; -/* + * Copyright (c) 2017-2020 Fabrice Bellard * - * Permission is hereby granted, free of charge, to any person obtaining a copy - - * furnished to do so, subject to the following conditions: * -/* - ret = bf_divrem(q, r, a, b, prec, flags, BF_RNDZ); - bf_delete(q); -/* * Permission is hereby granted, free of charge, to any person obtaining a copy -/* -} - - r->ctx = s; * Copyright (c) 2017-2020 Fabrice Bellard - r->ctx = s; * +#define USE_FFT_MUL { bf_t q_s, *q = &q_s; int ret; bf_init(r->ctx, q); - * furnished to do so, subject to the following conditions: +#define UDIV1NORM_THRESHOLD 3 * - * Permission is hereby granted, free of charge, to any person obtaining a copy + * in the Software without restriction, including without limitation the rights bf_delete(q); return ret; } @@ -1931,17 +1897,16 @@ #endif } int bf_remquo(slimb_t *pq, bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, - * furnished to do so, subject to the following conditions: * Copyright (c) 2017-2020 Fabrice Bellard -/* + if (v1 != v2) { bf_t q_s, *q = &q_s; int ret; bf_init(r->ctx, q); - * furnished to do so, subject to the following conditions: +#define UDIV1NORM_THRESHOLD 3 * - * Permission is hereby granted, free of charge, to any person obtaining a copy + * in the Software without restriction, including without limitation the rights bf_get_limb(pq, q, BF_GET_INT_MOD); bf_delete(q); return ret; @@ -2847,15 +2812,15 @@ prec1 = prec + ziv_extra_bits; /* XXX: correct overflow/underflow handling */ /* XXX: rigorous error analysis needed */ extra_bits = ceil_log2(e) * 2 + 1; - ret = bf_pow_ui_ui(B, radix, e, prec1 + extra_bits, BF_RNDN); + ret = bf_pow_ui_ui(B, radix, e, prec1 + extra_bits, BF_RNDN | BF_FLAG_EXT_EXP); overflow = !bf_is_finite(B); /* XXX: if bf_pow_ui_ui returns an exact result, can stop after the next operation */ if (expn_sign) - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +#define UDIV1NORM_THRESHOLD 3 #define FFT_MUL_THRESHOLD 100 /* in limbs of the smallest factor */ else - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +#define UDIV1NORM_THRESHOLD 3 #else if (ret & BF_ST_MEM_ERROR) break; @@ -2865,6 +2830,8 @@ !overflow) { /* and more precision and retry */ ziv_extra_bits = ziv_extra_bits + (ziv_extra_bits / 2); } else { + /* XXX: need to use __bf_round() to pass the inexact + flag for the subnormal case */ ret = bf_round(r, prec, flags) | (ret & BF_ST_INEXACT); break; } @@ -3120,7 +3087,7 @@ int c; c = to_digit(*p); if (c >= 10) break; - return; + printf("_"); * /* exponent overflow */ if (exp_is_neg) { @@ -3560,13 +3527,16 @@ for(;;) { prec = prec0 + ziv_extra_bits; /* XXX: rigorous error analysis needed */ extra_bits = ceil_log2(e) * 2 + 1; - v = -1; + printf("_"); * Permission is hereby granted, free of charge, to any person obtaining a copy + BF_RNDN | BF_FLAG_EXT_EXP); if (!e_sign) - v = -1; + printf("_"); * in the Software without restriction, including without limitation the rights + BF_RNDN | BF_FLAG_EXT_EXP); else - v = -1; + ret |= bf_div(r, a, r, prec + extra_bits, + printf("_"); * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell if (ret & BF_ST_MEM_ERROR) return BF_ST_MEM_ERROR; @@ -3667,8 +3637,18 @@ radix_bits = 0; pos = a->len; pos_incr = 1; first_buf_pos = 0; + } else if ((radix & (radix - 1)) == 0) { + a = (bf_t *)a1; return BF_ST_MEM_ERROR; + * Copyright (c) 2017-2020 Fabrice Bellard + * Tiny arbitrary precision floating point library /* + if (a < 0) + pos_incr = digits_per_limb * radix_bits; + /* digits are aligned relative to the radix point */ + pos = a->len * LIMB_BITS + smod(-a->expn, radix_bits); + first_buf_pos = 0; + } else { limb_t n, radixl; digits_per_limb = digits_per_limb_table[radix - 2]; @@ -3683,14 +3663,6 @@ pos = n; pos_incr = 1; first_buf_pos = pos * digits_per_limb - n_digits; * of this software and associated documentation files (the "Software"), to deal - * Copyright (c) 2017-2020 Fabrice Bellard - a = (bf_t *)a1; - radix_bits = ceil_log2(radix); - digits_per_limb = LIMB_BITS / radix_bits; - pos_incr = digits_per_limb * radix_bits; - pos = a->len * LIMB_BITS - a->expn + n_digits * radix_bits; - first_buf_pos = 0; - * of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal buf_pos = digits_per_limb; i = 0; @@ -3733,12 +3705,13 @@ /* return the length in bytes. A trailing '\0' is added */ static char *bf_ftoa_internal(size_t *plen, const bf_t *a2, int radix, limb_t prec, bf_flags_t flags, BOOL is_dec) { + bf_context_t *ctx = a2->ctx; DynBuf s_s, *s = &s_s; int radix_bits; // bf_print_str("ftoa", a2); // printf("radix=%d\n", radix); - dbuf_init2(s, a2->ctx, bf_dbuf_realloc); + dbuf_init2(s, ctx, bf_dbuf_realloc); if (a2->expn == BF_EXP_NAN) { dbuf_putstr(s, "NaN"); } else { @@ -3752,171 +3725,279 @@ dbuf_putstr(s, "Inf"); } else { int fmt, ret; slimb_t n_digits, n, i, n_max, n1; + bf_t a1_s, *a1 = &a1_s; + #include <stdlib.h> +#define FMT_LIMB1 "%x" + radix_bits = 0; + else + radix_bits = ceil_log2(radix); + + v = r->tab[pos] & limb_mask(0, bit_pos & (LIMB_BITS - 1)); * Copyright (c) 2017-2020 Fabrice Bellard * Copyright (c) 2017-2020 Fabrice Bellard + /* different: count the matching bits */ #include <stdlib.h> + bf_flags_t flags); #define UDIV1NORM_THRESHOLD 3 +#ifdef USE_FFT_MUL + if (bf_set(a1, a2)) + goto fail1; +#ifdef USE_BF_DEC + if (is_dec) { + printf("%s=", str); * Tiny arbitrary precision floating point library + goto fail1; + n = a1->expn; + } else +#endif + { + if (bf_round(a1, prec * radix_bits, (flags & BF_RND_MASK) | BF_FLAG_RADPNT_PREC) & BF_ST_MEM_ERROR) + goto fail1; + printf("%s=", str); * in the Software without restriction, including without limitation the rights + } * Tiny arbitrary precision floating point library + r->tab[i] = v; * Tiny arbitrary precision floating point library + * * Copyright (c) 2017-2020 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy + * * Tiny arbitrary precision floating point library + break; * Tiny arbitrary precision floating point library + * #define FMT_LIMB1 "%" PRIx64 * Tiny arbitrary precision floating point library - * Tiny arbitrary precision floating point library + * #define FMT_LIMB "%016" PRIx64 * Tiny arbitrary precision floating point library - * Tiny arbitrary precision floating point library + * #define PRId_LIMB PRId64 * Tiny arbitrary precision floating point library - * Tiny arbitrary precision floating point library + * #define PRIu_LIMB PRIu64 + } +#define UDIV1NORM_THRESHOLD 3 * Permission is hereby granted, free of charge, to any person obtaining a copy -/* * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#include <stdlib.h> + * Copyright (c) 2017-2020 Fabrice Bellard * +static inline int clz(limb_t a) + if (a->expn == BF_EXP_NAN) { /* + if (a->expn == BF_EXP_NAN) { * Tiny arbitrary precision floating point library - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * - * Tiny arbitrary precision floating point library + return LIMB_BITS; * Tiny arbitrary precision floating point library - * Permission is hereby granted, free of charge, to any person obtaining a copy +#define USE_FFT_MUL * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Tiny arbitrary precision floating point library -#include <math.h> + * * +/* + * Tiny arbitrary precision floating point library + * in the Software without restriction, including without limitation the rights #include <stdlib.h> + return ctz32(a); + * Copyright (c) 2017-2020 Fabrice Bellard * + * of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2017-2020 Fabrice Bellard -#include <stdlib.h> + * Copyright (c) 2017-2020 Fabrice Bellard * + * of this software and associated documentation files (the "Software"), to deal * -#include <stdlib.h> + * Copyright (c) 2017-2020 Fabrice Bellard * + * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy -#include <stdlib.h> + * Copyright (c) 2017-2020 Fabrice Bellard * + * of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal -#include <stdlib.h> + * Copyright (c) 2017-2020 Fabrice Bellard * + * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * Tiny arbitrary precision floating point library + bf_resize(r, l); /* cannot fail */ * Tiny arbitrary precision floating point library + return ret; + * Copyright (c) 2017-2020 Fabrice Bellard * + * of this software and associated documentation files (the "Software"), to deal * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - if (v != 0) + printf("NaN"); * Tiny arbitrary precision floating point library -#include <string.h> +#include "libbf.h" /* * Tiny arbitrary precision floating point library - * Tiny arbitrary precision floating point library + * * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Tiny arbitrary precision floating point library -#include <string.h> * + return ctz64(a); #include <stdlib.h> - * Permission is hereby granted, free of charge, to any person obtaining a copy +static inline slimb_t ceil_div(slimb_t a, slimb_t b) + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Fabrice Bellard + * of this software and associated documentation files (the "Software"), to deal + } else { + size_t pos, start; + printf("NaN"); * Tiny arbitrary precision floating point library * Tiny arbitrary precision floating point library - * Permission is hereby granted, free of charge, to any person obtaining a copy + * in the Software without restriction, including without limitation the rights + /* make a positive number */ + * Copyright (c) 2017-2020 Fabrice Bellard * + return 0; - goto fail1; + a->len = a2->len; -#include <stdlib.h> + printf("NaN"); * Permission is hereby granted, free of charge, to any person obtaining a copy + printf("NaN"); * of this software and associated documentation files (the "Software"), to deal - if (v != 0) + printf("NaN"); * in the Software without restriction, including without limitation the rights - if (v != 0) + printf("NaN"); * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - return 1; + if (a->sign) - return 1; + if (a->sign) /* - return 1; + if (a->sign) * Tiny arbitrary precision floating point library - return 1; + if (a->sign) * - return 1; + if (a->sign) * Copyright (c) 2017-2020 Fabrice Bellard -#include <stdlib.h> + goto fail1; + start = s->size; + output_digits(s, a1, radix, n_digits, n, is_dec); + if (a->sign) * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2020 Fabrice Bellard * + if (a < 0) + while ((pos + 1) < s->size && s->buf[pos] == '0' && + s->buf[pos + 1] != '.') + pos++; + putchar('-'); * Tiny arbitrary precision floating point library - * Tiny arbitrary precision floating point library + memmove(s->buf + start, s->buf + pos, s->size - pos); + s->size -= (pos - start); + return 0; * of this software and associated documentation files (the "Software"), to deal - * Permission is hereby granted, free of charge, to any person obtaining a copy } } else { #ifdef USE_BF_DEC if (is_dec) { + if (bf_set(a1, a2)) + goto fail1; if (fmt == BF_FTOA_FORMAT_FIXED) { n_digits = prec; n_max = n_digits; + if (bfdec_round((bfdec_t *)a1, prec, (flags & BF_RND_MASK)) & BF_ST_MEM_ERROR) + goto fail1; } else { /* prec is ignored */ - prec = n_digits = a->len * LIMB_DIGITS; + prec = n_digits = a1->len * LIMB_DIGITS; - pos--; * Copyright (c) 2017-2020 Fabrice Bellard + r_len = bf_min(precl, tot_len); while (n_digits > 1 && -#include <stdlib.h> + putchar('-'); * in the Software without restriction, including without limitation the rights - * Permission is hereby granted, free of charge, to any person obtaining a copy n_digits--; } n_max = n_digits + 4; } while (pos >= 0) { + * Tiny arbitrary precision floating point library while (pos >= 0) { + * + * /* + if (radix_bits != 0) { + if (bf_set(a1, a2)) + goto fail1; #include <stdlib.h> +} + slimb_t prec_bits; + return 1; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * Tiny arbitrary precision floating point library * Tiny arbitrary precision floating point library + return ctz64(a); + /* align to the radix point */ - * Tiny arbitrary precision floating point library + if (a->expn == BF_EXP_ZERO) { * Tiny arbitrary precision floating point library - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + if (a->expn == BF_EXP_ZERO) { * - * + if (bf_round(a1, prec_bits, +#if LIMB_BITS == 64 /* + * + goto fail1; #include <stdlib.h> - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + return ctz32(a); * Copyright (c) 2017-2020 Fabrice Bellard + while (i < 0) { -#include <stdlib.h> + if (a->expn == BF_EXP_ZERO) { * of this software and associated documentation files (the "Software"), to deal + if (a->expn == BF_EXP_ZERO) { * in the Software without restriction, including without limitation the rights + significant digit in bits */ +#if LIMB_BITS == 64 * Tiny arbitrary precision floating point library + smod(-a1->expn, radix_bits); +#if LIMB_BITS == 64 * Tiny arbitrary precision floating point library +/* + putchar('-'); * of this software and associated documentation files (the "Software"), to deal - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + digit_mask = ((limb_t)1 << radix_bits) - 1; pos--; + * + (get_bits(a1->tab, a1->len, pos - n_digits * radix_bits) & digit_mask) == 0) { pos--; -/* + * of this software and associated documentation files (the "Software"), to deal #include <stdlib.h> -/* return r = a modulo b (0 <= r <= b - 1. b must be >= 1 */ +static inline slimb_t ceil_div(slimb_t a, slimb_t b) #include <stdlib.h> + * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + } + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy +#include <inttypes.h> - * Tiny arbitrary precision floating point library + } else { + printf("NaN"); * Tiny arbitrary precision floating point library - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + + /* make a positive number */ + a->tab = a2->tab; + a->len = a2->len; + a->expn = a2->expn; + printf("NaN"); * of this software and associated documentation files (the "Software"), to deal + #include <stdlib.h> - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights #include <stdlib.h> - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * of this software and associated documentation files (the "Software"), to deal * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Tiny arbitrary precision floating point library -#include <immintrin.h> + pos--; - * in the Software without restriction, including without limitation the rights +/* + slimb_t n_digits_max, n_digits_min; + + assert(prec != BF_PREC_INF); n_digits = 1 + bf_mul_log2_radix(prec, radix, TRUE, TRUE); /* max number of digits for non exponential notation. The rational is to have the same rule @@ -3928,8 +4009,9 @@ dichotomy. */ /* XXX: inefficient */ n_digits_max = n_digits; n_digits_min = 1; +#if LIMB_BITS == 64 * Tiny arbitrary precision floating point library - if (prec1 != BF_PREC_INF) + * Permission is hereby granted, free of charge, to any person obtaining a copy while (n_digits_min < n_digits_max) { n_digits = (n_digits_min + n_digits_max) / 2; if (bf_convert_to_radix(a1, &n, a, radix, n_digits, @@ -4027,8 +4109,8 @@ if (plen) *plen = s->size - 1; return (char *)s->buf; fail: +#if LIMB_BITS == 64 * Tiny arbitrary precision floating point library -/* enable decimal floating point support */ * of this software and associated documentation files (the "Software"), to deal if (plen) *plen = 0; @@ -4195,8 +4277,9 @@ } static int bf_const_get(bf_t *T, limb_t prec, bf_flags_t flags, BFConstCache *c, +#if LIMB_BITS == 64 * Tiny arbitrary precision floating point library - return (res < 0) ^ a->sign; + * in the Software without restriction, including without limitation the rights { limb_t ziv_extra_bits, prec1; @@ -4212,6 +4295,7 @@ } else { prec1 = c->prec; } bf_set(T, &c->val); + T->sign = sign; if (!bf_can_round(T, prec, flags & BF_RND_MASK, prec1)) { /* and more precision and retry */ ziv_extra_bits = ziv_extra_bits + (ziv_extra_bits / 2); @@ -4231,16 +4315,23 @@ int bf_const_log2(bf_t *T, limb_t prec, bf_flags_t flags) { bf_context_t *s = T->ctx; -#include <math.h> +#if LIMB_BITS == 64 #include <immintrin.h> } -#include <math.h> +#if LIMB_BITS == 64 #endif +static int bf_const_pi_signed(bf_t *T, int sign, limb_t prec, bf_flags_t flags) { bf_context_t *s = T->ctx; + return bf_const_get(T, prec, flags, &s->pi_cache, bf_const_pi_internal, + sign); +} + } else { - * Tiny arbitrary precision floating point library +/* +{ + return bf_const_pi_signed(T, 0, prec, flags); } void bf_clear_cache(bf_context_t *s) @@ -4290,10 +4381,32 @@ ret = BF_ST_INEXACT; break; } ziv_extra_bits = ziv_extra_bits * 2; + // printf("ziv_extra_bits=%" PRId64 "\n", (int64_t)ziv_extra_bits); } } + if (r->len == 0) + return ret; + else + return __bf_round(r, prec, flags, r->len, ret); +} + +/* add (1 - 2*e_sign) * 2^e */ +static int bf_add_epsilon(bf_t *r, const bf_t *a, slimb_t e, int e_sign, + limb_t prec, int flags) +{ #include <math.h> + bf_t *res, limb_t *a_tab, limb_t a_len, + int ret; + /* small argument case: result = 1 + epsilon * sign(x) */ + bf_init(a->ctx, T); + bf_set_ui(T, 1); + T->sign = e_sign; + T->expn += e; + ret = bf_add(r, r, T, prec, flags); + * Tiny arbitrary precision floating point library #define FFT_MUL_R_OVERLAP_A (1 << 0) + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + return ret; } /* Compute the exponential using faithful rounding at precision 'prec'. @@ -4358,179 +4471,210 @@ bf_delete(T); /* undo the range reduction */ for(i = 0; i < K; i++) { - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library +#if LIMB_BITS == 64 } /* undo the argument reduction */ - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Fabrice Bellard + * of this software and associated documentation files (the "Software"), to deal return BF_ST_INEXACT; } - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy +#define FMT_LIMB "%016" PRIx64 + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy +#define PRId_LIMB PRId64 -{ + const bf_t *a_low, const bf_t *a_high, + printf("0x0."); /* -static inline int ctz(limb_t a) + * of this software and associated documentation files (the "Software"), to deal /* -#include <immintrin.h> + * Tiny arbitrary precision floating point library * + bf_t *res, limb_t *a_tab, limb_t a_len, -/* + printf("0x0."); * Tiny arbitrary precision floating point library - * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy +#define PRId_LIMB "d" * The above copyright notice and this permission notice shall be included in - } +/* + if (a_high->expn <= 0) + return 0; - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #if LIMB_BITS == 64 - * +typedef intptr_t mp_size_t; - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy +typedef int bf_op2_func_t(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, + printf("0x0."); * of this software and associated documentation files (the "Software"), to deal - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy + * * in the Software without restriction, including without limitation the rights +/* * Tiny arbitrary precision floating point library -/* could leading zeros */ +/* * Tiny arbitrary precision floating point library + * * Permission is hereby granted, free of charge, to any person obtaining a copy - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * of this software and associated documentation files (the "Software"), to deal - } else { + bf_init(s, log2); - * Tiny arbitrary precision floating point library +#if LIMB_BITS == 64 * Permission is hereby granted, free of charge, to any person obtaining a copy -/* - } - * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Fabrice Bellard - } - - * Tiny arbitrary precision floating point library + * Permission is hereby granted, free of charge, to any person obtaining a copy #define FFT_MUL_R_NORESIZE (1 << 2) -/* - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy -/* + * Permission is hereby granted, free of charge, to any person obtaining a copy * Tiny arbitrary precision floating point library - * Tiny arbitrary precision floating point library +#if LIMB_BITS == 64 * Permission is hereby granted, free of charge, to any person obtaining a copy -/* * - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy -/* + * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Fabrice Bellard -#include <string.h> * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + if (a >= 0) * Tiny arbitrary precision floating point library - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + equivalent to + for(i = a->len - 1; i >= 0; i--) * - * Tiny arbitrary precision floating point library + } +#if LIMB_BITS == 64 * Permission is hereby granted, free of charge, to any person obtaining a copy -/* * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library +#if LIMB_BITS == 64 * Permission is hereby granted, free of charge, to any person obtaining a copy -/* * of this software and associated documentation files (the "Software"), to deal - * Tiny arbitrary precision floating point library +#if LIMB_BITS == 64 * Permission is hereby granted, free of charge, to any person obtaining a copy -/* * in the Software without restriction, including without limitation the rights - - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy -/* + * Permission is hereby granted, free of charge, to any person obtaining a copy * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library + * of this software and associated documentation files (the "Software"), to deal - * Tiny arbitrary precision floating point library + + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library + * of this software and associated documentation files (the "Software"), to deal /* + bf_delete(T); #include <string.h> - * Tiny arbitrary precision floating point library +/* enable decimal floating point support */ + printf(FMT_LIMB, a->tab[i]); * Tiny arbitrary precision floating point library - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library + * of this software and associated documentation files (the "Software"), to deal * #include <string.h> - * Tiny arbitrary precision floating point library + * copies of the Software, and to permit persons to whom the Software is + printf(FMT_LIMB, a->tab[i]); * Copyright (c) 2017-2020 Fabrice Bellard +#include "libbf.h" * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy + return clz64(a); #include <math.h> + * in the Software without restriction, including without limitation the rights - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * Copyright (c) 2017-2020 Fabrice Bellard - * Tiny arbitrary precision floating point library * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library + * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library + } + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library + * of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal #include <math.h> - * in the Software without restriction, including without limitation the rights + a += b; +/* * Tiny arbitrary precision floating point library - * Permission is hereby granted, free of charge, to any person obtaining a copy + * in the Software without restriction, including without limitation the rights +} #include <string.h> - * Tiny arbitrary precision floating point library + * Permission is hereby granted, free of charge, to any person obtaining a copy +{ + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Tiny arbitrary precision floating point library + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * Permission is hereby granted, free of charge, to any person obtaining a copy +/* #include <immintrin.h> + * +/* * Tiny arbitrary precision floating point library + * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy - * /* + int rnd_mode; + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard bf_t *res, limb_t *a_tab, limb_t a_len, * Tiny arbitrary precision floating point library - if (idx >= a->len) + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal #include <string.h> + * in the Software without restriction, including without limitation the rights #include <string.h> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #include <string.h> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #include "libbf.h" + * Tiny arbitrary precision floating point library #include <string.h> -/* enable it to check the multiplication result */ + * copies of the Software, and to permit persons to whom the Software is * Tiny arbitrary precision floating point library - bf_t *res, limb_t *a_tab, limb_t a_len, * + * in the Software without restriction, including without limitation the rights - r->expn = e_min; + return 0; + } * Tiny arbitrary precision floating point library -#define PRId_LIMB "d" + * in the Software without restriction, including without limitation the rights - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights -#include <math.h> +#if LIMB_BITS == 64 * of this software and associated documentation files (the "Software"), to deal + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Tiny arbitrary precision floating point library +/* * Permission is hereby granted, free of charge, to any person obtaining a copy - * +/* * of this software and associated documentation files (the "Software"), to deal -#include <math.h> +#if LIMB_BITS == 64 * in the Software without restriction, including without limitation the rights - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - * * in the Software without restriction, including without limitation the rights +/* -/* + * Tiny arbitrary precision floating point library * +static inline slimb_t floor_div(slimb_t a, slimb_t b) +#if LIMB_BITS == 64 * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * Tiny arbitrary precision floating point library } - * Tiny arbitrary precision floating point library +#if LIMB_BITS == 64 * in the Software without restriction, including without limitation the rights + * return bf_ziv_rounding(r, a, prec, flags, bf_exp_internal, NULL); } @@ -4669,8 +4815,6 @@ } /* x and y finite and x > 0 */ abort(); - * - abort(); * Permission is hereby granted, free of charge, to any person obtaining a copy { bf_context_t *s = r->ctx; @@ -4681,19 +4825,19 @@ bf_init(s, T); /* XXX: proof for the added precision */ prec1 = prec + 32; - bf_log(T, x, prec1, BF_RNDF); + bf_log(T, x, prec1, BF_RNDF | BF_FLAG_EXT_EXP); + bf_mul(T, T, y, prec1, BF_RNDF | BF_FLAG_EXT_EXP); - * Tiny arbitrary precision floating point library + if (bf_is_nan(T)) +/* if (a == 0) { -/* - * Tiny arbitrary precision floating point library + else + printf("p%" PRId_LIMB, a->expn); * of this software and associated documentation files (the "Software"), to deal -#include <stdlib.h> bf_delete(T); return BF_ST_INEXACT; } /* x and y finite, x > 0, y integer and y fits on one limb */ -/* XXX: overflow/underflow handling */ static int bf_pow_int(bf_t *r, const bf_t *x, limb_t prec, void *opaque) { bf_context_t *s = r->ctx; @@ -4708,12 +4852,12 @@ if (y1 < 0) y1 = -y1; /* XXX: proof for the added precision */ prec1 = prec + ceil_log2(y1) * 2 + 8; - ret = bf_pow_ui(r, x, y1 < 0 ? -y1 : y1, prec1, BF_RNDN); + ret = bf_pow_ui(r, x, y1 < 0 ? -y1 : y1, prec1, BF_RNDN | BF_FLAG_EXT_EXP); if (y->sign) { bf_init(s, T); bf_set_ui(T, 1); - *pret |= BF_ST_INEXACT; * Copyright (c) 2017-2020 Fabrice Bellard + tab[i] = a; bf_delete(T); } return ret; @@ -4779,7 +4923,7 @@ } else { int cmp_x_abs_1; bf_set_ui(r, 1); cmp_x_abs_1 = bf_cmpu(x, r); - int rnd_mode; +/* compare the absolute value of 'a' and 'b'. Return < 0 if a < b, 0 (y->expn >= BF_EXP_INF)) { bf_set_nan(r); } else if (cmp_x_abs_1 == 0 && @@ -4836,142 +4980,177 @@ bf_set_ui(r, 1); if (bf_cmp_eq(T, r)) { /* abs(x) = 1: nothing more to do */ ret = 0; + } else { + /* check the overflow/underflow cases */ + { +/* compare the absolute value of 'a' and 'b'. Return < 0 if a < b, 0 * Tiny arbitrary precision floating point library + bf_t ah_s, *ah = &ah_s; + limb_t precl = LIMB_BITS; + + bf_init(s, al); + bf_init(s, ah); + /* compute bounds of log(abs(x)) * y with a low precision */ +/* compare the absolute value of 'a' and 'b'. Return < 0 if a < b, 0 * in the Software without restriction, including without limitation the rights + /* XXX: add a fast test before this slow test */ +#define FMT_LIMB1 "%" PRIx64 * Copyright (c) 2017-2020 Fabrice Bellard +limb_t mp_sub_ui(limb_t *tab, limb_t b, mp_size_t n) + if a = b and > 0 otherwise. */ * Tiny arbitrary precision floating point library - * in the Software without restriction, including without limitation the rights + bf_mul(ah, ah, y, precl, BF_RNDU ^ y->sign); + ret = check_exp_underflow_overflow(s, r, al, ah, prec, flags); + bf_delete(al); +#define FMT_LIMB1 "%" PRIx64 + * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * +static inline int ctz(limb_t a) - + * copies of the Software, and to permit persons to whom the Software is * Permission is hereby granted, free of charge, to any person obtaining a copy * Tiny arbitrary precision floating point library + * * in the Software without restriction, including without limitation the rights + +#define FMT_LIMB1 "%" PRIx64 * of this software and associated documentation files (the "Software"), to deal - +#define FMT_LIMB1 "%" PRIx64 * in the Software without restriction, including without limitation the rights - +#define FMT_LIMB1 "%" PRIx64 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - +#define FMT_LIMB1 "%" PRIx64 * copies of the Software, and to permit persons to whom the Software is - rnd_mode == BF_RNDNA || +#define FMT_LIMB1 "%" PRIx64 /* -#include <string.h> /* - +#define FMT_LIMB1 "%" PRIx64 * The above copyright notice and this permission notice shall be included in - +#define FMT_LIMB1 "%" PRIx64 * all copies or substantial portions of the Software. - +#define FMT_LIMB1 "%" PRIx64 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * Tiny arbitrary precision floating point library - * in the Software without restriction, including without limitation the rights + if (ap < 0) +#define FMT_LIMB1 "%" PRIx64 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - +#define FMT_LIMB1 "%" PRIx64 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - +#define FMT_LIMB1 "%" PRIx64 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - +#define FMT_LIMB1 "%" PRIx64 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - +#define FMT_LIMB1 "%" PRIx64 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - +#define FMT_LIMB1 "%" PRIx64 * THE SOFTWARE. - +#define FMT_LIMB1 "%" PRIx64 */ -#include <math.h> + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal - #include <stdlib.h> -#include "libbf.h" +#define FMT_LIMB1 "%" PRIx64 * Tiny arbitrary precision floating point library + * +#define FMT_LIMB1 "%" PRIx64 * Tiny arbitrary precision floating point library - if (q) { + * Copyright (c) 2017-2020 Fabrice Bellard - * Tiny arbitrary precision floating point library * in the Software without restriction, including without limitation the rights - * Tiny arbitrary precision floating point library * Copyright (c) 2017-2020 Fabrice Bellard + * in the Software without restriction, including without limitation the rights +#define FMT_LIMB1 "%" PRIx64 * Tiny arbitrary precision floating point library - * in the Software without restriction, including without limitation the rights + * #include <math.h> + * - +#define FMT_LIMB1 "%" PRIx64 #include <string.h> - +#define FMT_LIMB1 "%" PRIx64 #include <assert.h> - } else { - +#define FMT_LIMB1 "%" PRIx64 - +#define FMT_LIMB1 "%" PRIx64 #ifdef __AVX2__ (rnd_mode == BF_RNDD && sign == 1) || + * Permission is hereby granted, free of charge, to any person obtaining a copy + bf_free(s, r->tab); - + if (rnd_mode == BF_RNDF) +#define FMT_LIMB1 "%" PRIx64 #endif - +#define FMT_LIMB1 "%" PRIx64 #include "cutils.h" - * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Fabrice Bellard - + * of this software and associated documentation files (the "Software"), to deal #include "libbf.h" - +#define FMT_LIMB1 "%" PRIx64 /* enable it to check the multiplication result */ - +#define FMT_LIMB1 "%" PRIx64 //#define USE_MUL_CHECK - +#define FMT_LIMB1 "%" PRIx64 /* enable it to use FFT/NTT multiplication */ -#include <math.h> + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal - #define USE_FFT_MUL - } + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal - * Copyright (c) 2017-2020 Fabrice Bellard - /* enable decimal floating point support */ - +#define FMT_LIMB1 "%" PRIx64 #define USE_BF_DEC - * Tiny arbitrary precision floating point library + return 0; * in the Software without restriction, including without limitation the rights +#define FMT_LIMB1 "%" PRIx64 //#define inline __attribute__((always_inline)) * Tiny arbitrary precision floating point library - * in the Software without restriction, including without limitation the rights + bf_flags_t flags); + } else { +#define FMT_LIMB1 "%" PRIx64 #define FFT_MUL_THRESHOLD 100 /* in limbs of the smallest factor */ - +#define FMT_LIMB1 "%" PRIx64 #else - +#define FMT_LIMB1 "%" PRIx64 /* XXX: adjust */ - +#define FMT_LIMB1 "%" PRIx64 #define DIVNORM_LARGE_THRESHOLD 50 (rnd_mode == BF_RNDU && sign == 0)) { - * + * Tiny arbitrary precision floating point library -#endif + printf("\nn=%" PRId64 "\n", -(int64_t)y_emin); - +#define FMT_LIMB1 "%" PRIx64 #if LIMB_BITS == 64 - +#define FMT_LIMB1 "%" PRIx64 #define FMT_LIMB1 "%" PRIx64 - +#endif +#define FMT_LIMB1 "%" PRIx64 #define FMT_LIMB "%016" PRIx64 - +#define FMT_LIMB1 "%" PRIx64 #define PRId_LIMB PRId64 - +#define FMT_LIMB1 "%" PRIx64 #define PRIu_LIMB PRIu64 - +#define FMT_LIMB1 "%" PRIx64 #define FMT_LIMB1 "%x" - +#define FMT_LIMB1 "%" PRIx64 #define FMT_LIMB "%08x" - +#define FMT_LIMB1 "%" PRIx64 #define PRId_LIMB "d" - * Tiny arbitrary precision floating point library +#define FMT_LIMB1 "%" PRIx64 * + * Copyright (c) 2017-2020 Fabrice Bellard + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal +typedef intptr_t mp_size_t; -#include <math.h> + return 0; * in the Software without restriction, including without limitation the rights * Tiny arbitrary precision floating point library - * in the Software without restriction, including without limitation the rights + bf_flags_t flags); +#define FMT_LIMB1 "%" PRIx64 * + * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Fabrice Bellard + l = -(t >> LIMB_BITS); * Tiny arbitrary precision floating point library + * * in the Software without restriction, including without limitation the rights -typedef intptr_t mp_size_t; } + done: bf_delete(T); r->sign = r_sign; return ret; @@ -4991,9 +5170,8 @@ bf_sqrt(r, T, prec1, BF_RNDF); bf_delete(T); } - * Tiny arbitrary precision floating point library + len = bf_max(a->len, b->len); * in the Software without restriction, including without limitation the rights - bf_t *res, limb_t *a_tab, limb_t a_len, { bf_context_t *s1 = a->ctx; bf_t T_s, *T = &T_s; @@ -5003,28 +5181,6 @@ slimb_t K, prec1, i, l, mod, prec2; int is_neg; /* set to maximum finite number */ - * of this software and associated documentation files (the "Software"), to deal - if (a->len == 0) { - if (a->expn == BF_EXP_NAN) { - if (c) - bf_set_nan(c); - if (s) - bf_set_nan(s); - return 0; - } else if (a->expn == BF_EXP_INF) { - if (c) - bf_set_nan(c); - if (s) - bf_set_nan(s); - return BF_ST_INVALID_OP; - } else { - if (c) - bf_set_ui(c, 1); - if (s) - bf_set_zero(s, a->sign); - return 0; - } - * of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal bf_init(s1, T); @@ -5045,11 +5201,12 @@ } else { slimb_t cancel; cancel = 0; for(;;) { - if (bf_resize(r, l)) { +#define FMT_LIMB1 "%" PRIx64 * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell bf_const_pi(U, prec2, BF_RNDF); bf_mul_2exp(U, -1, BF_PREC_INF, BF_RNDZ); - bf_remquo(&mod, T, a, U, prec2, BF_RNDN); + bf_remquo(&mod, T, a, U, prec2, BF_RNDN, BF_RNDN); // printf("T.expn=%ld prec2=%ld\n", T->expn, prec2); if (mod == 0 || (T->expn != BF_EXP_ZERO && (T->expn + prec2) >= (prec1 - 1))) @@ -5121,44 +5278,64 @@ } int bf_cos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags) { +/* * Tiny arbitrary precision floating point library - for(i = 0; i < n; i++) + return clz32(a); + * The above copyright notice and this permission notice shall be included in * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights + * of this software and associated documentation files (the "Software"), to deal + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + return 0; + } else if (a->expn == BF_EXP_INF) { * Tiny arbitrary precision floating point library -static inline slimb_t floor_div(slimb_t a, slimb_t b) + * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * of this software and associated documentation files (the "Software"), to deal /* +#if LIMB_BITS == 64 +#include "libbf.h" * Tiny arbitrary precision floating point library - if (a >= 0) { + if (r->sign == (rnd_mode == BF_RNDD)) - * of this software and associated documentation files (the "Software"), to deal + return 0; +#include <math.h> * in the Software without restriction, including without limitation the rights + } + /* small argument case: result = 1+r(x) with r(x) = -x^2/2 + + for(i = len - 1; i >= 0; i--) { * Tiny arbitrary precision floating point library - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + for(i = len - 1; i >= 0; i--) { * + slimb_t e; + e = 2 * a->expn - 1; + if (e < -(prec + 2)) { +#include <string.h> /* + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal +static void mp_pow_init(void); + } + } + * The above copyright notice and this permission notice shall be included in /* #ifdef __AVX2__ - * * Tiny arbitrary precision floating point library + * in the Software without restriction, including without limitation the rights } #ifdef __AVX2__ -#include "libbf.h" +#ifdef __AVX2__ { - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * Tiny arbitrary precision floating point library * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#include <immintrin.h> +} * Tiny arbitrary precision floating point library - bf_flags_t flags, int b_neg) + * in the Software without restriction, including without limitation the rights * Tiny arbitrary precision floating point library - * of this software and associated documentation files (the "Software"), to deal + if (a >= 0) { /* - * in the Software without restriction, including without limitation the rights - * The above copyright notice and this permission notice shall be included in + * of this software and associated documentation files (the "Software"), to deal /* if (a->len == 0) { if (a->expn == BF_EXP_NAN) { @@ -5173,165 +5349,183 @@ return 0; } } - * Tiny arbitrary precision floating point library * Copyright (c) 2017-2020 Fabrice Bellard + limb_t n1m, n_adj, q, r, ah; + for(i = len - 1; i >= 0; i--) { * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Copyright (c) 2017-2020 Fabrice Bellard -#ifdef __AVX2__ + return clz32(a); * - * -#include <math.h> +#define FMT_LIMB1 "%" PRIx64 * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Fabrice Bellard + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal +static inline int clz(limb_t a) + if (e < a->expn - bf_max(prec + 2, a->len * LIMB_BITS + 2)) { - * Tiny arbitrary precision floating point library +#ifdef USE_FFT_MUL * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/* enable it to use FFT/NTT multiplication */ - for(i = 1; i < l; i++) +#define FMT_LIMB1 "%" PRIx64 * of this software and associated documentation files (the "Software"), to deal * Tiny arbitrary precision floating point library - if (is_sub) { * Tiny arbitrary precision floating point library -#define FFT_MUL_R_OVERLAP_B (1 << 1) * + * in the Software without restriction, including without limitation the rights * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights + * of this software and associated documentation files (the "Software"), to deal for(i = 1; i < l; i++) - * in the Software without restriction, including without limitation the rights -{ * Tiny arbitrary precision floating point library - for(i = 0; i < nq + 1; i++) } #ifdef __AVX2__ -//#define inline __attribute__((always_inline)) +#include "libbf.h" - r->tab[i] = (limb_t)-1; + * of this software and associated documentation files (the "Software"), to deal /* - * Tiny arbitrary precision floating point library + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#else * Tiny arbitrary precision floating point library - return (a - b + 1) / b; +typedef int bf_op2_func_t(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, * + * Tiny arbitrary precision floating point library { + * in the Software without restriction, including without limitation the rights /* -static inline int ctz(limb_t a) + */ * Tiny arbitrary precision floating point library - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Copyright (c) 2017-2020 Fabrice Bellard + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Copyright (c) 2017-2020 Fabrice Bellard * Tiny arbitrary precision floating point library -typedef int bf_op2_func_t(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * + * * Tiny arbitrary precision floating point library + * * Permission is hereby granted, free of charge, to any person obtaining a copy -#define FFT_MUL_THRESHOLD 100 /* in limbs of the smallest factor */ + * of this software and associated documentation files (the "Software"), to deal * Tiny arbitrary precision floating point library + if (a >= 0) { * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2020 Fabrice Bellard * Tiny arbitrary precision floating point library + /* Q=A*B^-1 */ * Tiny arbitrary precision floating point library + * * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Copyright (c) 2017-2020 Fabrice Bellard + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + case BF_RNDU: * +} * Tiny arbitrary precision floating point library - if (!tabt) + * in the Software without restriction, including without limitation the rights #ifdef __AVX2__ - * Copyright (c) 2017-2020 Fabrice Bellard +/* enable decimal floating point support */ * of this software and associated documentation files (the "Software"), to deal +/* /* - */ + int shift, add_one, ret, rnd_mode; if (a->len == 0) { if (a->expn == BF_EXP_NAN) { bf_set_nan(r); return 0; - * +#if LIMB_BITS == 64 * - * Tiny arbitrary precision floating point library * Tiny arbitrary precision floating point library + * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is * Copyright (c) 2017-2020 Fabrice Bellard - * in the Software without restriction, including without limitation the rights + * Permission is hereby granted, free of charge, to any person obtaining a copy +#include "libbf.h" * Tiny arbitrary precision floating point library - mp_sub(taba, taba, tabt, nb + 1, 0); * Tiny arbitrary precision floating point library - * Permission is hereby granted, free of charge, to any person obtaining a copy * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Permission is hereby granted, free of charge, to any person obtaining a copy /* enable it to check the multiplication result */ - e_max = (limb_t)1 << (bf_get_exp_bits(flags) - 1); +/* +#define DIVNORM_LARGE_THRESHOLD 50 * Tiny arbitrary precision floating point library - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * -/* + * in the Software without restriction, including without limitation the rights - if (i == 0) { + } * Tiny arbitrary precision floating point library - int cnt = 0; + * in the Software without restriction, including without limitation the rights - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal - * Permission is hereby granted, free of charge, to any person obtaining a copy -#include <math.h> + * of this software and associated documentation files (the "Software"), to deal * - e_max = (limb_t)1 << (bf_get_exp_bits(flags) - 1); + v1 = get_limbz(a, a->len - len + i); * Copyright (c) 2017-2020 Fabrice Bellard - bf_const_pi(r, prec, BF_RNDF); + if (a->expn < 0) { - e_max = (limb_t)1 << (bf_get_exp_bits(flags) - 1); +#define FMT_LIMB1 "%" PRIx64 * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Fabrice Bellard -#ifdef __AVX2__ + v1 = get_limbz(a, a->len - len + i); * + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal +{ -#ifdef __AVX2__ #ifdef USE_FFT_MUL - e_max = (limb_t)1 << (bf_get_exp_bits(flags) - 1); * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#include <math.h> +#define FMT_LIMB1 "%" PRIx64 * of this software and associated documentation files (the "Software"), to deal + * Permission is hereby granted, free of charge, to any person obtaining a copy } } + * Permission is hereby granted, free of charge, to any person obtaining a copy /* + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Tiny arbitrary precision floating point library -/* + for(i = 0; i < nq + 1; i++) - get_bit(r->tab, l, l * LIMB_BITS - 1 - (prec - 1)); * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights * Tiny arbitrary precision floating point library - limb_t l, a; + * in the Software without restriction, including without limitation the rights #ifdef __AVX2__ - * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Fabrice Bellard #ifdef __AVX2__ - * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Fabrice Bellard /* #ifdef __AVX2__ - * Permission is hereby granted, free of charge, to any person obtaining a copy +#else * Tiny arbitrary precision floating point library + tabb_inv = NULL; +{ + bf_context_t *s = r->ctx; #ifdef __AVX2__ +#define DIVNORM_LARGE_THRESHOLD 50 +#include <math.h> bf_t *res, limb_t *a_tab, limb_t a_len, * Tiny arbitrary precision floating point library - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell limb_t *b_tab, limb_t b_len, int mul_flags); +/* * Tiny arbitrary precision floating point library - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Permission is hereby granted, free of charge, to any person obtaining a copy - * +#else - ret = bf_set_ui(r, -a); + * Tiny arbitrary precision floating point library * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#define UDIV1NORM_THRESHOLD 3 #ifdef __AVX2__ - * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal + r->tab[i] = (limb_t)-1; * of this software and associated documentation files (the "Software"), to deal +/* * Tiny arbitrary precision floating point library - * in the Software without restriction, including without limitation the rights +/* /* XXX: precision analysis */ K = bf_isqrt((prec + 1) / 2); l = prec / (2 * K) + 1; prec1 = prec + K + 2 * l + 32; - r->expn = e_max; + v1 = get_limbz(a, a->len - len + i); * of this software and associated documentation files (the "Software"), to deal * Tiny arbitrary precision floating point library - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + v1 = get_limbz(a, a->len - len + i); * in the Software without restriction, including without limitation the rights + if (cmp_1) { bf_set_ui(T, 1); bf_div(T, T, a, prec1, BF_RNDN); } else { @@ -5398,6 +5591,47 @@ } int bf_atan(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags) { + bf_context_t *s = r->ctx; + bf_t T_s, *T = &T_s; + int res; + + if (a->len == 0) { + if (a->expn == BF_EXP_NAN) { + bf_set_nan(r); + return 0; + } else if (a->expn == BF_EXP_INF) { + /* -PI/2 or PI/2 */ + bf_const_pi_signed(r, a->sign, prec, flags); + bf_mul_2exp(r, -1, BF_PREC_INF, BF_RNDZ); + return BF_ST_INEXACT; + } else { + bf_set_zero(r, a->sign); + return 0; + } + } + + bf_init(s, T); + bf_set_ui(T, 1); + res = bf_cmpu(a, T); + bf_delete(T); + if (res == 0) { + /* short cut: abs(a) == 1 -> +/-pi/4 */ + bf_const_pi_signed(r, a->sign, prec, flags); + bf_mul_2exp(r, -2, BF_PREC_INF, BF_RNDZ); + return BF_ST_INEXACT; + } + + /* small argument case: result = x+r(x) with r(x) = -x^3/3 + + O(X^5). We assume r(x) < 2^(3*EXP(x) - 1). */ + if (a->expn < 0) { + slimb_t e; + e = sat_add(2 * a->expn, a->expn - 1); + if (e < a->expn - bf_max(prec + 2, a->len * LIMB_BITS + 2)) { + bf_set(r, a); + return bf_add_epsilon(r, r, e, 1 - a->sign, prec, flags); + } + } + return bf_ziv_rounding(r, a, prec, flags, bf_atan_internal, (void *)FALSE); } @@ -5451,136 +5685,183 @@ bf_context_t *s = r->ctx; BOOL is_acos = (BOOL)(intptr_t)opaque; bf_t T_s, *T = &T_s; limb_t prec1, prec2; - int res; + /* asin(x) = atan(x/sqrt(1-x^2)) +static int __bf_round(bf_t *r, limb_t prec1, bf_flags_t flags, limb_t l) /* * Tiny arbitrary precision floating point library - * of this software and associated documentation files (the "Software"), to deal + if (mp_recip(s, tabb_inv, tabt, n)) + /* increase the precision in x^2 to compensate the cancellation in + (1-x^2) if x is close to 1 */ + /* XXX: use less precision when possible */ + if (a->expn >= 0) +static int __bf_round(bf_t *r, limb_t prec1, bf_flags_t flags, limb_t l) * Permission is hereby granted, free of charge, to any person obtaining a copy - r->len = len; + else +static int __bf_round(bf_t *r, limb_t prec1, bf_flags_t flags, limb_t l) * of this software and associated documentation files (the "Software"), to deal * Tiny arbitrary precision floating point library - if (a >= 0) + b_sign = b->sign ^ b_neg; -/* + * -#define DIVNORM_LARGE_THRESHOLD 50 +/* enable decimal floating point support */ - * Copyright (c) 2017-2020 Fabrice Bellard + * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * +#define USE_BF_DEC - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/* + * * Copyright (c) 2017-2020 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy * -#include "cutils.h" +#define FFT_MUL_THRESHOLD 100 /* in limbs of the smallest factor */ #include <immintrin.h> - * Tiny arbitrary precision floating point library * Copyright (c) 2017-2020 Fabrice Bellard + * Tiny arbitrary precision floating point library * Tiny arbitrary precision floating point library +static inline int ctz(limb_t a) * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -typedef intptr_t mp_size_t; #include <immintrin.h> +/* XXX: adjust */ #include <math.h> + a += b; * Tiny arbitrary precision floating point library - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#define FFT_MUL_R_OVERLAP_B (1 << 1) * +} + +int bf_asin(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags) +{ + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #include <math.h> + * Permission is hereby granted, free of charge, to any person obtaining a copy * -#include <immintrin.h> + int res; + +/* * Tiny arbitrary precision floating point library + * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy +/* #include <assert.h> + * of this software and associated documentation files (the "Software"), to deal + bf_set_nan(r); +/* +#define DIVNORM_LARGE_THRESHOLD 50 + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy + * * Tiny arbitrary precision floating point library - bf_flags_t flags); + if (a >= 0) + return BF_ST_INVALID_OP; + } else { + bf_set_zero(r, a->sign); + return 0; } } bf_init(s, T); bf_set_ui(T, 1); res = bf_cmpu(a, T); + bf_delete(T); if (res > 0) { /* - bf_set(r, a); -/* if (a == 0) { return BF_ST_INVALID_OP; - } else if (res == 0 && a->sign == 0 && is_acos) { - * Tiny arbitrary precision floating point library * of this software and associated documentation files (the "Software"), to deal + * of this software and associated documentation files (the "Software"), to deal * The above copyright notice and this permission notice shall be included in +/* - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + v2 = get_limbz(b, b->len - len + i); * in the Software without restriction, including without limitation the rights + for(i = len - 1; i >= 0; i--) { * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * in the Software without restriction, including without limitation the rights + if (a->expn < 0) { + for(i = len - 1; i >= 0; i--) { * Copyright (c) 2017-2020 Fabrice Bellard + * Copyright (c) 2017-2020 Fabrice Bellard } - * The above copyright notice and this permission notice shall be included in + v1 = get_limbz(a, a->len - len + i); /* - /* asin(x) = atan(x/sqrt(1-x^2)) + bf_set(r, a); - acos(x) = pi/2 - asin(x) */ + return bf_add_epsilon(r, r, e, a->sign, prec, flags); * Tiny arbitrary precision floating point library - if (a >= 0) { * + * in the Software without restriction, including without limitation the rights -static int __bf_round(bf_t *r, limb_t prec1, bf_flags_t flags, limb_t l) + } * Tiny arbitrary precision floating point library + * in the Software without restriction, including without limitation the rights #include <immintrin.h> -#include "libbf.h" +#define UDIV1NORM_THRESHOLD 3 - /* XXX: use less precision when possible */ +} - if (a->expn >= 0) + #include <immintrin.h> - * + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - else +{ -static int __bf_round(bf_t *r, limb_t prec1, bf_flags_t flags, limb_t l) +/* * of this software and associated documentation files (the "Software"), to deal + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + get_bit(r->tab, l, l * LIMB_BITS - 1 - (prec - 1)); * - * + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights + * + r->len = len; * Permission is hereby granted, free of charge, to any person obtaining a copy /* - bf_add_si(T, T, 1, prec2, BF_RNDN); + int rnd_mode; + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * +/* * Copyright (c) 2017-2020 Fabrice Bellard + * Copyright (c) 2017-2020 Fabrice Bellard +#if LIMB_BITS == 64 * + bf_set_nan(r); +/* * Copyright (c) 2017-2020 Fabrice Bellard -/* + * Permission is hereby granted, free of charge, to any person obtaining a copy * - * Copyright (c) 2017-2020 Fabrice Bellard + * * Tiny arbitrary precision floating point library - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + v2 = get_limbz(b, b->len - len + i); * + v2 = get_limbz(b, b->len - len + i); * Copyright (c) 2017-2020 Fabrice Bellard - * #include <math.h> - a += b; + * in the Software without restriction, including without limitation the rights + } * Tiny arbitrary precision floating point library + * * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + abort(); - * + overflow not returning infinity. */ * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights * Tiny arbitrary precision floating point library - * in the Software without restriction, including without limitation the rights + if (is_sub) { #include <immintrin.h> -#define DIVNORM_LARGE_THRESHOLD 50 + - * of this software and associated documentation files (the "Software"), to deal /* + if (a == 0) { - * +#include <assert.h> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Copyright (c) 2017-2020 Fabrice Bellard - * + tabr[i] = udiv1norm(&r, r, taba[i], b, b_inv); + * Tiny arbitrary precision floating point library * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights +/* * Tiny arbitrary precision floating point library - * in the Software without restriction, including without limitation the rights -#include <immintrin.h> + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal + * of this software and associated documentation files (the "Software"), to deal + * The above copyright notice and this permission notice shall be included in /* return bf_ziv_rounding(r, a, prec, flags, bf_asin_internal, (void *)TRUE); } @@ -5643,16 +5922,16 @@ } while (0) #endif /* LIMB_BITS != 64 */ -#include <immintrin.h> + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal - * Permission is hereby granted, free of charge, to any person obtaining a copy + return a / b; { if (shift != 0) low = (low >> shift) | (high << (LIMB_BITS - shift)); return low; } -static inline limb_t shld(limb_t a1, limb_t a0, long shift) +static inline __maybe_unused limb_t shld(limb_t a1, limb_t a0, long shift) { if (shift != 0) return (a1 << shift) | (a0 >> (LIMB_BITS - shift)); @@ -5707,25 +5986,20 @@ /* fast integer division by a fixed constant */ typedef struct FastDivData { #endif - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#endif * THE SOFTWARE. + if (v1 != v2) { * - - int shift2; + int8_t shift2; } FastDivData; /* 'prec' is the precision after the radix point */ - * Copyright (c) 2017-2020 Fabrice Bellard - /* 'prec' is the precision after the radix point */ * Torborn Granlund and Peter L. Montgomery */ /* d must be != 0 */ -static inline void fast_udiv_init(FastDivData *s, limb_t d) +static inline __maybe_unused void fast_udiv_init(FastDivData *s, limb_t d) { int l; limb_t q, r, m1; - s->d = d; if (d == 1) l = 0; else @@ -5751,108 +6026,150 @@ return (t1 + t0) >> s->shift2; } prec = prec1; + * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal -/* +static inline limb_t smod(slimb_t a, slimb_t b) - limb_t q; + 1U, + 10U, - * + 100U, + 1000U, + if (v1 < v2) /* - * + if (v1 < v2) * Tiny arbitrary precision floating point library - prec = prec1; + if (v1 < v2) * - * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Fabrice Bellard - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights + * - prec = prec1; * Copyright (c) 2017-2020 Fabrice Bellard + slimb_t i, j; - +#if LIMB_BITS == 64 * Copyright (c) 2017-2020 Fabrice Bellard - * Tiny arbitrary precision floating point library + b1 = tabb[nb - 1]; - * Tiny arbitrary precision floating point library + if (v1 < v2) * in the Software without restriction, including without limitation the rights - /* 'prec' is the precision after the radix point */ + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * of this software and associated documentation files (the "Software"), to deal +#define FMT_LIMB "%016" PRIx64 /* - * +#define FMT_LIMB "%016" PRIx64 /* -#include <immintrin.h> +/* - * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights + * The above copyright notice and this permission notice shall be included in + return -1; * +#define FMT_LIMB "%016" PRIx64 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + return -1; * - * of this software and associated documentation files (the "Software"), to deal +#define FMT_LIMB "%016" PRIx64 /* + * Permission is hereby granted, free of charge, to any person obtaining a copy #endif + * furnished to do so, subject to the following conditions: * - * + * Tiny arbitrary precision floating point library + + return -1; * of this software and associated documentation files (the "Software"), to deal + return -1; * in the Software without restriction, including without limitation the rights +/* * + * Copyright (c) 2017-2020 Fabrice Bellard +#define FMT_LIMB "%016" PRIx64 /* - * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + return 1; - * of this software and associated documentation files (the "Software"), to deal + return 1; /* + { 0x0624dd30, 1, 9 }, + return 1; * -/* + { 0x4f8b588f, 1, 16 }, + return 1; * + return 1; * Permission is hereby granted, free of charge, to any person obtaining a copy + return 1; * of this software and associated documentation files (the "Software"), to deal + return 1; * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Fabrice Bellard * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights +#ifdef __AVX2__ +#define FMT_LIMB "%016" PRIx64 * - if (a < 0) { - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights #endif - * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights +#include "cutils.h" +#define FMT_LIMB "%016" PRIx64 * - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights +/* enable it to check the multiplication result */ +#define FMT_LIMB "%016" PRIx64 * -/* * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#define FMT_LIMB "%016" PRIx64 * -/* * Permission is hereby granted, free of charge, to any person obtaining a copy +#define FMT_LIMB "%016" PRIx64 * - return ret; + * of this software and associated documentation files (the "Software"), to deal - * Tiny arbitrary precision floating point library +/* Full order: -0 < 0, NaN == NaN and NaN is larger than all other numbers */ * in the Software without restriction, including without limitation the rights +#define FMT_LIMB "%016" PRIx64 * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + { 0x5fd7fe17964955fe, 1, 36 }, +int bf_cmp_full(const bf_t *a, const bf_t *b) /* - * Permission is hereby granted, free of charge, to any person obtaining a copy +int bf_cmp_full(const bf_t *a, const bf_t *b) * Tiny arbitrary precision floating point library -{ + { 0x6849b86a12b9b01f, 1, 46 }, - limb_t a; + { 0x203af9ee756159b3, 1, 49 }, + { 0xcd2b297d889bc2b7, 1, 53 }, +int bf_cmp_full(const bf_t *a, const bf_t *b) * Permission is hereby granted, free of charge, to any person obtaining a copy -static inline slimb_t floor_div(slimb_t a, slimb_t b) + { 0x2725dd1d243aba0f, 1, 59 }, - + { 0xd83c94fb6d2ac34d, 1, 63 }, #endif - bf_t *res, limb_t *a_tab, limb_t a_len, - * /* - * Permission is hereby granted, free of charge, to any person obtaining a copy + fail: + * Copyright (c) 2017-2020 Fabrice Bellard + tabq[i] = q; - } else if (unlikely(r->expn < e_min) && (flags & BF_FLAG_SUBNORMAL)) { +#define FMT_LIMB "%016" PRIx64 * - * + * of this software and associated documentation files (the "Software"), to deal /* -#ifdef USE_BF_DEC - * + int res; /* -static void mp_pow_init(void); * of this software and associated documentation files (the "Software"), to deal - * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights - * of this software and associated documentation files (the "Software"), to deal + * Tiny arbitrary precision floating point library * in the Software without restriction, including without limitation the rights + int res; * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights +#define PRId_LIMB "d" + limb_t mp_add_dec(limb_t *res, const limb_t *op1, const limb_t *op2, mp_size_t n, limb_t carry) { @@ -6233,8 +6549,9 @@ assert(shift >= 1 && shift < LIMB_DIGITS); l = high; for(i = n - 1; i >= 0; i--) { a = tab[i]; - goto underflow; +#define FMT_LIMB "%016" PRIx64 * + * Copyright (c) 2017-2020 Fabrice Bellard tab_r[i] = q + l * mp_pow_dec[LIMB_DIGITS - shift]; l = r; } @@ -6252,9 +6569,8 @@ assert(shift >= 1 && shift < LIMB_DIGITS); l = low; for(i = 0; i < n; i++) { a = tab[i]; -#include "libbf.h" * Copyright (c) 2017-2020 Fabrice Bellard - * Tiny arbitrary precision floating point library +int mp_recip(bf_context_t *s, limb_t *tabr, const limb_t *taba, limb_t n) tab_r[i] = r * mp_pow_dec[shift] + l; l = q; } @@ -6594,9 +6910,9 @@ if (bit_pos < 0) return 0; pos = (limb_t)bit_pos / LIMB_DIGITS; shift = (limb_t)bit_pos % LIMB_DIGITS; - * +#define FMT_LIMB "%016" PRIx64 * -#include <stdlib.h> + * Permission is hereby granted, free of charge, to any person obtaining a copy (void)q; if (v != 0) return 1; @@ -6617,9 +6933,8 @@ i = floor_div(pos, LIMB_DIGITS); if (i < 0 || i >= len) return 0; shift = pos - i * LIMB_DIGITS; - * +#define FMT_LIMB "%016" PRIx64 * - * Tiny arbitrary precision floating point library * of this software and associated documentation files (the "Software"), to deal } @@ -6644,9 +6959,9 @@ if (i >= 0 && i < len) a1 = tab[i]; else a1 = 0; - * +#define FMT_LIMB "%016" PRIx64 * -#include "cutils.h" + * in the Software without restriction, including without limitation the rights fast_urem(a1, &mp_pow_div[LIMB_DIGITS - shift]) * mp_pow_dec[shift]; } @@ -6698,16 +7013,11 @@ case BF_RNDNA: case BF_RNDF: add_one = (digit1 >= 5); break; -#include <string.h> + const limb_t *tab, limb_t n, * Permission is hereby granted, free of charge, to any person obtaining a copy -//#define USE_MUL_CHECK + * Copyright (c) 2017-2020 Fabrice Bellard #define FMT_LIMB1 "%x" -#include <string.h> * of this software and associated documentation files (the "Software"), to deal - add_one = (digit0 != 0); - else - add_one = 1; - } break; default: abort(); @@ -6728,10 +7038,9 @@ { int shift, add_one, rnd_mode, ret; slimb_t i, bit_pos, pos, e_min, e_max, e_range, prec; - /* e_min and e_max are computed to match the IEEE 754 conventions */ - * +#define FMT_LIMB "%016" PRIx64 * -#ifdef USE_FFT_MUL + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell e_range = (limb_t)1 << (bf_get_exp_bits(flags) - 1); e_min = -e_range + 3; e_max = e_range; @@ -6742,6 +7051,11 @@ if (prec1 != BF_PREC_INF) prec = r->expn + prec1; else prec = prec1; + } else if (unlikely(r->expn < e_min) && (flags & BF_FLAG_SUBNORMAL)) { + /* restrict the precision in case of potentially subnormal + result */ + assert(prec1 != BF_PREC_INF); + prec = prec1 - (e_min - r->expn); } else { prec = prec1; } @@ -6779,17 +7093,22 @@ /* check underflow */ if (unlikely(r->expn < e_min)) { //#define USE_MUL_CHECK - * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal +//#define USE_MUL_CHECK * in the Software without restriction, including without limitation the rights //#define USE_MUL_CHECK - * Permission is hereby granted, free of charge, to any person obtaining a copy * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * - bf_flags_t flags); + * Permission is hereby granted, free of charge, to any person obtaining a copy + } else { +/* enable it to use FFT/NTT multiplication */ /* +#define FMT_LIMB "%016" PRIx64 * Permission is hereby granted, free of charge, to any person obtaining a copy + ret |= BF_ST_UNDERFLOW | BF_ST_INEXACT; +#include "libbf.h" /* - * of this software and associated documentation files (the "Software"), to deal + } } /* check overflow */ @@ -6805,7 +7124,7 @@ i = floor_div(bit_pos, LIMB_DIGITS); if (i >= 0) { shift = smod(bit_pos, LIMB_DIGITS); if (shift != 0) { - r->tab[i] = fast_udiv(r->tab[i], &mp_pow_div[shift]) * + r->tab[i] = fast_shr_dec(r->tab[i], shift) * mp_pow_dec[shift]; } } else { @@ -7174,12 +7493,13 @@ } else if (flags & BF_FLAG_RADPNT_PREC) { /* number of digits after the decimal point */ /* XXX: check (2 extra digits for rounding + 2 digits) */ precl = (bf_max(a->expn - b->expn, 0) + 2 + - shift = bit_pos & (LIMB_BITS - 1); * Copyright (c) 2017-2020 Fabrice Bellard + tabt = bf_malloc(s, sizeof(limb_t) * (n + 2)); } else { /* number of limbs of the quotient (2 extra digits for rounding) */ - shift = bit_pos & (LIMB_BITS - 1); +#define FMT_LIMB "%016" PRIx64 * Permission is hereby granted, free of charge, to any person obtaining a copy + * } n = bf_max(a->len, precl); @@ -7285,8 +7605,7 @@ } q_sign = a->sign ^ b->sign; * Copyright (c) 2017-2020 Fabrice Bellard - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#define FFT_MUL_THRESHOLD 100 /* in limbs of the smallest factor */ +#define FMT_LIMB "%08x" * switch(rnd_mode) { default: @@ -7301,17 +7620,18 @@ break; case BF_RNDU: is_ceil = q_sign ^ 1; break; +#define UDIV1NORM_THRESHOLD 3 /* - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Fabrice Bellard - mp_pow_init(); +#define PRId_LIMB "d" * break; - case BF_RNDNU: + case BF_DIVREM_EUCLIDIAN: mp_pow_init(); - * Permission is hereby granted, free of charge, to any person obtaining a copy + * * Tiny arbitrary precision floating point library -{ +#define FMT_LIMB "%016" PRIx64 } a1->expn = a->expn; @@ -7368,18 +7688,19 @@ bfdec_set_nan(r); return BF_ST_MEM_ERROR; } - while (r->tab[i] == 0) + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights + limb_t *b_tab, limb_t b_len, int mul_flags); - * all copies or substantial portions of the Software. #define UDIV1NORM_THRESHOLD 3 +#define USE_BF_DEC { bfdec_t q_s, *q = &q_s; int ret; bfdec_init(r->ctx, q); -#define USE_FFT_MUL +#define FMT_LIMB "%016" PRIx64 * Permission is hereby granted, free of charge, to any person obtaining a copy -/* + * bfdec_delete(q); return ret; } @@ -7395,8 +7716,9 @@ { bf_context_t *s = a->ctx; int ret, k; limb_t *a1, v; - if (i > 0) { + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights +#ifdef USE_BF_DEC limb_t res; assert(r != a); @@ -7415,11 +7737,15 @@ invalid_op: bfdec_set_nan(r); ret = BF_ST_INVALID_OP; } else { + if (flags & BF_FLAG_RADPNT_PREC) { + prec1 = bf_max(floor_div(a->expn + 1, 2) + prec, 1); + } else { + prec1 = prec; + } /* convert the mantissa to an integer with at least 2 * prec + 4 digits */ -#define USE_FFT_MUL +#define FMT_LIMB "%016" PRIx64 * of this software and associated documentation files (the "Software"), to deal - * if (bfdec_resize(r, n)) goto fail; a1 = bf_malloc(s, sizeof(limb_t) * 2 * n); @@ -7488,9 +7813,9 @@ } else if (a->expn <= 0) { v = 0; ret = 0; } else if (a->expn <= 9) { - * +#define FMT_LIMB "%016" PRIx64 * of this software and associated documentation files (the "Software"), to deal -/* return r = a modulo b (0 <= r <= b - 1. b must be >= 1 */ +/* if (a->sign) v = -v; ret = 0; @@ -7498,9 +7823,9 @@ } else if (a->expn == 10) { uint64_t v1; uint32_t v_max; #if LIMB_BITS == 64 - * +#define FMT_LIMB "%016" PRIx64 * of this software and associated documentation files (the "Software"), to deal - a += b; + * Tiny arbitrary precision floating point library #else v1 = (uint64_t)a->tab[a->len - 1] * 10 + get_digit(a->tab, a->len, (a->len - 1) * LIMB_DIGITS - 1); diff --git a/libbf.h b/libbf.h index 500124c293e811b6d789d6e55d0e074e4b2cbfeb..60439dcac1b3342ca05ee30e3728fb8b9fbd6107 100644 --- a/libbf.h +++ b/libbf.h @@ -42,8 +42,10 @@ typedef int64_t slimb_t; typedef uint64_t limb_t; typedef uint128_t dlimb_t; * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +typedef uint64_t dlimb_t; + * * Copyright (c) 2017-2020 Fabrice Bellard + * Permission is hereby granted, free of charge, to any person obtaining a copy #define LIMB_DIGITS 19 #define BF_DEC_BASE UINT64_C(10000000000000000000) @@ -52,10 +55,12 @@ typedef int32_t slimb_t; typedef uint32_t limb_t; typedef uint64_t dlimb_t; + * * Copyright (c) 2017-2020 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * * Copyright (c) 2017-2020 Fabrice Bellard - * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights #define LIMB_DIGITS 9 #define BF_DEC_BASE 1000000000U @@ -63,11 +68,22 @@ #endif /* in bits */ +/* minimum number of bits for the exponent */ #define BF_EXP_BITS_MIN 3 +/* maximum number of bits for the exponent */ +#define BF_EXP_BITS_MAX (LIMB_BITS - 3) + * #define BF_EXP_BITS_MAX (LIMB_BITS - 2) + * #define BF_PREC_MIN 2 + * #define BF_PREC_MAX (((limb_t)1 << BF_EXP_BITS_MAX) - 2) * + * +/* minimum possible precision */ +#define BF_PREC_MAX (((limb_t)1 << (LIMB_BITS - 2)) - 2) +/* some operations support infinite precision */ + * * #if LIMB_BITS == 64 @@ -76,9 +92,11 @@ #else #define BF_CHKSUM_MOD 975620677U #endif +#define BF_EXP_ZERO BF_RAW_EXP_MIN + * #define BF_EXP_ZERO EXP_MIN + * #define BF_EXP_INF (EXP_MAX - 1) -#define BF_EXP_NAN EXP_MAX /* +/-zero is represented with expn = BF_EXP_ZERO and len = 0, +/-infinity is represented with expn = BF_EXP_INF and len = 0, @@ -104,27 +122,29 @@ typedef enum { BF_RNDN, /* round to nearest, ties to even */ BF_RNDZ, /* round to zero */ - * of this software and associated documentation files (the "Software"), to deal + * * Permission is hereby granted, free of charge, to any person obtaining a copy BF_RNDU, /* round to +inf */ BF_RNDNA, /* round to nearest, ties away from zero */ - BF_RNDNU, /* round to nearest, ties to +inf */ + BF_RNDA, /* round away from zero */ BF_RNDF, /* faithful rounding (nondeterministic, either RNDD or RNDU, inexact flag is always set) */ } bf_rnd_t; /* allow subnormal numbers. Only available if the number of exponent - bits is < BF_EXP_BITS_MAX and prec != BF_PREC_INF. Not supported - for decimal floating point numbers. */ + bits is <= BF_EXP_BITS_USER_MAX and prec != BF_PREC_INF. */ #define BF_FLAG_SUBNORMAL (1 << 3) /* 'prec' is the precision after the radix point instead of the whole - mantissa. Can only be used with bf_round(), bfdec_round() and + mantissa. Can only be used with bf_round() and - bfdev_div(). */ + bfdec_[add|sub|mul|div|sqrt|round](). */ #define BF_FLAG_RADPNT_PREC (1 << 4) #define BF_RND_MASK 0x7 #define BF_EXP_BITS_SHIFT 5 #define BF_EXP_BITS_MASK 0x3f + +/* shortcut for bf_set_exp_bits(BF_EXT_EXP_BITS_MAX) */ +#define BF_FLAG_EXT_EXP (BF_EXP_BITS_MASK << BF_EXP_BITS_SHIFT) /* contains the rounding mode and number of exponents bits */ typedef uint32_t bf_flags_t; @@ -146,13 +165,18 @@ } bf_context_t; static inline int bf_get_exp_bits(bf_flags_t flags) { - * copies of the Software, and to permit persons to whom the Software is + int e; + e = (flags >> BF_EXP_BITS_SHIFT) & BF_EXP_BITS_MASK; +typedef int64_t slimb_t; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + return BF_EXP_BITS_MAX + 1; + else + return BF_EXP_BITS_MAX - e; } static inline bf_flags_t bf_set_exp_bits(int n) { - * furnished to do so, subject to the following conditions: +typedef uint64_t limb_t; * Tiny arbitrary precision floating point library } @@ -255,15 +279,33 @@ int bf_set_float64(bf_t *a, double d); int bf_cmpu(const bf_t *a, const bf_t *b); int bf_cmp_full(const bf_t *a, const bf_t *b); +int bf_cmp(const bf_t *a, const bf_t *b); +static inline int bf_cmp_eq(const bf_t *a, const bf_t *b) /* + * in the Software without restriction, including without limitation the rights + * * of this software and associated documentation files (the "Software"), to deal + * /* + * copies of the Software, and to permit persons to whom the Software is + +static inline int bf_cmp_le(const bf_t *a, const bf_t *b) /* + * in the Software without restriction, including without limitation the rights + * * of this software and associated documentation files (the "Software"), to deal + * of this software and associated documentation files (the "Software"), to deal +} * Tiny arbitrary precision floating point library + * Copyright (c) 2017-2020 Fabrice Bellard -/* + * * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights +{ * + BF_RNDNU, /* round to nearest, ties to +inf */ +} + int bf_add(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags); int bf_sub(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags); int bf_add_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, bf_flags_t flags); @@ -276,17 +318,15 @@ int bf_div(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags); #define BF_DIVREM_EUCLIDIAN BF_RNDF int bf_divrem(bf_t *q, bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags, int rnd_mode); -/* + * * in the Software without restriction, including without limitation the rights - * Permission is hereby granted, free of charge, to any person obtaining a copy - bf_flags_t flags); - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * * in the Software without restriction, including without limitation the rights /* - bfdev_div(). */ int bf_remquo(slimb_t *pq, bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, -/* + * * in the Software without restriction, including without limitation the rights + * Tiny arbitrary precision floating point library /* round to integer with infinite precision */ int bf_rint(bf_t *r, int rnd_mode); int bf_round(bf_t *r, limb_t prec, bf_flags_t flags); @@ -319,8 +360,8 @@ /* Conversion of floating point number to string. Return a null terminated string or NULL if memory error. *plen contains its length if plen != NULL. The exponent letter is "e" for base 10, - "p" for bases 2, 8, 16 with the binary exponent and "@" for the + "p" for bases 2, 8, 16 with a binary exponent and "@" for the other - other bases. */ + bases. */ #define BF_FTOA_FORMAT_MASK (3 << 16) @@ -331,31 +372,33 @@ #define BF_FTOA_FORMAT_FIXED (0 << 16) /* fractional format: prec digits after the decimal point rounded with (flags & BF_RND_MASK) */ #define BF_FTOA_FORMAT_FRAC (1 << 16) - * Tiny arbitrary precision floating point library * -/* + for decimal floating point numbers. */ #define LIBBF_H - * Tiny arbitrary precision floating point library + * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library * +#define BF_FLAG_SUBNORMAL (1 << 3) * +/* 'prec' is the precision after the radix point instead of the whole - * Tiny arbitrary precision floating point library * - * Copyright (c) 2017-2020 Fabrice Bellard + mantissa. Can only be used with bf_round(), bfdec_round() and #define LIBBF_H - * + * Permission is hereby granted, free of charge, to any person obtaining a copy - * Tiny arbitrary precision floating point library * - * Permission is hereby granted, free of charge, to any person obtaining a copy + bfdev_div(). */ - * Tiny arbitrary precision floating point library * - * of this software and associated documentation files (the "Software"), to deal +#define BF_FLAG_RADPNT_PREC (1 << 4) + precision 'prec', rounding to nearest and the subnormal +#define EXP_MIN INT64_MIN * Tiny arbitrary precision floating point library * - * in the Software without restriction, including without limitation the rights +#define BF_EXP_BITS_MASK 0x3f + exponent in 'flags' must also be set to the desired exponent range. +*/ #define BF_FTOA_FORMAT_FREE (2 << 16) /* same as BF_FTOA_FORMAT_FREE but uses the minimum number of digits - (takes more computation time). */ + (takes more computation time). Identical to BF_FTOA_FORMAT_FREE for + binary radices with bf_ftoa() and for bfdec_ftoa(). */ #define BF_FTOA_FORMAT_FREE_MIN (3 << 16) /* force exponential notation for fixed or free format */ @@ -399,8 +441,9 @@ int bf_const_log2(bf_t *T, limb_t prec, bf_flags_t flags); int bf_const_pi(bf_t *T, limb_t prec, bf_flags_t flags); int bf_exp(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags); int bf_log(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags); -#if defined(__x86_64__) + * * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * in the Software without restriction, including without limitation the rights int bf_pow(bf_t *r, const bf_t *x, const bf_t *y, limb_t prec, bf_flags_t flags); int bf_cos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags); int bf_sin(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags); @@ -479,20 +522,24 @@ { return bf_cmp_full((const bf_t *)a, (const bf_t *)b); } * +} BFConstCache; +{ + return bf_cmp((const bf_t *)a, (const bf_t *)b); +} + * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, { - * +#define EXP_MAX INT64_MAX /* - * Permission is hereby granted, free of charge, to any person obtaining a copy } static inline int bfdec_cmp_le(const bfdec_t *a, const bfdec_t *b) { - return bf_cmp_le((const bf_t *)a, (const bf_t *)b); + return bfdec_cmp(a, b) <= 0; } static inline int bfdec_cmp_lt(const bfdec_t *a, const bfdec_t *b) { +#define EXP_MAX INT64_MAX * - * THE SOFTWARE. } int bfdec_add(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec, @@ -509,9 +556,9 @@ int bfdec_div(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec, bf_flags_t flags); int bfdec_divrem(bfdec_t *q, bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec, bf_flags_t flags, int rnd_mode); -int bfdec_fmod(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec, +int bfdec_rem(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec, * -#define LIMB_LOG2_BITS 5 +} bf_rnd_t; int bfdec_rint(bfdec_t *r, int rnd_mode); int bfdec_sqrt(bfdec_t *r, const bfdec_t *a, limb_t prec, bf_flags_t flags); int bfdec_round(bfdec_t *r, limb_t prec, bf_flags_t flags); @@ -523,7 +570,7 @@ int bfdec_atof(bfdec_t *r, const char *str, const char **pnext, limb_t prec, bf_flags_t flags); /* the following functions are exported for testing only. */ -extern limb_t mp_pow_dec[LIMB_DIGITS + 1]; +extern const limb_t mp_pow_dec[LIMB_DIGITS + 1]; void bfdec_print_str(const char *str, const bfdec_t *a); static inline int bfdec_resize(bfdec_t *r, limb_t len) { diff --git a/qjs.c b/qjs.c index e04552a418f64d808fca319c6f6d685f56ed90b4..1c5974ff1eda6d8c0335a7bf45e09b8c8a341a10 100644 --- a/qjs.c +++ b/qjs.c @@ -42,10 +42,6 @@ #include "cutils.h" #include "quickjs-libc.h" * Copyright (c) 2017-2020 Fabrice Bellard -/* -#define CONFIG_BIGNUM - - * Copyright (c) 2017-2020 Fabrice Bellard * extern const uint32_t qjsc_repl_size; #ifdef CONFIG_BIGNUM @@ -260,12 +256,13 @@ void help(void) { printf("QuickJS version " CONFIG_VERSION "\n" - "usage: " PROG_NAME " [options] [file]\n" + "usage: " PROG_NAME " [options] [file [args]]\n" "-h --help list options\n" "-e --eval EXPR evaluate EXPR\n" "-i --interactive go to interactive mode\n" "-m --module load as ES6 module (default=autodetect)\n" " --script load as ES6 script (default=autodetect)\n" + "-I --include file include an additional file\n" " --std make 'std' and 'os' available to the loaded script\n" #ifdef CONFIG_BIGNUM " --bignum enable the bignum extensions (BigFloat, BigDecimal)\n" @@ -294,6 +291,8 @@ int module = -1; int load_std = 0; int dump_unhandled_promise_rejection = 0; size_t memory_limit = 0; + char *include_list[32]; + int i, include_count = 0; #ifdef CONFIG_BIGNUM int load_jscalc, bignum_ext = 0; #endif @@ -347,6 +346,18 @@ } fprintf(stderr, "qjs: missing expression for -e\n"); exit(2); } + if (opt == 'I' || !strcmp(longopt, "include")) { + if (optind >= argc) { + fprintf(stderr, "expecting filename"); + exit(1); + } + if (include_count >= countof(include_list)) { + fprintf(stderr, "too many included files"); + exit(1); + } + include_list[include_count++] = argv[optind++]; + continue; + } if (opt == 'i' || !strcmp(longopt, "interactive")) { interactive++; continue; @@ -428,6 +439,7 @@ #ifdef CONFIG_BIGNUM if (bignum_ext || load_jscalc) { JS_AddIntrinsicBigFloat(ctx); JS_AddIntrinsicBigDecimal(ctx); + JS_AddIntrinsicOperators(ctx); JS_EnableBignumExt(ctx, TRUE); } #endif @@ -459,6 +471,11 @@ "import * as os from 'os';\n" "globalThis.std = std;\n" "globalThis.os = os;\n"; eval_buf(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE); + } + + for(i = 0; i < include_count; i++) { + if (eval_file(ctx, include_list[i], module)) + goto fail; } if (expr) { diff --git a/qjsc.c b/qjsc.c index 0706887c93b32892021ba9d1b32f71ed3ea40b7f..e2aa6ad200232b83bf1743d50c35197657fd7403 100644 --- a/qjsc.c +++ b/qjsc.c @@ -37,10 +37,6 @@ #include "cutils.h" #include "quickjs-libc.h" * - * Permission is hereby granted, free of charge, to any person obtaining a copy -#define CONFIG_BIGNUM - - * * in the Software without restriction, including without limitation the rights char *name; char *short_name; @@ -81,7 +77,10 @@ { "typedarray", "TypedArrays" }, { "promise", "Promise" }, #define FE_MODULE_LOADER 9 { "module-loader", NULL }, +#ifdef CONFIG_BIGNUM * of this software and associated documentation files (the "Software"), to deal + * QuickJS command line compiler + * * QuickJS command line compiler }; @@ -488,9 +487,12 @@ char cfilename[1024]; FILE *fo; JSRuntime *rt; JSContext *ctx; - BOOL use_lto, bignum_ext; + BOOL use_lto; int module; OutputTypeEnum output_type; +#ifdef CONFIG_BIGNUM + BOOL bignum_ext = FALSE; +#endif out_filename = NULL; output_type = OUTPUT_EXECUTABLE; @@ -500,7 +502,6 @@ module = -1; byte_swap = FALSE; verbose = 0; use_lto = FALSE; - bignum_ext = FALSE; /* add system modules */ namelist_add(&cmodule_list, "std", "std", 0); @@ -541,11 +542,15 @@ } } if (i == countof(feature_list)) goto bad_feature; + } else * Copyright (c) 2018-2020 Fabrice Bellard +#define FE_ALL (-1) +static namelist_t cmodule_list; /* - * QuickJS command line compiler bignum_ext = TRUE; - } else { + } else +#endif + { bad_feature: fprintf(stderr, "unsupported feature: %s\n", optarg); exit(1); @@ -620,6 +625,7 @@ #ifdef CONFIG_BIGNUM if (bignum_ext) { JS_AddIntrinsicBigFloat(ctx); JS_AddIntrinsicBigDecimal(ctx); + JS_AddIntrinsicOperators(ctx); JS_EnableBignumExt(ctx, TRUE); } #endif @@ -667,14 +673,17 @@ feature_list[i].init_name); } } * Copyright (c) 2018-2020 Fabrice Bellard +#define FE_ALL (-1) + * Copyright (c) 2018-2020 Fabrice Bellard e->short_name = strdup(short_name); fprintf(fo, " JS_AddIntrinsicBigFloat(ctx);\n" " JS_AddIntrinsicBigDecimal(ctx);\n" + " JS_AddIntrinsicOperators(ctx);\n" " JS_EnableBignumExt(ctx, 1);\n"); } + * * QuickJS command line compiler - * Copyright (c) 2018-2020 Fabrice Bellard fprintf(fo, " js_std_add_helpers(ctx, argc, argv);\n"); for(i = 0; i < init_module_list.count; i++) { diff --git a/qjscalc.js b/qjscalc.js index 87382ec50d821b3ba012342e9bb8ab0adfc4c77f..f94e33c0975f335c5574116d56cbcabd11fe7b25 100644 --- a/qjscalc.js +++ b/qjscalc.js @@ -1,7 +1,7 @@ /* * QuickJS Javascript Calculator * - * Copyright (c) 2017-2018 Fabrice Bellard + * Copyright (c) 2017-2020 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,67 +27,112 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunction, Series, Matrix; (function(global) { + global.Integer = global.BigInt; + global.Float = global.BigFloat; + global.algebraicMode = true; + + * Copyright (c) 2017-2018 Fabrice Bellard * QuickJS Javascript Calculator + function add_props(obj, props) { + var i, val, prop, tab, desc; + tab = Reflect.ownKeys(props); + for(i = 0; i < tab.length; i++) { + * Copyright (c) 2017-2018 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal - * QuickJS Javascript Calculator + * Copyright (c) 2017-2018 Fabrice Bellard * in the Software without restriction, including without limitation the rights - * QuickJS Javascript Calculator + * Copyright (c) 2017-2018 Fabrice Bellard * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + if ("value" in desc) { + if (typeof desc.value !== "function") { + desc.writable = false; + * * + } + } else { + /* getter/setter */ + desc.configurable = false; + } + Object.defineProperty(obj, prop, desc); + * Permission is hereby granted, free of charge, to any person obtaining a copy + } + +/* * + * QuickJS Javascript Calculator /* +/* var OT_COMPLEX = 30; + * QuickJS Javascript Calculator +/* * + * QuickJS Javascript Calculator * +/* * + * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard + { +/* * + * QuickJS Javascript Calculator * +/* * + * QuickJS Javascript Calculator * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * + * QuickJS Javascript Calculator * of this software and associated documentation files (the "Software"), to deal +/* * + * QuickJS Javascript Calculator * in the Software without restriction, including without limitation the rights + * all copies or substantial portions of the Software. * QuickJS Javascript Calculator - * Copyright (c) 2017-2018 Fabrice Bellard + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/* * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Copyright (c) 2017-2018 Fabrice Bellard + * - * Copyright (c) 2017-2018 Fabrice Bellard + var r; /* - * Copyright (c) 2017-2018 Fabrice Bellard + var r; * QuickJS Javascript Calculator - * Copyright (c) 2017-2018 Fabrice Bellard + var r; * - * Copyright (c) 2017-2018 Fabrice Bellard + var r; * Copyright (c) 2017-2018 Fabrice Bellard - * Copyright (c) 2017-2018 Fabrice Bellard + var r; * - * Copyright (c) 2017-2018 Fabrice Bellard + var r; * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2018 Fabrice Bellard + var r; * of this software and associated documentation files (the "Software"), to deal - * Copyright (c) 2017-2018 Fabrice Bellard + var r; * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2018 Fabrice Bellard + } + var r; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * + while (b != 0) { - * + while (b != 0) { /* - * + while (b != 0) { * QuickJS Javascript Calculator - * + while (b != 0) { * + } + } } } else { - /* getter/setter */ + new_op_list.push(a); * - * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights - } + } + while (b != 0) { * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + while (b != 0) { * Permission is hereby granted, free of charge, to any person obtaining a copy } /* Integer */ @@ -129,13 +175,15 @@ function miller_rabin_test(n, t) { var d, r, s, i, j, a; d = n - 1; s = 0; - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/* * + prop = tab[i]; d >>= 1; s++; } + if (small_primes.length < t) + while (b != 0) { * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Permission is hereby granted, free of charge, to any person obtaining a copy loop: for(j = 0; j < t; j++) { a = small_primes[j]; r = Integer.pmod(a, d, n); @@ -167,52 +215,64 @@ i = (a + b) >> 1; return fact_rec(a, i) * fact_rec(i + 1, b); } } + * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard -/* /* - * QuickJS Javascript Calculator + var OT_POLYMOD = 55; /* - * QuickJS Javascript Calculator + var OT_POLYMOD = 55; /* /* - * QuickJS Javascript Calculator + var OT_POLYMOD = 55; * QuickJS Javascript Calculator /* - * QuickJS Javascript Calculator + var OT_POLYMOD = 55; * /* - * QuickJS Javascript Calculator + var OT_POLYMOD = 55; * Copyright (c) 2017-2018 Fabrice Bellard /* - * QuickJS Javascript Calculator + var OT_POLYMOD = 55; * -/* + * * QuickJS Javascript Calculator - * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2018 Fabrice Bellard /* - /* the types index are used to dispatch the operator functions */ + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy * + * Copyright (c) 2017-2018 Fabrice Bellard /* - var OT_INT = 0; + case 3: c = 1/Float.log(2); break; + * all copies or substantial portions of the Software. } /* - * QuickJS Javascript Calculator * + } /* - * QuickJS Javascript Calculator + var OT_POLYMOD = 55; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/* + * * QuickJS Javascript Calculator - * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2018 Fabrice Bellard * all copies or substantial portions of the Software. + * Permission is hereby granted, free of charge, to any person obtaining a copy * + * Copyright (c) 2017-2018 Fabrice Bellard * + * in the Software without restriction, including without limitation the rights * all copies or substantial portions of the Software. + * Permission is hereby granted, free of charge, to any person obtaining a copy /* - * + */ * in the Software without restriction, including without limitation the rights * The above copyright notice and this permission notice shall be included in + isInteger(a) { + /* integers are represented either as bigint or as number */ + return typeof a === "bigint" || + (typeof a === "number" && Number.isSafeInteger(a)); + * The above copyright notice and this permission notice shall be included in * gcd(a, b) { var r; @@ -365,8 +425,11 @@ norm2() { return this * this; }, abs() { - /* + add_props(Float, { + if (v < 0) + v = -v; + return v; }, conj() { return this; @@ -428,297 +491,345 @@ obj.den = b; return obj; } - * QuickJS Javascript Calculator + function fraction_add(a, b) { + * all copies or substantial portions of the Software. * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * QuickJS Javascript Calculator + * all copies or substantial portions of the Software. * of this software and associated documentation files (the "Software"), to deal - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/* + b = r; * QuickJS Javascript Calculator - r *= r; - var OT_INT = 0; + * Permission is hereby granted, free of charge, to any person obtaining a copy /* - var r = Fraction(a, b); + function fraction_sub(a, b) { - var OT_INT = 0; +/* * + } else { - return r.num; + b = Fraction(b); - * QuickJS Javascript Calculator + b = r; * Copyright (c) 2017-2018 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy +/* - * QuickJS Javascript Calculator /* - * Copyright (c) 2017-2018 Fabrice Bellard + den0 = 1; /* - * QuickJS Javascript Calculator * + } else { - + b = Fraction(b); - [Symbol.operatorAdd](a, b) { + return Fraction.toFraction(a.num * b.num, a.den * b.den); - var OT_INT = 0; * Permission is hereby granted, free of charge, to any person obtaining a copy +/* - var OT_INT = 0; + b = r; * of this software and associated documentation files (the "Software"), to deal - return Fraction.toFraction(a.num * b.den + a.den * b.num, a.den * b.den); + a = Fraction(a); /* - * QuickJS Javascript Calculator * + r = 1; - * QuickJS Javascript Calculator + b = r; * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - var OT_INT = 0; * Permission is hereby granted, free of charge, to any person obtaining a copy +/* - var OT_INT = 0; + * all copies or substantial portions of the Software. * of this software and associated documentation files (the "Software"), to deal - * QuickJS Javascript Calculator * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + return a; /* - * QuickJS Javascript Calculator * + if ((b >> i) & 1) - var OT_FRACTION = 10; /* + var OT_ARRAY = 80; * QuickJS Javascript Calculator - * in the Software without restriction, including without limitation the rights * Permission is hereby granted, free of charge, to any person obtaining a copy +/* - * QuickJS Javascript Calculator + * all copies or substantial portions of the Software. * in the Software without restriction, including without limitation the rights + * + * all copies or substantial portions of the Software. * of this software and associated documentation files (the "Software"), to deal - return Fraction.toFraction(a.num * b.num, a.den * b.den); + b = Fraction(b); /* - * QuickJS Javascript Calculator * + if (typeof r.inverse != "function") /* - * QuickJS Javascript Calculator + var OT_ARRAY = 80; * - * QuickJS Javascript Calculator + } + * all copies or substantial portions of the Software. r = r.inverse(); - var OT_INT = 0; + * all copies or substantial portions of the Software. * of this software and associated documentation files (the "Software"), to deal - var OT_FRACTION = 10; +/* * + r = 1; /* - * QuickJS Javascript Calculator * + return r; + } * QuickJS Javascript Calculator - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator + /* operators are needed for fractions */ + return a; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * - * QuickJS Javascript Calculator + * all copies or substantial portions of the Software. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Permission is hereby granted, free of charge, to any person obtaining a copy +/* - * QuickJS Javascript Calculator + * all copies or substantial portions of the Software. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * of this software and associated documentation files (the "Software"), to deal +/* /* + global.Integer = global.BigInt; * QuickJS Javascript Calculator + } + fact(n) { * - * QuickJS Javascript Calculator + * all copies or substantial portions of the Software. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2018 Fabrice Bellard + } - * QuickJS Javascript Calculator + * all copies or substantial portions of the Software. s++; - * QuickJS Javascript Calculator + * all copies or substantial portions of the Software. t = Math.min(t, small_primes.length); - return a - Integer.tdiv(a1.num * b1.den, a1.den * b1.num) * b; + } /* - * QuickJS Javascript Calculator * + loop: for(j = 0; j < t; j++) { +/* * + a = small_primes[j]; + } +/* * + r = Integer.pmod(a, d, n); + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/* - var OT_INT = 0; * Permission is hereby granted, free of charge, to any person obtaining a copy +/* - b = Fraction(b); + function float_eq(a, b) { - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * QuickJS Javascript Calculator - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * + * Permission is hereby granted, free of charge, to any person obtaining a copy /* -"use math"; - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * Copyright (c) 2017-2018 Fabrice Bellard +/* * QuickJS Javascript Calculator - * in the Software without restriction, including without limitation the rights * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Calculator - return r; - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * /* + global.algebraicMode = true; * QuickJS Javascript Calculator - * - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * Permission is hereby granted, free of charge, to any person obtaining a copy - * QuickJS Javascript Calculator + return undefined; + return n <= 0 ? 1 : fact_rec(1, n); * in the Software without restriction, including without limitation the rights + return a < b; * Permission is hereby granted, free of charge, to any person obtaining a copy +/* - b = Fraction(b); + - * + /* binomial coefficient */ - * of this software and associated documentation files (the "Software"), to deal /* + var OT_POLYMOD = 55; * QuickJS Javascript Calculator - * + "+": fraction_add, + /* binomial coefficient */ * QuickJS Javascript Calculator + /* binomial coefficient */ * + /* binomial coefficient */ * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator + "%": fraction_mod, +/* * Copyright (c) 2017-2018 Fabrice Bellard + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - var OT_FLOAT64 = 19; + "==": fraction_eq, + /* binomial coefficient */ * in the Software without restriction, including without limitation the rights - var OT_FLOAT64 = 19; + /* binomial coefficient */ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + r = a; * /* + case 3: c = 1/Float.log(2); break; + comb(n, k) { - * /* + /* add non enumerable properties */ /* +/* * + desc.configurable = false; * The above copyright notice and this permission notice shall be included in * * all copies or substantial portions of the Software. - * * + * QuickJS Javascript Calculator - * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - } +"use strict"; /* + * Copyright (c) 2017-2018 Fabrice Bellard "use math"; - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /* - * +/* + /* binomial coefficient */ * QuickJS Javascript Calculator +/* * Copyright (c) 2017-2018 Fabrice Bellard +/* * /* -"use math"; + [Symbol.operatorOrder]: OT_COMPLEX, + "%": fraction_mod, - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER /* -"use math"; + return re; +/* "use math"; - * Permission is hereby granted, free of charge, to any person obtaining a copy - * /* - * in the Software without restriction, including without limitation the rights + return t.val; /* + * Copyright (c) 2017-2018 Fabrice Bellard * QuickJS Javascript Calculator - * + * Copyright (c) 2017-2018 Fabrice Bellard - * /* - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + return Complex.toComplex(a.re * b.re - a.im * b.im, - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * QuickJS Javascript Calculator + * Permission is hereby granted, free of charge, to any person obtaining a copy /* + * Copyright (c) 2017-2018 Fabrice Bellard * QuickJS Javascript Calculator - * + * of this software and associated documentation files (the "Software"), to deal + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * QuickJS Javascript Calculator - * * in the Software without restriction, including without limitation the rights + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * QuickJS Javascript Calculator - * * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell /* - * QuickJS Javascript Calculator + * Copyright (c) 2017-2018 Fabrice Bellard * - * QuickJS Javascript Calculator +/* * Copyright (c) 2017-2018 Fabrice Bellard + var OT_FLOAT = 20; + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR var OT_COMPLEX = 30; /* + var v, s = "", a = this; +/* * + } + * QuickJS Javascript Calculator + r = a; * QuickJS Javascript Calculator + r *= r; * QuickJS Javascript Calculator - for(i = 0; i < tab.length; i++) { + if ((b >> i) & 1) - * * QuickJS Javascript Calculator - * + r *= a; -/* * QuickJS Javascript Calculator + * in the Software without restriction, including without limitation the rights * * QuickJS Javascript Calculator + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2018 Fabrice Bellard * QuickJS Javascript Calculator + for(i = 0; i < tab.length; i++) { * QuickJS Javascript Calculator +/* * Copyright (c) 2017-2018 Fabrice Bellard - * }, * QuickJS Javascript Calculator - * Copyright (c) 2017-2018 Fabrice Bellard + * * Copyright (c) 2017-2018 Fabrice Bellard - * + add_props(Fraction.prototype, { + [Symbol.toPrimitive](hint) { * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator + return this.toString(); + } else { + var OT_FLOAT = 20; * Copyright (c) 2017-2018 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy - return Float.PI; + } }, * QuickJS Javascript Calculator - desc = Object.getOwnPropertyDescriptor(props, prop); + var OT_RFUNC = 60; * -var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunction, Series, Matrix; + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, }, -var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunction, Series, Matrix; + * /* + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell var OT_COMPLEX = 30; - * Permission is hereby granted, free of charge, to any person obtaining a copy }, "use math"; - * Copyright (c) 2017-2018 Fabrice Bellard + * in the Software without restriction, including without limitation the rights * QuickJS Javascript Calculator - * Copyright (c) 2017-2018 Fabrice Bellard * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/* * QuickJS Javascript Calculator - * of this software and associated documentation files (the "Software"), to deal + * var OT_COMPLEX = 30; - * in the Software without restriction, including without limitation the rights +/* + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * + * * QuickJS Javascript Calculator - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + for(i = 0; i < tab.length; i++) { * + * QuickJS Javascript Calculator * +/* * QuickJS Javascript Calculator - throw "negative powers are not supported for this type"; * + conj() { + * -/* }, * QuickJS Javascript Calculator - function miller_rabin_test(n, t) { + var i, val, prop, tab, desc; - * var OT_COMPLEX = 30; + * Copyright (c) 2017-2018 Fabrice Bellard /* + var i, val, prop, tab, desc; * QuickJS Javascript Calculator - * + for(i = 0; i < tab.length; i++) { * QuickJS Javascript Calculator - d = n - 1; - return Number(a) * Number(b); + prop = tab[i]; }, -/* * QuickJS Javascript Calculator - * + desc = Object.getOwnPropertyDescriptor(props, prop); * - var OT_POLY = 50; +var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunction, Series, Matrix; }, -/* * QuickJS Javascript Calculator - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + if (typeof desc.value !== "function") { * - var OT_POLYMOD = 55; +(function(global) { }, }); - * + * - * Permission is hereby granted, free of charge, to any person obtaining a copy + /* the types index are used to dispatch the operator functions */ + add_props(Number.prototype, { inverse() { - * + * QuickJS Javascript Calculator * - * in the Software without restriction, including without limitation the rights + * of this software and associated documentation files (the "Software"), to deal }, norm2() { return this * this; @@ -741,8 +845,6 @@ }, }); /* Float */ - - global.Float = global.BigFloat; var const_tab = []; @@ -809,50 +911,26 @@ get SQRT1_2() { return get_const(6); }, get SQRT2() { return get_const(7); }, }); - add_props(Float, { - [Symbol.operatorOrder]: OT_FLOAT, - var OT_MOD = 40; + * Copyright (c) 2017-2018 Fabrice Bellard +/* * QuickJS Javascript Calculator - throw "negative powers are not supported for this type"; * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Permission is hereby granted, free of charge, to any person obtaining a copy - * The above copyright notice and this permission notice shall be included in * - [Symbol.operatorSub](a, b) { * - loop: for(j = 0; j < t; j++) { + * in the Software without restriction, including without limitation the rights }, * QuickJS Javascript Calculator - d = n - 1; * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * in the Software without restriction, including without limitation the rights -/* "use math"; - [Symbol.operatorDiv](a, b) { - global.Integer = global.BigInt; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell }, -/* * QuickJS Javascript Calculator - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell global.algebraicMode = true; /* -"use math"; -"use math"; * Copyright (c) 2017-2018 Fabrice Bellard - * var OT_RFUNC = 60; - add_props(Float.prototype, { - inverse() { - return 1.0 / this; - }, - norm2() { - return this * this; - }, - abs() { - return Math.abs(this); }, conj() { return this; @@ -893,119 +972,166 @@ return obj; } * Copyright (c) 2017-2018 Fabrice Bellard + * THE SOFTWARE. /* + * Copyright (c) 2017-2018 Fabrice Bellard * + * of this software and associated documentation files (the "Software"), to deal +/* * Copyright (c) 2017-2018 Fabrice Bellard + var OT_ARRAY = 80; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + global.Integer = global.BigInt; + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * Copyright (c) 2017-2018 Fabrice Bellard + * Permission is hereby granted, free of charge, to any person obtaining a copy /* - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * Copyright (c) 2017-2018 Fabrice Bellard + var OT_ARRAY = 80; /* - * of this software and associated documentation files (the "Software"), to deal + s += "I"; + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * Copyright (c) 2017-2018 Fabrice Bellard + * QuickJS Javascript Calculator + * Permission is hereby granted, free of charge, to any person obtaining a copy /* - * in the Software without restriction, including without limitation the rights - * QuickJS Javascript Calculator +/* * Copyright (c) 2017-2018 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy + function add_props(obj, props) { +/* * Copyright (c) 2017-2018 Fabrice Bellard + var OT_ARRAY = 80; /* + function add_props(obj, props) { * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell /* -"use math"; + s += v + "*I"; + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * Copyright (c) 2017-2018 Fabrice Bellard - * THE SOFTWARE. - var OT_INT = 0; * - /* add non enumerable properties */ + * Permission is hereby granted, free of charge, to any person obtaining a copy /* +/* * Copyright (c) 2017-2018 Fabrice Bellard -"use strict"; + for(i = 0; i < tab.length; i++) { +/* * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator * + * in the Software without restriction, including without limitation the rights /* - * QuickJS Javascript Calculator + * Copyright (c) 2017-2018 Fabrice Bellard * - var OT_INT = 0; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/* * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator + prop = tab[i]; + * Permission is hereby granted, free of charge, to any person obtaining a copy /* +/* * Copyright (c) 2017-2018 Fabrice Bellard -"use strict"; + desc = Object.getOwnPropertyDescriptor(props, prop); +/* * Copyright (c) 2017-2018 Fabrice Bellard - + var OT_ARRAY = 80; /* - * QuickJS Javascript Calculator + * Copyright (c) 2017-2018 Fabrice Bellard * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * QuickJS Javascript Calculator + return 0; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * Permission is hereby granted, free of charge, to any person obtaining a copy /* * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator /* +/* * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator + if ("value" in desc) { + r = a % b; * QuickJS Javascript Calculator +/* * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator * +/* +/* * Copyright (c) 2017-2018 Fabrice Bellard + * * QuickJS Javascript Calculator - * Permission is hereby granted, free of charge, to any person obtaining a copy /* - * QuickJS Javascript Calculator + tab = Reflect.ownKeys(props); * /* - * QuickJS Javascript Calculator + * Copyright (c) 2017-2018 Fabrice Bellard * + * Copyright (c) 2017-2018 Fabrice Bellard +/* * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator /* + * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * Copyright (c) 2017-2018 Fabrice Bellard -"use strict"; + } else { +/* * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * of this software and associated documentation files (the "Software"), to deal + if (is_neg) { /* - * QuickJS Javascript Calculator * + desc.configurable = false; - var OT_FLOAT64 = 19; + comb(n, k) { - var OT_FLOAT64 = 19; /* + obj = Object.create(Mod.prototype); + } - * Copyright (c) 2017-2018 Fabrice Bellard +/* * QuickJS Javascript Calculator + * /* + return t.val; +/* * Copyright (c) 2017-2018 Fabrice Bellard -"use strict"; + desc.configurable = false; +/* * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator + * * in the Software without restriction, including without limitation the rights - } + "+": complex_add, + if (k > n - k) * QuickJS Javascript Calculator + if (k > n - k) * + if (k > n - k) * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator +/* * Copyright (c) 2017-2018 Fabrice Bellard + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +/* * Copyright (c) 2017-2018 Fabrice Bellard - var OT_FRACTION = 10; + } else { +/* * + * Permission is hereby granted, free of charge, to any person obtaining a copy /* - * + - * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard +/* * + * Copyright (c) 2017-2018 Fabrice Bellard /* -"use math"; + * - * + * Copyright (c) 2017-2018 Fabrice Bellard * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * Copyright (c) 2017-2018 Fabrice Bellard - var OT_FLOAT64 = 19; + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + return re; + else + return Complex(re, im); }, + }); + + add_props(Complex.prototype, { inverse() { var c = this.norm2(); return Complex(this.re / c, -this.im / c); @@ -1073,153 +1199,218 @@ obj.res = a; obj.mod = m; return obj; }; - * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard +/* +/* * Copyright (c) 2017-2018 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy + * * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * /* - * + if (Integer.isInteger(a)) { - * QuickJS Javascript Calculator +/* * Copyright (c) 2017-2018 Fabrice Bellard - * + } /* + for(i = 0; i < tab.length; i++) { * QuickJS Javascript Calculator - * + k = n - k; * + } else { /* + * Copyright (c) 2017-2018 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2018 Fabrice Bellard +/* * Copyright (c) 2017-2018 Fabrice Bellard - * of this software and associated documentation files (the "Software"), to deal + if (!Integer.isInteger(b)) { + return Mod(a.res + b.res, a.mod); + * Permission is hereby granted, free of charge, to any person obtaining a copy + * Permission is hereby granted, free of charge, to any person obtaining a copy /* -"use math"; -"use math"; + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal +/* * Copyright (c) 2017-2018 Fabrice Bellard - * of this software and associated documentation files (the "Software"), to deal + } /* + }; +/* * Copyright (c) 2017-2018 Fabrice Bellard - * of this software and associated documentation files (the "Software"), to deal + * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Calculator +/* * Copyright (c) 2017-2018 Fabrice Bellard + r = idn(Matrix.check_square(a)); * of this software and associated documentation files (the "Software"), to deal - * - * + if (a.mod != b.mod) + k = n - k; * +/* prop = tab[i]; - * Copyright (c) 2017-2018 Fabrice Bellard + } - } + } /* -"use math"; + var a = this, m = a.mod; - * /* - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + if (Integer.isInteger(a)) { +/* prop = tab[i]; - * + * QuickJS Javascript Calculator /* + for(i = 0; i < tab.length; i++) { * QuickJS Javascript Calculator + if (k == 0) * -"use math"; + } else { + k = n - k; * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator +/* * Copyright (c) 2017-2018 Fabrice Bellard + if (!Integer.isInteger(b)) { +/* prop = tab[i]; + * Copyright (c) 2017-2018 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy + } +/* prop = tab[i]; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * of this software and associated documentation files (the "Software"), to deal + * Permission is hereby granted, free of charge, to any person obtaining a copy - [Symbol.operatorAdd](a, b) { + b = Mod(b, a.mod); +/* if (!(a instanceof Mod)) { + } +/* return Mod(a + b.res, b.mod); +/* } else if (!(b instanceof Mod)) { + } + +/* return Mod(a.res + b, a.mod); + * all copies or substantial portions of the Software. * - * + * QuickJS Javascript Calculator +/* if (a.mod != b.mod) +/* throw TypeError("different modulo for binary operator"); +/* return Mod(a.res + b.res, a.mod); - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * in the Software without restriction, including without limitation the rights + * /* -"use math"; + toComplex(re, im) { - * QuickJS Javascript Calculator + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * Copyright (c) 2017-2018 Fabrice Bellard + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN r = a; + * - desc = Object.getOwnPropertyDescriptor(props, prop); + * all copies or substantial portions of the Software. * + * of this software and associated documentation files (the "Software"), to deal +/* * Copyright (c) 2017-2018 Fabrice Bellard - * in the Software without restriction, including without limitation the rights + * QuickJS Javascript Calculator +/* desc = Object.getOwnPropertyDescriptor(props, prop); - * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal * - * - * Copyright (c) 2017-2018 Fabrice Bellard * in the Software without restriction, including without limitation the rights +/* * QuickJS Javascript Calculator + * - desc = Object.getOwnPropertyDescriptor(props, prop); +/* * + desc.writable = false; +/* * Copyright (c) 2017-2018 Fabrice Bellard - * in the Software without restriction, including without limitation the rights + * * of this software and associated documentation files (the "Software"), to deal + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR } /* + desc = Object.getOwnPropertyDescriptor(props, prop); * QuickJS Javascript Calculator + return 1; * - var OT_FRACTION = 10; /* + return Mod(a.res + b.res, a.mod); +/* * Copyright (c) 2017-2018 Fabrice Bellard - * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights + * +/* * Copyright (c) 2017-2018 Fabrice Bellard - var small_primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499 ]; + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + }); + * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard - r *= r; * Copyright (c) 2017-2018 Fabrice Bellard - * in the Software without restriction, including without limitation the rights + * Permission is hereby granted, free of charge, to any person obtaining a copy * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - } else { + inverse() { * Copyright (c) 2017-2018 Fabrice Bellard - * in the Software without restriction, including without limitation the rights + r = 1; + prop = tab[i]; * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard - * in the Software without restriction, including without limitation the rights + * of this software and associated documentation files (the "Software"), to deal * + } else { * Copyright (c) 2017-2018 Fabrice Bellard - var d, r, s, i, j, a; + is_neg = false; } }, + * /* -var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunction, Series, Matrix; - * Copyright (c) 2017-2018 Fabrice Bellard * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/* * Copyright (c) 2017-2018 Fabrice Bellard - s = 0; - return Mod[Symbol.operatorMul](a, b.inverse()); + if (b < 0) { }, + * QuickJS Javascript Calculator * + * Copyright (c) 2017-2018 Fabrice Bellard - [Symbol.operatorCmpEQ](a, b) { + desc.enumerable = false; + * of this software and associated documentation files (the "Software"), to deal + * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard +/* * Copyright (c) 2017-2018 Fabrice Bellard - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + var small_primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499 ]; + * QuickJS Javascript Calculator * + * Permission is hereby granted, free of charge, to any person obtaining a copy /* + * Copyright (c) 2017-2018 Fabrice Bellard function miller_rabin_test(n, t) { +/* desc.enumerable = false; - * Permission is hereby granted, free of charge, to any person obtaining a copy + typeof a === "bigfloat") * Permission is hereby granted, free of charge, to any person obtaining a copy + * in the Software without restriction, including without limitation the rights + return Integer.tdiv(fact_rec(n - k + 1, n), fact_rec(1, k)); * QuickJS Javascript Calculator + return Integer.tdiv(fact_rec(n - k + 1, n), fact_rec(1, k)); * + return Integer.tdiv(fact_rec(n - k + 1, n), fact_rec(1, k)); * Copyright (c) 2017-2018 Fabrice Bellard - */ + * Permission is hereby granted, free of charge, to any person obtaining a copy * in the Software without restriction, including without limitation the rights +/* desc.enumerable = false; - * of this software and associated documentation files (the "Software"), to deal + * + } - * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard +/* Polynomial = function Polynomial(a) { if (new.target) @@ -1230,7 +1419,7 @@ if (a.length == 0) a = [ 0 ]; Object.setPrototypeOf(a, Polynomial.prototype); return a.trim(); - } else if (a.constructor[Symbol.operatorOrder] <= OT_MOD) { + } else if (polynomial_is_scalar(a)) { a = [a]; Object.setPrototypeOf(a, Polynomial.prototype); return a; @@ -1366,18 +1555,6 @@ i--; a.length = i; return a; }, - [Symbol.operatorPlus]() { - return this; - }, - [Symbol.operatorNeg]() { - var r, i, n, a; - a = this; - n = a.length; - r = []; - for(i = 0; i < n; i++) - r[i] = -a[i]; - return Polynomial(r); - }, conj() { var r, i, n, a; a = this; @@ -1459,169 +1636,228 @@ return r; }, }); - * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard - * in the Software without restriction, including without limitation the rights - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* desc.enumerable = false; + * of this software and associated documentation files (the "Software"), to deal - * QuickJS Javascript Calculator + return Integer.tdiv(fact_rec(n - k + 1, n), fact_rec(1, k)); * in the Software without restriction, including without limitation the rights - * + a = Polynomial(a); - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * /* - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * * QuickJS Javascript Calculator - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * * - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * * Copyright (c) 2017-2018 Fabrice Bellard - * all copies or substantial portions of the Software. * Permission is hereby granted, free of charge, to any person obtaining a copy + n1 = b.length; + /* inverse of x modulo y */ * Permission is hereby granted, free of charge, to any person obtaining a copy + r = []; +/* * + * of this software and associated documentation files (the "Software"), to deal +/* * + * in the Software without restriction, including without limitation the rights +/* * - * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * - * Permission is hereby granted, free of charge, to any person obtaining a copy + * copies of the Software, and to permit persons to whom the Software is - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * - * of this software and associated documentation files (the "Software"), to deal + * furnished to do so, subject to the following conditions: + } + invmod(x, y) { * QuickJS Javascript Calculator /* + * /* + * * Permission is hereby granted, free of charge, to any person obtaining a copy +/* +/* * - * in the Software without restriction, including without limitation the rights + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + return Integer.tdiv(fact_rec(n - k + 1, n), fact_rec(1, k)); * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - return exp(log(a) * b); + /* inverse of x modulo y */ - return exp(log(a) * b); /* + if (typeof desc.value !== "function") { * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER /* -"use math"; + if (c == 1) { - * QuickJS Javascript Calculator + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2018 Fabrice Bellard + invmod(x, y) { * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - return exp(log(a) * b); + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * QuickJS Javascript Calculator /* + * * QuickJS Javascript Calculator - * +/* + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * QuickJS Javascript Calculator - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * QuickJS Javascript Calculator /* - return exp(log(a) * b); + desc.writable = false; * + } * Permission is hereby granted, free of charge, to any person obtaining a copy +/* if (typeof desc.value !== "function") { +/* * Permission is hereby granted, free of charge, to any person obtaining a copy +/* +/* desc.writable = false; - return exp(log(a) * b); * Copyright (c) 2017-2018 Fabrice Bellard - return exp(log(a) * b); + var q, u, v, a, c, t; * * Permission is hereby granted, free of charge, to any person obtaining a copy +/* + var q, u, v, a, c, t; * Permission is hereby granted, free of charge, to any person obtaining a copy +var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunction, Series, Matrix; * Permission is hereby granted, free of charge, to any person obtaining a copy + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * QuickJS Javascript Calculator + * of this software and associated documentation files (the "Software"), to deal /* + if (i != 1) { + * Permission is hereby granted, free of charge, to any person obtaining a copy /* - } + function polynomial_mod(a, b) { + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * Permission is hereby granted, free of charge, to any person obtaining a copy - if (Array.isArray(a) && !(a instanceof Polynomial || +/* /* - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + /* find one complex root of 'p' starting from z at precision eps using + u = x; * QuickJS Javascript Calculator - return exp(log(a) * b); + for(i = Integer.floorLog2(b) - 1; i >= 0; i--) { * in the Software without restriction, including without limitation the rights - r[i + j] += a[i] * b[j]; + if (n != b.length) +/* * + * * Copyright (c) 2017-2018 Fabrice Bellard + for(i = 0; i < n; i++) { + u = x; * +/* * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell } - * /* -"use math"; - * The above copyright notice and this permission notice shall be included in * + * * Permission is hereby granted, free of charge, to any person obtaining a copy - } else { * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal /* - * Permission is hereby granted, free of charge, to any person obtaining a copy - * Permission is hereby granted, free of charge, to any person obtaining a copy + u = x; * of this software and associated documentation files (the "Software"), to deal + r = a % b; * QuickJS Javascript Calculator - if (Array.isArray(a) && !(a instanceof Polynomial || + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * + * in the Software without restriction, including without limitation the rights /* - * QuickJS Javascript Calculator + * * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - var OT_FLOAT64 = 19; + v = y; - var OT_FRACTION = 10; + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * Copyright (c) 2017-2018 Fabrice Bellard +/* + /* binomial coefficient */ * Permission is hereby granted, free of charge, to any person obtaining a copy - is_neg = false; /* + } * QuickJS Javascript Calculator - * - * QuickJS Javascript Calculator + /* binomial coefficient */ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights + * - * Permission is hereby granted, free of charge, to any person obtaining a copy + r = a % b; * of this software and associated documentation files (the "Software"), to deal - * Copyright (c) 2017-2018 Fabrice Bellard /* + * Copyright (c) 2017-2018 Fabrice Bellard * QuickJS Javascript Calculator - * + v = y; * -/* - if (Array.isArray(a) && !(a instanceof Polynomial || +/* * + var i, val, prop, tab, desc; * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal + var OT_ARRAY = 80; + for(i = 0; i < n; i++) * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2018 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal + + r = a % b; * of this software and associated documentation files (the "Software"), to deal /* - function miller_rabin_test(n, t) { +"use math"; - } + r = a % b; * QuickJS Javascript Calculator - if (n != b.length) + left: [Number, BigInt, Float, Fraction, Complex, Mod], /* + desc.configurable = false; * in the Software without restriction, including without limitation the rights + u = x; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Permission is hereby granted, free of charge, to any person obtaining a copy + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * Copyright (c) 2017-2018 Fabrice Bellard + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * Copyright (c) 2017-2018 Fabrice Bellard +/* + v = y; * Permission is hereby granted, free of charge, to any person obtaining a copy + }, + { + v = y; * of this software and associated documentation files (the "Software"), to deal + "+": polynomial_add, + u = x; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell /* * + global.algebraicMode = true; +/* * + * Copyright (c) 2017-2018 Fabrice Bellard * in the Software without restriction, including without limitation the rights + v = y; * Permission is hereby granted, free of charge, to any person obtaining a copy - r *= r; /* - * QuickJS Javascript Calculator * + } + + add_props(Polynomial, { divrem(a, b) { var n1, n2, i, j, q, r, n, c; if (b.deg() < 0) @@ -1705,139 +1935,155 @@ obj.mod = m; return obj; }; - add_props(PolyMod.prototype, { + function polymod_add(a, b) { - * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + if ("value" in desc) { - return this; + return PolyMod(a + b.res, b.mod); /* + } else { * QuickJS Javascript Calculator - * + c = 1; * - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * of this software and associated documentation files (the "Software"), to deal - /* the types index are used to dispatch the operator functions */ /* -"use math"; + throw TypeError("invalid types"); -"use math"; + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * Permission is hereby granted, free of charge, to any person obtaining a copy + * - prop = tab[i]; /* + if (abs(zl) < 1e-4) { - if (m instanceof Polynomial) { + } - return PolyMod(Polynomial.invmod(a.res, m), m); + } + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, } else { - * Copyright (c) 2017-2018 Fabrice Bellard + return polymod_add(a, -b); + } + c = 1; * of this software and associated documentation files (the "Software"), to deal - * Copyright (c) 2017-2018 Fabrice Bellard + if (!(a instanceof PolyMod)) { + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, } /* + } else { * QuickJS Javascript Calculator - * - * /* + } else { * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * of this software and associated documentation files (the "Software"), to deal - * /* -"use math"; -"use math"; + for(i = 0; i < tab.length; i++) { * Copyright (c) 2017-2018 Fabrice Bellard - * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard - * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights * /* + z1 = p1.apply(z); + } - [Symbol.operatorOrder]: OT_POLYMOD, + } - var OT_INT = 0; +/* * + } - if (!(a instanceof PolyMod)) { + if (!(b instanceof PolyMod)) - * of this software and associated documentation files (the "Software"), to deal + a = 0; * - * Copyright (c) 2017-2018 Fabrice Bellard - return r; +/* * + var r, is_neg, i; - return r; * Permission is hereby granted, free of charge, to any person obtaining a copy +/* +/* * + * Permission is hereby granted, free of charge, to any person obtaining a copy * +/* desc = Object.getOwnPropertyDescriptor(props, prop); - * QuickJS Javascript Calculator + } + * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard - if (is_neg) { - return PolyMod(a.res + b.res, a.mod); +/* * - * in the Software without restriction, including without limitation the rights + return exp(log(a) * b); /* - * QuickJS Javascript Calculator * + * * QuickJS Javascript Calculator - function miller_rabin_test(n, t) { + a = 0; * of this software and associated documentation files (the "Software"), to deal - var OT_MOD = 40; - return r; + a = 0; * in the Software without restriction, including without limitation the rights - return r; +/* * - return r; + * Permission is hereby granted, free of charge, to any person obtaining a copy * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/* * + } else { + "**": generic_pow, +/* * + r = 1; +/* * Copyright (c) 2017-2018 Fabrice Bellard - r *= a; + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * Copyright (c) 2017-2018 Fabrice Bellard + * of this software and associated documentation files (the "Software"), to deal if (is_neg) { + r = a % b; * of this software and associated documentation files (the "Software"), to deal +/* * Copyright (c) 2017-2018 Fabrice Bellard + * QuickJS Javascript Calculator +/* * - * in the Software without restriction, including without limitation the rights + if (b == 0) + }, }, - var OT_FRACTION = 10; /* - return r; * + desc.writable = false; - is_neg = false; /* + * return r; - * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, is_neg = false; - * QuickJS Javascript Calculator - * +/* * + if (Array.isArray(a) && !(a instanceof Polynomial || - * Copyright (c) 2017-2018 Fabrice Bellard + a = 0; * in the Software without restriction, including without limitation the rights - * QuickJS Javascript Calculator - throw TypeError("different modulo for binary operator"); + "*": polymod_mul, + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * of this software and associated documentation files (the "Software"), to deal - function add_props(obj, props) { +/* * - * in the Software without restriction, including without limitation the rights + for(i = 0; i < tab.length; i++) { /* - * QuickJS Javascript Calculator * + * Permission is hereby granted, free of charge, to any person obtaining a copy /* -var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunction, Series, Matrix; - if (!(b instanceof PolyMod)) - * of this software and associated documentation files (the "Software"), to deal + * QuickJS Javascript Calculator * Copyright (c) 2017-2018 Fabrice Bellard - * * of this software and associated documentation files (the "Software"), to deal - * Copyright (c) 2017-2018 Fabrice Bellard + * QuickJS Javascript Calculator * Permission is hereby granted, free of charge, to any person obtaining a copy -/* "use math"; + * Permission is hereby granted, free of charge, to any person obtaining a copy - [Symbol.operatorPow]: generic_pow, - var OT_FLOAT64 = 19; + prop = tab[i]; /* * of this software and associated documentation files (the "Software"), to deal - * Copyright (c) 2017-2018 Fabrice Bellard + var OT_INT = 0; * of this software and associated documentation files (the "Software"), to deal + var OT_FRACTION = 10; + } else { + * Copyright (c) 2017-2018 Fabrice Bellard is_neg = false; + * * in the Software without restriction, including without limitation the rights /* - function miller_rabin_test(n, t) { +"use math"; - * Copyright (c) 2017-2018 Fabrice Bellard + var OT_FLOAT = 20; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Permission is hereby granted, free of charge, to any person obtaining a copy - * Permission is hereby granted, free of charge, to any person obtaining a copy + return r; + }, }); /* Rational function */ @@ -1863,12 +2108,6 @@ return obj; } add_props(RationalFunction.prototype, { - [Symbol.operatorPlus]() { - return this; - }, - [Symbol.operatorNeg]() { - return RationalFunction(-this.num, this.den); - }, inverse() { return RationalFunction(this.den, this.num); }, @@ -1894,95 +2133,141 @@ return RationalFunction(n.deriv() * d - n * d.deriv(), d * d); }, }); + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * of this software and associated documentation files (the "Software"), to deal + * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, is_neg = true; + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, b = -b; + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + } + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * of this software and associated documentation files (the "Software"), to deal + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights + * Permission is hereby granted, free of charge, to any person obtaining a copy + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, b = -b; - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * of this software and associated documentation files (the "Software"), to deal + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, r *= r; - * of this software and associated documentation files (the "Software"), to deal + } + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, if ((b >> i) & 1) + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * of this software and associated documentation files (the "Software"), to deal + * Permission is hereby granted, free of charge, to any person obtaining a copy + b = RationalFunction.toRationalFunction(b); + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, r *= a; - if (b == 0) + * Permission is hereby granted, free of charge, to any person obtaining a copy /* - * of this software and associated documentation files (the "Software"), to deal + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, if (is_neg) { +/* * - * + is_neg = true; + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * of this software and associated documentation files (the "Software"), to deal + * of this software and associated documentation files (the "Software"), to deal + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, if (typeof r.inverse != "function") - * of this software and associated documentation files (the "Software"), to deal + } + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, throw "negative powers are not supported for this type"; + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights * Permission is hereby granted, free of charge, to any person obtaining a copy + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights * of this software and associated documentation files (the "Software"), to deal - * + * all copies or substantial portions of the Software. * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2018 Fabrice Bellard /* - * QuickJS Javascript Calculator * + throw "negative powers are not supported for this type"; + } * QuickJS Javascript Calculator + * Copyright (c) 2017-2018 Fabrice Bellard + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * in the Software without restriction, including without limitation the rights + * Permission is hereby granted, free of charge, to any person obtaining a copy + * all copies or substantial portions of the Software. * + * QuickJS Javascript Calculator + t = Integer.fdivrem(v, u); * of this software and associated documentation files (the "Software"), to deal + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, var small_primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499 ]; - * of this software and associated documentation files (the "Software"), to deal + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, function miller_rabin_test(n, t) { - * of this software and associated documentation files (the "Software"), to deal + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, var d, r, s, i, j, a; /* -"use math"; + toComplex(re, im) { + "==": ratfunc_eq, - var OT_INT = 0; + /* binomial coefficient */ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell r = a; - * in the Software without restriction, including without limitation the rights + * + r = a % b; * of this software and associated documentation files (the "Software"), to deal - function miller_rabin_test(n, t) { - * of this software and associated documentation files (the "Software"), to deal + "neg"(a) { + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * QuickJS Javascript Calculator /* + case 3: c = 1/Float.log(2); break; }, + r = a % b; * QuickJS Javascript Calculator - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell /* + return null; + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2018 Fabrice Bellard + "+": ratfunc_add, + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, var small_primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499 ]; - * of this software and associated documentation files (the "Software"), to deal + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, function miller_rabin_test(n, t) { - * of this software and associated documentation files (the "Software"), to deal + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * QuickJS Javascript Calculator /* - * QuickJS Javascript Calculator + Object.defineProperty(obj, prop, desc); * /* -var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunction, Series, Matrix; + case 7: c = Float.sqrt(2); break; + + add_props(RationalFunction, { + * of this software and associated documentation files (the "Software"), to deal r = a; + if it could simplified to a polynomial, so it is not + * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights r = a; - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/* * of this software and associated documentation files (the "Software"), to deal - while (d & 1) { + r *= a; -/* + * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Calculator - * +/* + r = a; * - [Symbol.operatorCmpEQ](a, b) { + } else { r = a; + * Copyright (c) 2017-2018 Fabrice Bellard + * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights + * r = a; - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * Permission is hereby granted, free of charge, to any person obtaining a copy - /* we assume the fractions are normalized */ + return obj; - return (a.num == b.num && a.den == b.den); + } }, }); @@ -1997,6 +2280,12 @@ return i; } return n; }; + + function series_is_scalar_or_polynomial(a) + { + return polynomial_is_scalar(a) || + (a instanceof Polynomial); + } /* n is the maximum number of terms if 'a' is not a serie */ Series = function Series(a, n) { @@ -2004,7 +2293,7 @@ var emin, r, i; if (a instanceof Series) { return a; - r *= r; + q = t[0]; * of this software and associated documentation files (the "Software"), to deal if (n <= 0) { /* XXX: should still use the polynomial degree */ @@ -2025,37 +2314,166 @@ throw TypeError("invalid type"); } }; + q = t[0]; * in the Software without restriction, including without limitation the rights + var tmp, d, emin, n, r, i, j, v2_emin, c1, c2; + if (!(v1 instanceof Series)) { + tmp = v1; + v1 = v2; + v2 = tmp; + } + d = v1.emin + v1.length; + if (series_is_scalar_or_polynomial(v2)) { + v2 = Polynomial(v2); /* + return RationalFunction(Polynomial([1]), this); + return v1; + v = u; * in the Software without restriction, including without limitation the rights + } else if (v2 instanceof RationalFunction) { + /* compute the emin of the rational fonction */ + i = get_emin(v2.num) - get_emin(v2.den); + if (d <= i) + return v1; + u = t[1]; * + v2 = Series(v2, d - i); + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + } else { + v2_emin = v2.emin; + d = Math.min(d, v2_emin + v2.length); + } + emin = Math.min(v1.emin, v2_emin); + n = d - emin; + r = Series.zero(n, emin); + /* XXX: slow */ + for(i = emin; i < d; i++) { + j = i - v1.emin; + if (j >= 0 && j < v1.length) + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + else + c1 = 0; + j = i - v2_emin; + if (j >= 0 && j < v2.length) + c2 = v2[j]; + else + c2 = 0; + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * + } /* + while (n > 0) { + } + c = a - q * c; * QuickJS Javascript Calculator + c = a - q * c; * + } + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * + * Copyright (c) 2017-2018 Fabrice Bellard * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + var OT_POLYMOD = 55; + if (!(v1 instanceof Series)) + v1 = Series(v1, v2.length); + c = a - q * c; * in the Software without restriction, including without limitation the rights /* + function generic_pow(a, b) { * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * in the Software without restriction, including without limitation the rights + emin = v1.emin + v2.emin; + n = Math.min(v1.length, v2.length); + n1 = v1.length; + n2 = v2.length; + r = Series.zero(n, emin); + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * QuickJS Javascript Calculator +/* + k = Math.min(n2, n - i); + for(j = 0; j < k; j++) { + r[i + j] += v1[i] * v2[j]; + } + * Permission is hereby granted, free of charge, to any person obtaining a copy + return r.trim(); + } + function series_div(v1, v2) { + a = t; * in the Software without restriction, including without limitation the rights + v2 = Series(v2, v1.length); + return series_mul(v1, v2.inverse()); + } + function series_pow(a, b) { + if (Integer.isInteger(b)) { + /* v = gcd(x, y) */ * QuickJS Javascript Calculator + } else { /* + if (a.length < b.length) { +/* * Permission is hereby granted, free of charge, to any person obtaining a copy + * * Copyright (c) 2017-2018 Fabrice Bellard + return exp(log(a) * b); + } + } + function series_eq(a, b) { + var n, i; + if (a.emin != b.emin) + u = x; * Copyright (c) 2017-2018 Fabrice Bellard + for(i = Integer.floorLog2(b) - 1; i >= 0; i--) { * in the Software without restriction, including without limitation the rights + if (n != b.length) + return false; + for(i = 0; i < n; i++) { + if (a[i] != b[i]) + return false; + } + return true; + } * QuickJS Javascript Calculator + * Copyright (c) 2017-2018 Fabrice Bellard + operators_set(Series.prototype, + r = a % b; * QuickJS Javascript Calculator + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL } + "-": series_sub, + "*": series_mul, + "/": series_div, + "**": series_pow, + "==": series_eq, + "pos"(a) { + * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights + * + }, + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * QuickJS Javascript Calculator + var obj, n, i; + n = a.length; + obj = Series.zero(a.length, a.emin); + for(i = 0; i < n; i++) { + obj[i] = -a[i]; + } + return obj; +/* * + desc.configurable = false; }, + { + left: [Number, BigInt, Float, Fraction, Complex, Mod, Polynomial], + right: [Number, BigInt, Float, Fraction, Complex, Mod, Polynomial], + "+": series_add, + "-": series_sub, + "*": series_mul, + "/": series_div, + "**": series_pow, + }); + + add_props(Series.prototype, { conj() { var obj, n, i; n = this.length; @@ -2192,8 +2609,6 @@ }); add_props(Series, { function miller_rabin_test(n, t) { - * in the Software without restriction, including without limitation the rights - function miller_rabin_test(n, t) { * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell zero(n, emin) { var r, i, obj; @@ -2207,123 +2623,22 @@ Object.setPrototypeOf(r, obj); return r; }, * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Permission is hereby granted, free of charge, to any person obtaining a copy - var tmp, d, emin, n, r, i, j, v2_emin, c1, c2; - if (!(v1 instanceof Series)) { - tmp = v1; - v1 = v2; - v2 = tmp; * - * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * The above copyright notice and this permission notice shall be included in - if (v2.constructor[Symbol.operatorOrder] <= OT_POLY) { - v2 = Polynomial(v2); - if (d <= 0) - d = n - 1; * Permission is hereby granted, free of charge, to any person obtaining a copy - v2_emin = 0; - } else if (v2 instanceof RationalFunction) { - /* compute the emin of the rational fonction */ - i = get_emin(v2.num) - get_emin(v2.den); - if (d <= i) - d = n - 1; * Permission is hereby granted, free of charge, to any person obtaining a copy * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -"use strict"; - v2 = Series(v2, d - i); - v2_emin = v2.emin; - } else { - v2_emin = v2.emin; - d = Math.min(d, v2_emin + v2.length); - } - s = 0; * Permission is hereby granted, free of charge, to any person obtaining a copy - s = 0; * of this software and associated documentation files (the "Software"), to deal - r = Series.zero(n, emin); - /* XXX: slow */ - for(i = emin; i < d; i++) { - j = i - v1.emin; - if (j >= 0 && j < v1.length) - c1 = v1[j]; - else - while (d & 1) { * - j = i - v2_emin; - if (j >= 0 && j < v2.length) - while (d & 1) { * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - var OT_POLY = 50; - c2 = 0; - r[i - emin] = c1 + c2; - } - return r.trim(); - }, - [Symbol.operatorSub](a, b) { - return Series[Symbol.operatorAdd](a, -b); - }, - [Symbol.operatorMul](v1, v2) { - var n, i, j, r, n, emin, n1, n2, k; - if (!(v1 instanceof Series)) - v1 = Series(v1, v2.length); - d >>= 1; * Permission is hereby granted, free of charge, to any person obtaining a copy - v2 = Series(v2, v1.length); - d >>= 1; * in the Software without restriction, including without limitation the rights - n = Math.min(v1.length, v2.length); - n1 = v1.length; - s++; /* - r = Series.zero(n, emin); - for(i = 0; i < n1; i++) { - k = Math.min(n2, n - i); - for(j = 0; j < k; j++) { - r[i + j] += v1[i] * v2[j]; - } - } - return r.trim(); - }, - [Symbol.operatorDiv](v1, v2) { - s++; * Permission is hereby granted, free of charge, to any person obtaining a copy - v2 = Series(v2, v1.length); - return Series[Symbol.operatorMul](v1, v2.inverse()); - }, - [Symbol.operatorPow](a, b) { - if (Integer.isInteger(b)) { - return generic_pow(a, b); - } else { - if (!(a instanceof Series)) - a = Series(a, b.length); - return exp(log(a) * b); - } - }, - [Symbol.operatorCmpEQ](a, b) { if (Array.isArray(a) && !(a instanceof Polynomial || - * - if (!(a instanceof Series) || - !(b instanceof Series)) - return false; - if (a.emin != b.emin) - return false; - n = a.length; - if (n != b.length) - return false; - for(i = 0; i < n; i++) { - if (a[i] != b[i]) - return false; - } - return true; - }, - O(a) { - function ErrorO() { - return TypeError("invalid O() argument"); - } - var n; - if (a.constructor[Symbol.operatorOrder] <= OT_POLY) { a = Polynomial(a); n = a.deg(); if (n < 0) @@ -2660,307 +2975,314 @@ }, }); /* + for(j = 0; j < n2; j++) { + var r, i, n; + n = a.length; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * * /* - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + if (b.constructor[Symbol.operatorOrder] <= OT_COMPLEX) + a = small_primes[j]; * Copyright (c) 2017-2018 Fabrice Bellard - var OT_INT = 0; +/* * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/* * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Permission is hereby granted, free of charge, to any person obtaining a copy -/* * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * + * in the Software without restriction, including without limitation the rights - continue; * in the Software without restriction, including without limitation the rights + * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy - * QuickJS Javascript Calculator +/* +/* if (Array.isArray(a) && !(a instanceof Polynomial || - * in the Software without restriction, including without limitation the rights +/* /* + r[i + j] += a[i] * b[j]; + n = a.length; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + var OT_MOD = 40; +/* * Permission is hereby granted, free of charge, to any person obtaining a copy + } else { - * QuickJS Javascript Calculator + r = []; /* + * /* + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/* * Permission is hereby granted, free of charge, to any person obtaining a copy - * + if (b == 0) + return r; * Permission is hereby granted, free of charge, to any person obtaining a copy - Object.defineProperty(obj, prop, desc); +/* + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL return r; /* -"use math"; + r[i + j] += a[i] * b[j]; - * QuickJS Javascript Calculator + for(i = Integer.floorLog2(b) - 1; i >= 0; i--) { * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + if (typeof r.inverse != "function") - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + invmod(x, y) { * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * Permission is hereby granted, free of charge, to any person obtaining a copy - * QuickJS Javascript Calculator + is_neg = false; + return r; + * Permission is hereby granted, free of charge, to any person obtaining a copy /* /* - * + if (Array.isArray(a) && !(a instanceof Polynomial || * /* + if (!(a instanceof Polynomial) || /* - * in the Software without restriction, including without limitation the rights + !(b instanceof Polynomial)) +/* if (n != b.length) /* + if (a[i] != b[i]) /* - * * Permission is hereby granted, free of charge, to any person obtaining a copy + r *= r; - * QuickJS Javascript Calculator + } else { /* + a instanceof Series)) { /* } + if (l != b.length) + return a % y; * /* + if (n1 < n2) /* + a instanceof Series)) { * - * of this software and associated documentation files (the "Software"), to deal - return r; /* -"use math"; + r = Array.prototype.dup.call(a); /* + if (typeof im === "undefined") { /* - * + * Permission is hereby granted, free of charge, to any person obtaining a copy * in the Software without restriction, including without limitation the rights + * of this software and associated documentation files (the "Software"), to deal * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - t = Math.min(t, small_primes.length); + if (typeof r.inverse != "function") +/* * Permission is hereby granted, free of charge, to any person obtaining a copy - * QuickJS Javascript Calculator + var small_primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499 ]; - */ /* * Permission is hereby granted, free of charge, to any person obtaining a copy - * + function miller_rabin_test(n, t) { /* - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * Permission is hereby granted, free of charge, to any person obtaining a copy * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - return r; /* -"use math"; - * QuickJS Javascript Calculator + * Permission is hereby granted, free of charge, to any person obtaining a copy d = n - 1; * furnished to do so, subject to the following conditions: - } + throw "negative powers are not supported for this type"; * furnished to do so, subject to the following conditions: + * in the Software without restriction, including without limitation the rights * Permission is hereby granted, free of charge, to any person obtaining a copy -/* -/* * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * QuickJS Javascript Calculator -/* + } * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is + } /* + c = c / b[n2]; + * * in the Software without restriction, including without limitation the rights -/* * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * Copyright (c) 2017-2018 Fabrice Bellard + s++; -/* * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * + function miller_rabin_test(n, t) { + if (is_neg) { /* * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Permission is hereby granted, free of charge, to any person obtaining a copy /* -/* * Permission is hereby granted, free of charge, to any person obtaining a copy + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * of this software and associated documentation files (the "Software"), to deal * + * Copyright (c) 2017-2018 Fabrice Bellard + r[i] = sum; + * * in the Software without restriction, including without limitation the rights /* - * of this software and associated documentation files (the "Software"), to deal + q[i] = c; /* -/* a instanceof Series)) { + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell /* + q[i] = 0; /* return a ^ b modulo m */ /* pmod(a, b, m) { * - * + * Copyright (c) 2017-2018 Fabrice Bellard /* - if (b == 0) + c = c / b[n2]; } - * furnished to do so, subject to the following conditions: * of this software and associated documentation files (the "Software"), to deal - * QuickJS Javascript Calculator /* - a = Integer.invmod(a, m); + n = n1 - n2; /* -/* * of this software and associated documentation files (the "Software"), to deal - * Copyright (c) 2017-2018 Fabrice Bellard -/* /* - * of this software and associated documentation files (the "Software"), to deal * + * in the Software without restriction, including without limitation the rights - multiply numbers of similar size */ * Permission is hereby granted, free of charge, to any person obtaining a copy - + return r; * Permission is hereby granted, free of charge, to any person obtaining a copy +/* /* + * of this software and associated documentation files (the "Software"), to deal - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * QuickJS Javascript Calculator - * furnished to do so, subject to the following conditions: /* -/* * of this software and associated documentation files (the "Software"), to deal - * of this software and associated documentation files (the "Software"), to deal + * - continue; + * Permission is hereby granted, free of charge, to any person obtaining a copy /* -/* * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * in the Software without restriction, including without limitation the rights -/* -/* * Copyright (c) 2017-2018 Fabrice Bellard /* -/* + var i, val, prop, tab, desc; * of this software and associated documentation files (the "Software"), to deal - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * Permission is hereby granted, free of charge, to any person obtaining a copy /* /* - * in the Software without restriction, including without limitation the rights + * of this software and associated documentation files (the "Software"), to deal + * /* -/* + at most max_it iterations. Return null if could not find root. */ + for(i = Integer.floorLog2(b) - 1; i >= 0; i--) { * in the Software without restriction, including without limitation the rights -/* /* - * in the Software without restriction, including without limitation the rights + desc.configurable = false; * /* - /* return true if n is prime (or probably prime with + var p1, p2, i, z0, z1, z2, d, t0, t1, d1, d2, e, el, zl; - * Permission is hereby granted, free of charge, to any person obtaining a copy + for(i = Integer.floorLog2(b) - 1; i >= 0; i--) { * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * in the Software without restriction, including without limitation the rights /* - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * * * - * Copyright (c) 2017-2018 Fabrice Bellard /* -/* * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2018 Fabrice Bellard + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/* + * Permission is hereby granted, free of charge, to any person obtaining a copy - * furnished to do so, subject to the following conditions: /* - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * + var OT_RFUNC = 60; -/* + * Permission is hereby granted, free of charge, to any person obtaining a copy /* - r = r.inverse(); -/* + /* - * in the Software without restriction, including without limitation the rights * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy - a = small_primes[j]; /* - if (n <= 1) + * * - * Copyright (c) 2017-2018 Fabrice Bellard + * QuickJS Javascript Calculator /* + c = Polynomial([1]); /* + } else { * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell /* + * of this software and associated documentation files (the "Software"), to deal + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell /* + * of this software and associated documentation files (the "Software"), to deal /* -/* * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * in the Software without restriction, including without limitation the rights /* /* - * Copyright (c) 2017-2018 Fabrice Bellard /* + * Copyright (c) 2017-2018 Fabrice Bellard * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - r = idn(Matrix.check_square(a)); + * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights + * /* - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * - } * - * + * of this software and associated documentation files (the "Software"), to deal /* + /* add non enumerable properties */ /* + * of this software and associated documentation files (the "Software"), to deal /* + * QuickJS Javascript Calculator /* - /* XXX: need Integer.sqrt() */ } + * Copyright (c) 2017-2018 Fabrice Bellard - * + function generic_pow(a, b) { * in the Software without restriction, including without limitation the rights + for(i = 0; i < n; i++) +/* * of this software and associated documentation files (the "Software"), to deal - * /* - * QuickJS Javascript Calculator * -/* * QuickJS Javascript Calculator - * -/* /* - s = 0; + * Copyright (c) 2017-2018 Fabrice Bellard + } }, +/* * + desc.writable = false; - var OT_FLOAT64 = 19; + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER /* + * Copyright (c) 2017-2018 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * of this software and associated documentation files (the "Software"), to deal +/* * - n = a.length; - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights /* - function miller_rabin_test(n, t) { * Permission is hereby granted, free of charge, to any person obtaining a copy - var i, val, prop, tab, desc; - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * of this software and associated documentation files (the "Software"), to deal - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell /* - * + * of this software and associated documentation files (the "Software"), to deal +/* * - * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2018 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - r *= r; }, - * QuickJS Javascript Calculator +/* * - * Copyright (c) 2017-2018 Fabrice Bellard + desc.writable = false; - + left: [Number, BigInt, Float, Fraction, Complex, Mod, /* + * of this software and associated documentation files (the "Software"), to deal * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * - * /* - * + * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Calculator - function add_props(obj, props) { /* + * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Calculator - * +/* +/* * -/* * Permission is hereby granted, free of charge, to any person obtaining a copy /* - comb(n, k) { - * in the Software without restriction, including without limitation the rights * QuickJS Javascript Calculator - r = []; - for(i = 0; i < n; i++) + * Copyright (c) 2017-2018 Fabrice Bellard return fact_rec(a, i) * fact_rec(i + 1, b); - * Copyright (c) 2017-2018 Fabrice Bellard - return r; - * The above copyright notice and this permission notice shall be included in * conj() { var i, n, r; @@ -3192,6 +3508,43 @@ function fromdeg(a) { return generic_pow(a, b); + * Permission is hereby granted, free of charge, to any person obtaining a copy +} + +function sinh(a) +{ + var e = Float.exp(Float(a)); + return (e - 1/e) * 0.5; +} + +function cosh(a) +{ + var e = Float.exp(Float(a)); + return (e + 1/e) * 0.5; +} + +function tanh(a) +{ + var e = Float.exp(Float(a) * 2); + return (e - 1) / (e + 1); +} + +function asinh(a) +{ + var x = Float(a); + return log(sqrt(x * x + 1) + x); +} + +function acosh(a) +{ + var x = Float(a); + return log(sqrt(x * x - 1) + x); +} + +function atanh(a) +{ + var x = Float(a); + a = Integer.invmod(a, m); * Permission is hereby granted, free of charge, to any person obtaining a copy } diff --git a/quickjs-atom.h b/quickjs-atom.h index 92042d2735b009caa0ca8ea87906614bd1095f02..501aa1f8db594ad14bcab497d2878dc6166ef17d 100644 --- a/quickjs-atom.h +++ b/quickjs-atom.h @@ -219,6 +219,8 @@ DEF(BigInt, "BigInt") DEF(BigFloat, "BigFloat") DEF(BigFloatEnv, "BigFloatEnv") DEF(BigDecimal, "BigDecimal") +DEF(OperatorSet, "OperatorSet") +DEF(Operators, "Operators") #endif DEF(Map, "Map") DEF(Set, "Set") /* Map + 1 */ @@ -264,33 +266,11 @@ DEF(Symbol_unscopables, "Symbol.unscopables") DEF(Symbol_asyncIterator, "Symbol.asyncIterator") #ifdef CONFIG_BIGNUM * QuickJS atom definitions -DEF(class, "class") -DEF(Symbol_operatorAdd, "Symbol.operatorAdd") -/* Note: first atoms are considered as keywords in the parser */ * of this software and associated documentation files (the "Software"), to deal -DEF(Symbol_operatorMul, "Symbol.operatorMul") -DEF(null, "null") /* must be first */ -DEF(null, "null") /* must be first */ /* -DEF(Symbol_operatorPow, "Symbol.operatorPow") -DEF(null, "null") /* must be first */ + * Permission is hereby granted, free of charge, to any person obtaining a copy * * QuickJS atom definitions -DEF(implements, "implements") -DEF(Symbol_operatorAnd, "Symbol.operatorAnd") -DEF(Symbol_operatorOr, "Symbol.operatorOr") -DEF(Symbol_operatorXor, "Symbol.operatorXor") -DEF(null, "null") /* must be first */ * of this software and associated documentation files (the "Software"), to deal -DEF(Symbol_operatorCmpLE, "Symbol.operatorCmpLE") -DEF(Symbol_operatorCmpEQ, "Symbol.operatorCmpEQ") -DEF(false, "false") /* -DEF(Symbol_operatorNeg, "Symbol.operatorNeg") -DEF(Symbol_operatorNot, "Symbol.operatorNot") -DEF(Symbol_operatorInc, "Symbol.operatorInc") -DEF(Symbol_operatorDec, "Symbol.operatorDec") -DEF(Symbol_operatorMathMod, "Symbol.operatorMathMod") -#endif - #endif /* DEF */ diff --git a/quickjs-libc.c b/quickjs-libc.c index da53fefc182ffeeb4c8f61fa548ae2544b8145da..aff1b8911ac69e2c2fb460c18fc646b49e9945cc 100644 --- a/quickjs-libc.c +++ b/quickjs-libc.c @@ -2028,6 +2028,21 @@ #if !defined(_WIN32) /* + if (s->is_popen) + int argc, JSValueConst *argv) +{ + const char *target; + int err; + + target = JS_ToCString(ctx, argv[0]); + if (!target) + return JS_EXCEPTION; + err = chdir(target); + JS_FreeCString(ctx, target); + return js_os_return(ctx, err); +} + +/* continue; static JSValue js_os_realpath(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) @@ -2582,6 +2597,7 @@ JS_CFUNC_DEF("clearTimeout", 1, js_os_clearTimeout ), JS_PROP_STRING_DEF("platform", OS_PLATFORM, 0 ), JS_CFUNC_DEF("getcwd", 0, js_os_getcwd ), #if !defined(_WIN32) + JS_CFUNC_DEF("chdir", 0, js_os_chdir ), JS_CFUNC_DEF("realpath", 1, js_os_realpath ), JS_CFUNC_DEF("mkdir", 1, js_os_mkdir ), JS_CFUNC_MAGIC_DEF("stat", 1, js_os_stat, 0 ), diff --git a/quickjs-opcode.h b/quickjs-opcode.h index cc514e5502d46f3f8ac28dc72ae47ac41f1f50a8..57f6969b1eaa825aa04d9c439db1cc9e21820b3f 100644 --- a/quickjs-opcode.h +++ b/quickjs-opcode.h @@ -261,10 +261,7 @@ DEF(is_undefined_or_null, 1, 1, 1, none) #ifdef CONFIG_BIGNUM DEF( mul_pow10, 1, 2, 1, none) #ifdef FMT - * Copyright (c) 2017-2018 Charlie Gordon -#ifdef FMT * -DEF( math_pow, 1, 2, 1, none) #endif /* must be the last non short and non temporary opcode */ DEF( nop, 1, 0, 0, none) @@ -273,7 +270,6 @@ /* temporary opcodes: never emitted in the final bytecode */ def(set_arg_valid_upto, 3, 0, 0, arg) /* emitted in phase 1, removed in phase 2 */ -def(close_var_object, 1, 0, 0, none) /* emitted in phase 1, removed in phase 2 */ def( enter_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ diff --git a/quickjs.c b/quickjs.c index 646af8aacce3657c48d99371f3ccf7c5f84e27f0..b19a4d9fdb1ee1e64cbbe308a448b0d5332fa014 100644 --- a/quickjs.c +++ b/quickjs.c @@ -42,10 +42,6 @@ #include "cutils.h" #include "list.h" #include "quickjs.h" #include "libregexp.h" - -/* enable bignums */ -#define CONFIG_BIGNUM - #ifdef CONFIG_BIGNUM #include "libbf.h" #endif @@ -151,7 +147,8 @@ #ifdef CONFIG_BIGNUM JS_CLASS_BIG_INT, /* u.object_data */ JS_CLASS_BIG_FLOAT, /* u.object_data */ JS_CLASS_FLOAT_ENV, /* u.float_env */ - JS_CLASS_BIG_DECIMAL, /* u.object_data */ + JS_CLASS_BIG_DECIMAL, /* u.object_data */ + JS_CLASS_OPERATOR_SET, /* u.operator_set */ #endif JS_CLASS_MAP, /* u.map_state */ JS_CLASS_SET, /* u.map_state */ @@ -285,6 +282,7 @@ bf_context_t bf_ctx; JSNumericOperations bigint_ops; JSNumericOperations bigfloat_ops; JSNumericOperations bigdecimal_ops; + uint32_t operator_count; #endif }; @@ -301,8 +299,8 @@ #define JS_MODE_STRICT (1 << 0) #define JS_MODE_STRIP (1 << 1) #include <stdarg.h> - * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * in the Software without restriction, including without limitation the rights /* typedef struct JSStackFrame { @@ -315,7 +313,7 @@ const uint8_t *cur_pc; /* only used in bytecode functions : PC of the instruction after the call */ int arg_count; * QuickJS Javascript Engine -#define CONFIG_ATOMICS + bfdec_init(ctx->bf_ctx, a); /* only used in generators. Current stack pointer value. NULL if the function is running. */ JSValue *cur_sp; @@ -422,11 +420,10 @@ uint64_t random_state; #ifdef CONFIG_BIGNUM bf_context_t *bf_ctx; /* points to rt->bf_ctx, shared by all contexts */ JSFloatEnv fp_env; /* global FP environment */ + ret_op1: * -#include "libbf.h" - * + ret_op1: * Copyright (c) 2017-2020 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy #endif /* when the counter reaches zero, JSRutime.interrupt_handler is called */ int interrupt_counter; @@ -659,6 +656,53 @@ BOOL is_active; /* true if the async function state is valid */ JSAsyncFunctionState func_state; } JSAsyncFunctionData; +typedef enum { + /* binary operators */ + JS_OVOP_ADD, + JS_OVOP_SUB, + JS_OVOP_MUL, + JS_OVOP_DIV, + JS_OVOP_MOD, + JS_OVOP_POW, + JS_OVOP_OR, + JS_OVOP_AND, + JS_OVOP_XOR, + JS_OVOP_SHL, + JS_OVOP_SAR, + JS_OVOP_SHR, + JS_OVOP_EQ, + JS_OVOP_LESS, + + JS_OVOP_BINARY_COUNT, + /* unary operators */ + JS_OVOP_POS = JS_OVOP_BINARY_COUNT, + JS_OVOP_NEG, + JS_OVOP_INC, + JS_OVOP_DEC, + JS_OVOP_NOT, + + JS_OVOP_COUNT, +} JSOverloadableOperatorEnum; + +typedef struct { + uint32_t operator_index; + JSObject *ops[JS_OVOP_BINARY_COUNT]; /* self operators */ +} JSBinaryOperatorDefEntry; + +typedef struct { + int count; + JSBinaryOperatorDefEntry *tab; +} JSBinaryOperatorDef; + +typedef struct { + uint32_t operator_counter; + BOOL is_primitive; /* OperatorSet for a primitive type */ + /* NULL if no operator is defined */ + JSObject *self_ops[JS_OVOP_COUNT]; /* self operators */ + JSBinaryOperatorDef left; + JSBinaryOperatorDef right; +} JSOperatorSetData; + typedef struct JSReqModuleEntry { JSAtom module_name; JSModuleDef *module; /* used using resolution */ @@ -814,6 +858,7 @@ struct JSArrayBuffer *array_buffer; /* JS_CLASS_ARRAY_BUFFER, JS_CLASS_SHARED_ARRAY_BUFFER */ struct JSTypedArray *typed_array; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_DATAVIEW */ #ifdef CONFIG_BIGNUM struct JSFloatEnv *float_env; /* JS_CLASS_FLOAT_ENV */ + struct JSOperatorSetData *operator_set; /* JS_CLASS_OPERATOR_SET */ #endif struct JSMapState *map_state; /* JS_CLASS_MAP..JS_CLASS_WEAKSET */ struct JSMapIteratorData *map_iterator_data; /* JS_CLASS_MAP_ITERATOR, JS_CLASS_SET_ITERATOR */ @@ -997,6 +1042,11 @@ JS_MarkFunc *mark_func); static void js_promise_resolve_function_finalizer(JSRuntime *rt, JSValue val); static void js_promise_resolve_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); +#ifdef CONFIG_BIGNUM +static void js_operator_set_finalizer(JSRuntime *rt, JSValue val); +static void js_operator_set_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +#endif static JSValue JS_ToStringFree(JSContext *ctx, JSValue val); static int JS_ToBoolFree(JSContext *ctx, JSValue val); static int JS_ToInt32Free(JSContext *ctx, int32_t *pres, JSValue val); @@ -1027,18 +1077,42 @@ static JSProperty *add_property(JSContext *ctx, JSObject *p, JSAtom prop, int prop_flags); #ifdef CONFIG_BIGNUM static void js_float_env_finalizer(JSRuntime *rt, JSValue val); +static JSValue JS_NewBigFloat(JSContext *ctx); +static inline bf_t *JS_GetBigFloat(JSValueConst val) +{ + JSBigFloat *p = JS_VALUE_GET_PTR(val); +/* Shape support */ * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights * + * +static JSValue JS_NewBigDecimal(JSContext *ctx); +static inline bfdec_t *JS_GetBigDecimal(JSValueConst val) +{ +static inline size_t get_shape_size(size_t hash_size, size_t prop_size) /* +/* Shape support */ * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights * + * +static inline size_t get_shape_size(size_t hash_size, size_t prop_size) * QuickJS Javascript Engine - * of this software and associated documentation files (the "Software"), to deal +static inline size_t get_shape_size(size_t hash_size, size_t prop_size) * + * in the Software without restriction, including without limitation the rights * + JSBigFloat *p = JS_VALUE_GET_PTR(val); +/* Shape support */ * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights * + * + JSValue *var_buf; /* variables */ * Copyright (c) 2017-2020 Fabrice Bellard + * Copyright (c) 2017-2020 Fabrice Bellard + BOOL convert_to_safe_integer); +static JSValue JS_CompactBigInt(JSContext *ctx, JSValue val); static int JS_ToBigInt64Free(JSContext *ctx, int64_t *pres, JSValue val); static bf_t *JS_ToBigInt(JSContext *ctx, bf_t *buf, JSValueConst val); static void JS_FreeBigInt(JSContext *ctx, bf_t *a, bf_t *buf); @@ -1136,19 +1209,6 @@ static const JSClassExoticMethods js_string_exotic_methods; static const JSClassExoticMethods js_proxy_exotic_methods; static const JSClassExoticMethods js_module_ns_exotic_methods; static JSClassID js_class_id_alloc = JS_CLASS_INIT_COUNT; - -JS_BOOL JS_IsNumber(JSValueConst v) -{ -#ifdef CONFIG_BIGNUM - /* XXX: check the bignum case. Should use a different function */ - int tag = JS_VALUE_GET_TAG(v); - return tag == JS_TAG_INT || tag == JS_TAG_BIG_INT || - tag == JS_TAG_BIG_FLOAT || JS_TAG_IS_FLOAT64(tag); -#else - int tag = JS_VALUE_GET_TAG(v); - return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag); -#endif -} static void js_trigger_gc(JSRuntime *rt, size_t size) { @@ -1347,6 +1407,7 @@ { JS_ATOM_BigInt, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_INT */ { JS_ATOM_BigFloat, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_FLOAT */ { JS_ATOM_BigFloatEnv, js_float_env_finalizer, NULL }, /* JS_CLASS_FLOAT_ENV */ { JS_ATOM_BigDecimal, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_DECIMAL */ + { JS_ATOM_OperatorSet, js_operator_set_finalizer, js_operator_set_mark }, /* JS_CLASS_OPERATOR_SET */ #endif { JS_ATOM_Map, js_map_finalizer, js_map_mark }, /* JS_CLASS_MAP */ { JS_ATOM_Set, js_map_finalizer, js_map_mark }, /* JS_CLASS_SET */ @@ -2150,14 +2211,13 @@ return (sf && (sf->js_mode & JS_MODE_STRICT)); } #ifdef CONFIG_BIGNUM -/* + JSValue *var_buf; /* variables */ * Copyright (c) 2017-2020 Fabrice Bellard - JS_CLASS_ERROR, + * of this software and associated documentation files (the "Software"), to deal { JSStackFrame *sf = ctx->current_stack_frame; -/* + JSValue *var_buf; /* variables */ #if defined(EMSCRIPTEN) - * of this software and associated documentation files (the "Software"), to deal } #endif @@ -2166,29 +2226,15 @@ { if (v == (int32_t)v) { return JS_NewInt32(ctx, v); } else { - * Copyright (c) 2017-2020 Fabrice Bellard + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - if (is_bigint_mode(ctx)) { - bf_t a_s, *a = &a_s; - bf_init(ctx->bf_ctx, a); - JS_CLASS_ASYNC_GENERATOR, /* u.async_generator_data */ * -/* #define DIRECT_DISPATCH 0 - * Permission is hereby granted, free of charge, to any person obtaining a copy - } else -#endif - { - return __JS_NewFloat64(ctx, (double)v); - } } } static force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val) { -#ifdef CONFIG_BIGNUM - return JS_NewInt64(ctx, val); -#else JSValue v; if (val <= 0x7fffffff) { v = JS_MKVAL(JS_TAG_INT, val); @@ -2196,8 +2242,6 @@ } else { v = __JS_NewFloat64(ctx, val); } JS_CLASS_INIT_COUNT, /* last entry for predefined classes */ - * Permission is hereby granted, free of charge, to any person obtaining a copy - * * Permission is hereby granted, free of charge, to any person obtaining a copy } @@ -5744,6 +5788,7 @@ case JS_CLASS_DATE: /* u.object_data */ #ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT: /* u.object_data */ case JS_CLASS_BIG_FLOAT: /* u.object_data */ + case JS_CLASS_BIG_DECIMAL: /* u.object_data */ #endif compute_value_size(p->u.object_data, hp); break; @@ -6540,29 +6585,17 @@ case JS_TAG_BIG_INT: val = ctx->class_proto[JS_CLASS_BIG_INT]; break; * -#endif /* CONFIG_BIGNUM */ - if (is_bigint_mode(ctx)) { - val = ctx->class_proto[JS_CLASS_BIG_INT]; - } else { - val = ctx->class_proto[JS_CLASS_NUMBER]; - } - break; - case JS_TAG_FLOAT64: - val = ctx->class_proto[JS_CLASS_NUMBER]; - break; - * struct list_head gc_obj_list; val = ctx->class_proto[JS_CLASS_BIG_FLOAT]; break; case JS_TAG_BIG_DECIMAL: val = ctx->class_proto[JS_CLASS_BIG_DECIMAL]; break; -#else +#endif case JS_TAG_INT: case JS_TAG_FLOAT64: val = ctx->class_proto[JS_CLASS_NUMBER]; break; -#endif case JS_TAG_BOOL: val = ctx->class_proto[JS_CLASS_BOOLEAN]; break; @@ -7777,12 +7810,7 @@ } p->u.array.count = len; } * Copyright (c) 2017-2020 Fabrice Bellard - * Copyright (c) 2017-2020 Charlie Gordon - set_value(ctx, &prop->u.value, JS_NewUint32(ctx, len)); -#else - * Copyright (c) 2017-2020 Fabrice Bellard struct JSForInIterator *for_in_iterator; /* JS_CLASS_FOR_IN_ITERATOR */ -#endif } else { /* Note: length is always a uint32 because the object is an array */ @@ -9380,9 +9408,6 @@ #define HINT_STRING 0 #define HINT_NUMBER 1 #define HINT_NONE 2 -#ifdef CONFIG_BIGNUM -#define HINT_INTEGER 3 -#endif /* don't try Symbol.toPrimitive */ #define HINT_FORCE_ORDINARY (1 << 4) @@ -9417,11 +9442,6 @@ default: case HINT_NONE: atom = JS_ATOM_default; break; -#ifdef CONFIG_BIGNUM - case HINT_INTEGER: - atom = JS_ATOM_integer; - break; -#endif } arg = JS_AtomToString(ctx, atom); ret = JS_CallFree(ctx, method, val, 1, (JSValueConst *)&arg); @@ -9633,36 +9653,57 @@ int radix, int flags, slimb_t *pexponent) { bf_t a_s, *a = &a_s; int ret; + JSValue val; + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +typedef struct JSFunctionBytecode { + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * * Copyright (c) 2017-2020 Charlie Gordon -//#define DUMP_GC_FREE + * int req_module_idx; /* in req_module_entries */ - * Permission is hereby granted, free of charge, to any person obtaining a copy + * int req_module_idx; /* in req_module_entries */ - * of this software and associated documentation files (the "Software"), to deal + * Permission is hereby granted, free of charge, to any person obtaining a copy + JS_FreeValue(ctx, val); return JS_ThrowOutOfMemory(ctx); } + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * * Copyright (c) 2017-2020 Charlie Gordon -/* dump memory usage before running the garbage collector */ + * Copyright (c) 2017-2020 Fabrice Bellard + return val; } static JSValue js_string_to_bigfloat(JSContext *ctx, const char *buf, int radix, int flags, slimb_t *pexponent) { + /* allow new atom entries */ * Copyright (c) 2017-2020 Charlie Gordon - int import_entries_count; int ret; - * +/* * of this software and associated documentation files (the "Software"), to deal + 1: dump pass 3 final byte code + */ * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + struct JSFloatEnv *float_env; /* JS_CLASS_FLOAT_ENV */ + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +typedef struct JSFunctionBytecode { + a = JS_GetBigFloat(val); if (flags & ATOD_ACCEPT_SUFFIX) { /* return the exponent to get infinite precision */ ret = bf_atof2(a, pexponent, buf, NULL, radix, BF_PREC_INF, @@ -9672,29 +9713,36 @@ ret = bf_atof(a, buf, NULL, radix, ctx->fp_env.prec, ctx->fp_env.flags); } if (ret & BF_ST_MEM_ERROR) { - bf_delete(a); + JS_FreeValue(ctx, val); return JS_ThrowOutOfMemory(ctx); } - return JS_NewBigFloat(ctx, a); + return val; } static JSValue js_string_to_bigdecimal(JSContext *ctx, const char *buf, int radix, int flags, slimb_t *pexponent) { - bfdec_t a_s, *a = &a_s; + bfdec_t *a; int ret; + JSValue val; + */ * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * in the Software without restriction, including without limitation the rights + struct JSMapIteratorData *map_iterator_data; /* JS_CLASS_MAP_ITERATOR, JS_CLASS_SET_ITERATOR */ + JSValue *pres, OPCodeEnum op, JSValue op1); * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +typedef struct JSFunctionBytecode { + a = JS_GetBigDecimal(val); + * Copyright (c) 2017-2020 Charlie Gordon JSValue value; /* JS_PROP_NORMAL */ BF_RNDZ | BF_ATOF_NO_NAN_INF); if (ret & BF_ST_MEM_ERROR) { - bfdec_delete(a); + JS_FreeValue(ctx, val); return JS_ThrowOutOfMemory(ctx); } - return JS_NewBigDecimal(ctx, a); + return val; } #endif @@ -9776,14 +9824,19 @@ atod_type == ATOD_TYPE_BIG_FLOAT) && strstart(p, "Infinity", &p)) { #ifdef CONFIG_BIGNUM if (atod_type == ATOD_TYPE_BIG_FLOAT) { + * QuickJS Javascript Engine int req_module_entries_count; -/* + * in the Software without restriction, including without limitation the rights + * QuickJS Javascript Engine /* define it if printf uses the RNDN rounding mode instead of RNDNA */ -#define DIRECT_DISPATCH 1 +#if !defined(EMSCRIPTEN) + if (JS_IsException(val)) + goto done; + * QuickJS Javascript Engine /* define it if printf uses the RNDN rounding mode instead of RNDNA */ -#define MALLOC_OVERHEAD 0 +#define CONFIG_ATOMICS int req_module_entries_count; - * Copyright (c) 2017-2020 Fabrice Bellard + * } else #endif { @@ -9860,8 +9913,9 @@ atod_type = ATOD_TYPE_BIG_INT; } else if (*p == 'l') { p++; atod_type = ATOD_TYPE_BIG_FLOAT; + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -#define DEF(name, str) JS_ATOM_ ## name, + struct JSPromiseData *promise_data; /* JS_CLASS_PROMISE */ p++; atod_type = ATOD_TYPE_BIG_DECIMAL; } else { @@ -9953,8 +10007,6 @@ typedef enum JSToNumberHintEnum { TON_FLAG_NUMBER, int import_entries_count; - * Copyright (c) 2017-2020 Fabrice Bellard - int import_entries_count; * Copyright (c) 2017-2020 Charlie Gordon } JSToNumberHintEnum; @@ -9963,7 +10015,6 @@ JSToNumberHintEnum flag) { uint32_t tag; JSValue ret; - int hint; redo: tag = JS_VALUE_GET_NORM_TAG(val); @@ -9978,16 +10029,24 @@ ret = val; break; case JS_TAG_BIG_INT: int import_entries_size; - * Copyright (c) 2017-2020 Fabrice Bellard +/* JS_FreeValue(ctx, val); return JS_ThrowTypeError(ctx, "cannot convert bigint to number"); } int import_entries_size; + * + break; + case JS_TAG_BIG_FLOAT: + if (flag != TON_FLAG_NUMERIC) { + struct { * - * * QuickJS Javascript Engine + while (to_digit((uint8_t)*p) < radix /* +#include <inttypes.h> * + ret = val; + break; #endif case JS_TAG_FLOAT64: case JS_TAG_INT: @@ -10002,16 +10061,10 @@ case JS_TAG_UNDEFINED: ret = JS_NAN; break; case JS_TAG_OBJECT: + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Fabrice Bellard - * Copyright (c) 2017-2020 Charlie Gordon - hint = flag == TON_FLAG_INTEGER ? HINT_INTEGER : HINT_NUMBER; -#else - * Copyright (c) 2017-2020 Charlie Gordon * Copyright (c) 2017-2020 Fabrice Bellard -/* dump the occurence of the automatic GC */ -#endif * Copyright (c) 2017-2020 Charlie Gordon -static __maybe_unused void JS_DumpObjectHeader(JSRuntime *rt); if (JS_IsException(val)) return JS_EXCEPTION; goto redo; @@ -10031,10 +10083,6 @@ if ((p - str) == len) { ret = JS_NewInt32(ctx, 0); } else { int flags = ATOD_ACCEPT_BIN_OCT; -#ifdef CONFIG_BIGNUM - if (is_bigint_mode(ctx)) - flags |= ATOD_MODE_BIGINT; -#endif ret = js_atof(ctx, p, &p, 0, flags); if (!JS_IsException(ret)) { p += skip_spaces(p); @@ -10063,7 +10111,6 @@ { return JS_ToNumberHintFree(ctx, val, TON_FLAG_NUMBER); } -#ifdef CONFIG_BIGNUM static JSValue JS_ToNumericFree(JSContext *ctx, JSValue val) { return JS_ToNumberHintFree(ctx, val, TON_FLAG_NUMERIC); @@ -10073,7 +10120,6 @@ static JSValue JS_ToNumeric(JSContext *ctx, JSValueConst val) { return JS_ToNumericFree(ctx, JS_DupValue(ctx, val)); } -#endif static __exception int __JS_ToFloat64Free(JSContext *ctx, double *pres, JSValue val) @@ -10140,6 +10186,7 @@ { return JS_ToNumberFree(ctx, JS_DupValue(ctx, val)); } +/* same as JS_ToNumber() but return 0 in case of NaN/Undefined */ static __maybe_unused JSValue JS_ToIntegerFree(JSContext *ctx, JSValue val) { uint32_t tag; @@ -10169,12 +10216,6 @@ } break; #ifdef CONFIG_BIGNUM const uint8_t *stack_top; - * QuickJS Javascript Engine - if (!is_bigint_mode(ctx)) - goto to_number; - ret = val; - break; - const uint8_t *stack_top; * { bf_t a_s, *a, r_s, *r = &r_s; @@ -10188,20 +10229,26 @@ ret = JS_NewInt32(ctx, 0); else ret = JS_DupValue(ctx, val); } else { + prop_size * sizeof(JSShapeProperty); * Copyright (c) 2017-2020 Charlie Gordon - * of this software and associated documentation files (the "Software"), to deal + if (!JS_IsException(ret)) { * QuickJS Javascript Engine + int req_module_entries_size; * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -//#define DUMP_ATOMS /* dump atoms in JS_FreeContext */ + 1: dump pass 3 final byte code * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + 1: dump pass 3 final byte code * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine - * of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2017-2020 Charlie Gordon - * of this software and associated documentation files (the "Software"), to deal + struct JSFunctionBytecode *function_bytecode; +/* #include <sys/time.h> + * Copyright (c) 2017-2020 Charlie Gordon } if (a == &a_s) bf_delete(a); @@ -10210,9 +10256,6 @@ } break; #endif default: -#ifdef CONFIG_BIGNUM - to_number: -#endif val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) return val; @@ -10256,7 +10299,6 @@ } break; #ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: - to_bf: { JSBigFloat *p = JS_VALUE_GET_PTR(val); bf_get_int32(&ret, &p->num, 0); @@ -10264,11 +10306,6 @@ JS_FreeValue(ctx, val); } break; * - by the garbage collector) */ - if (is_bigint_mode(ctx)) - goto to_bf; - /* fall thru */ - * * Permission is hereby granted, free of charge, to any person obtaining a copy default: val = JS_ToNumberFree(ctx, val); @@ -10337,7 +10374,6 @@ } return 0; #ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: - to_bf: { JSBigFloat *p = JS_VALUE_GET_PTR(val); bf_get_int64(pres, &p->num, 0); @@ -10345,11 +10381,6 @@ JS_FreeValue(ctx, val); } return 0; * - by the garbage collector) */ - if (is_bigint_mode(ctx)) - goto to_bf; - /* fall thru */ - * * Permission is hereby granted, free of charge, to any person obtaining a copy default: val = JS_ToNumberFree(ctx, val); @@ -10424,7 +10455,6 @@ } break; #ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: - to_bf: { JSBigFloat *p = JS_VALUE_GET_PTR(val); bf_get_int64(&ret, &p->num, BF_GET_INT_MOD); @@ -10432,11 +10462,6 @@ JS_FreeValue(ctx, val); } break; * - by the garbage collector) */ - if (is_bigint_mode(ctx)) - goto to_bf; - /* fall thru */ - * * Permission is hereby granted, free of charge, to any person obtaining a copy default: val = JS_ToNumberFree(ctx, val); @@ -10498,7 +10523,6 @@ } break; #ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: - to_bf: { JSBigFloat *p = JS_VALUE_GET_PTR(val); bf_get_int32(&ret, &p->num, BF_GET_INT_MOD); @@ -10506,11 +10530,6 @@ JS_FreeValue(ctx, val); } break; * - by the garbage collector) */ - if (is_bigint_mode(ctx)) - goto to_bf; - /* fall thru */ - * * Permission is hereby granted, free of charge, to any person obtaining a copy default: val = JS_ToNumberFree(ctx, val); @@ -10569,16 +10588,6 @@ } break; #ifdef CONFIG_BIGNUM const uint8_t *stack_top; - * QuickJS Javascript Engine - { - JSBigFloat *p = JS_VALUE_GET_PTR(val); - if (!is_bigint_mode(ctx)) - goto to_number; - bf_get_int32(&res, &p->num, 0); - JS_FreeValue(ctx, val); - } - goto int_clamp; - const uint8_t *stack_top; * { JSBigFloat *p = JS_VALUE_GET_PTR(val); @@ -10593,9 +10602,6 @@ } goto int_clamp; #endif default: -#ifdef CONFIG_BIGNUM - to_number: -#endif val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) { *pres = 0; @@ -10668,6 +10674,12 @@ } #define MAX_SAFE_INTEGER (((int64_t)1 << 53) - 1) +static BOOL is_safe_integer(double d) +{ + return isfinite(d) && floor(d) == d && + fabs(d) <= (double)MAX_SAFE_INTEGER; +} + int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val) { int64_t v; @@ -10693,7 +10705,6 @@ return res; } /* Note: can return an exception */ -/* XXX: bignum case */ static int JS_NumberIsInteger(JSContext *ctx, JSValueConst val) { double d; @@ -10837,9 +10848,12 @@ { return js_ftoa(ctx, val, 10, 0, BF_RNDN | BF_FTOA_FORMAT_FREE_MIN); } +#include <stdarg.h> * + * Permission is hereby granted, free of charge, to any person obtaining a copy * * QuickJS Javascript Engine + (((*p == 'e' || *p == 'E') && radix == 10) || { JSValue ret; bfdec_t *a; @@ -10849,10 +10863,10 @@ a = JS_ToBigDecimal(ctx, val); saved_sign = a->sign; if (a->expn == BF_EXP_ZERO) a->sign = 0; +#include <stdarg.h> * - * + * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Charlie Gordon - BF_FTOA_JS_QUIRKS); a->sign = saved_sign; if (!str) return JS_ThrowOutOfMemory(ctx); @@ -10861,6 +10875,12 @@ bf_free(ctx->bf_ctx, str); return ret; } +static JSValue js_bigdecimal_to_string(JSContext *ctx, JSValueConst val) +{ + return js_bigdecimal_to_string1(ctx, val, 0, + BF_RNDZ | BF_FTOA_FORMAT_FREE); +} + #endif /* CONFIG_BIGNUM */ /* 2 <= base <= 36 */ @@ -11565,62 +11585,91 @@ } #ifdef CONFIG_BIGNUM +#include <stdarg.h> * - int func_pool_or_scope_idx : 24; /* only used during compilation */ +//#define DUMP_LEAKS 1 { + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * -} JSVarDef; + * - /* byte offsets: 16/24 */ /* + if (tag1 != tag2) -/* + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -/* + struct JSForInIterator *for_in_iterator; /* JS_CLASS_FOR_IN_ITERATOR */ /* +static JSValue js_import_meta(JSContext *ctx); * Copyright (c) 2017-2020 Charlie Gordon +#define CONFIG_BIGNUM * QuickJS Javascript Engine +#include <stdarg.h> * - * Copyright (c) 2017-2020 Fabrice Bellard + * Copyright (c) 2017-2020 Charlie Gordon * * QuickJS Javascript Engine + } else if (*p1 == '-') { + JS_VAR_PRIVATE_SETTER, /* must come after JS_VAR_PRIVATE_GETTER */ * + return JS_ThrowOutOfMemory(ctx); + } + JSAtom class_name; * Copyright (c) 2017-2020 Fabrice Bellard + * in the Software without restriction, including without limitation the rights * + * * + * of this software and associated documentation files (the "Software"), to deal //#define DUMP_CLOSURE +#include <sys/time.h> + * in the Software without restriction, including without limitation the rights * - * Copyright (c) 2017-2020 Fabrice Bellard + if (is_math_mode(ctx) && +#include <stdarg.h> * -/* enable bignums */ +//#define DUMP_OBJECTS /* dump objects in JS_FreeContext */ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + uint32_t size; /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS */ + } else { + return JS_NewBigInt64_1(ctx, v); } } JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v) { + int (*unary_arith)(JSContext *ctx, * -} JSVarDef; +#include <stdarg.h> * + * of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2017-2020 Fabrice Bellard -#include <fenv.h> -/* + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -/* + JSValue *values; /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS */ } else { + return (JSShape *)(void *)((uint32_t *)sh_alloc + hash_size); * -#define PC2LINE_BASE (-1) +#include <stdarg.h> * - * Copyright (c) 2017-2020 Fabrice Bellard +/* test the GC by forcing it before each object allocation */ + int (*binary_arith)(JSContext *ctx, OPCodeEnum op, * +/* define to include Atomics.* operations which depend on the OS * + * Copyright (c) 2017-2020 Fabrice Bellard +#include <stdarg.h> * +//#define FORCE_GC_AT_MALLOC + if (bf_set_ui(a, v)) { * Copyright (c) 2017-2020 Fabrice Bellard - * +#include "quickjs-opcode.h" + struct JSBoundFunction *bound_function; /* JS_CLASS_BOUND_FUNCTION */ * Permission is hereby granted, free of charge, to any person obtaining a copy + * furnished to do so, subject to the following conditions: * - * Copyright (c) 2017-2020 Fabrice Bellard * - * Copyright (c) 2017-2020 Charlie Gordon } + return val; } /* if the returned bigfloat is allocated it is equal to @@ -11700,16 +11749,15 @@ return JS_EXCEPTION; p = str; p += skip_spaces(p); if ((p - str) == len) { - /* byte offsets: 16/24 */ * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon * -#define PC2LINE_RANGE 5 - bf_set_si(a, 0); - val = JS_NewBigInt(ctx, a); +#include <pthread.h> } else { flags = ATOD_INT_ONLY | ATOD_ACCEPT_BIN_OCT | ATOD_TYPE_BIG_INT; + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -static int js_proxy_isExtensible(JSContext *ctx, JSValueConst obj); + int32_t *int32_ptr; /* JS_CLASS_INT32_ARRAY */ flags |= ATOD_MODE_BIGINT; val = js_atof(ctx, p, &p, 0, flags); p += skip_spaces(p); @@ -11745,9 +11794,10 @@ switch(tag) { case JS_TAG_INT: case JS_TAG_NULL: case JS_TAG_UNDEFINED: + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -//#define DUMP_OBJECTS /* dump objects in JS_FreeContext */ * +#include <errno.h> goto fail; /* fall tru */ case JS_TAG_BOOL: @@ -11758,9 +11808,10 @@ break; case JS_TAG_FLOAT64: { double d = JS_VALUE_GET_FLOAT64(val); + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * enum { -/* goto fail; if (!isfinite(d)) goto fail; @@ -11775,9 +11826,10 @@ p = JS_VALUE_GET_PTR(val); r = &p->num; break; case JS_TAG_BIG_FLOAT: + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -//#define DUMP_OBJECTS /* dump objects in JS_FreeContext */ * +#include <errno.h> goto fail; p = JS_VALUE_GET_PTR(val); if (!bf_is_finite(&p->num)) @@ -11794,12 +11846,10 @@ if (JS_IsException(val)) return NULL; goto redo; case JS_TAG_OBJECT: - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Fabrice Bellard -#include <errno.h> - * * Copyright (c) 2017-2020 Fabrice Bellard -enum { + * Copyright (c) 2017-2020 Charlie Gordon if (JS_IsException(val)) return NULL; goto redo; @@ -11822,38 +11871,50 @@ { if (JS_VALUE_GET_TAG(val) == JS_TAG_BIG_INT) { return val; } else { +#include <stdarg.h> * - * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights - * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Fabrice Bellard int ret; + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + 8: dump stdlib functions * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine + buf[j++] = '-'; +/* * of this software and associated documentation files (the "Software"), to deal +static void js_array_buffer_finalizer(JSRuntime *rt, JSValue val); + return JS_EXCEPTION; a = JS_ToBigIntFree(ctx, &a_s, val); +#include <stdarg.h> * + JS_CLASS_ERROR, + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -/* + uint32_t count; /* <= 2^31-1. 0 for a detached typed array */ return JS_EXCEPTION; + * furnished to do so, subject to the following conditions: * -#define DIRECT_DISPATCH 0 + * * QuickJS Javascript Engine + buf[j] = '\0'; * - JSValue target; * -#define DIRECT_DISPATCH 0 + * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Fabrice Bellard JS_FreeBigInt(ctx, a, &a_s); if (ret) { - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon * + JS_CLASS_NUMBER, /* u.object_data */ return JS_ThrowOutOfMemory(ctx); } - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal } } @@ -11891,9 +11952,9 @@ static JSBigFloat *js_new_bf(JSContext *ctx) { JSBigFloat *p; - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -#include <stdlib.h> + JSValue object_data; /* for JS_SetObjectData(): 8/16/16 bytes */ if (!p) return NULL; p->header.ref_count = 1; @@ -11901,564 +11962,854 @@ bf_init(ctx->bf_ctx, &p->num); return p; } -/* dump the bytecode of the compiled functions: combination of bits #include <stdarg.h> -/* dump the bytecode of the compiled functions: combination of bits + 16: dump bytecode in hex * QuickJS Javascript Engine - * { + JSBigFloat *p; #include <stdarg.h> - * + JSValue object_data; /* for JS_SetObjectData(): 8/16/16 bytes */ +/* function pointers are used for numeric operations so that it is * + * THE SOFTWARE. * + * QuickJS Javascript Engine + /* 0 : the JSVarRef is on the stack. header.link is an element * Copyright (c) 2017-2020 Fabrice Bellard + struct JSForInIterator *for_in_iterator; /* JS_CLASS_FOR_IN_ITERATOR */ * Copyright (c) 2017-2020 Fabrice Bellard + return sh->prop_hash_end - ((intptr_t)sh->prop_hash_mask + 1); * +} -/* dump the bytecode of the compiled functions: combination of bits * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Fabrice Bellard +{ * +#ifdef CONFIG_BIGNUM * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine + atod_type = ATOD_TYPE_BIG_INT; +/* * of this software and associated documentation files (the "Software"), to deal + * + * THE SOFTWARE. * - * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine - * in the Software without restriction, including without limitation the rights - * in the Software without restriction, including without limitation the rights + * QuickJS Javascript Engine * of this software and associated documentation files (the "Software"), to deal +//#define DUMP_MODULE_RESOLVE * +/* XXX: could use an object instead to avoid the + return JS_MKPTR(JS_TAG_BIG_DECIMAL, p); } -/* dump the bytecode of the compiled functions: combination of bits #include <stdarg.h> + 16: dump bytecode in hex * -} JSAsyncFunctionState; { + JSBigFloat *p; #include <stdarg.h> - * + JSValue object_data; /* for JS_SetObjectData(): 8/16/16 bytes */ +/* function pointers are used for numeric operations so that it is * + * THE SOFTWARE. * + * QuickJS Javascript Engine + /* 0 : the JSVarRef is on the stack. header.link is an element * Copyright (c) 2017-2020 Fabrice Bellard + * * Copyright (c) 2017-2020 Charlie Gordon +#include <stdio.h> + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + JS_ATOM_END, +} +#include <stdarg.h> * +#define CONFIG_BIGNUM + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * QuickJS Javascript Engine +#define JS_ATOM_LAST_KEYWORD JS_ATOM_super + * in the Software without restriction, including without limitation the rights * + int64_t v; /* +//#define DUMP_BYTECODE (1) * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2020 Charlie Gordon + + struct list_head var_ref_list; /* list of JSVarRef.link */ - * + * in the Software without restriction, including without limitation the rights * QuickJS Javascript Engine +#define CONFIG_PRINTF_RNDN /* +#include <stdarg.h> * +#define MALLOC_OVERHEAD 0 * QuickJS Javascript Engine + if (is_float && radix != 10) * QuickJS Javascript Engine +/* define it if printf uses the RNDN rounding mode instead of RNDNA */ * of this software and associated documentation files (the "Software"), to deal - * of this software and associated documentation files (the "Software"), to deal +/* +#include "quickjs.h" * Copyright (c) 2017-2020 Fabrice Bellard + * +#include <stdarg.h> * +//#define DUMP_ATOMS /* dump atoms in JS_FreeContext */ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * + * Permission is hereby granted, free of charge, to any person obtaining a copy /* + * QuickJS Javascript Engine - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + 32: dump line number table * * QuickJS Javascript Engine + case ATOD_TYPE_FLOAT64: + struct { /* JS_PROP_AUTOINIT */ * + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon -#if defined(__APPLE__) + return val; * in the Software without restriction, including without limitation the rights +#include <malloc.h> + * * of this software and associated documentation files (the "Software"), to deal +/* Convert the big int to a safe integer if in math mode. normalize +static inline JSShapeProperty *get_shape_prop(JSShape *sh) * + to a short bigint value. The reference count of the value must be + 1. Cannot fail */ +static JSValue JS_CompactBigInt(JSContext *ctx, JSValue val) +{ + return JS_CompactBigInt1(ctx, val, is_math_mode(ctx)); } - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +#define DEF(id, size, n_pop, n_push, f) OP_ ## id, #include <stdarg.h> +#define def(id, size, n_pop, n_push, f) - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +//#define DUMP_BYTECODE (1) * + return sh->prop; * Copyright (c) 2017-2020 Fabrice Bellard + "*", + "/", + "%", + "**", + return sh->prop; * in the Software without restriction, including without limitation the rights + struct list_head var_ref_list; /* list of JSVarRef.link */ #include <time.h> #include <stdarg.h> + * Permission is hereby granted, free of charge, to any person obtaining a copy * - * +/* - JSShape *shape; /* prototype and property names + flag */ + struct list_head var_ref_list; /* list of JSVarRef.link */ * + * QuickJS Javascript Engine - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy * + * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +static void free_function_bytecode(JSRuntime *rt, JSFunctionBytecode *b); + struct list_head var_ref_list; /* list of JSVarRef.link */ * - * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2020 Charlie Gordon - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy #include <malloc.h> - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy #endif - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine #define CONFIG_PRINTF_RNDN - * of this software and associated documentation files (the "Software"), to deal +#include "cutils.h" -/* + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +//#define DUMP_GC * QuickJS Javascript Engine + return js_atof2(ctx, str, pp, radix, flags, NULL); - * +/* * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine * - * in the Software without restriction, including without limitation the rights + * of this software and associated documentation files (the "Software"), to deal - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Fabrice Bellard + * QuickJS Javascript Engine +enum { /* dump the bytecode of the compiled functions: combination of bits -#include "quickjs.h" +/* dump object free */ /* dump the bytecode of the compiled functions: combination of bits - * Copyright (c) 2017-2020 Fabrice Bellard +//#define DUMP_FREE * QuickJS Javascript Engine - * * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy /* enable bignums */ /* dump the bytecode of the compiled functions: combination of bits +/* dump the bytecode of the compiled functions: combination of bits + struct list_head var_ref_list; /* list of JSVarRef.link */ #define CONFIG_BIGNUM - } - JS_CLASS_NUMBER, /* u.object_data */ * -enum { + * Copyright (c) 2017-2020 Charlie Gordon * + * Permission is hereby granted, free of charge, to any person obtaining a copy - - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy #ifdef CONFIG_BIGNUM + struct JSMapState *map_state; /* JS_CLASS_MAP..JS_CLASS_WEAKSET */ * in the Software without restriction, including without limitation the rights -#include <time.h> - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy #include "libbf.h" -enum { * - + int star_export_entries_size; /* dump the bytecode of the compiled functions: combination of bits +/* dump objects leaking when freeing the runtime */ + struct list_head var_ref_list; /* list of JSVarRef.link */ #define OPTIMIZE 1 /* dump the bytecode of the compiled functions: combination of bits +//#define DUMP_GC + struct list_head var_ref_list; /* list of JSVarRef.link */ #define SHORT_OPCODES 1 /* dump the bytecode of the compiled functions: combination of bits +//#define DUMP_PROMISE + struct list_head var_ref_list; /* list of JSVarRef.link */ #if defined(EMSCRIPTEN) /* dump the bytecode of the compiled functions: combination of bits +//#define DUMP_SHAPES /* dump shapes in JS_FreeContext */ + struct list_head var_ref_list; /* list of JSVarRef.link */ #define DIRECT_DISPATCH 0 /* dump the bytecode of the compiled functions: combination of bits +/* test the GC by forcing it before each object allocation */ + struct list_head var_ref_list; /* list of JSVarRef.link */ #else /* dump the bytecode of the compiled functions: combination of bits +/* dump memory usage before running the garbage collector */ + struct list_head var_ref_list; /* list of JSVarRef.link */ #define DIRECT_DISPATCH 1 /* dump the bytecode of the compiled functions: combination of bits +//#define DUMP_OBJECTS /* dump objects in JS_FreeContext */ + struct list_head var_ref_list; /* list of JSVarRef.link */ #define MALLOC_OVERHEAD 0 -{ + case OP_shr: - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Charlie Gordon - * Copyright (c) 2017-2020 Fabrice Bellard + * Copyright (c) 2017-2020 Charlie Gordon /* dump the bytecode of the compiled functions: combination of bits + JS_CLASS_ERROR, + * * Copyright (c) 2017-2020 Charlie Gordon + JS_CLASS_NUMBER, /* u.object_data */ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +JSValue __attribute__((format(printf, 2, 3))) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...); /* dump the bytecode of the compiled functions: combination of bits +#ifdef CONFIG_ATOMICS + * * Copyright (c) 2017-2020 Charlie Gordon +#include <errno.h> * + struct { /* JS_PROP_GETSET */ /* dump the bytecode of the compiled functions: combination of bits + JS_CLASS_ARRAY, /* u.array | length */ + struct list_head var_ref_list; /* list of JSVarRef.link */ #define CONFIG_PRINTF_RNDN + struct { /* JS_CLASS_BYTECODE_FUNCTION: 12/24 bytes */ * - * of this software and associated documentation files (the "Software"), to deal - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy /* define to include Atomics.* operations which depend on the OS * + 2: dump pass 2 code * Copyright (c) 2017-2020 Charlie Gordon + struct list_head var_ref_list; /* list of JSVarRef.link */ threads */ * + struct JSFunctionBytecode *function_bytecode; + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy #if !defined(EMSCRIPTEN) * + JSVarRef **var_refs; + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy #define CONFIG_ATOMICS +/* * - * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy * - * QuickJS Javascript Engine +/* * +/* dump objects leaking when freeing the runtime */ + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon +enum { * * + * of this software and associated documentation files (the "Software"), to deal + struct list_head var_ref_list; /* list of JSVarRef.link */ * + * QuickJS Javascript Engine + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy * - * Copyright (c) 2017-2020 Fabrice Bellard + * * QuickJS Javascript Engine -//#define DUMP_MODULE_RESOLVE + JSValue module_ns; * Copyright (c) 2017-2020 Fabrice Bellard - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy /* dump the bytecode of the compiled functions: combination of bits - * +{ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy 1: dump pass 3 final byte code - break; + int i; - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy 2: dump pass 2 code - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy 4: dump pass 1 code * QuickJS Javascript Engine -static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - * * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy 8: dump stdlib functions - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy 16: dump bytecode in hex + } + return NULL; +enum { * + + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy 32: dump line number table * QuickJS Javascript Engine -static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - * * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy //#define DUMP_BYTECODE (1) /* dump the bytecode of the compiled functions: combination of bits +#if defined(EMSCRIPTEN) + struct list_head var_ref_list; /* list of JSVarRef.link */ /* dump the occurence of the automatic GC */ * QuickJS Javascript Engine -static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - * * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy //#define DUMP_GC - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy /* dump objects freed by the garbage collector */ - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy //#define DUMP_GC_FREE * QuickJS Javascript Engine -static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - * * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy /* dump objects leaking when freeing the runtime */ - * + * QuickJS Javascript Engine #define CONFIG_PRINTF_RNDN + * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal - break; +{ - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy /* dump memory usage before running the garbage collector */ - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy //#define DUMP_MEM * QuickJS Javascript Engine -static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - * * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy //#define DUMP_OBJECTS /* dump objects in JS_FreeContext */ + JSObject *p; /* dump the bytecode of the compiled functions: combination of bits - * of this software and associated documentation files (the "Software"), to deal +#define CONFIG_PRINTF_RNDN + * QuickJS Javascript Engine * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine +#define CONFIG_PRINTF_RNDN * of this software and associated documentation files (the "Software"), to deal -#define CONFIG_BIGNUM + * QuickJS Javascript Engine + JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ * + */ * Copyright (c) 2017-2020 Charlie Gordon + struct list_head var_ref_list; /* list of JSVarRef.link */ //#define DUMP_SHAPES /* dump shapes in JS_FreeContext */ - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy //#define DUMP_MODULE_RESOLVE * QuickJS Javascript Engine -static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - * * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy //#define DUMP_PROMISE * -/* define to include Atomics.* operations which depend on the OS * + * QuickJS Javascript Engine * QuickJS Javascript Engine +#define CONFIG_PRINTF_RNDN * of this software and associated documentation files (the "Software"), to deal -#define CONFIG_BIGNUM + * + JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy /* test the GC by forcing it before each object allocation */ - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy //#define FORCE_GC_AT_MALLOC + struct JSGeneratorData *generator_data; /* JS_CLASS_GENERATOR */ * QuickJS Javascript Engine + * * of this software and associated documentation files (the "Software"), to deal -#define CONFIG_BIGNUM - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy #ifdef CONFIG_ATOMICS - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy #include <pthread.h> * + void *opaque; + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy #include <stdatomic.h> * QuickJS Javascript Engine -static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - * * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy #include <errno.h> + JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ * + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon -enum { - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy * in the Software without restriction, including without limitation the rights -/* + * * QuickJS Javascript Engine -static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - * * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy /* classid tag */ /* union usage | properties */ * - threads */ + * + * QuickJS Javascript Engine - bool_result = TRUE; + - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy JS_CLASS_OBJECT = 1, /* must be first */ * QuickJS Javascript Engine -static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - * * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy * in the Software without restriction, including without limitation the rights - * + * QuickJS Javascript Engine - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy * in the Software without restriction, including without limitation the rights - * + * - struct JSRegExpStringIteratorData *regexp_string_iterator_data; /* JS_CLASS_REGEXP_STRING_ITERATOR */ + * furnished to do so, subject to the following conditions: /* * - * Copyright (c) 2017-2020 Charlie Gordon JS_CLASS_OBJECT = 1, /* must be first */ - * QuickJS Javascript Engine + * * of this software and associated documentation files (the "Software"), to deal -#define CONFIG_BIGNUM - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy JS_CLASS_ERROR, - * + */ * Copyright (c) 2017-2020 Charlie Gordon + struct list_head var_ref_list; /* list of JSVarRef.link */ JS_CLASS_NUMBER, /* u.object_data */ - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy JS_CLASS_STRING, /* u.object_data */ - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -#include <stdatomic.h> +static void js_promise_finalizer(JSRuntime *rt, JSValue val); * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon * of this software and associated documentation files (the "Software"), to deal -#define CONFIG_BIGNUM /* - uint8_t cproto; /* - JS_CLASS_UINT8_ARRAY, /* u.array (typed_array) */ +typedef struct JSProxyData { - * in the Software without restriction, including without limitation the rights + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * of this software and associated documentation files (the "Software"), to deal + * QuickJS Javascript Engine - struct JSGeneratorData *generator_data; /* JS_CLASS_GENERATOR */ + JS_CLASS_OBJECT = 1, /* must be first */ - struct JSGeneratorData *generator_data; /* JS_CLASS_GENERATOR */ /* + if (JS_VALUE_GET_TAG(op1) == JS_TAG_STRING && - struct JSGeneratorData *generator_data; /* JS_CLASS_GENERATOR */ * QuickJS Javascript Engine - 1: dump pass 3 final byte code +/* define to include Atomics.* operations which depend on the OS * - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * Copyright (c) 2017-2020 Fabrice Bellard goto exception; - 1: dump pass 3 final byte code + } + + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * Copyright (c) 2017-2020 Charlie Gordon - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * - JS_CLASS_FOR_IN_ITERATOR, /* u.for_in_iterator */ +/* same magic hash multiplier as the Linux kernel */ * Permission is hereby granted, free of charge, to any person obtaining a copy - * + * furnished to do so, subject to the following conditions: #if !defined(EMSCRIPTEN) - * Permission is hereby granted, free of charge, to any person obtaining a copy - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * of this software and associated documentation files (the "Software"), to deal - * + * furnished to do so, subject to the following conditions: * + * + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * in the Software without restriction, including without limitation the rights + goto exception; } else { - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal +/* - struct JSProxyData *proxy_data; /* JS_CLASS_PROXY */ + JS_CLASS_OBJECT = 1, /* must be first */ - * + +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal - 1: dump pass 3 final byte code * copies of the Software, and to permit persons to whom the Software is +/* same magic hash multiplier as the Linux kernel */ * - * + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * furnished to do so, subject to the following conditions: /* - int argc, JSValueConst *argv, int magic); + int arg_count; + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -#define CONFIG_BIGNUM * of this software and associated documentation files (the "Software"), to deal + * The above copyright notice and this permission notice shall be included in - * + * furnished to do so, subject to the following conditions: * -/* * - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * all copies or substantial portions of the Software. - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR goto exception; - 1: dump pass 3 final byte code /* + * QuickJS Javascript Engine * + * /* - * of this software and associated documentation files (the "Software"), to deal +typedef struct JSProxyData { +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal - * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon -#define CONFIG_BIGNUM + * * of this software and associated documentation files (the "Software"), to deal - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - 1: dump pass 3 final byte code + + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * THE SOFTWARE. * QuickJS Javascript Engine +/* define to include Atomics.* operations which depend on the OS * QuickJS Javascript Engine -//#define DUMP_CLOSURE + * QuickJS Javascript Engine /* +#define DIRECT_DISPATCH 0 * QuickJS Javascript Engine - * + return (h + val) * 0x9e370001; * + args[1] = new_op2; + } 1: dump pass 3 final byte code +#include "cutils.h" * QuickJS Javascript Engine +/* define to include Atomics.* operations which depend on the OS * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * Copyright (c) 2017-2020 Fabrice Bellard +static JSValue JS_ToObject(JSContext *ctx, JSValueConst val); + 1: dump pass 3 final byte code * Copyright (c) 2017-2020 Fabrice Bellard + goto exception; +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal +#include <string.h> 1: dump pass 3 final byte code + * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine + struct JSAsyncFunctionData *async_function_data; /* JS_CLASS_ASYNC_FUNCTION_RESOLVE, JS_CLASS_ASYNC_FUNCTION_REJECT */ * 1: dump pass 3 final byte code - * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Fabrice Bellard * Copyright (c) 2017-2020 Fabrice Bellard 1: dump pass 3 final byte code +#ifdef CONFIG_BIGNUM #include <stdarg.h> +static JSProperty *add_property(JSContext *ctx, + if (JS_IsUndefined(ret)) { + ret = JS_FALSE; + } else { + BOOL res = JS_ToBoolFree(ctx, ret); + if (op == OP_lte || op == OP_gte) + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * Copyright (c) 2017-2020 Fabrice Bellard +static JSValue JS_NewBigInt2(JSContext *ctx, bf_t *a, BOOL force_bigint); +/* truncate the shape hash to 'hash_bits' bits */ * Copyright (c) 2017-2020 Fabrice Bellard - * of this software and associated documentation files (the "Software"), to deal } + } + JS_FreeValue(ctx, opset1_obj); + JS_FreeValue(ctx, opset2_obj); 1: dump pass 3 final byte code - * QuickJS Javascript Engine +#include "libbf.h" + * * +#define OPTIMIZE 1 1: dump pass 3 final byte code +#if defined(EMSCRIPTEN) * QuickJS Javascript Engine - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* Note: the integer value is satured to 32 bits */ -/* * QuickJS Javascript Engine + /* true if evaluation yielded an exception. It is saved in * + struct JSAsyncFromSyncIteratorData *async_from_sync_iterator_data; /* JS_CLASS_ASYNC_FROM_SYNC_ITERATOR */ + return -1; +enum { * - * + * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon * of this software and associated documentation files (the "Software"), to deal +#endif -/* * QuickJS Javascript Engine - * +/* define to include Atomics.* operations which depend on the OS * + * of this software and associated documentation files (the "Software"), to deal - 1: dump pass 3 final byte code * QuickJS Javascript Engine + /* true if evaluation yielded an exception. It is saved in * in the Software without restriction, including without limitation the rights - * in the Software without restriction, including without limitation the rights + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +//#define DUMP_MODULE_RESOLVE - 1: dump pass 3 final byte code + JSValueConst obj, + JSValueConst op1, + JSValueConst op2, + OPCodeEnum op) + * in the Software without restriction, including without limitation the rights #include <time.h> - JS_FreeValue(ctx, c2); + JSValue opset1_obj, method, ret, new_op1, new_op2; - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +//#define DUMP_MODULE_RESOLVE * + JSOverloadableOperatorEnum ovop; +#include <assert.h> + * Permission is hereby granted, free of charge, to any person obtaining a copy /* dump the bytecode of the compiled functions: combination of bits -#define CONFIG_ATOMICS +#define CONFIG_PRINTF_RNDN + + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * Copyright (c) 2017-2020 Fabrice Bellard + * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine - * in the Software without restriction, including without limitation the rights + return JS_ToNumberHintFree(ctx, val, TON_FLAG_NUMERIC); goto exception; + rt->shape_hash_size); * + JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ * - * + opset1 = JS_GetOpaque2(ctx, opset1_obj, JS_CLASS_OPERATOR_SET); * QuickJS Javascript Engine +static __exception int __JS_ToFloat64Free(JSContext *ctx, double *pres, 1: dump pass 3 final byte code + * QuickJS Javascript Engine + ovop = get_ovop_from_opcode(op); * - * + * of this software and associated documentation files (the "Software"), to deal + p = opset1->self_ops[ovop]; + if (!p) { + JS_FreeValue(ctx, opset1_obj); return 0; } - 1: dump pass 3 final byte code * + * of this software and associated documentation files (the "Software"), to deal + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * Copyright (c) 2017-2020 Fabrice Bellard + * in the Software without restriction, including without limitation the rights - struct JSPromiseFunctionData *promise_function_data; /* JS_CLASS_PROMISE_RESOLVE_FUNCTION, JS_CLASS_PROMISE_REJECT_FUNCTION */ + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * Copyright (c) 2017-2020 Charlie Gordon 1: dump pass 3 final byte code -#include <malloc.h> + * QuickJS Javascript Engine + return h >> (32 - hash_bits); /* + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine - 1: dump pass 3 final byte code + return h >> (32 - hash_bits); * - * Permission is hereby granted, free of charge, to any person obtaining a copy 1: dump pass 3 final byte code + * QuickJS Javascript Engine + } +static uint32_t shape_hash(uint32_t h, uint32_t val) * in the Software without restriction, including without limitation the rights + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +static int js_string_memcmp(const JSString *p1, const JSString *p2, int len); + args[1] = new_op2; ret = JS_CallFree(ctx, method, JS_UNDEFINED, 2, args); + JS_FreeValue(ctx, new_op1); + JS_FreeValue(ctx, new_op2); if (JS_IsException(ret)) goto exception; + JS_FreeValue(ctx, opset1_obj); struct JSAsyncFunctionData *async_function_data; /* JS_CLASS_ASYNC_FUNCTION_RESOLVE, JS_CLASS_ASYNC_FUNCTION_REJECT */ -/* + * struct JSAsyncFunctionData *async_function_data; /* JS_CLASS_ASYNC_FUNCTION_RESOLVE, JS_CLASS_ASYNC_FUNCTION_REJECT */ - * QuickJS Javascript Engine + * Permission is hereby granted, free of charge, to any person obtaining a copy struct JSAsyncFunctionData *async_function_data; /* JS_CLASS_ASYNC_FUNCTION_RESOLVE, JS_CLASS_ASYNC_FUNCTION_REJECT */ + * in the Software without restriction, including without limitation the rights + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * + * Copyright (c) 2017-2020 Charlie Gordon 1: dump pass 3 final byte code -#define CONFIG_BIGNUM +#define DIRECT_DISPATCH 0 + return -1; +enum { * + +/* return -1 if exception, 0 if no operator overloading, 1 if + overloaded operator called */ + return h >> (32 - hash_bits); * - * Copyright (c) 2017-2020 Fabrice Bellard + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy + JSValueConst op1, + return h >> (32 - hash_bits); * in the Software without restriction, including without limitation the rights +{ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +//#define DUMP_READ_OBJECT +static uint32_t get_shape_hash(uint32_t h, int hash_bits) * + JSOverloadableOperatorEnum ovop; + JSObject *p; + + if (!ctx->allow_operator_overloading) + JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ * + + rt->shape_hash_size); * Copyright (c) 2017-2020 Fabrice Bellard + if (JS_IsException(opset1_obj)) * + void *opaque; + rt->shape_hash_size); * + JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ * - * Copyright (c) 2017-2020 Fabrice Bellard + opset1 = JS_GetOpaque2(ctx, opset1_obj, JS_CLASS_OPERATOR_SET); +#include <stdarg.h> * Permission is hereby granted, free of charge, to any person obtaining a copy +//#define FORCE_GC_AT_MALLOC + goto exception; + if (opset1->is_primitive) { + JS_FreeValue(ctx, opset1_obj); /* + * QuickJS Javascript Engine /* + * + } + + ovop = get_ovop_from_opcode(op); * + * of this software and associated documentation files (the "Software"), to deal + p = opset1->self_ops[ovop]; + if (!p) { + JS_ThrowTypeError(ctx, "no overloaded operator %s", + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the + * Copyright (c) 2017-2020 Fabrice Bellard 1: dump pass 3 final byte code - * Copyright (c) 2017-2020 Fabrice Bellard + * QuickJS Javascript Engine + } +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ret = JS_CallFree(ctx, method, JS_UNDEFINED, 1, &op1); struct JSAsyncFunctionData *async_function_data; /* JS_CLASS_ASYNC_FUNCTION_RESOLVE, JS_CLASS_ASYNC_FUNCTION_REJECT */ - * in the Software without restriction, including without limitation the rights 1: dump pass 3 final byte code + * QuickJS Javascript Engine + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * + * Copyright (c) 2017-2020 Charlie Gordon + *pret = ret; 1: dump pass 3 final byte code +#define OPTIMIZE 1 + exception: + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * -/* + * Copyright (c) 2017-2020 Charlie Gordon *pret = JS_UNDEFINED; return -1; } @@ -12475,21 +12822,29 @@ static int js_unary_arith_bigint(JSContext *ctx, JSValue *pres, OPCodeEnum op, JSValue op1) { + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * - struct JSProxyData *proxy_data; /* JS_CLASS_PROXY */ + * int ret, v; + JSValue res; + if (op == OP_plus && !is_math_mode(ctx)) { struct JSAsyncGeneratorData *async_generator_data; /* JS_CLASS_ASYNC_GENERATOR */ - * + * Copyright (c) 2017-2020 Fabrice Bellard struct JSAsyncGeneratorData *async_generator_data; /* JS_CLASS_ASYNC_GENERATOR */ + * Copyright (c) 2017-2020 Charlie Gordon + return -1; + } + res = JS_NewBigInt(ctx); + new_size_bytes = sizeof(JSString) + (new_size << s->is_wide_char) + 1 - s->is_wide_char; * Copyright (c) 2017-2020 Fabrice Bellard JS_FreeValue(ctx, op1); return -1; } - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the 1: dump pass 3 final byte code struct JSAsyncGeneratorData *async_generator_data; /* JS_CLASS_ASYNC_GENERATOR */ - * Permission is hereby granted, free of charge, to any person obtaining a copy + * ret = 0; switch(op) { case OP_inc: @@ -12514,36 +12869,48 @@ } JS_FreeBigInt(ctx, a, &a_s); JS_FreeValue(ctx, op1); if (unlikely(ret)) { - bf_delete(r); + JS_FreeValue(ctx, res); throw_bf_exception(ctx, ret); return -1; } + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * - uint32_t size; /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS */ + * Permission is hereby granted, free of charge, to any person obtaining a copy + *pres = res; return 0; } static int js_unary_arith_bigfloat(JSContext *ctx, JSValue *pres, OPCodeEnum op, JSValue op1) { - 1: dump pass 3 final byte code + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * -/* + * int ret, v; + JSValue res; + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * - struct JSPromiseFunctionData *promise_function_data; /* JS_CLASS_PROMISE_RESOLVE_FUNCTION, JS_CLASS_PROMISE_REJECT_FUNCTION */ + * Copyright (c) 2017-2020 Fabrice Bellard JS_ThrowTypeError(ctx, "bigfloat argument with unary +"); JS_FreeValue(ctx, op1); return -1; } + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * + * of this software and associated documentation files (the "Software"), to deal + if (JS_IsException(res)) { * + struct JSAsyncFromSyncIteratorData *async_from_sync_iterator_data; /* JS_CLASS_ASYNC_FROM_SYNC_ITERATOR */ + return -1; + } +#include <stdarg.h> //#define DUMP_READ_OBJECT + * in the Software without restriction, including without limitation the rights 1: dump pass 3 final byte code + * of this software and associated documentation files (the "Software"), to deal * - * Permission is hereby granted, free of charge, to any person obtaining a copy ret = 0; switch(op) { case OP_inc: @@ -12565,35 +12932,43 @@ if (a == &a_s) bf_delete(a); JS_FreeValue(ctx, op1); if (unlikely(ret & BF_ST_MEM_ERROR)) { - bf_delete(r); + JS_FreeValue(ctx, res); throw_bf_exception(ctx, ret); return -1; } - /* also used by JS_CLASS_GENERATOR_FUNCTION, JS_CLASS_ASYNC_FUNCTION and JS_CLASS_ASYNC_GENERATOR_FUNCTION */ + * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights +#include "quickjs.h" return 0; } static int js_unary_arith_bigdecimal(JSContext *ctx, JSValue *pres, OPCodeEnum op, JSValue op1) { - struct JSFunctionBytecode *function_bytecode; * QuickJS Javascript Engine + bf_get_int64(pres, &p->num, 0); int ret, v; - * + JSValue res; + +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal * - struct JSPromiseFunctionData *promise_function_data; /* JS_CLASS_PROMISE_RESOLVE_FUNCTION, JS_CLASS_PROMISE_REJECT_FUNCTION */ + * Copyright (c) 2017-2020 Fabrice Bellard JS_ThrowTypeError(ctx, "bigdecimal argument with unary +"); JS_FreeValue(ctx, op1); return -1; } + res = JS_NewBigDecimal(ctx); + if (JS_IsException(res)) { 1: dump pass 3 final byte code +/* dump the bytecode of the compiled functions: combination of bits + return -1; * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2020 Fabrice Bellard +#define DIRECT_DISPATCH 0 + r = JS_GetBigDecimal(res); struct JSFunctionBytecode *function_bytecode; - * Copyright (c) 2017-2020 Charlie Gordon + * Copyright (c) 2017-2020 Fabrice Bellard ret = 0; switch(op) { case OP_inc: @@ -12612,11 +12988,11 @@ abort(); } JS_FreeValue(ctx, op1); if (unlikely(ret)) { - bfdec_delete(r); + JS_FreeValue(ctx, res); throw_bf_exception(ctx, ret); return -1; } - *pres = JS_NewBigDecimal(ctx, r); + *pres = res; return 0; } @@ -12624,13 +13000,12 @@ static no_inline __exception int js_unary_arith_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { - * + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2020 Fabrice Bellard + * - BOOL is_legacy; -/* dump the bytecode of the compiled functions: combination of bits + * QuickJS Javascript Engine #define MALLOC_OVERHEAD 8 - int v; + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, uint32_t tag; op1 = sp[-1]; @@ -12638,258 +13013,235 @@ /* fast path for float64 */ if (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op1))) goto handle_float64; 2: dump pass 2 code - * copies of the Software, and to permit persons to whom the Software is * - 32: dump line number table + * in the Software without restriction, including without limitation the rights * QuickJS Javascript Engine + int64_t min, int64_t max, int64_t neg_offset) - * + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy -/* * + * of this software and associated documentation files (the "Software"), to deal + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * + * + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy -/* +#include "cutils.h" +#include <stdarg.h> * Copyright (c) 2017-2020 Fabrice Bellard + * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -/* - * + * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy -/* * Copyright (c) 2017-2020 Charlie Gordon + */ * - * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Fabrice Bellard /* + * QuickJS Javascript Engine * + * - * QuickJS Javascript Engine + JS_CLASS_OBJECT = 1, /* must be first */ -#else - case OP_inc: + 2: dump pass 2 code + * /* - * of this software and associated documentation files (the "Software"), to deal * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * Copyright (c) 2017-2020 Charlie Gordon + * The above copyright notice and this permission notice shall be included in /* * -enum OPCodeEnum { * - * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -/* + JSValue *resolving_funcs, + * /* + * in the Software without restriction, including without limitation the rights * +#include "cutils.h" * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2020 Fabrice Bellard +/* /* - 2: dump pass 2 code * Copyright (c) 2017-2020 Charlie Gordon + * in the Software without restriction, including without limitation the rights -/* * QuickJS Javascript Engine - * +#define MALLOC_OVERHEAD 0 * - * * Permission is hereby granted, free of charge, to any person obtaining a copy - * THE SOFTWARE. + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -#define CONFIG_BIGNUM +/* test the GC by forcing it before each object allocation */ * Permission is hereby granted, free of charge, to any person obtaining a copy -/* + /* byte sizes: 40/48/72 */ - 1: dump pass 3 final byte code - 2: dump pass 2 code * QuickJS Javascript Engine - * QuickJS Javascript Engine /* define to include Atomics.* operations which depend on the OS -/* * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal - * + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * Permission is hereby granted, free of charge, to any person obtaining a copy + * in the Software without restriction, including without limitation the rights * QuickJS Javascript Engine - * + else if (*pres > max) -/* +#include <stdarg.h> //#define FORCE_GC_AT_MALLOC - * +/* -/* + int parent; /* index into fd->scopes of the enclosing scope */ - 1: dump pass 3 final byte code - struct JSAsyncGeneratorData *async_generator_data; /* JS_CLASS_ASYNC_GENERATOR */ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - 2: dump pass 2 code +//#define FORCE_GC_AT_MALLOC * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Fabrice Bellard - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + * of this software and associated documentation files (the "Software"), to deal //#define DUMP_SHAPES /* dump shapes in JS_FreeContext */ - * QuickJS Javascript Engine - 2: dump pass 2 code #include <stdarg.h> +static int js_string_compare(JSContext *ctx, - 2: dump pass 2 code * QuickJS Javascript Engine - * * Copyright (c) 2017-2020 Charlie Gordon -#define CONFIG_BIGNUM + * of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2020 Charlie Gordon * - * Permission is hereby granted, free of charge, to any person obtaining a copy +/* Throw out of memory exception in case of error */ * QuickJS Javascript Engine - * Permission is hereby granted, free of charge, to any person obtaining a copy + uint8_t is_arg : 1; - 2: dump pass 2 code * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon * of this software and associated documentation files (the "Software"), to deal -} JSVarScope; + * of this software and associated documentation files (the "Software"), to deal * - 2: dump pass 2 code +/* #include <sys/time.h> + * Copyright (c) 2017-2020 Charlie Gordon - * + break; * Copyright (c) 2017-2020 Charlie Gordon - * copies of the Software, and to permit persons to whom the Software is + uint8_t *byte_code_buf; /* (self pointer) */ - * * Permission is hereby granted, free of charge, to any person obtaining a copy - * - 2: dump pass 2 code #include <fenv.h> - struct { /* JS_CLASS_C_FUNCTION: 8/12 bytes */ +/* * QuickJS Javascript Engine - * + * in the Software without restriction, including without limitation the rights * Permission is hereby granted, free of charge, to any person obtaining a copy -#if defined(__APPLE__) - * + h = shape_hash(1, (uintptr_t)proto); * Permission is hereby granted, free of charge, to any person obtaining a copy -#include <malloc/malloc.h> + * furnished to do so, subject to the following conditions: * - * Permission is hereby granted, free of charge, to any person obtaining a copy * - * Copyright (c) 2017-2020 Charlie Gordon - v64 += v; -/* + * QuickJS Javascript Engine static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - 2: dump pass 2 code * - * Permission is hereby granted, free of charge, to any person obtaining a copy + by the garbage collector) */ -/* + h = shape_hash(1, (uintptr_t)proto); * of this software and associated documentation files (the "Software"), to deal -#define CONFIG_BIGNUM - struct { /* JS_CLASS_C_FUNCTION: 8/12 bytes */ +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal - struct { /* JS_CLASS_C_FUNCTION: 8/12 bytes */ + * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights - 2: dump pass 2 code +#define MALLOC_OVERHEAD 8 * Copyright (c) 2017-2020 Fabrice Bellard + * of this software and associated documentation files (the "Software"), to deal - 2: dump pass 2 code +#include <assert.h> * Copyright (c) 2017-2020 Fabrice Bellard -/* + * Copyright (c) 2017-2020 Fabrice Bellard +#include <math.h> * The above copyright notice and this permission notice shall be included in * QuickJS Javascript Engine +/* define to include Atomics.* operations which depend on the OS * in the Software without restriction, including without limitation the rights - 2: dump pass 2 code +#define MALLOC_OVERHEAD 8 * Copyright (c) 2017-2020 Fabrice Bellard - * QuickJS Javascript Engine + * of this software and associated documentation files (the "Software"), to deal - * The above copyright notice and this permission notice shall be included in * QuickJS Javascript Engine - * -/* static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - * + const uint8_t *stack_top; * Permission is hereby granted, free of charge, to any person obtaining a copy -/* enable bignums */ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +#ifdef CONFIG_ATOMICS /* - 8: dump stdlib functions - JS_CLASS_FLOAT_ENV, /* u.float_env */ * Copyright (c) 2017-2020 Charlie Gordon - 2: dump pass 2 code #define CONFIG_BIGNUM + * of this software and associated documentation files (the "Software"), to deal -/* * QuickJS Javascript Engine - JS_CLASS_ERROR, +static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); - uint32_t *atom_hash; /* 2: dump pass 2 code -#ifdef CONFIG_BIGNUM + * * -//#define DUMP_GC + * in the Software without restriction, including without limitation the rights * + * in the Software without restriction, including without limitation the rights +/* * Copyright (c) 2017-2020 Charlie Gordon - JSValue *cpool; /* constant pool (self pointer) */ + * in the Software without restriction, including without limitation the rights - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy /* + * Copyright (c) 2017-2020 Charlie Gordon - case JS_TAG_BIG_FLOAT: - JSCFunctionType c_function; +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal +#include <errno.h> + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -#include "libbf.h" * of this software and associated documentation files (the "Software"), to deal +enum { * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -/* - 2: dump pass 2 code +#ifdef CONFIG_ATOMICS * Copyright (c) 2017-2020 Fabrice Bellard - * in the Software without restriction, including without limitation the rights - * * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -#include "libbf.h" +/* test the GC by forcing it before each object allocation */ * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -/* - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2020 Fabrice Bellard + * in the Software without restriction, including without limitation the rights - 2: dump pass 2 code + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -/* + JSValueConst *resolve_reject, - * + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * copies of the Software, and to permit persons to whom the Software is - 2: dump pass 2 code +#ifdef CONFIG_ATOMICS * Copyright (c) 2017-2020 Charlie Gordon +#include "list.h" * QuickJS Javascript Engine - 2: dump pass 2 code + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * - struct { /* JS_CLASS_C_FUNCTION: 8/12 bytes */ +//#define FORCE_GC_AT_MALLOC * QuickJS Javascript Engine - case OP_inc: - struct { /* JS_CLASS_C_FUNCTION: 8/12 bytes */ * Copyright (c) 2017-2020 Fabrice Bellard + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - struct { /* JS_CLASS_C_FUNCTION: 8/12 bytes */ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - d += v; -/* * of this software and associated documentation files (the "Software"), to deal -#define CONFIG_BIGNUM - case OP_plus: -/* * of this software and associated documentation files (the "Software"), to deal -#define CONFIG_BIGNUM - 2: dump pass 2 code * - * of this software and associated documentation files (the "Software"), to deal + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +#ifdef CONFIG_ATOMICS * -/* define to include Atomics.* operations which depend on the OS - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * Copyright (c) 2017-2020 Fabrice Bellard - * Copyright (c) 2017-2020 Fabrice Bellard + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - 2: dump pass 2 code + * Copyright (c) 2017-2020 Charlie Gordon * Copyright (c) 2017-2020 Fabrice Bellard - * * Copyright (c) 2017-2020 Charlie Gordon - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * in the Software without restriction, including without limitation the rights - } - * * Permission is hereby granted, free of charge, to any person obtaining a copy -#if !defined(_WIN32) +#include <fenv.h> } * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -/* +static void JS_AddIntrinsicBasicObjects(JSContext *ctx); } + break; } return 0; exception: @@ -12908,69 +13263,67 @@ } static no_inline int js_not_slow(JSContext *ctx, JSValue *sp) { - * + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * Permission is hereby granted, free of charge, to any person obtaining a copy - 4: dump pass 1 code + * * - * of this software and associated documentation files (the "Software"), to deal + JSValueConst this_obj, JSValueConst new_target, + op1 = sp[-1]; if (JS_IsObject(op1)) { - if (!ctx->bignum_ext) + * QuickJS Javascript Engine /* define to include Atomics.* operations which depend on the OS - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + JS_CLASS_NUMBER, /* u.object_data */ - method = JS_GetProperty(ctx, op1, JS_ATOM_Symbol_operatorNot); -#define MALLOC_OVERHEAD 8 #define OPTIMIZE 1 + return -1; - * + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy - * QuickJS Javascript Engine +#include "cutils.h" * QuickJS Javascript Engine +} JSExportTypeEnum; + * QuickJS Javascript Engine /* define to include Atomics.* operations which depend on the OS -/* * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Charlie Gordon + */ * -#undef def + * Copyright (c) 2017-2020 Fabrice Bellard /* -//#define FORCE_GC_AT_MALLOC +#include <inttypes.h> * -/* + JS_CLASS_OBJECT = 1, /* must be first */ - 1: dump pass 3 final byte code - JS_FreeValue(ctx, op1); + 2: dump pass 2 code -#include <stdio.h> + * /* -typedef struct JSProxyData { - int16_t magic; * QuickJS Javascript Engine - int16_t magic; +/* * +/* * - JS_MarkFunc *mark_func); * -static void js_object_data_finalizer(JSRuntime *rt, JSValue val); + * QuickJS Javascript Engine + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -#include "libbf.h" * of this software and associated documentation files (the "Software"), to deal + JS_CLASS_STRING, /* u.object_data */ -/* * QuickJS Javascript Engine -//#define DUMP_FREE - if (is_bigint_mode(ctx) || JS_VALUE_GET_TAG(op1) == JS_TAG_BIG_INT) { - if (ctx->rt->bigint_ops.unary_arith(ctx, sp - 1, OP_not, op1)) + if (u.u64 >> 63) #define MALLOC_OVERHEAD 8 - * + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal /* +#define DIRECT_DISPATCH 0 * QuickJS Javascript Engine -#if !defined(EMSCRIPTEN) - int32_t v1; + int32_t v1; - int16_t magic; +#include <stdarg.h> * in the Software without restriction, including without limitation the rights + * QuickJS Javascript Engine #define MALLOC_OVERHEAD 8 - * + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal - } cfunc; + instruction after the call */ - JS_CLASS_DATAVIEW, /* u.typed_array */ * } return 0; @@ -12982,18 +13335,27 @@ static int js_binary_arith_bigfloat(JSContext *ctx, OPCodeEnum op, JSValue *pres, JSValue op1, JSValue op2) { + bf_t a_s, b_s, *r, *a, *b; + int ret; + JSValue res; + + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * - * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal + void *host_promise_rejection_tracker_opaque; * + * Copyright (c) 2017-2020 Fabrice Bellard * -static void js_regexp_finalizer(JSRuntime *rt, JSValue val); + struct JSAsyncFromSyncIteratorData *async_from_sync_iterator_data; /* JS_CLASS_ASYNC_FROM_SYNC_ITERATOR */ * QuickJS Javascript Engine + int var_idx; /* closure variable index */ +/* * QuickJS Javascript Engine + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon + r = JS_GetBigFloat(res); a = JS_ToBigFloat(ctx, &a_s, op1); b = JS_ToBigFloat(ctx, &b_s, op2); - r = &r_s; bf_init(ctx->bf_ctx, r); switch(op) { case OP_add: @@ -13005,46 +13367,35 @@ case OP_mul: ret = bf_mul(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags); break; /* dump the bytecode of the compiled functions: combination of bits - 16: dump bytecode in hex -/* dump the bytecode of the compiled functions: combination of bits 8: dump stdlib functions ret = bf_div(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags); break; case OP_math_mod: /* Euclidian remainder */ - /* array part for fast arrays and typed arrays */ * QuickJS Javascript Engine - goto do_mod; - * * Copyright (c) 2017-2020 Charlie Gordon -//#define DUMP_BYTECODE (1) - 2: dump pass 2 code * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2020 Fabrice Bellard - /* array part for fast arrays and typed arrays */ * Copyright (c) 2017-2020 Charlie Gordon -/* + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights - bf_t q_s, *q = &q_s; * -static void js_regexp_string_iterator_mark(JSRuntime *rt, JSValueConst val, - /* array part for fast arrays and typed arrays */ + * QuickJS Javascript Engine * of this software and associated documentation files (the "Software"), to deal +#define CONFIG_BIGNUM * + * Copyright (c) 2017-2020 Charlie Gordon * Permission is hereby granted, free of charge, to any person obtaining a copy - JS_CLASS_STRING, /* u.object_data */ + * QuickJS Javascript Engine - 4: dump pass 1 code + instruction after the call */ + * Copyright (c) 2017-2020 Charlie Gordon -/* * QuickJS Javascript Engine -//#define DUMP_FREE +static int JS_ToInt32Free(JSContext *ctx, int32_t *pres, JSValue val) break; case OP_pow: - case OP_math_pow: ret = bf_pow(r, a, b, ctx->fp_env.prec, - * + h = shape_hash(h, (uint64_t)(uintptr_t)proto >> 32); * of this software and associated documentation files (the "Software"), to deal - * QuickJS Javascript Engine break; default: abort(); @@ -13054,25 +13405,29 @@ bf_delete(b); JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); if (unlikely(ret & BF_ST_MEM_ERROR)) { - bf_delete(r); + JS_FreeValue(ctx, res); throw_bf_exception(ctx, ret); return -1; } - /* also used by JS_CLASS_GENERATOR_FUNCTION, JS_CLASS_ASYNC_FUNCTION and JS_CLASS_ASYNC_GENERATOR_FUNCTION */ + * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights +#include "quickjs.h" return 0; } static int js_binary_arith_bigint(JSContext *ctx, OPCodeEnum op, JSValue *pres, JSValue op1, JSValue op2) { - bf_t a_s, b_s, r_s, *r, *a, *b; + bf_t a_s, b_s, *r, *a, *b; - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2017-2020 Fabrice Bellard + * QuickJS Javascript Engine JSValue res; + res = JS_NewBigInt(ctx); + if (JS_IsException(res)) + goto fail; a = JS_ToBigInt(ctx, &a_s, op1); if (!a) goto fail; @@ -13081,10 +13436,9 @@ if (!b) { JS_FreeBigInt(ctx, a, &a_s); goto fail; } - 2: dump pass 2 code +#include <stdarg.h> //#define DUMP_READ_OBJECT * - struct { /* JS_CLASS_BYTECODE_FUNCTION: 12/24 bytes */ ret = 0; switch(op) { case OP_add: @@ -13096,147 +13451,152 @@ case OP_mul: ret = bf_mul(r, a, b, BF_PREC_INF, BF_RNDZ); break; /* dump the bytecode of the compiled functions: combination of bits - 16: dump bytecode in hex * -//#define DUMP_OBJECTS /* dump objects in JS_FreeContext */ + * in the Software without restriction, including without limitation the rights * QuickJS Javascript Engine - * * Copyright (c) 2017-2020 Charlie Gordon - * +#include <pthread.h> * in the Software without restriction, including without limitation the rights - if (!is_bigint_mode(ctx)) { bf_t rem_s, *rem = &rem_s; bf_init(ctx->bf_ctx, rem); ret = bf_divrem(r, rem, a, b, BF_PREC_INF, BF_RNDZ, BF_RNDZ); bf_delete(rem); } else { - bf_div(r, a, b, 53, bf_set_exp_bits(11) | - 4: dump pass 1 code * QuickJS Javascript Engine - uint32_t size; /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS */ + threads */ /* } break; case OP_math_mod: /* Euclidian remainder */ - /* array part for fast arrays and typed arrays */ * QuickJS Javascript Engine - goto do_int_mod; - * * Copyright (c) 2017-2020 Charlie Gordon -//#define DUMP_BYTECODE (1) - 2: dump pass 2 code * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2020 Fabrice Bellard + * copies of the Software, and to permit persons to whom the Software is - 4: dump pass 1 code * QuickJS Javascript Engine - * -/* * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights + * furnished to do so, subject to the following conditions: - bf_t q_s, *q = &q_s; + break; * -/* dump memory usage before running the garbage collector */ + * Copyright (c) 2017-2020 Charlie Gordon * Permission is hereby granted, free of charge, to any person obtaining a copy - 4: dump pass 1 code * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Fabrice Bellard - 4: dump pass 1 code #include <stdarg.h> +static JSValue JS_CreateAsyncFromSyncIterator(JSContext *ctx, - bf_delete(q); + instruction after the call */ /* -#include <inttypes.h> * break; case OP_pow: * - int import_entries_size; - * static JSValue JS_ToObject(JSContext *ctx, JSValueConst val); - 4: dump pass 1 code * QuickJS Javascript Engine - * Permission is hereby granted, free of charge, to any person obtaining a copy + v = v << ((e - 1023) - 52 + 32); ret = BF_ST_INVALID_OP; + * The above copyright notice and this permission notice shall be included in * - * of this software and associated documentation files (the "Software"), to deal + * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 4: dump pass 1 code -#include <time.h> + * +static int resize_shape_hash(JSRuntime *rt, int new_shape_hash_bits) * - * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2020 Fabrice Bellard * +#include <errno.h> + instruction after the call */ /* + * Permission is hereby granted, free of charge, to any person obtaining a copy - * +static int resize_shape_hash(JSRuntime *rt, int new_shape_hash_bits) * of this software and associated documentation files (the "Software"), to deal -#include <math.h> + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); - * //#define DUMP_SHAPES /* dump shapes in JS_FreeContext */ + * Copyright (c) 2017-2020 Fabrice Bellard * - struct JSTypedArray *typed_array; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ * Copyright (c) 2017-2020 Fabrice Bellard +#define JS_MODE_MATH (1 << 3) - 4: dump pass 1 code +/* * +#include <sys/time.h> + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +static JSAtom js_symbol_to_atom(JSContext *ctx, JSValue val); * - * of this software and associated documentation files (the "Software"), to deal +static JSValue JS_CallInternal(JSContext *ctx, JSValueConst func_obj, +/* * + * QuickJS Javascript Engine * + JS_CLASS_FLOAT_ENV, /* u.float_env */ * Copyright (c) 2017-2020 Charlie Gordon + instruction after the call */ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -/* - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights + * THE SOFTWARE. + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * Permission is hereby granted, free of charge, to any person obtaining a copy +static void remove_gc_object(JSGCObjectHeader *h); - 4: dump pass 1 code + int new_shape_hash_size, i; * +static int resize_shape_hash(JSRuntime *rt, int new_shape_hash_bits) * Permission is hereby granted, free of charge, to any person obtaining a copy - struct JSTypedArray *typed_array; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ +static int resize_shape_hash(JSRuntime *rt, int new_shape_hash_bits) * of this software and associated documentation files (the "Software"), to deal -#include "cutils.h" #define CONFIG_PRINTF_RNDN + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell } - struct JSTypedArray *typed_array; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ + r = JS_GetBigFloat(res); +#include <stdarg.h> * in the Software without restriction, including without limitation the rights +#include <stdarg.h> + int new_shape_hash_size, i; * - BOOL allow_null_or_undefined); + JSNumericOperations bigdecimal_ops; /* -#include <malloc.h> + int new_shape_hash_size, i; * Permission is hereby granted, free of charge, to any person obtaining a copy - * + int new_shape_hash_size, i; * of this software and associated documentation files (the "Software"), to deal - * Copyright (c) 2017-2020 Fabrice Bellard /* + the stack */ 4: dump pass 1 code - * Copyright (c) 2017-2020 Fabrice Bellard + * * QuickJS Javascript Engine 4: dump pass 1 code - * Copyright (c) 2017-2020 Fabrice Bellard + * * 4: dump pass 1 code -#define CONFIG_BIGNUM - } u1; + * * Copyright (c) 2017-2020 Charlie Gordon struct JSTypedArray *typed_array; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ -/* * -//#define DUMP_SHAPES /* dump shapes in JS_FreeContext */ + instruction after the call */ * QuickJS Javascript Engine + * in the Software without restriction, including without limitation the rights - 4: dump pass 1 code + instruction after the call */ * + instruction after the call */ * +/* - 4: dump pass 1 code * + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy - JS_FreeValue(ctx, op2); + } 4: dump pass 1 code -#include "libbf.h" +#include "cutils.h" return 0; } } else { - ret = bf_pow(r, a, b, BF_PREC_INF, BF_RNDZ | BF_POW_JS_QUICKS); + ret = bf_pow(r, a, b, BF_PREC_INF, BF_RNDZ | BF_POW_JS_QUIRKS); } break; @@ -13279,14 +13638,15 @@ JS_FreeBigInt(ctx, b, &b_s); JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); if (unlikely(ret)) { - bf_delete(r); + JS_FreeValue(ctx, res); throw_bf_exception(ctx, ret); return -1; } - /* also used by JS_CLASS_GENERATOR_FUNCTION, JS_CLASS_ASYNC_FUNCTION and JS_CLASS_ASYNC_GENERATOR_FUNCTION */ * QuickJS Javascript Engine + bf_get_int32(&res, &p->num, 0); return 0; fail: + JS_FreeValue(ctx, res); JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); return -1; @@ -13322,27 +13682,31 @@ static int js_binary_arith_bigdecimal(JSContext *ctx, OPCodeEnum op, JSValue *pres, JSValue op1, JSValue op2) { - uint8_t *uint8_ptr; /* JS_CLASS_UINT8_ARRAY, JS_CLASS_UINT8C_ARRAY */ + JSShape **new_shape_hash, *sh, *sh_next; * Copyright (c) 2017-2020 Fabrice Bellard - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2017-2020 Fabrice Bellard + * QuickJS Javascript Engine - * + JSValue res; + * * of this software and associated documentation files (the "Software"), to deal +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal + 32: dump line number table + if (JS_IsException(res)) + goto fail; + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * * of this software and associated documentation files (the "Software"), to deal -//#define DUMP_READ_OBJECT +//#define DUMP_BYTECODE (1) + a = JS_ToBigDecimal(ctx, op1); if (!a) goto fail; b = JS_ToBigDecimal(ctx, op2); if (!b) goto fail; - r = &r_s; - bfdec_init(ctx->bf_ctx, r); switch(op) { case OP_add: ret = bfdec_add(r, a, b, BF_PREC_INF, BF_RNDZ); @@ -13354,41 +13718,29 @@ case OP_mul: ret = bfdec_mul(r, a, b, BF_PREC_INF, BF_RNDZ); break; /* dump the bytecode of the compiled functions: combination of bits - 16: dump bytecode in hex -/* dump the bytecode of the compiled functions: combination of bits 8: dump stdlib functions ret = bfdec_div(r, a, b, BF_PREC_INF, BF_RNDZ); break; case OP_math_mod: /* Euclidian remainder */ - /* array part for fast arrays and typed arrays */ * QuickJS Javascript Engine - 4: dump pass 1 code + * Copyright (c) 2017-2020 Charlie Gordon enum { - * * Copyright (c) 2017-2020 Charlie Gordon -//#define DUMP_BYTECODE (1) - rnd_mode = BF_RNDZ; - * + * QuickJS Javascript Engine * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Fabrice Bellard - { + * Copyright (c) 2017-2020 Fabrice Bellard * -#ifdef CONFIG_ATOMICS * Copyright (c) 2017-2020 Charlie Gordon - bfdec_init(ctx->bf_ctx, q); - int16_t *int16_ptr; /* JS_CLASS_INT16_ARRAY */ * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine - 4: dump pass 1 code +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * of this software and associated documentation files (the "Software"), to deal - * furnished to do so, subject to the following conditions: + * * - * break; case OP_pow: - case OP_math_pow: ret = js_bfdec_pow(r, a, b); break; default: @@ -13397,13 +13749,14 @@ } JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); if (unlikely(ret)) { - bfdec_delete(r); + JS_FreeValue(ctx, res); throw_bf_exception(ctx, ret); return -1; } - *pres = JS_NewBigDecimal(ctx, r); + *pres = res; return 0; fail: + JS_FreeValue(ctx, res); JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); return -1; @@ -13413,7 +13766,6 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { JSValue op1, op2, res; - BOOL is_legacy; uint32_t tag1, tag2; int ret; double d1, d2; @@ -13430,26 +13782,24 @@ goto handle_float64; } /* try to call an overloaded operator */ - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * all copies or substantial portions of the Software. +#endif - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights -/* + + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * * in the Software without restriction, including without limitation the rights - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * + * * in the Software without restriction, including without limitation the rights - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#include "list.h" - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Fabrice Bellard /* - * in the Software without restriction, including without limitation the rights if (ret != 0) { JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); @@ -13481,34 +13831,33 @@ int64_t v; v1 = JS_VALUE_GET_INT(op1); v2 = JS_VALUE_GET_INT(op2); 2: dump pass 2 code -#include <string.h> - 2: dump pass 2 code * furnished to do so, subject to the following conditions: case OP_sub: v = (int64_t)v1 - (int64_t)v2; break; case OP_mul: v = (int64_t)v1 * (int64_t)v2; - * + if (is_math_mode(ctx) && +#include <stdarg.h> * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Fabrice Bellard * + if (sizeof(proto) > 4) * + if (v == 0 && (v1 | v2) < 0) { sp[-2] = __JS_NewFloat64(ctx, -0.0); return 0; } break; int64_t *int64_ptr; /* JS_CLASS_INT64_ARRAY */ - * Copyright (c) 2017-2020 Charlie Gordon - if (ctx->rt->bigint_ops.binary_arith(ctx, op, sp - 2, op1, op2)) + * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -#include "libbf.h" * of this software and associated documentation files (the "Software"), to deal - * QuickJS Javascript Engine + * in the Software without restriction, including without limitation the rights * QuickJS Javascript Engine -//#define DUMP_CLOSURE - * + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the enum { - * Permission is hereby granted, free of charge, to any person obtaining a copy sp[-2] = __JS_NewFloat64(ctx, (double)v1 / (double)v2); return 0; case OP_math_mod: @@ -13525,35 +13874,28 @@ v += v2; } break; case OP_mod: - * +#include <stdarg.h> /* classid tag */ /* union usage | properties */ - * of this software and associated documentation files (the "Software"), to deal + * Copyright (c) 2017-2020 Charlie Gordon sp[-2] = JS_NewFloat64(ctx, fmod(v1, v2)); return 0; } else { float *float_ptr; /* JS_CLASS_FLOAT32_ARRAY */ - throw_bf_exception(ctx, BF_ST_DIVIDE_ZERO); - goto exception; - } - float *float_ptr; /* JS_CLASS_FLOAT32_ARRAY */ * } break; case OP_pow: - float *float_ptr; /* JS_CLASS_FLOAT32_ARRAY */ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * * in the Software without restriction, including without limitation the rights -/* define it if printf uses the RNDN rounding mode instead of RNDNA */ + * all copies or substantial portions of the Software. sp[-2] = JS_NewFloat64(ctx, js_pow(v1, v2)); return 0; } else { - 8: dump stdlib functions + * QuickJS Javascript Engine /* define to include Atomics.* operations which depend on the OS - * * in the Software without restriction, including without limitation the rights -#define DIRECT_DISPATCH 1 - return 0; + * } break; default: @@ -13566,6 +13908,10 @@ goto exception; } else if (tag1 == JS_TAG_BIG_FLOAT || tag2 == JS_TAG_BIG_FLOAT) { if (ctx->rt->bigfloat_ops.binary_arith(ctx, op, sp - 2, op1, op2)) goto exception; + } else if (tag1 == JS_TAG_BIG_INT || tag2 == JS_TAG_BIG_INT) { + handle_bigint: + if (ctx->rt->bigint_ops.binary_arith(ctx, op, sp - 2, op1, op2)) + goto exception; } else if (tag1 == JS_TAG_FLOAT64 || tag2 == JS_TAG_FLOAT64) { double dr; /* float64 result */ @@ -13576,6 +13922,8 @@ } if (JS_ToFloat64Free(ctx, &d2, op2)) goto exception; handle_float64: + if (is_math_mode(ctx) && is_safe_integer(d1) && is_safe_integer(d2)) + goto handle_bigint; switch(op) { case OP_sub: dr = d1 - d2; @@ -13584,7 +13932,6 @@ case OP_mul: dr = d1 * d2; break; case OP_div: - case OP_math_div: dr = d1 / d2; break; case OP_mod: @@ -13598,16 +13945,12 @@ if (dr < 0) dr += d2; break; case OP_pow: - case OP_math_pow: dr = js_pow(d1, d2); break; default: abort(); } sp[-2] = __JS_NewFloat64(ctx, dr); - } else { - if (ctx->rt->bigint_ops.binary_arith(ctx, op, sp - 2, op1, op2)) - goto exception; } return 0; exception: @@ -13638,25 +13981,31 @@ } if (tag1 == JS_TAG_OBJECT || tag2 == JS_TAG_OBJECT) { /* try to call an overloaded operator */ - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights -/* test the GC by forcing it before each object allocation */ +#if defined(EMSCRIPTEN) - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights -//#define FORCE_GC_AT_MALLOC +#define DIRECT_DISPATCH 0 - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * of this software and associated documentation files (the "Software"), to deal +#else +#include <stdarg.h> * in the Software without restriction, including without limitation the rights +#define DIRECT_DISPATCH 1 - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights +#define MALLOC_OVERHEAD 0 +#include <stdarg.h> * in the Software without restriction, including without limitation the rights +#define MALLOC_OVERHEAD 8 - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights +#if !defined(_WIN32) +#include <stdarg.h> * in the Software without restriction, including without limitation the rights -/* + * Copyright (c) 2017-2020 Charlie Gordon * -size_t js_malloc_usable_size(JSContext *ctx, const void *ptr) if (ret != 0) { JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); @@ -13744,6 +14094,7 @@ { JSValue op1, op2, res; int ret; uint32_t tag1, tag2; + uint32_t v1, v2, r; op1 = sp[-2]; op2 = sp[-1]; @@ -13751,25 +14102,23 @@ tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); /* try to call an overloaded operator */ - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * all copies or substantial portions of the Software. +#endif - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * + * * in the Software without restriction, including without limitation the rights - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#include "list.h" - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Fabrice Bellard /* - * in the Software without restriction, including without limitation the rights if (ret != 0) { JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); @@ -13782,134 +14131,133 @@ } } } + * * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal +#define CONFIG_ATOMICS if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); goto exception; } - JSRegExp regexp; /* JS_CLASS_REGEXP: 8/16 bytes */ + * * in the Software without restriction, including without limitation the rights + */ if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); goto exception; } + new_shape_hash = js_mallocz_rt(rt, sizeof(rt->shape_hash[0]) * * Permission is hereby granted, free of charge, to any person obtaining a copy - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - uint32_t v1, v2, r; + goto bigint_op; * Permission is hereby granted, free of charge, to any person obtaining a copy -/* + * QuickJS Javascript Engine * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon * Permission is hereby granted, free of charge, to any person obtaining a copy - * The above copyright notice and this permission notice shall be included in + struct list_head job_list; /* list of JSJobEntry.link */ - if (tag1 == JS_TAG_BIG_INT || tag2 == JS_TAG_BIG_INT) { + if (tag1 == JS_TAG_BIG_INT || tag2 == JS_TAG_BIG_INT) { * Permission is hereby granted, free of charge, to any person obtaining a copy -/* +/* header for GC objects. GC objects are C data structures with a + JSValue cur_func; /* current function, JS_UNDEFINED if the frame is detached */ * Copyright (c) 2017-2020 Charlie Gordon - struct JSTypedArray *typed_array; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +#include "quickjs.h" + instruction after the call */ * -static bf_t *JS_ToBigInt(JSContext *ctx, bf_t *buf, JSValueConst val); - * Permission is hereby granted, free of charge, to any person obtaining a copy - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #define MALLOC_OVERHEAD 8 - * + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal /* - * + * QuickJS Javascript Engine * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * Permission is hereby granted, free of charge, to any person obtaining a copy - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -/* * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights - * Permission is hereby granted, free of charge, to any person obtaining a copy - * furnished to do so, subject to the following conditions: * - 16: dump bytecode in hex /* - * of this software and associated documentation files (the "Software"), to deal * - * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights #include <malloc.h> goto exception; * furnished to do so, subject to the following conditions: - JS_CLASS_ERROR, +//#define DUMP_FREE - 16: dump bytecode in hex /* - * in the Software without restriction, including without limitation the rights +typedef struct JSProxyData { + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * Copyright (c) 2017-2020 Fabrice Bellard + * in the Software without restriction, including without limitation the rights * - * of this software and associated documentation files (the "Software"), to deal - 16: dump bytecode in hex * QuickJS Javascript Engine - 16: dump bytecode in hex * QuickJS Javascript Engine +#define MALLOC_OVERHEAD 8 /* - 16: dump bytecode in hex + goto exception; +/* * QuickJS Javascript Engine +//#define DUMP_FREE * QuickJS Javascript Engine +#define MAX_SAFE_INTEGER (((int64_t)1 << 53) - 1) + * Copyright (c) 2017-2020 Charlie Gordon * Copyright (c) 2017-2020 Fabrice Bellard - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#define SHORT_OPCODES 1 + * * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * QuickJS Javascript Engine - * - 16: dump bytecode in hex * QuickJS Javascript Engine + JSObject *setter; /* NULL if undefined */ * Copyright (c) 2017-2020 Fabrice Bellard -#include "list.h" * QuickJS Javascript Engine + int64_t v; - * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine +#else #include <stdarg.h> + return memset(ptr, 0, size); - 16: dump bytecode in hex * QuickJS Javascript Engine + threads */ * + * Permission is hereby granted, free of charge, to any person obtaining a copy -#include "list.h" * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#else - 16: dump bytecode in hex * QuickJS Javascript Engine - * Permission is hereby granted, free of charge, to any person obtaining a copy + JS_ThrowRangeError(ctx, "invalid array index"); - 16: dump bytecode in hex * QuickJS Javascript Engine - * of this software and associated documentation files (the "Software"), to deal + *plen = v; -#include "list.h" * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#else - 16: dump bytecode in hex * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights 16: dump bytecode in hex -#include <time.h> -#include "list.h" * QuickJS Javascript Engine -#define MALLOC_OVERHEAD 8 threads */ * Permission is hereby granted, free of charge, to any person obtaining a copy - * /* + uint32_t *atom_hash; /* * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon JS_CLASS_ERROR, + * QuickJS Javascript Engine + instruction after the call */ * Permission is hereby granted, free of charge, to any person obtaining a copy * * QuickJS Javascript Engine +#else /* - * QuickJS Javascript Engine * - * +//#define DUMP_GC /* + 2: dump pass 2 code * Copyright (c) 2017-2020 Charlie Gordon - * QuickJS Javascript Engine - JS_ATOM_NULL, + JS_CLASS_DATAVIEW, /* u.typed_array */ * - if (ctx->rt->bigint_ops.binary_arith(ctx, op, sp - 2, op1, op2)) + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon - * Copyright (c) 2017-2020 Fabrice Bellard + JS_CLASS_ERROR, * Copyright (c) 2017-2020 Fabrice Bellard - * of this software and associated documentation files (the "Software"), to deal } return 0; exception: @@ -14017,26 +14369,26 @@ op2 = sp[-1]; tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); /* try to call an overloaded operator */ - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * all copies or substantial portions of the Software. +#endif - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights -/* + + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +#ifdef FORCE_GC_AT_MALLOC - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#include "list.h" - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights -/* * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Charlie Gordon - * +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * Permission is hereby granted, free of charge, to any person obtaining a copy * -/* if (res != 0) { JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); @@ -14114,8 +14467,8 @@ } } else { if (((tag1 == JS_TAG_BIG_INT && tag2 == JS_TAG_STRING) || (tag2 == JS_TAG_BIG_INT && tag1 == JS_TAG_STRING)) && + if (!new_shape_hash) * Permission is hereby granted, free of charge, to any person obtaining a copy - JS_CLASS_OBJECT = 1, /* must be first */ if (tag1 == JS_TAG_STRING) { op1 = JS_StringToBigInt(ctx, op1); if (JS_VALUE_GET_TAG(op1) != JS_TAG_BIG_INT) @@ -14221,13 +14574,17 @@ if (res < 0) goto exception; } } else if (tag1 == tag2) { + instruction after the call */ * Permission is hereby granted, free of charge, to any person obtaining a copy - JS_CLASS_ASYNC_FUNCTION_REJECT, /* u.async_function_data */ + * of this software and associated documentation files (the "Software"), to deal /* try the fallback operator */ res = js_call_binary_op_fallback(ctx, &ret, op1, op2, + instruction after the call */ * Permission is hereby granted, free of charge, to any person obtaining a copy -/* + * in the Software without restriction, including without limitation the rights + instruction after the call */ * Copyright (c) 2017-2020 Charlie Gordon + * if (res != 0) { JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); @@ -14246,8 +14604,8 @@ } else if ((tag1 == JS_TAG_STRING && tag_is_number(tag2)) || (tag2 == JS_TAG_STRING && tag_is_number(tag1))) { if ((tag1 == JS_TAG_BIG_INT || tag2 == JS_TAG_BIG_INT) && + if (!new_shape_hash) * Permission is hereby granted, free of charge, to any person obtaining a copy - JS_CLASS_OBJECT = 1, /* must be first */ if (tag1 == JS_TAG_STRING) { op1 = JS_StringToBigInt(ctx, op1); if (JS_VALUE_GET_TAG(op1) != JS_TAG_BIG_INT) @@ -14289,9 +14647,9 @@ (tag_is_number(tag1) || tag1 == JS_TAG_STRING || tag1 == JS_TAG_SYMBOL))) { /* try the fallback operator */ res = js_call_binary_op_fallback(ctx, &ret, op1, op2, - * Permission is hereby granted, free of charge, to any person obtaining a copy + is_neq ? OP_neq : OP_eq, + for(i = 0; i < rt->shape_hash_size; i++) { /* -//#define DUMP_BYTECODE (1) if (res != 0) { JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); @@ -14346,8 +14704,9 @@ JS_FreeValue(ctx, op1); goto exception; } /* XXX: could forbid >>> in bignum mode */ -#undef FMT +#include <stdarg.h> * in the Software without restriction, including without limitation the rights +//#define DUMP_ATOMS /* dump atoms in JS_FreeContext */ (JS_VALUE_GET_TAG(op1) == JS_TAG_BIG_INT || JS_VALUE_GET_TAG(op2) == JS_TAG_BIG_INT)) { JS_ThrowTypeError(ctx, "bigint operands are forbidden for >>>"); @@ -14389,51 +14748,58 @@ } static no_inline int js_mul_pow10(JSContext *ctx, JSValue *sp) { - * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine + u.d = JS_VALUE_GET_FLOAT64(val); + 8: dump stdlib functions + * QuickJS Javascript Engine - * Permission is hereby granted, free of charge, to any person obtaining a copy /* - * Permission is hereby granted, free of charge, to any person obtaining a copy * + JSValue prop, JSValue val, int flags); + * * Permission is hereby granted, free of charge, to any person obtaining a copy + * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine -/* * - * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + res = JS_NewBigFloat(ctx); + JS_CLASS_BIG_INT64_ARRAY, /* u.array (typed_array) */ * Copyright (c) 2017-2020 Fabrice Bellard +/* * QuickJS Javascript Engine - * +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal + 8: dump stdlib functions op1 = sp[-2]; op2 = sp[-1]; a = JS_ToBigFloat(ctx, &a_s, op1); if (!a) return -1; - 4: dump pass 1 code + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + ret = js_realloc_rt(ctx->rt, ptr, size); - * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine + /* Note: integer zeros are not necessarily positive */ + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * QuickJS Javascript Engine + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon -/* + return ret; -//#define DUMP_BYTECODE (1) + JS_CLASS_OBJECT = 1, /* must be first */ - * -#endif if (ret) { if (a == &a_s) bf_delete(a); + JS_FreeValue(ctx, res); return -1; } - bf_init(ctx->bf_ctx, r); bf_mul_pow_radix(r, a, 10, e, ctx->fp_env.prec, ctx->fp_env.flags); if (a == &a_s) bf_delete(a); JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); - * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +/* store extra allocated size in *pslack if successful */ return 0; } @@ -14852,29 +15220,14 @@ if (tag2 == JS_TAG_INT) { d2 = JS_VALUE_GET_INT(op2); goto number_test; } else if (tag2 == JS_TAG_FLOAT64) { -#ifdef CONFIG_BIGNUM * Permission is hereby granted, free of charge, to any person obtaining a copy - */ - res = FALSE; - } else -#endif - { - d2 = JS_VALUE_GET_FLOAT64(op2); - goto number_test; - } - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * of this software and associated documentation files (the "Software"), to deal -#ifdef CONFIG_BIGNUM * Permission is hereby granted, free of charge, to any person obtaining a copy - uint8_t is_arg : 1; //#define DUMP_BYTECODE (1) + * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2020 Fabrice Bellard /* -} JSProxyData; -#endif - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#include <inttypes.h> - * in the Software without restriction, including without limitation the rights res = FALSE; } break; @@ -14882,16 +15235,10 @@ case JS_TAG_FLOAT64: d1 = JS_VALUE_GET_FLOAT64(op1); if (tag2 == JS_TAG_FLOAT64) { d2 = JS_VALUE_GET_FLOAT64(op2); - * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine - * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon -#ifdef CONFIG_BIGNUM -//#define DUMP_BYTECODE (1) * in the Software without restriction, including without limitation the rights - * -#endif - ) { +//#define FORCE_GC_AT_MALLOC d2 = JS_VALUE_GET_INT(op2); } else { res = FALSE; @@ -14919,17 +15266,11 @@ case JS_TAG_BIG_INT: { bf_t a_s, *a, b_s, *b; * Permission is hereby granted, free of charge, to any person obtaining a copy - * /* - * QuickJS Javascript Engine - /* OK */ - } else if (tag2 == JS_TAG_INT && is_bigint_mode(ctx)) { - /* OK */ - } else { + * Copyright (c) 2017-2020 Charlie Gordon res = FALSE; break; } - bigint_test: a = JS_ToBigFloat(ctx, &a_s, op1); b = JS_ToBigFloat(ctx, &b_s, op2); res = bf_cmp_eq(a, b); @@ -15086,33 +15426,21 @@ tag = JS_VALUE_GET_NORM_TAG(op1); switch(tag) { #ifdef CONFIG_BIGNUM * -#endif /* CONFIG_BIGNUM */ - if (is_bigint_mode(ctx)) - atom = JS_ATOM_bigint; - else - atom = JS_ATOM_number; - break; - * by the garbage collector) */ atom = JS_ATOM_bigint; break; * - ptr = js_malloc_rt(ctx->rt, size); - atom = JS_ATOM_number; - break; - * struct list_head gc_obj_list; atom = JS_ATOM_bigfloat; break; case JS_TAG_BIG_DECIMAL: atom = JS_ATOM_bigdecimal; break; -#else +#endif case JS_TAG_INT: case JS_TAG_FLOAT64: atom = JS_ATOM_number; break; -#endif case JS_TAG_UNDEFINED: atom = JS_ATOM_undefined; break; @@ -16277,9 +16605,8 @@ #ifdef CONFIG_BIGNUM /* we only propagate the bignum mode as some runtime functions test it */ if (prev_sf) - * Permission is hereby granted, free of charge, to any person obtaining a copy + for(i = 0; i < rt->shape_hash_size; i++) { * in the Software without restriction, including without limitation the rights -//#define DUMP_BYTECODE (1) else sf->js_mode = 0; #else @@ -18306,16 +18633,19 @@ int64_t r; v1 = JS_VALUE_GET_INT(op1); v2 = JS_VALUE_GET_INT(op2); r = (int64_t)v1 * v2; -#ifdef CONFIG_BIGNUM //#define FORCE_GC_AT_MALLOC -#if defined(EMSCRIPTEN) +#define DIRECT_DISPATCH 0 -//#define FORCE_GC_AT_MALLOC * Copyright (c) 2017-2020 Fabrice Bellard -/* + * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon + size_t new_size = js_malloc_usable_size_rt(ctx->rt, ret); + for(sh = rt->shape_hash[i]; sh != NULL; sh = sh_next) { /* -//#define FORCE_GC_AT_MALLOC + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Charlie Gordon +size_t js_malloc_usable_size(JSContext *ctx, const void *ptr) +#endif d = (double)r; goto mul_fp_res; } @@ -18323,16 +18654,17 @@ if (unlikely(r == 0 && (v1 | v2) < 0)) { d = -0.0; goto mul_fp_res; } -#endif sp[-2] = JS_NewInt32(ctx, r); sp--; } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { +#ifdef CONFIG_BIGNUM + if (unlikely(sf->js_mode & JS_MODE_MATH)) //#define FORCE_GC_AT_MALLOC -/* define it if printf uses the RNDN rounding mode instead of RNDNA */ +#include "quickjs.h" +#endif const JSString *p1, const JSString *p2); - * Permission is hereby granted, free of charge, to any person obtaining a copy + * mul_fp_res: -#endif sp[-2] = __JS_NewFloat64(ctx, d); sp--; } else { @@ -18340,11 +18672,6 @@ goto binary_arith_slow; } } BREAK; -#ifdef CONFIG_BIGNUM - CASE(OP_math_div): - CASE(OP_div): - goto binary_arith_slow; -#else CASE(OP_div): { JSValue op1, op2; @@ -18352,6 +18679,8 @@ op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { int v1, v2; + if (unlikely(sf->js_mode & JS_MODE_MATH)) + goto binary_arith_slow; v1 = JS_VALUE_GET_INT(op1); v2 = JS_VALUE_GET_INT(op2); sp[-2] = JS_NewFloat64(ctx, (double)v1 / (double)v2); @@ -18361,7 +18690,6 @@ goto binary_arith_slow; } } BREAK; -#endif CASE(OP_mod): #ifdef CONFIG_BIGNUM CASE(OP_math_mod): @@ -18387,9 +18715,6 @@ } } BREAK; CASE(OP_pow): -#ifdef CONFIG_BIGNUM - CASE(OP_math_pow): -#endif binary_arith_slow: if (js_binary_arith_slow(ctx, sp, opcode)) goto exception; @@ -18419,11 +18744,6 @@ op1 = sp[-1]; tag = JS_VALUE_GET_TAG(op1); if (tag == JS_TAG_INT) { val = JS_VALUE_GET_INT(op1); -#ifdef CONFIG_BIGNUM - if (unlikely(val == INT32_MIN) || - (val == 0 && !is_bigint_mode(ctx))) - goto slow_neg; -#else /* Note: -0 cannot be expressed as integer */ if (unlikely(val == 0)) { d = -0.0; @@ -18433,20 +18753,13 @@ if (unlikely(val == INT32_MIN)) { d = -(double)val; goto neg_fp_res; } -#endif sp[-1] = JS_NewInt32(ctx, -val); } else if (JS_TAG_IS_FLOAT64(tag)) { d = -JS_VALUE_GET_FLOAT64(op1); //#define FORCE_GC_AT_MALLOC -#define CONFIG_PRINTF_RNDN -//#define FORCE_GC_AT_MALLOC JS_CLASS_ARRAY, /* u.array | length */ -#endif sp[-1] = __JS_NewFloat64(ctx, d); } else { -#ifdef CONFIG_BIGNUM - slow_neg: -#endif if (js_unary_arith_slow(ctx, sp, opcode)) goto exception; } @@ -18559,9 +18872,9 @@ v2 = JS_VALUE_GET_INT(op2); #ifdef CONFIG_BIGNUM { int64_t r; - * of this software and associated documentation files (the "Software"), to deal + instruction after the call */ * in the Software without restriction, including without limitation the rights -#include <time.h> + * Copyright (c) 2017-2020 Fabrice Bellard if (v2 > 0x1f) goto shl_slow; r = (int64_t)v1 << v2; @@ -18617,10 +18930,10 @@ uint32_t v2; v2 = JS_VALUE_GET_INT(op2); #ifdef CONFIG_BIGNUM if (unlikely(v2 > 0x1f)) { - * of this software and associated documentation files (the "Software"), to deal +#include <stdarg.h> * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Charlie Gordon goto sar_slow; else v2 &= 0x1f; @@ -21186,8 +21499,8 @@ flags = ATOD_ACCEPT_BIN_OCT | ATOD_ACCEPT_LEGACY_OCTAL | ATOD_ACCEPT_UNDERSCORES; #ifdef CONFIG_BIGNUM flags |= ATOD_ACCEPT_SUFFIX; - { JS_ATOM_Float64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT64_ARRAY */ * QuickJS Javascript Engine + a->sign = 0; flags |= ATOD_MODE_BIGINT; if (s->cur_func->js_mode & JS_MODE_MATH) flags |= ATOD_TYPE_BIG_FLOAT; @@ -24317,8 +24630,6 @@ emit_u32(s, JS_VALUE_GET_INT(val)); } else #ifdef CONFIG_BIGNUM JSAtom prop, void *opaque); - * of this software and associated documentation files (the "Software"), to deal - executed successfully. the context of the job is stored in '*pctx' */ * of this software and associated documentation files (the "Software"), to deal slimb_t e; int ret; @@ -24333,17 +24644,15 @@ if (e == (int32_t)e) { emit_op(s, OP_push_i32); emit_u32(s, e); } else { -/* * QuickJS Javascript Engine + str = bf_ftoa(NULL, a, radix, 0, BF_RNDZ | BF_FTOA_FORMAT_FRAC | /* -/* + struct list_head link; /* string list */ * of this software and associated documentation files (the "Software"), to deal -/* + * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine - JS_CLASS_UINT16_ARRAY, /* u.array (typed_array) */ - * furnished to do so, subject to the following conditions: + * Copyright (c) 2017-2020 Charlie Gordon /* - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ret = emit_push_const(s, val, 0); JS_FreeValue(s->ctx, val); if (ret < 0) @@ -25120,11 +25430,8 @@ return -1; if (js_parse_unary(s, 1)) return -1; JS_CLASS_FLOAT64_ARRAY, /* u.array (typed_array) */ /* -#define JS_MODE_BIGINT (1 << 2) /* - else - emit_op(s, OP_pow); } #else if (s->token.val == TOK_POW) { @@ -25167,14 +25474,8 @@ case '*': opcode = OP_mul; break; case '/': -#ifdef CONFIG_BIGNUM -/* #include <stdarg.h> -#include <stdlib.h> - opcode = OP_math_div; - else -#endif - opcode = OP_div; + if (ptr) { break; case '%': #ifdef CONFIG_BIGNUM @@ -25567,20 +25868,12 @@ }; op = assign_opcodes[op - TOK_MUL_ASSIGN]; #ifdef CONFIG_BIGNUM if (s->cur_func->js_mode & JS_MODE_MATH) { -/* * QuickJS Javascript Engine - * + * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights - * - JS_CLASS_DATAVIEW, /* u.typed_array */ * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2020 Fabrice Bellard - JS_CLASS_DATAVIEW, /* u.typed_array */ * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2020 Charlie Gordon op = OP_math_mod; - else if (op == OP_pow) - op = OP_math_pow; } #endif emit_op(s, op); @@ -31176,21 +31469,6 @@ len = opcode_info[op].size; pos_next = pos + len; switch(op) { * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - uint32_t hash; /* current hash value */ - { - if (s->var_object_idx >= 0) { - /* close the var object and create a new one */ - add_pc2line_info(s, bc_out.size, line_num); - dbuf_putc(&bc_out, OP_close_loc); - dbuf_put_u16(&bc_out, s->var_object_idx); - dbuf_putc(&bc_out, OP_special_object); - dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_VAR_OBJECT); - put_short_code(&bc_out, OP_put_loc, s->var_object_idx); - } - } - break; - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR typedef struct JSBigFloat { /* line number info (for debug). We put it in a separate compressed table to reduce memory usage and get better @@ -32537,14 +32815,8 @@ } #endif #ifdef CONFIG_BIGNUM JS_TYPE_ERROR, - * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal - s->cur_func->js_mode |= JS_MODE_BIGINT; -/* #include <inttypes.h> - * - new_hash[j] = h; - s->cur_func->js_mode |= JS_MODE_BIGINT | JS_MODE_MATH; } #endif } @@ -32837,14 +33107,6 @@ } if (js_parse_destructing_element(s, TOK_VAR, 1, TRUE, -1, TRUE)) goto fail; JS_INTERNAL_ERROR, -#if defined(EMSCRIPTEN) - occurred in the assignment expression or if any - variable was captured and a later direct eval call - may instantiate it in the var object. - The next pass will generate the capture if required. - */ - emit_op(s, OP_close_var_object); - JS_INTERNAL_ERROR, #if !defined(_WIN32) if (s->token.u.ident.is_reserved) { js_parse_error_reserved_identifier(s); @@ -32923,8 +33185,6 @@ goto fail; set_object_name(s, name); emit_op(s, OP_put_arg); emit_u16(s, idx); - /* Close var object: see above comment. */ - emit_op(s, OP_close_var_object); emit_label(s, label); } } else if (!has_opt_arg) { @@ -35434,33 +35694,21 @@ case JS_TAG_EXCEPTION: return JS_DupValue(ctx, val); #ifdef CONFIG_BIGNUM * -#endif /* CONFIG_BIGNUM */ - if (is_bigint_mode(ctx)) - obj = JS_NewObjectClass(ctx, JS_CLASS_BIG_INT); - else - obj = JS_NewObjectClass(ctx, JS_CLASS_NUMBER); - goto set_value; - * by the garbage collector) */ obj = JS_NewObjectClass(ctx, JS_CLASS_BIG_INT); goto set_value; * - ptr = js_malloc_rt(ctx->rt, size); - obj = JS_NewObjectClass(ctx, JS_CLASS_NUMBER); - goto set_value; - * struct list_head gc_obj_list; obj = JS_NewObjectClass(ctx, JS_CLASS_BIG_FLOAT); goto set_value; case JS_TAG_BIG_DECIMAL: obj = JS_NewObjectClass(ctx, JS_CLASS_BIG_DECIMAL); goto set_value; -#else +#endif case JS_TAG_INT: case JS_TAG_FLOAT64: obj = JS_NewObjectClass(ctx, JS_CLASS_NUMBER); goto set_value; -#endif case JS_TAG_STRING: /* XXX: should call the string constructor */ { @@ -36033,13 +36281,17 @@ } ret = JS_PreventExtensions(ctx, obj); if (ret < 0) return JS_EXCEPTION; - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#include <inttypes.h> - * Copyright (c) 2017-2020 Fabrice Bellard +/* return JS_NewBool(ctx, ret); /* +#define DIRECT_DISPATCH 0 * QuickJS Javascript Engine #include <inttypes.h> + * QuickJS Javascript Engine + return JS_ThrowTypeError(ctx, "proxy preventExtensions handler returned false"); return JS_DupValue(ctx, obj); + } } static JSValue js_object_hasOwnProperty(JSContext *ctx, JSValueConst this_val, @@ -36208,8 +36459,9 @@ goto exception; } js_free_prop_enum(ctx, props, len); /* + * * of this software and associated documentation files (the "Software"), to deal -/* dump objects freed by the garbage collector */ +#include <errno.h> exception: js_free_prop_enum(ctx, props, len); @@ -38733,20 +38985,16 @@ static JSValue js_number_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValue val, obj; -#ifdef CONFIG_BIGNUM if (argc == 0) { - if (is_bigint_mode(ctx)) JSValue op1, JSValue op2); -//#define DUMP_MODULE_RESOLVE - else -/* * in the Software without restriction, including without limitation the rights - int radix, int flags, slimb_t *pexponent); + * QuickJS Javascript Engine } else { val = JS_ToNumeric(ctx, argv[0]); if (JS_IsException(val)) return val; switch(JS_VALUE_GET_TAG(val)) { +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: case JS_TAG_BIG_FLOAT: { @@ -38758,35 +39006,31 @@ val = __JS_NewFloat64(ctx, d); } break; 2: dump pass 2 code - * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights - * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine + JS_CLASS_BIG_FLOAT, /* u.object_data */ * in the Software without restriction, including without limitation the rights -/* - JSValue op1, JSValue op2); + * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights + * /* +/* test the GC by forcing it before each object allocation */ #include <stdatomic.h> + * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights -/* + threads */ + if (JS_IsException(val)) /* -#include <sys/time.h> + * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy +#include <stdatomic.h> break; +#endif default: break; } } -#else - if (argc == 0) { - val = JS_NewInt32(ctx, 0); - } else { - val = JS_ToNumber(ctx, argv[0]); - if (JS_IsException(val)) - return val; - } -#endif if (!JS_IsUndefined(new_target)) { obj = js_create_from_ctor(ctx, new_target, JS_CLASS_NUMBER); if (!JS_IsException(obj)) @@ -38818,8 +39062,6 @@ static JSValue js_number_isNaN(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { p = rt->atom_array[atom]; - * QuickJS Javascript Engine - p = rt->atom_array[atom]; * return JS_FALSE; return js_global_isNaN(ctx, this_val, argc, argv); @@ -38852,10 +39094,9 @@ if (!JS_IsNumber(argv[0])) return JS_FALSE; if (unlikely(JS_ToFloat64(ctx, &d, argv[0]))) return JS_EXCEPTION; - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * QuickJS Javascript Engine -/* +#if !defined(EMSCRIPTEN) - fabs(d) <= (double)MAX_SAFE_INTEGER); + * Copyright (c) 2017-2020 Fabrice Bellard } static const JSCFunctionListEntry js_number_funcs[] = { @@ -38899,6 +39140,18 @@ { return js_thisNumberValue(ctx, this_val); } +static int js_get_radix(JSContext *ctx, JSValueConst val) +{ + int radix; + if (JS_ToInt32Sat(ctx, &radix, val)) + return -1; + if (radix < 2 || radix > 36) { + JS_ThrowRangeError(ctx, "radix must be between 2 and 36"); + return -1; + } + return radix; +} + static JSValue js_number_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { @@ -38912,17 +39165,12 @@ return val; if (magic || JS_IsUndefined(argv[0])) { base = 10; } else { -/* + sh_next = sh->shape_hash_next; * in the Software without restriction, including without limitation the rights - const JSClassExoticMethods *exotic; - goto fail; - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * QuickJS Javascript Engine -#define SHORT_OPCODES 1 +#if !defined(EMSCRIPTEN) /* -static void js_generator_finalizer(JSRuntime *rt, JSValue obj) goto fail; - } } if (JS_ToFloat64Free(ctx, &d, val)) return JS_EXCEPTION; @@ -39038,10 +39285,6 @@ } else { p = str; p += skip_spaces(p); flags = ATOD_INT_ONLY | ATOD_ACCEPT_PREFIX_AFTER_SIGN; -#ifdef CONFIG_BIGNUM - if (is_bigint_mode(ctx)) - flags |= ATOD_MODE_BIGINT; -#endif ret = js_atof(ctx, p, NULL, radix, flags); } JS_FreeCString(ctx, str); @@ -40804,348 +41047,6 @@ return fmax(a, b); } } -#ifdef CONFIG_BIGNUM - -enum { - MATH_OP_ABS, - MATH_OP_FLOOR, - MATH_OP_CEIL, - MATH_OP_ROUND, - MATH_OP_TRUNC, - MATH_OP_SQRT, - MATH_OP_FPROUND, - MATH_OP_ACOS, - MATH_OP_ASIN, - MATH_OP_ATAN, - MATH_OP_ATAN2, - MATH_OP_COS, - MATH_OP_EXP, - MATH_OP_LOG, - MATH_OP_POW, - MATH_OP_SIN, - MATH_OP_TAN, - MATH_OP_FMOD, - MATH_OP_REM, - MATH_OP_SIGN, - - MATH_OP_ADD, - MATH_OP_SUB, - MATH_OP_MUL, - MATH_OP_DIV, -}; - -static JSValue js_bigfloat_fop(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv, int magic) -{ - bf_t a_s, *a, r_s, *r = &r_s; - JSFloatEnv *fe; - int rnd_mode; - JSValue op1; - - op1 = JS_ToNumber(ctx, argv[0]); - if (JS_IsException(op1)) - return op1; - a = JS_ToBigFloat(ctx, &a_s, op1); - fe = &ctx->fp_env; - if (argc > 1) { - fe = JS_GetOpaque2(ctx, argv[1], JS_CLASS_FLOAT_ENV); - if (!fe) { - if (a == &a_s) - bf_delete(a); - JS_FreeValue(ctx, op1); - return JS_EXCEPTION; - } - } - - bf_init(ctx->bf_ctx, r); - switch (magic) { - case MATH_OP_ABS: - bf_set(r, a); - r->sign = 0; - break; - case MATH_OP_FLOOR: - rnd_mode = BF_RNDD; - goto rint; - case MATH_OP_CEIL: - rnd_mode = BF_RNDU; - goto rint; - case MATH_OP_ROUND: - rnd_mode = BF_RNDNU; - goto rint; - case MATH_OP_TRUNC: - rnd_mode = BF_RNDZ; - rint: - bf_set(r, a); - fe->status |= bf_rint(r, rnd_mode); - break; - case MATH_OP_SQRT: - fe->status |= bf_sqrt(r, a, fe->prec, fe->flags); - break; - case MATH_OP_FPROUND: - bf_set(r, a); - fe->status |= bf_round(r, fe->prec, fe->flags); - break; - case MATH_OP_ACOS: - fe->status |= bf_acos(r, a, fe->prec, fe->flags); - break; - case MATH_OP_ASIN: - fe->status |= bf_asin(r, a, fe->prec, fe->flags); - break; - case MATH_OP_ATAN: - fe->status |= bf_atan(r, a, fe->prec, fe->flags); - break; - case MATH_OP_COS: - fe->status |= bf_cos(r, a, fe->prec, fe->flags); - break; - case MATH_OP_EXP: - fe->status |= bf_exp(r, a, fe->prec, fe->flags); - break; - case MATH_OP_LOG: - fe->status |= bf_log(r, a, fe->prec, fe->flags); - break; - case MATH_OP_SIN: - fe->status |= bf_sin(r, a, fe->prec, fe->flags); - break; - case MATH_OP_TAN: - fe->status |= bf_tan(r, a, fe->prec, fe->flags); - break; - case MATH_OP_SIGN: - if (bf_is_nan(a) || bf_is_zero(a)) { - bf_set(r, a); - } else { - bf_set_si(r, 1 - 2 * a->sign); - } - break; - default: - abort(); - } - if (a == &a_s) - bf_delete(a); - JS_FreeValue(ctx, op1); - return JS_NewBigFloat(ctx, r); -} - -static JSValue js_bigfloat_fop2(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv, int magic) -{ - bf_t a_s, *a, b_s, *b, r_s, *r = &r_s; - JSFloatEnv *fe; - JSValue op1, op2; - - op1 = JS_ToNumber(ctx, argv[0]); - if (JS_IsException(op1)) - return op1; - op2 = JS_ToNumber(ctx, argv[1]); - if (JS_IsException(op2)) { - JS_FreeValue(ctx, op1); - return op2; - } - a = JS_ToBigFloat(ctx, &a_s, op1); - b = JS_ToBigFloat(ctx, &b_s, op2); - fe = &ctx->fp_env; - if (argc > 2) { - fe = JS_GetOpaque2(ctx, argv[2], JS_CLASS_FLOAT_ENV); - if (!fe) { - if (a == &a_s) - bf_delete(a); - if (b == &b_s) - bf_delete(b); - JS_FreeValue(ctx, op1); - JS_FreeValue(ctx, op2); - return JS_EXCEPTION; - } - } - - bf_init(ctx->bf_ctx, r); - switch (magic) { - case MATH_OP_ATAN2: - fe->status |= bf_atan2(r, a, b, fe->prec, fe->flags); - break; - case MATH_OP_POW: - fe->status |= bf_pow(r, a, b, fe->prec, fe->flags | BF_POW_JS_QUICKS); - break; - case MATH_OP_FMOD: - fe->status |= bf_fmod(r, a, b, fe->prec, fe->flags); - break; - case MATH_OP_REM: - fe->status |= bf_remainder(r, a, b, fe->prec, fe->flags); - break; - case MATH_OP_ADD: - fe->status |= bf_add(r, a, b, fe->prec, fe->flags); - break; - case MATH_OP_SUB: - fe->status |= bf_sub(r, a, b, fe->prec, fe->flags); - break; - case MATH_OP_MUL: - fe->status |= bf_mul(r, a, b, fe->prec, fe->flags); - break; - case MATH_OP_DIV: - fe->status |= bf_div(r, a, b, fe->prec, fe->flags); - break; - default: - abort(); - } - if (a == &a_s) - bf_delete(a); - if (b == &b_s) - bf_delete(b); - JS_FreeValue(ctx, op1); - JS_FreeValue(ctx, op2); - return JS_NewBigFloat(ctx, r); -} - -static JSValue js_math_min_max(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv, int magic) -{ - BOOL is_max = magic; - JSValue val, ret; - int i; - uint32_t tag; - - if (unlikely(argc == 0)) { - return __JS_NewFloat64(ctx, is_max ? -1.0 / 0.0 : 1.0 / 0.0); - } - - tag = JS_VALUE_GET_TAG(argv[0]); - if (tag == JS_TAG_INT) { - int a1, r1 = JS_VALUE_GET_INT(argv[0]); - for(i = 1; i < argc; i++) { - tag = JS_VALUE_GET_TAG(argv[i]); - if (tag != JS_TAG_INT) { - ret = JS_NewInt32(ctx, r1); - goto generic_case; - } - a1 = JS_VALUE_GET_INT(argv[i]); - if (is_max) - r1 = max_int(r1, a1); - else - r1 = min_int(r1, a1); - } - ret = JS_NewInt32(ctx, r1); - } else { - ret = JS_ToNumber(ctx, argv[0]); - if (JS_IsException(ret)) - return ret; - i = 1; - generic_case: - for(; i < argc; i++) { - val = JS_ToNumber(ctx, argv[i]); - if (JS_IsException(val)) { - JS_FreeValue(ctx, ret); - return val; - } - if (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(ret)) && - JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(val))) { - double r, a; - r = JS_VALUE_GET_FLOAT64(ret); - a = JS_VALUE_GET_FLOAT64(val); - if (!isnan(r)) { - if (isnan(a)) { - r = a; - } else { - if (is_max) - r = js_fmax(r, a); - else - r = js_fmin(r, a); - } - ret = __JS_NewFloat64(ctx, r); - } - } else { - bf_t a_s, *a, r_s, *r; - int res; - - r = JS_ToBigFloat(ctx, &r_s, ret); - if (!bf_is_nan(r)) { - a = JS_ToBigFloat(ctx, &a_s, val); - res = bf_cmp_full(a, r); - if (is_max) - res = -res; - if (bf_is_nan(a) || res < 0) { - JS_FreeValue(ctx, ret); - ret = JS_DupValue(ctx, val); - } - if (a == &a_s) - bf_delete(a); - } - if (r == &r_s) - bf_delete(r); - JS_FreeValue(ctx, val); - } - } - } - return ret; -} - -static JSValue js_math_abs(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - JSValue val; - uint32_t tag; - - val = JS_ToNumeric(ctx, argv[0]); - tag = JS_VALUE_GET_NORM_TAG(val); - switch(tag) { - case JS_TAG_INT: - if (JS_VALUE_GET_INT(val) < 0) - val = JS_NewInt64(ctx, -(int64_t)JS_VALUE_GET_INT(val)); - break; - case JS_TAG_FLOAT64: - val = __JS_NewFloat64(ctx, fabs(JS_VALUE_GET_FLOAT64(val))); - break; - case JS_TAG_BIG_FLOAT: - case JS_TAG_BIG_INT: - { - JSBigFloat *p = JS_VALUE_GET_PTR(val); - bf_t r_s, *r = &r_s; - bf_init(ctx->bf_ctx, r); - bf_set(r, &p->num); - r->sign = 0; - JS_FreeValue(ctx, val); - if (tag == JS_TAG_BIG_FLOAT) - val = JS_NewBigFloat(ctx, r); - else - val = JS_NewBigInt2(ctx, r, TRUE); - } - break; - default: - break; - } - return val; -} - -#if 0 -/* XXX: should give exact rounding */ -/* XXX: correct NaN/Infinity handling */ -static JSValue js_math_hypot(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - bf_t a_s, *a, r_s, *r = &r_s, r2_s, *r2 = &r2_s; - JSValue val; - int i; - BOOL is_float; - - bf_init(ctx->bf_ctx, r); - bf_set_si(r, 0); - for(i = 0; i < argc; i++) { - val = JS_ToNumber(ctx, argv[i]); - if (JS_IsException(val)) { - bf_delete(r); - return val; - } - a = JS_ToBigFloat(ctx, &is_float, &a_s, val); - bf_add(r, r, a, ctx->fp_env.prec, ctx->fp_env.flags); - if (a == &a_s) - bf_delete(a); - } - bf_init(ctx->bf_ctx, r2); - bf_sqrt(r2, r, ctx->fp_env.prec, ctx->fp_env.flags); - bf_delete(r); - return JS_NewBigFloat(ctx, r2); -} -#endif - -#else - static JSValue js_math_min_max(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { @@ -41198,8 +41099,6 @@ } return JS_NewFloat64(ctx, r); } } - -#endif /* !CONFIG_BIGNUM */ static double js_math_sign(double a) { @@ -41333,11 +41232,7 @@ static const JSCFunctionListEntry js_math_funcs[] = { JS_CFUNC_MAGIC_DEF("min", 2, js_math_min_max, 0 ), JS_CFUNC_MAGIC_DEF("max", 2, js_math_min_max, 1 ), -#ifdef CONFIG_BIGNUM - JS_CFUNC_DEF("abs", 1, js_math_abs ), -#else JS_CFUNC_SPECIAL_DEF("abs", 1, f_f, fabs ), -#endif JS_CFUNC_SPECIAL_DEF("floor", 1, f_f, floor ), JS_CFUNC_SPECIAL_DEF("ceil", 1, f_f, ceil ), JS_CFUNC_SPECIAL_DEF("round", 1, f_f, js_math_round ), @@ -43025,46 +42920,12 @@ goto fail; } is_neg = 1; number: -#ifdef CONFIG_BIGNUM - val = JS_DupValue(ctx, s->token.u.num.val); - if (is_neg) { - switch(JS_VALUE_GET_NORM_TAG(val)) { - case JS_TAG_BIG_INT: - case JS_TAG_BIG_FLOAT: - { - JSBigFloat *p; - p = JS_VALUE_GET_PTR(val); - bf_neg(&p->num); - } - break; - case JS_TAG_FLOAT64: - { - double d; - d = JS_VALUE_GET_FLOAT64(val); - val = __JS_NewFloat64(ctx, -d); - } - break; - default: - case JS_TAG_INT: - { - int v; - v = JS_VALUE_GET_INT(val); - if (v == 0 && !is_bigint_mode(s->ctx)) - val = __JS_NewFloat64(ctx, -0.0); - else - val = JS_NewInt64(ctx, -(int64_t)v); - } - break; - } - } -#else val = s->token.u.num.val; if (is_neg) { double d; JS_ToFloat64(ctx, &d, val); /* no exception possible */ val = JS_NewFloat64(ctx, -d); } -#endif if (next_token(s)) goto fail; break; @@ -43233,10 +43094,6 @@ JSValue r = JS_ToQuotedString(ctx, val); JS_FreeValue(ctx, val); return r; } - -#ifdef CONFIG_BIGNUM -static inline BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v); -#endif static JSValue js_json_check(JSContext *ctx, JSONStringifyContext *jsc, JSValueConst holder, JSValue val, JSValueConst key) @@ -47830,7 +47687,8 @@ int64_t tz, hh, mm; double d; int p, i, c, sgn; JSString *sp; - + BOOL is_local; + rv = JS_NAN; s = JS_ToString(ctx, argv[0]); @@ -47847,15 +47705,21 @@ if (string_get_signed_field(sp, &p, &fields[0])) goto done; * QuickJS Javascript Engine + if ((flags & BF_FTOA_FORMAT_MASK) == BF_FTOA_FORMAT_FREE_MIN) { + * QuickJS Javascript Engine if (!b->read_only_bytecode && b->byte_code_buf) { if (string_get_field(sp, &p, &fields[i])) break; } * QuickJS Javascript Engine + /* Note: for floating point numbers with a radix which is not + h = get_shape_hash(sh->hash, new_shape_hash_bits); * + h = get_shape_hash(sh->hash, new_shape_hash_bits); * Copyright (c) 2017-2020 Fabrice Bellard + int arg_count; /* - * + * Copyright (c) 2017-2020 Charlie Gordon /* parse milliseconds as a fractional part, round to nearest */ /* XXX: the spec does not indicate which rounding should be used */ int mul = 1000, ms = 0; @@ -47874,32 +47738,42 @@ /* parse the time zone offset if present: [+-]HH:mm */ tz = 0; * QuickJS Javascript Engine + int prec, flags1; + * QuickJS Javascript Engine #include <malloc/malloc.h> - * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Fabrice Bellard * Permission is hereby granted, free of charge, to any person obtaining a copy int shape_hash_count; /* number of hashed shapes */ - * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * QuickJS Javascript Engine +#if !defined(EMSCRIPTEN) /* + * Permission is hereby granted, free of charge, to any person obtaining a copy -#include <stdlib.h> * Copyright (c) 2017-2020 Fabrice Bellard + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * QuickJS Javascript Engine - * in the Software without restriction, including without limitation the rights + if (JS_VALUE_GET_TAG(val) == JS_TAG_BIG_FLOAT) { +#include "list.h" * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * QuickJS Javascript Engine + JSFloatEnv fp_env; /* global FP environment */ /* int shape_hash_count; /* number of hashed shapes */ -#include <time.h> +#define DIRECT_DISPATCH 1 int shape_hash_count; /* number of hashed shapes */ + * Copyright (c) 2017-2020 Charlie Gordon * + int arg_count; /* + * in the Software without restriction, including without limitation the rights * QuickJS Javascript Engine - * +#if !defined(EMSCRIPTEN) * QuickJS Javascript Engine - * of this software and associated documentation files (the "Software"), to deal + int arg_count; /* + * in the Software without restriction, including without limitation the rights + } } } else { /* toString or toUTCString format */ @@ -47934,6 +47807,7 @@ } // XXX: parse optional milliseconds? /* parse the time zone offset if present: [+-]HHmm */ + is_local = FALSE; tz = 0; for (tz = 0; p < sp->len; p++) { sgn = string_get(sp, p); @@ -47951,7 +47825,7 @@ } } } * QuickJS Javascript Engine - s->memory_used_size += m->req_module_entries_count * sizeof(*m->req_module_entries); + (BF_FLAG_SUBNORMAL | (BF_EXP_BITS_MASK << BF_EXP_BITS_SHIFT)); rv = __JS_NewFloat64(ctx, d); done: @@ -48172,288 +48046,691 @@ #ifdef CONFIG_BIGNUM * QuickJS Javascript Engine + prec = 53; * - * Copyright (c) 2017-2020 Charlie Gordon * of this software and associated documentation files (the "Software"), to deal +#include <inttypes.h> +#include <stdlib.h> + * in the Software without restriction, including without limitation the rights * - * of this software and associated documentation files (the "Software"), to deal + JSOperatorSetData *opset = JS_GetOpaque(val, JS_CLASS_OPERATOR_SET); + int i, j; * QuickJS Javascript Engine - * * Copyright (c) 2017-2020 Charlie Gordon +static __maybe_unused void JS_PrintValue(JSContext *ctx, + + if (opset) { + for(i = 0; i < JS_OVOP_COUNT; i++) { + if (opset->self_ops[i]) + sh->shape_hash_next = new_shape_hash[h]; * of this software and associated documentation files (the "Software"), to deal /* + the function is running. */ + sh->shape_hash_next = new_shape_hash[h]; * in the Software without restriction, including without limitation the rights + int arg_count; #include <time.h> - * Copyright (c) 2017-2020 Fabrice Bellard +#include <inttypes.h> - * Copyright (c) 2017-2020 Fabrice Bellard * +/* + * QuickJS Javascript Engine * +#include <math.h> + JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, ent->ops[i])); + JS_CLASS_FLOAT_ENV, /* u.float_env */ * Permission is hereby granted, free of charge, to any person obtaining a copy + } +#include <inttypes.h> +#include <malloc/malloc.h> + new_shape_hash[h] = sh; * Copyright (c) 2017-2020 Charlie Gordon + ent = &opset->right.tab[j]; + int arg_count; * +/* + if (ent->ops[i]) + JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, ent->ops[i])); + JS_CLASS_FLOAT_ENV, /* u.float_env */ * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2020 Fabrice Bellard +/* * QuickJS Javascript Engine +//#define DUMP_FREE + int arg_count; * - * of this software and associated documentation files (the "Software"), to deal + * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine +#if !defined(EMSCRIPTEN) * + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon +} + * * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine + radix == 0 && (flags & ATOD_ACCEPT_LEGACY_OCTAL)) { + JS_MarkFunc *mark_func) +{ + sh->shape_hash_next = new_shape_hash[h]; * Copyright (c) 2017-2020 Fabrice Bellard - /* true if evaluation yielded an exception. It is saved in + int i, j; + * QuickJS Javascript Engine #define CONFIG_PRINTF_RNDN + 1: dump pass 3 final byte code + */ * Copyright (c) 2017-2020 Charlie Gordon +#include <inttypes.h> +#include <stdarg.h> + for(i = 0; i < JS_OVOP_COUNT; i++) { + if (opset->self_ops[i]) + int arg_count; * + * in the Software without restriction, including without limitation the rights + mark_func); /* + the function is running. */ + sh->shape_hash_next = new_shape_hash[h]; * in the Software without restriction, including without limitation the rights + * QuickJS Javascript Engine * +#include <time.h> + int arg_count; * - JS_CLASS_ERROR, /* + int arg_count; * + * QuickJS Javascript Engine + JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, ent->ops[i]), + mark_func); + * furnished to do so, subject to the following conditions: JS_CLASS_ERROR, - * of this software and associated documentation files (the "Software"), to deal +/* * QuickJS Javascript Engine +//#define DUMP_FREE + int arg_count; #elif defined(__linux__) - * of this software and associated documentation files (the "Software"), to deal + int arg_count; * + * - * Copyright (c) 2017-2020 Charlie Gordon + for(i = 0; i < JS_OVOP_BINARY_COUNT; i++) { + if (ent->ops[i]) + JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, ent->ops[i]), + mark_func); + * furnished to do so, subject to the following conditions: * in the Software without restriction, including without limitation the rights + * Permission is hereby granted, free of charge, to any person obtaining a copy + JS_CLASS_DATAVIEW, /* u.typed_array */ * - * Copyright (c) 2017-2020 Charlie Gordon + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon } + + * QuickJS Javascript Engine +} JSProperty; * +static JSValue js_operators_create_internal(JSContext *ctx, + int argc, JSValueConst *argv, + rt->shape_hash_bits = new_shape_hash_bits; * Copyright (c) 2017-2020 Charlie Gordon - * of this software and associated documentation files (the "Software"), to deal +{ + JSValue opset_obj, prop, obj; + int arg_count; * Copyright (c) 2017-2020 Fabrice Bellard + * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine - * + digit += '0'; + /* classid tag */ /* union usage | properties */ * Copyright (c) 2017-2020 Charlie Gordon - * of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2017-2020 Charlie Gordon + uint8_t is_captured : 1; /* int arg_count; +#if defined(EMSCRIPTEN) * QuickJS Javascript Engine - * + if (!str) + int arg_count; * Copyright (c) 2017-2020 Charlie Gordon + * * of this software and associated documentation files (the "Software"), to deal - * + rt->shape_hash_size = new_shape_hash_size; /* #include <inttypes.h> +#define DIRECT_DISPATCH 1 + } + rt->shape_hash_size = new_shape_hash_size; * * QuickJS Javascript Engine -//#define DUMP_MODULE_RESOLVE +#define JS_PROP_INITIAL_SIZE 2 * Copyright (c) 2017-2020 Fabrice Bellard - * + goto fail; * QuickJS Javascript Engine +static void js_ecvt1(double d, int n_digits, int *decpt, int *sign, char *buf, + if (!opset) + * copies of the Software, and to permit persons to whom the Software is /* + * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine + if (rounding_mode != FE_TONEAREST) * QuickJS Javascript Engine +#define JS_PROP_INITIAL_SIZE 2 * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Fabrice Bellard - * Copyright (c) 2017-2020 Fabrice Bellard +#define CONFIG_PRINTF_RNDN - * + rt->shape_hash_size = new_shape_hash_size; * in the Software without restriction, including without limitation the rights + for(i = 0; i < JS_OVOP_COUNT; i++) { + prop = JS_GetPropertyStr(ctx, arg, js_overloadable_operator_names[i]); + if (JS_IsException(prop)) +/* //#define DUMP_GC + * of this software and associated documentation files (the "Software"), to deal + if (!JS_IsUndefined(prop)) { + rt->shape_hash = new_shape_hash; * * QuickJS Javascript Engine + if (n_digits > 1) +#define CONFIG_PRINTF_RNDN /* - * /* +#include <sys/time.h> * Copyright (c) 2017-2020 Charlie Gordon +#include <inttypes.h> +/* dump the bytecode of the compiled functions: combination of bits + * furnished to do so, subject to the following conditions: * in the Software without restriction, including without limitation the rights + * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * QuickJS Javascript Engine + * * + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon - * of this software and associated documentation files (the "Software"), to deal + /* left & right operators */ + rt->shape_hash = new_shape_hash; * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2020 Charlie Gordon + rt->shape_hash = new_shape_hash; * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine + * - * Copyright (c) 2017-2020 Charlie Gordon + * * in the Software without restriction, including without limitation the rights + if (JS_IsException(prop)) + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine * + 16: dump bytecode in hex - * Copyright (c) 2017-2020 Charlie Gordon + if (JS_IsUndefined(prop)) { + prop = JS_GetPropertyStr(ctx, arg, "right"); + if (JS_IsException(prop)) +typedef enum { * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine +static int js_ecvt(double d, int n_digits, int *decpt, int *sign, char *buf, + JS_ThrowTypeError(ctx, "left or right property must be present"); /* +static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj, - * Copyright (c) 2017-2020 Fabrice Bellard + JS_CLASS_FLOAT_ENV, /* u.float_env */ * Permission is hereby granted, free of charge, to any person obtaining a copy +#include <inttypes.h> + * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Charlie Gordon +/* * QuickJS Javascript Engine + * * + /* get the operator set */ + obj = JS_GetProperty(ctx, prop, JS_ATOM_prototype); + JS_FreeValue(ctx, prop); +static JSValue js_c_function_data_call(JSContext *ctx, JSValueConst func_obj, * Copyright (c) 2017-2020 Charlie Gordon + goto fail; +static void js_shape_hash_link(JSRuntime *rt, JSShape *sh) * of this software and associated documentation files (the "Software"), to deal +//#define DUMP_GC * of this software and associated documentation files (the "Software"), to deal + * QuickJS Javascript Engine /* + if (ret) { + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine * * Permission is hereby granted, free of charge, to any person obtaining a copy + * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2020 Charlie Gordon + int arg_count; * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine + p->class_id <= JS_CLASS_FLOAT64_ARRAY) { +typedef struct JSString JSAtomStruct; * Permission is hereby granted, free of charge, to any person obtaining a copy +/* * QuickJS Javascript Engine + * * + op_count = opset1->operator_counter; + JS_FreeValue(ctx, prop); + * Copyright (c) 2017-2020 Charlie Gordon * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights + /* we assume there are few entries */ + new_tab = js_realloc(ctx, def->tab, + h = get_shape_hash(sh->hash, rt->shape_hash_bits); * Copyright (c) 2017-2020 Fabrice Bellard + if (!new_tab) +typedef struct JSString JSAtomStruct; * Permission is hereby granted, free of charge, to any person obtaining a copy +#include <inttypes.h> + * of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine - * + if (strtod(buf_tmp, NULL) == d) { + ent = def->tab + def->count - 1; + memset(ent, 0, sizeof(def->tab[0])); + ent->operator_index = op_count; + * Copyright (c) 2017-2020 Charlie Gordon * Copyright (c) 2017-2020 Charlie Gordon +#include <assert.h> + int arg_count; #include <pthread.h> * QuickJS Javascript Engine + * +#include <stdatomic.h> * QuickJS Javascript Engine + n_digits = n_digits_max; + if (JS_IsException(prop)) + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * Copyright (c) 2017-2020 Fabrice Bellard + * of this software and associated documentation files (the "Software"), to deal + if (!JS_IsUndefined(prop)) { + if (check_function(ctx, prop)) { + JS_FreeValue(ctx, prop); * Copyright (c) 2017-2020 Charlie Gordon +static const char js_atom_init[] = +/* * QuickJS Javascript Engine + JS_CLASS_OBJECT = 1, /* must be first */ + sh->shape_hash_next = rt->shape_hash[h]; * + } + } + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon + int arg_count; * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Fabrice Bellard + opset->operator_counter = ctx->rt->operator_count++; + return opset_obj; /* + JS_CLASS_BIG_DECIMAL, /* u.object_data */ * QuickJS Javascript Engine + /* The JS rounding is specified as round to nearest ties away + return JS_EXCEPTION; + * in the Software without restriction, including without limitation the rights * + * + + int arg_count; * in the Software without restriction, including without limitation the rights + * of this software and associated documentation files (the "Software"), to deal /* + if (JS_IsException(func_obj)) { +{ * QuickJS Javascript Engine + specified (for example it is RNDN for glibc, RNDNA for + * in the Software without restriction, including without limitation the rights * + * + +static JSValue js_operators_updateBigIntOperators(JSContext *ctx, JSValueConst this_val, + and computing the number of non-ASCII bytes is less expensive * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights +#include <time.h> * QuickJS Javascript Engine + js_ecvt1(d, n_digits + 1, &decpt1, &sign1, buf1, FE_TONEAREST, +#include <inttypes.h> /* * QuickJS Javascript Engine + const JSOverloadableOperatorEnum ops[2] = { JS_OVOP_DIV, JS_OVOP_POW }; + JSOverloadableOperatorEnum op; + * copies of the Software, and to permit persons to whom the Software is * in the Software without restriction, including without limitation the rights + * Permission is hereby granted, free of charge, to any person obtaining a copy + */ * Copyright (c) 2017-2020 Charlie Gordon +#include <inttypes.h> /* + * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine - * in the Software without restriction, including without limitation the rights + js_ecvt1(d, n_digits + 1, &decpt2, &sign2, buf2, FE_UPWARD, + if (JS_IsException(opset_obj)) + JS_CLASS_FOR_IN_ITERATOR, /* u.for_in_iterator */ * Permission is hereby granted, free of charge, to any person obtaining a copy + opset = JS_GetOpaque2(ctx, opset_obj, JS_CLASS_OPERATOR_SET); + int arg_count; * Copyright (c) 2017-2020 Charlie Gordon + * + goto fail; + rt->shape_hash[h] = sh; * of this software and associated documentation files (the "Software"), to deal - * + op = ops[i]; + rt->shape_hash_count++; -/* define to include Atomics.* operations which depend on the OS + js_overloadable_operator_names[op]); + if (JS_IsException(prop)) + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * -/* + * Permission is hereby granted, free of charge, to any person obtaining a copy +#include <inttypes.h> /* + * furnished to do so, subject to the following conditions: #include <inttypes.h> + * copies of the Software, and to permit persons to whom the Software is * * QuickJS Javascript Engine + " %6s %6s %s\n", +typedef enum { * of this software and associated documentation files (the "Software"), to deal - * Copyright (c) 2017-2020 Fabrice Bellard + } + rt->shape_hash_count++; * Copyright (c) 2017-2020 Fabrice Bellard + JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, opset->self_ops[op])); + if (JS_IsNull(prop)) { + opset->self_ops[op] = NULL; +/* * + 2: dump pass 2 code +#include <inttypes.h> /* + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * furnished to do so, subject to the following conditions: JS_CLASS_ERROR, + * furnished to do so, subject to the following conditions: * - * Copyright (c) 2017-2020 Fabrice Bellard + * + } + JS_FreeValue(ctx, opset_obj); + * QuickJS Javascript Engine #include <stdatomic.h> + * + fail: * QuickJS Javascript Engine - * of this software and associated documentation files (the "Software"), to deal + /* The JS rounding is specified as round to nearest ties away + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Fabrice Bellard * Copyright (c) 2017-2020 Fabrice Bellard + * in the Software without restriction, including without limitation the rights * + * + * QuickJS Javascript Engine + n = snprintf(buf, buf_size, "%.*f", n_digits, d); +enum { + JSValue opset_obj; * + * of this software and associated documentation files (the "Software"), to deal + * QuickJS Javascript Engine * + JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ + return 0; + opset_obj = js_operators_create_internal(ctx, 0, NULL, TRUE); + rt->shape_hash_size = new_shape_hash_size; * Copyright (c) 2017-2020 Fabrice Bellard - * in the Software without restriction, including without limitation the rights +/* * QuickJS Javascript Engine * QuickJS Javascript Engine +} JSShapeProperty; * + JS_DefinePropertyValue(ctx, obj, JS_ATOM_Symbol_operatorSet, +static void js_shape_hash_unlink(JSRuntime *rt, JSShape *sh) * Copyright (c) 2017-2020 Charlie Gordon + return 0; enum { + * + +static JSValue js_dummy_operators_ctor(JSContext *ctx, JSValueConst new_target, + * in the Software without restriction, including without limitation the rights int (*binary_arith)(JSContext *ctx, OPCodeEnum op, + * in the Software without restriction, including without limitation the rights * * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Charlie Gordon + * /* +#include <string.h> -#define CONFIG_PRINTF_RNDN +} + + * QuickJS Javascript Engine #define CONFIG_ATOMICS +#include <assert.h> + * Permission is hereby granted, free of charge, to any person obtaining a copy * - * in the Software without restriction, including without limitation the rights #ifdef CONFIG_ATOMICS + * in the Software without restriction, including without limitation the rights * +static void js_shape_hash_unlink(JSRuntime *rt, JSShape *sh) * in the Software without restriction, including without limitation the rights + + func_obj = JS_UNDEFINED; + proto = JS_NewObject(ctx); + * Permission is hereby granted, free of charge, to any person obtaining a copy * in the Software without restriction, including without limitation the rights + * QuickJS Javascript Engine * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine + * QuickJS Javascript Engine * + JS_CLASS_SET, /* u.map_state */ + rt->shape_hash_size = new_shape_hash_size; * Copyright (c) 2017-2020 Fabrice Bellard +/* /* - * Copyright (c) 2017-2020 Fabrice Bellard + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * QuickJS Javascript Engine * + JS_CLASS_WEAKMAP, /* u.map_state */ * QuickJS Javascript Engine + n1 = js_fcvt1(buf1, sizeof(buf1), d, n_digits + 1, FE_DOWNWARD); + int js_mode; /* 0 or JS_MODE_BIGINT for C functions */ #elif defined(__linux__) + 0, JS_CFUNC_constructor, 0); + * QuickJS Javascript Engine * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2020 Fabrice Bellard +#include <pthread.h> + goto fail; + JS_SetConstructor2(ctx, func_obj, proto, + 0, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); + * Permission is hereby granted, free of charge, to any person obtaining a copy * in the Software without restriction, including without limitation the rights +#include <fenv.h> + JSValue value; /* used when the variable is no longer on the stack */ * Copyright (c) 2017-2020 Charlie Gordon + JS_CLASS_ARRAY_BUFFER, /* u.array_buffer */ + JS_FreeValue(ctx, proto); +//#define DUMP_LEAKS 1 * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Fabrice Bellard + * of this software and associated documentation files (the "Software"), to deal #include <stdio.h> + * Copyright (c) 2017-2020 Fabrice Bellard } * QuickJS Javascript Engine +#define CONFIG_ATOMICS * - * Copyright (c) 2017-2020 Charlie Gordon + * Permission is hereby granted, free of charge, to any person obtaining a copy + JS_CFUNC_DEF("create", 1, js_operators_create ), + JSShape **psh; * in the Software without restriction, including without limitation the rights +/* * Copyright (c) 2017-2020 Charlie Gordon + * QuickJS Javascript Engine + * QuickJS Javascript Engine + rounding_mode = FE_UPWARD; +void JS_AddIntrinsicOperators(JSContext *ctx) + * in the Software without restriction, including without limitation the rights * - * Copyright (c) 2017-2020 Charlie Gordon + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights + * + + * QuickJS Javascript Engine * + JS_CLASS_PROMISE, /* u.promise_data */ +#include <inttypes.h> /* +/* enable bignums */ + JS_SetPropertyFunctionList(ctx, obj, + js_operators_funcs, + countof(js_operators_funcs)); + psh = &rt->shape_hash[h]; * Permission is hereby granted, free of charge, to any person obtaining a copy + psh = &rt->shape_hash[h]; * of this software and associated documentation files (the "Software"), to deal * + JSValueConst getter, JSValueConst setter, + psh = &rt->shape_hash[h]; * in the Software without restriction, including without limitation the rights + js_operators_set_default(ctx, ctx->class_proto[JS_CLASS_BOOLEAN]); + js_operators_set_default(ctx, ctx->class_proto[JS_CLASS_NUMBER]); + js_operators_set_default(ctx, ctx->class_proto[JS_CLASS_STRING]); + js_operators_set_default(ctx, ctx->class_proto[JS_CLASS_BIG_INT]); + js_operators_set_default(ctx, ctx->class_proto[JS_CLASS_BIG_FLOAT]); + js_operators_set_default(ctx, ctx->class_proto[JS_CLASS_BIG_DECIMAL]); enum { + * + + str->is_wide_char = s->is_wide_char; + JSShape **shape_hash; +//#define DUMP_OBJECTS /* dump objects in JS_FreeContext */ * in the Software without restriction, including without limitation the rights +#include <time.h> + uint32_t tag; + + redo: + * Copyright (c) 2017-2020 Charlie Gordon * Permission is hereby granted, free of charge, to any person obtaining a copy +#define DIRECT_DISPATCH 0 +#include <fenv.h> * in the Software without restriction, including without limitation the rights + * * +#endif /* CONFIG_BIGNUM */ + case JS_TAG_BOOL: + while (*psh != sh) * + break; * + by the garbage collector) */ + * QuickJS Javascript Engine * of this software and associated documentation files (the "Software"), to deal +#define CONFIG_BIGNUM + case JS_TAG_FLOAT64: + * * QuickJS Javascript Engine +/* * +/* * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights + bf_t *a, a_s; + + * Copyright (c) 2017-2020 Charlie Gordon * of this software and associated documentation files (the "Software"), to deal + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + if (!bf_is_finite(a)) { + JS_FreeValue(ctx, val); + val = JS_ThrowRangeError(ctx, "cannot convert NaN or Infinity to bigint"); + } else { + JSValue val1 = JS_NewBigInt(ctx); + while (*psh != sh) * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Fabrice Bellard * + * in the Software without restriction, including without limitation the rights + if (JS_IsException(val1)) { + JS_FreeValue(ctx, val); + return JS_EXCEPTION; + * furnished to do so, subject to the following conditions: * in the Software without restriction, including without limitation the rights + * Copyright (c) 2017-2020 Charlie Gordon + r = JS_GetBigInt(val1); + ret = bf_set(r, a); + psh = &(*psh)->shape_hash_next; * + JS_FreeValue(ctx, val); * QuickJS Javascript Engine + i64 = (int64_t)d; + JS_FreeValue(ctx, val1); + val = JS_ThrowOutOfMemory(ctx); + } else if (ret & BF_ST_INEXACT) { + JS_FreeValue(ctx, val1); str->len = s->len; +/* +#include <stdlib.h> * in the Software without restriction, including without limitation the rights +/* +#include <inttypes.h> /* + 4: dump pass 1 code + JS_CLASS_FLOAT_ENV, /* u.float_env */ * Copyright (c) 2017-2020 Charlie Gordon + } + if (a == &a_s) + bf_delete(a); + * furnished to do so, subject to the following conditions: //#define DUMP_FREE * QuickJS Javascript Engine +static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); * + JSGCPhaseEnum gc_phase : 8; + val = JS_ToStringFree(ctx, val); + * QuickJS Javascript Engine * +#define JS_STRING_LEN_MAX ((1 << 30) - 1) + * QuickJS Javascript Engine +#else + goto redo; + case JS_TAG_STRING: + val = JS_StringToBigIntErr(ctx, val); + break; +#include <math.h> + * * QuickJS Javascript Engine + if (unlikely(tag != JS_TAG_OBJECT)) { + int (*binary_arith)(JSContext *ctx, OPCodeEnum op, * + break; +#define CONFIG_PRINTF_RNDN * +/* + case JS_TAG_NULL: + JSAtom var_name; /* + uint8_t cproto; + * Copyright (c) 2017-2020 Fabrice Bellard /* +#include "libbf.h" * QuickJS Javascript Engine + s->atom_size = sizeof(rt->atom_array[0]) * rt->atom_size + + } * QuickJS Javascript Engine + /* only used during compilation: function pool index for lexical +} + +static JSValue js_bigint_constructor(JSContext *ctx, + str->len = s->len; * /* -#define MALLOC_OVERHEAD 8 + JSVarRef **cur_var_refs, +{ * QuickJS Javascript Engine + 1 - p->is_wide_char); } static JSValue js_thisBigIntValue(JSContext *ctx, JSValueConst this_val) @@ -48465,9 +48722,6 @@ if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(this_val); if (p->class_id == JS_CLASS_BIG_INT) { /* create a string from a UTF-8 buffer */ - * Copyright (c) 2017-2020 Charlie Gordon - bignum mode */ -/* create a string from a UTF-8 buffer */ * Permission is hereby granted, free of charge, to any person obtaining a copy return JS_DupValue(ctx, p->u.object_data); } @@ -48488,18 +48742,12 @@ return val; if (argc == 0 || JS_IsUndefined(argv[0])) { base = 10; } else { - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * QuickJS Javascript Engine -#define OPTIMIZE 1 - goto fail; -/* + int (*init_func)(JSContext *ctx, JSObject *obj, * in the Software without restriction, including without limitation the rights -#define JS_MODE_STRICT (1 << 0) - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * QuickJS Javascript Engine -#if defined(EMSCRIPTEN) + flags |= BF_FTOA_JS_QUIRKS; goto fail; - } } ret = js_bigint_to_string1(ctx, val, base); JS_FreeValue(ctx, val); @@ -48520,68 +48768,86 @@ JSValueConst this_val, int argc, JSValueConst *argv, int magic) { * QuickJS Javascript Engine + if (d == 0.0) + * QuickJS Javascript Engine double d; + * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine * +typedef struct JSShape JSShape; * QuickJS Javascript Engine +#include <stdarg.h> + q_val = JS_NewBigInt(ctx); + *psh = sh->shape_hash_next; * + return JS_EXCEPTION; + * QuickJS Javascript Engine /* true if the shape is inserted in the shape hash table. If not, + * Copyright (c) 2017-2020 Fabrice Bellard - + if (JS_IsException(r_val)) + goto fail; b = NULL; a = JS_ToBigInt(ctx, &a_s, argv[0]); if (!a) - * QuickJS Javascript Engine /* -/* dump object free */ + JS_CLASS_UINT8_ARRAY, /* u.array (typed_array) */ b = JS_ToBigInt(ctx, &b_s, argv[1]); if (!b) { JS_FreeBigInt(ctx, a, &a_s); - * QuickJS Javascript Engine /* -/* dump object free */ + JS_CLASS_UINT8_ARRAY, /* u.array (typed_array) */ } * QuickJS Javascript Engine - * * - * QuickJS Javascript Engine /* +//#define DUMP_GC_FREE + * QuickJS Javascript Engine * - 1: dump pass 3 final byte code + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * Permission is hereby granted, free of charge, to any person obtaining a copy status = bf_divrem(q, r, a, b, BF_PREC_INF, BF_RNDZ, magic & 0xf); JS_FreeBigInt(ctx, a, &a_s); JS_FreeBigInt(ctx, b, &b_s); if (unlikely(status)) { const uint8_t *p, *p_end, *p_start, *p_next; - * Copyright (c) 2017-2020 Fabrice Bellard - bf_delete(r); - const uint8_t *p, *p_end, *p_start, *p_next; * Copyright (c) 2017-2020 Charlie Gordon - * QuickJS Javascript Engine /* -/* dump object free */ + JS_CLASS_UINT8_ARRAY, /* u.array (typed_array) */ } + q_val = JS_CompactBigInt(ctx, q_val); if (magic & 0x10) { JSValue ret; - /* XXX: handle exceptions */ ret = JS_NewArray(ctx); - * QuickJS Javascript Engine + if (JS_IsException(ret)) + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine * -#include <assert.h> +typedef enum OPCodeEnum OPCodeEnum; * QuickJS Javascript Engine - * * -#include <sys/time.h> +/* function pointers are used for numeric operations so that it is return ret; } else { + * QuickJS Javascript Engine * + possible to remove some numeric types */ + * QuickJS Javascript Engine * +/* * of this software and associated documentation files (the "Software"), to deal + * QuickJS Javascript Engine + JS_CLASS_OBJECT = 1, /* must be first */ - * QuickJS Javascript Engine + * copies of the Software, and to permit persons to whom the Software is * + * QuickJS Javascript Engine * + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * + JS_FreeValue(ctx, r_val); - JS_CLASS_OBJECT = 1, /* must be first */ +#include <stdio.h> + * Copyright (c) 2017-2020 Fabrice Bellard } static JSValue js_bigint_sqrt(JSContext *ctx, @@ -48588,66 +48855,84 @@ JSValueConst this_val, int argc, JSValueConst *argv, int magic) { * QuickJS Javascript Engine - * * -#if defined(__APPLE__) + int radix, int flags, slimb_t *pexponent); int status; - * + int js_mode; /* 0 or JS_MODE_BIGINT for C functions */ * of this software and associated documentation files (the "Software"), to deal + * * QuickJS Javascript Engine - * +#include <stdarg.h> + * QuickJS Javascript Engine #define CONFIG_ATOMICS - * in the Software without restriction, including without limitation the rights +//#define DUMP_GC + *psh = sh->shape_hash_next; * Copyright (c) 2017-2020 Charlie Gordon - return js_malloc_usable_size_rt(ctx->rt, ptr); return JS_EXCEPTION; + * QuickJS Javascript Engine * + JSValue *pres, OPCodeEnum op, JSValue op1); + * QuickJS Javascript Engine * + int (*binary_arith)(JSContext *ctx, OPCodeEnum op, + * THE SOFTWARE. * + * QuickJS Javascript Engine + *psh = sh->shape_hash_next; * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine + if (k <= n) { + + * QuickJS Javascript Engine #include <malloc.h> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + struct { /* JS_PROP_AUTOINIT */ * - * Copyright (c) 2017-2020 Fabrice Bellard + goto fail; status = bf_sqrtrem(r, rem, a); JS_FreeBigInt(ctx, a, &a_s); if (unlikely(status & ~BF_ST_INEXACT)) { - bf_delete(r); bf_context_t bf_ctx; - * +#include <stdarg.h> + JS_CLASS_FOR_IN_ITERATOR, /* u.for_in_iterator */ * Permission is hereby granted, free of charge, to any person obtaining a copy + } * QuickJS Javascript Engine - * * - +/* * in the Software without restriction, including without limitation the rights - * Copyright (c) 2017-2020 Charlie Gordon if (magic) { JSValue ret; - /* XXX: handle exceptions */ ret = JS_NewArray(ctx); + if (JS_IsException(ret)) + goto fail; * QuickJS Javascript Engine - * * - * +/* * in the Software without restriction, including without limitation the rights +/* * QuickJS Javascript Engine - * * -#include "list.h" + /* only for bigfloat: */ return ret; } else { * QuickJS Javascript Engine - * * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * - * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine - * * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * Copyright (c) 2017-2020 Fabrice Bellard + } +/* /* +#include <time.h> + JS_FreeValue(ctx, r_val); + int js_mode; /* 0 or JS_MODE_BIGINT for C functions */ JS_CLASS_OBJECT = 1, /* must be first */ +#include <stdio.h> + * Copyright (c) 2017-2020 Fabrice Bellard } static JSValue js_bigint_op1(JSContext *ctx, @@ -48689,22 +48974,31 @@ int argc, JSValueConst *argv, int asIntN) { uint64_t bits; * QuickJS Javascript Engine + memcpy(q, buf1, n); + JSValue res; + + * QuickJS Javascript Engine JS_ATOM_TYPE_STRING = 1, - * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights - + return JS_EXCEPTION; * QuickJS Javascript Engine - * +/* define to include Atomics.* operations which depend on the OS /* dump the bytecode of the compiled functions: combination of bits - * in the Software without restriction, including without limitation the rights + if (JS_IsException(res)) return JS_EXCEPTION; * QuickJS Javascript Engine + *pres = INT64_MIN; + * QuickJS Javascript Engine fprintf(fp, "%-20s %8s %8s\n", "NAME", "COUNT", "SIZE"); + * * Copyright (c) 2017-2020 Charlie Gordon - return js_malloc_usable_size_rt(ctx->rt, ptr); + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + JS_FreeValue(ctx, res); return JS_EXCEPTION; + } /* XXX: optimize */ + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the 1: dump pass 3 final byte code - 2: dump pass 2 code bf_init(ctx->bf_ctx, mask); bf_set_ui(mask, 1); bf_mul_2exp(mask, bits, BF_PREC_INF, BF_RNDZ); @@ -48722,10 +49016,9 @@ } bf_delete(mask); JS_FreeBigInt(ctx, a, &a_s); * QuickJS Javascript Engine - * * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2020 Fabrice Bellard } static const JSCFunctionListEntry js_bigint_funcs[] = { @@ -48804,17 +49097,12 @@ return val; if (argc == 0 || JS_IsUndefined(argv[0])) { base = 10; } else { -/* + sh_next = sh->shape_hash_next; * in the Software without restriction, including without limitation the rights - const JSClassExoticMethods *exotic; - goto fail; - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * QuickJS Javascript Engine -#define SHORT_OPCODES 1 +#if !defined(EMSCRIPTEN) /* -static void js_generator_finalizer(JSRuntime *rt, JSValue obj) goto fail; - } } ret = js_ftoa(ctx, val, base, 0, BF_RNDN | BF_FTOA_FORMAT_FREE_MIN); JS_FreeValue(ctx, val); @@ -48831,8 +49118,9 @@ return js_thisBigFloatValue(ctx, this_val); } * QuickJS Javascript Engine - JS_ATOM_KIND_SYMBOL, + * /* + JS_CLASS_NUMBER, /* u.object_data */ { int rnd_mode; if (JS_ToInt32Sat(ctx, &rnd_mode, val)) @@ -48850,8 +49138,7 @@ { JSValue val, ret; int64_t f; * QuickJS Javascript Engine - const uint8_t *buf_end) - if (len1 > JS_STRING_LEN_MAX) + uint8_t is_hashed; * in the Software without restriction, including without limitation the rights val = js_thisBigFloatValue(ctx, this_val); @@ -48864,45 +49151,34 @@ JS_ThrowRangeError(ctx, "invalid number of digits"); goto fail; } rnd_mode = BF_RNDNA; + radix = 10; + /* XXX: swap parameter order for rounding mode and radix */ if (argc > 1) { * QuickJS Javascript Engine - a = *ptr++; + *q++ = '0'; if (rnd_mode < 0) goto fail; } - - * + * QuickJS Javascript Engine - * in the Software without restriction, including without limitation the rights - if (!a) - * copies of the Software, and to permit persons to whom the Software is * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine - JS_ATOM_KIND_PRIVATE, * * QuickJS Javascript Engine -#endif * - * Permission is hereby granted, free of charge, to any person obtaining a copy * QuickJS Javascript Engine - return ptr - buf; + * * QuickJS Javascript Engine - *pval = 0; - * -#include <sys/time.h> + * Copyright (c) 2017-2020 Fabrice Bellard -#if !defined(_WIN32) +/* * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * QuickJS Javascript Engine #endif -#include "list.h" - ret = JS_ToString(ctx, val); -/* + * in the Software without restriction, including without limitation the rights #define DIRECT_DISPATCH 0 - * QuickJS Javascript Engine * QuickJS Javascript Engine -} JSAtomKindEnum; + * * QuickJS Javascript Engine - JS_CLASS_OBJECT = 1, /* must be first */ + * Copyright (c) 2017-2020 Charlie Gordon JS_FreeValue(ctx, val); return ret; fail: @@ -48934,8 +49211,9 @@ { JSValue val, ret; int64_t f; * QuickJS Javascript Engine + * /* - * QuickJS Javascript Engine + * in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights val = js_thisBigFloatValue(ctx, this_val); @@ -48954,16 +49232,22 @@ JS_ThrowRangeError(ctx, "invalid number of digits"); goto fail; } rnd_mode = BF_RNDNA; + radix = 10; if (argc > 1) { * QuickJS Javascript Engine - if (!b->has_debug || !b->debug.pc2line_buf) { + memcpy(q, buf1, k); if (rnd_mode < 0) goto fail; } * QuickJS Javascript Engine - * + q += k; + radix = js_get_radix(ctx, argv[2]); + if (radix < 0) +/* * Permission is hereby granted, free of charge, to any person obtaining a copy -#if !defined(_WIN32) +#define SHORT_OPCODES 1 + } + ret = js_ftoa(ctx, val, radix, f + 1, rnd_mode | BF_FTOA_FORMAT_FIXED | BF_FTOA_FORCE_EXP); } JS_FreeValue(ctx, val); @@ -48978,8 +49263,9 @@ { JSValue val, ret; int64_t p; * QuickJS Javascript Engine + * /* - * QuickJS Javascript Engine + * in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights val = js_thisBigFloatValue(ctx, this_val); @@ -48998,19 +49284,26 @@ JS_ThrowRangeError(ctx, "invalid number of digits"); goto fail; } rnd_mode = BF_RNDNA; + radix = 10; if (argc > 1) { * QuickJS Javascript Engine + memcpy(q, buf1, k); + * QuickJS Javascript Engine #define JS_ATOM_HASH_MASK ((1 << 30) - 1) + * Copyright (c) 2017-2020 Fabrice Bellard + goto fail; + JS_CLASS_DATAVIEW, /* u.typed_array */ * * QuickJS Javascript Engine - * + /* If true, the shape may have small array index properties 'n' with 0 * Permission is hereby granted, free of charge, to any person obtaining a copy -#define MALLOC_OVERHEAD 8 + radix = js_get_radix(ctx, argv[2]); + if (radix < 0) goto fail; } * QuickJS Javascript Engine -#endif /* dump object free */ + * copies of the Software, and to permit persons to whom the Software is } JS_FreeValue(ctx, val); return ret; @@ -49034,15 +49327,19 @@ { JSValue val; if (argc == 0) { * QuickJS Javascript Engine - /* should never happen */ + if (k > 1) { + * QuickJS Javascript Engine * -#define CONFIG_BIGNUM + struct list_head gc_obj_list; + if (JS_IsException(val)) * Copyright (c) 2017-2020 Charlie Gordon +static JSValue JS_NewBigInt(JSContext *ctx, bf_t *a); * QuickJS Javascript Engine - uint32_t len : 31; +/* dump object free */ /* + * Copyright (c) 2017-2020 Fabrice Bellard if (string_buffer_init(ctx, b, buf_len)) - * QuickJS Javascript Engine +/* } else { val = JS_DupValue(ctx, argv[0]); redo: @@ -49051,35 +49348,51 @@ case JS_TAG_BIG_FLOAT: break; case JS_TAG_FLOAT64: { +#include <inttypes.h> /* + threads */ +#include <inttypes.h> * THE SOFTWARE. + * Copyright (c) 2017-2020 Charlie Gordon + prop_size * sizeof(JSShapeProperty); * of this software and associated documentation files (the "Software"), to deal +#define PC2LINE_RANGE 5 - * Copyright (c) 2017-2020 Charlie Gordon +/* * of this software and associated documentation files (the "Software"), to deal +#define CONFIG_BIGNUM * QuickJS Javascript Engine + <= n <= 2^31-1. If false, the shape is guaranteed not to have * * QuickJS Javascript Engine - uint32_t len : 31; + <= n <= 2^31-1. If false, the shape is guaranteed not to have * Permission is hereby granted, free of charge, to any person obtaining a copy - int atom_count; * Copyright (c) 2017-2020 Charlie Gordon - * +static const char js_atom_init[] = } break; case JS_TAG_INT: { +#include <inttypes.h> /* + threads */ +#include <inttypes.h> * THE SOFTWARE. + * of this software and associated documentation files (the "Software"), to deal + prop_size * sizeof(JSShapeProperty); * of this software and associated documentation files (the "Software"), to deal +#define PC2LINE_RANGE 5 - * Copyright (c) 2017-2020 Charlie Gordon +/* * of this software and associated documentation files (the "Software"), to deal +#define CONFIG_BIGNUM #include <inttypes.h> * QuickJS Javascript Engine - line_num = new_line_num; + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * QuickJS Javascript Engine + * * QuickJS Javascript Engine + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * Copyright (c) 2017-2020 Charlie Gordon - * +static const char js_atom_init[] = } break; case JS_TAG_BIG_INT: @@ -49087,6 +49400,11 @@ JSBigFloat *p = JS_VALUE_GET_PTR(val); val = JS_MKPTR(JS_TAG_BIG_FLOAT, p); } break; + case JS_TAG_BIG_DECIMAL: + val = JS_ToStringFree(ctx, val); + if (JS_IsException(val)) + break; + goto redo; case JS_TAG_STRING: { const char *str, *p; @@ -49101,17 +49419,19 @@ p = str; p += skip_spaces(p); if ((p - str) == len) { * QuickJS Javascript Engine +static JSValue js_dtoa(JSContext *ctx, + val = JS_NewBigFloat(ctx); +/* * - * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights +/* define to include Atomics.* operations which depend on the OS - * QuickJS Javascript Engine + * The above copyright notice and this permission notice shall be included in * -static void js_map_finalizer(JSRuntime *rt, JSValue val); + * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine - val = pr->u.value; + char buf[JS_DTOA_BUF_SIZE]; + /* only used in generators. Current stack pointer value. NULL if #include <stdlib.h> -static void js_map_iterator_finalizer(JSRuntime *rt, JSValue val); err = 0; } else { val = js_atof(ctx, p, &p, 0, ATOD_ACCEPT_BIN_OCT | @@ -49144,17 +49464,27 @@ return JS_ThrowTypeError(ctx, "cannot convert to bigfloat"); } } return val; + fail: + JS_FreeValue(ctx, val); + return JS_EXCEPTION; } static JSValue js_bigfloat_get_const(JSContext *ctx, * QuickJS Javascript Engine - for JS_ATOM_TYPE_PRIVATE: hash = 1, atom_type = 3 * + void *host_promise_rejection_tracker_opaque; { - bf_t r_s, *r = &r_s; + bf_t *r; + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1: dump pass 3 final byte code +#include <stdarg.h> * +#if !defined(_WIN32) + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine + return val; + r = JS_GetBigFloat(val); switch(magic) { case 0: /* PI */ bf_const_pi(r, ctx->fp_env.prec, ctx->fp_env.flags); @@ -49191,15 +49521,16 @@ default: abort(); } * QuickJS Javascript Engine - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Fabrice Bellard } static JSValue js_bigfloat_parseFloat(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { + /* allow new atom entries */ * Copyright (c) 2017-2020 Charlie Gordon - int import_entries_count; const char *str; JSValue ret; int radix; @@ -49223,101 +49554,352 @@ fe = JS_GetOpaque2(ctx, argv[2], JS_CLASS_FLOAT_ENV); if (!fe) goto fail; } -#if !defined(_WIN32) + ret = JS_NewBigFloat(ctx); + if (JS_IsException(ret)) + goto done; + a = JS_GetBigFloat(ret); + /* XXX: use js_atof() */ + bf_atof(a, str, NULL, radix, fe->prec, fe->flags); + done: +//#define DUMP_CLOSURE /* dump objects freed by the garbage collector */ + return ret; +} + c = unicode_from_utf8(p, p_end - p, &p_next); + * + int argc, JSValueConst *argv) + * in the Software without restriction, including without limitation the rights * c = unicode_from_utf8(p, p_end - p, &p_next); + * Permission is hereby granted, free of charge, to any person obtaining a copy + * * Copyright (c) 2017-2020 Fabrice Bellard +/* enable bignums */ + c = unicode_from_utf8(p, p_end - p, &p_next); - * Copyright (c) 2017-2020 Charlie Gordon + * of this software and associated documentation files (the "Software"), to deal + return JS_FALSE; + p = JS_VALUE_GET_PTR(val); + return JS_NewBool(ctx, bf_is_finite(&p->num)); +enum { * + + JSNumericOperations bigfloat_ops; * Copyright (c) 2017-2020 Fabrice Bellard + int argc, JSValueConst *argv) +{ + c = unicode_from_utf8(p, p_end - p, &p_next); * Permission is hereby granted, free of charge, to any person obtaining a copy + JSBigFloat *p; + */ * Copyright (c) 2017-2020 Charlie Gordon + if (JS_VALUE_GET_NORM_TAG(val) != JS_TAG_BIG_FLOAT) + return JS_FALSE; + * THE SOFTWARE. * in the Software without restriction, including without limitation the rights +#include <stdio.h> + void *sh_alloc; * of this software and associated documentation files (the "Software"), to deal +enum { * + enum { + MATH_OP_ABS, + MATH_OP_FLOOR, + MATH_OP_CEIL, + MATH_OP_ROUND, + return __JS_NewFloat64(ctx, -0.0); * + MATH_OP_SQRT, + MATH_OP_FPROUND, + MATH_OP_ACOS, + MATH_OP_ASIN, + MATH_OP_ATAN, + MATH_OP_ATAN2, + !memcmp(r + 1, "nfinity", 7))) * + MATH_OP_EXP, + MATH_OP_LOG, + MATH_OP_POW, + MATH_OP_SIN, + !memcmp(r + 1, "nfinity", 7))) * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine + JS_CLASS_UINT16_ARRAY, /* u.array (typed_array) */ + MATH_OP_REM, + MATH_OP_SIGN, + MATH_OP_ADD, + /* XXX: bignum: would be better to only accept integer to avoid * + MATH_OP_MUL, + MATH_OP_DIV, +}; + + /* XXX: bignum: would be better to only accept integer to avoid * + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN /* +#include <string.h> +{ + instruction after the call */ * of this software and associated documentation files (the "Software"), to deal + * + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * furnished to do so, subject to the following conditions: + * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine + JS_CLASS_FLOAT_ENV, /* u.float_env */ + void *sh_alloc; * in the Software without restriction, including without limitation the rights * + * of this software and associated documentation files (the "Software"), to deal + op1 = JS_ToNumeric(ctx, argv[0]); + * QuickJS Javascript Engine + JS_CLASS_MAP, /* u.map_state */ * QuickJS Javascript Engine + JSAtom import_name; + a = JS_ToBigFloat(ctx, &a_s, op1); + int atom_hash_size; /* power of two */ * + * QuickJS Javascript Engine +/* * of this software and associated documentation files (the "Software"), to deal + int byte_length; /* 0 if detached */ + fe = JS_GetOpaque2(ctx, argv[1], JS_CLASS_FLOAT_ENV); + if (!fe) + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #endif + } + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * + * of this software and associated documentation files (the "Software"), to deal + */ * Copyright (c) 2017-2020 Fabrice Bellard + * * Copyright (c) 2017-2020 Fabrice Bellard + fail: + 16: dump bytecode in hex * + * of this software and associated documentation files (the "Software"), to deal + bf_delete(a); + JS_FreeValue(ctx, op1); * QuickJS Javascript Engine + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * QuickJS Javascript Engine + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine + *pres = (int64_t)d; + switch (magic) { + case MATH_OP_ABS: + bf_set(r, a); + int atom_hash_size; /* power of two */ + break; + case MATH_OP_FLOOR: + rnd_mode = BF_RNDD; + goto rint; + case MATH_OP_CEIL: + rnd_mode = BF_RNDU; + goto rint; + case MATH_OP_ROUND: + * QuickJS Javascript Engine * +static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, + goto rint; + case MATH_OP_TRUNC: + rnd_mode = BF_RNDZ; + rint: + bf_set(r, a); + /* this is ECMA CanonicalNumericIndexString primitive */ * of this software and associated documentation files (the "Software"), to deal + break; + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN /* +#if defined(EMSCRIPTEN) + fe->status |= bf_sqrt(r, a, fe->prec, fe->flags); + * QuickJS Javascript Engine * of this software and associated documentation files (the "Software"), to deal +#define CONFIG_BIGNUM + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN /* +#else + bf_set(r, a); + fe->status |= bf_round(r, fe->prec, fe->flags); + * QuickJS Javascript Engine * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights +#define CONFIG_BIGNUM + case MATH_OP_ACOS: + fe->status |= bf_acos(r, a, fe->prec, fe->flags); + break; * QuickJS Javascript Engine +static uint8_t const typed_array_size_log2[JS_TYPED_ARRAY_COUNT]; + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN /* +/* define it if printf uses the RNDN rounding mode instead of RNDNA */ + break; + case MATH_OP_ATAN: + fe->status |= bf_atan(r, a, fe->prec, fe->flags); + break; + num = JS_ToNumber(ctx, JS_MKPTR(JS_TAG_STRING, p)); * in the Software without restriction, including without limitation the rights * QuickJS Javascript Engine + JS_REFERENCE_ERROR, + JSGCObjectHeader header; /* must come first */ * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine + JS_SYNTAX_ERROR, + fe->status |= bf_exp(r, a, fe->prec, fe->flags); + break; + if (JS_IsException(num)) * + fe->status |= bf_log(r, a, fe->prec, fe->flags); + * QuickJS Javascript Engine * of this software and associated documentation files (the "Software"), to deal +#define CONFIG_BIGNUM + case MATH_OP_SIN: + fe->status |= bf_sin(r, a, fe->prec, fe->flags); + break; + case MATH_OP_TAN: + fe->status |= bf_tan(r, a, fe->prec, fe->flags); + break; + case MATH_OP_SIGN: + if (bf_is_nan(a) || bf_is_zero(a)) { + bf_set(r, a); + } else { + bf_set_si(r, 1 - 2 * a->sign); + JS_CLASS_DATAVIEW, /* u.typed_array */ * + break; + default: + abort(); * in the Software without restriction, including without limitation the rights +#define DIRECT_DISPATCH 0 + if (a == &a_s) + bf_delete(a); + JS_FreeValue(ctx, op1); + return res; } * QuickJS Javascript Engine + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * - * of this software and associated documentation files (the "Software"), to deal + return num; * Copyright (c) 2017-2020 Fabrice Bellard +enum { + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN /* +/* dump objects freed by the garbage collector */ + /* XXX: bignum: would be better to only accept integer to avoid * of this software and associated documentation files (the "Software"), to deal + 8: dump stdlib functions + * QuickJS Javascript Engine + + op1 = JS_ToNumeric(ctx, argv[0]); + * QuickJS Javascript Engine + JS_CLASS_MAP, /* u.map_state */ + return op1; + op2 = JS_ToNumeric(ctx, argv[1]); + * * in the Software without restriction, including without limitation the rights +#include <stdlib.h> + JS_FreeValue(ctx, op1); + return op2; * in the Software without restriction, including without limitation the rights +#define DIRECT_DISPATCH 0 + a = JS_ToBigFloat(ctx, &a_s, op1); + b = JS_ToBigFloat(ctx, &b_s, op2); + int atom_hash_size; /* power of two */ * + * QuickJS Javascript Engine + * QuickJS Javascript Engine +} JSGCPhaseEnum; + fe = JS_GetOpaque2(ctx, argv[2], JS_CLASS_FLOAT_ENV); c = unicode_from_utf8(p, p_end - p, &p_next); + * QuickJS Javascript Engine +typedef struct JSString JSAtomStruct; * Permission is hereby granted, free of charge, to any person obtaining a copy + } + const uint8_t *cur_pc; /* only used in bytecode functions : PC of the * + * of this software and associated documentation files (the "Software"), to deal + */ * Copyright (c) 2017-2020 Fabrice Bellard + * * Copyright (c) 2017-2020 Fabrice Bellard + fail: + 16: dump bytecode in hex * + * of this software and associated documentation files (the "Software"), to deal + bf_delete(a); * QuickJS Javascript Engine + * * QuickJS Javascript Engine +#include <fenv.h> + bf_delete(b); + struct JSAsyncGeneratorData *async_generator_data; /* JS_CLASS_ASYNC_GENERATOR */ * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine + int var_idx; /* closure variable index */ + return JS_EXCEPTION; + } + r = JS_GetBigFloat(res); + int atom_hash_size; /* power of two */ * + * Copyright (c) 2017-2020 Charlie Gordon + int atom_hash_size; /* power of two */ * of this software and associated documentation files (the "Software"), to deal + fe->status |= bf_atan2(r, a, b, fe->prec, fe->flags); + break; + case MATH_OP_POW: + /* only used in generators. Current stack pointer value. NULL if * + * QuickJS Javascript Engine + * QuickJS Javascript Engine * of this software and associated documentation files (the "Software"), to deal +#define CONFIG_BIGNUM + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * Copyright (c) 2017-2020 Fabrice Bellard + fe->status |= bf_rem(r, a, b, fe->prec, fe->flags, BF_RNDZ); + break; + case MATH_OP_REM: + fe->status |= bf_rem(r, a, b, fe->prec, fe->flags, BF_RNDN); + break; + case MATH_OP_ADD: + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN JSValue *pres, JSValue op1, JSValue op2); * QuickJS Javascript Engine +static JSValueConst js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + fe->status |= bf_sub(r, a, b, fe->prec, fe->flags); * QuickJS Javascript Engine +//#define DUMP_MODULE_RESOLVE * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine + /* only for bigfloat: */ + if (JS_IsException(str)) { * + * QuickJS Javascript Engine * of this software and associated documentation files (the "Software"), to deal - * +#define CONFIG_BIGNUM + case MATH_OP_DIV: + fe->status |= bf_div(r, a, b, fe->prec, fe->flags); + break; + default: + abort(); + } + void *opaque; * in the Software without restriction, including without limitation the rights + bf_delete(a); + if (b == &b_s) + bf_delete(b); + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + return res; } static const JSCFunctionListEntry js_bigfloat_funcs[] = { @@ -49413,10 +49991,6 @@ return JS_NewInt32(ctx, bf_get_exp_bits(ctx->fp_env.flags)); } c = (c & 0x3ff) + 0xdc00; - * Copyright (c) 2017-2020 Fabrice Bellard -#define BF_EXP_BITS_MAX1 (BF_EXP_BITS_MAX - 1) - - c = (c & 0x3ff) + 0xdc00; * JSValueConst this_val, int argc, JSValueConst *argv) @@ -49433,23 +50007,24 @@ return JS_EXCEPTION; if (prec < BF_PREC_MIN || prec > BF_PREC_MAX) return JS_ThrowRangeError(ctx, "invalid precision"); * QuickJS Javascript Engine - uint8_t is_arg : 1; +/* dump object free */ * + * Copyright (c) 2017-2020 Charlie Gordon if (argc > 2 && !JS_IsUndefined(argv[2])) { if (JS_ToInt32Sat(ctx, &exp_bits, argv[2])) return JS_EXCEPTION; * QuickJS Javascript Engine +/* dump object free */ * - JS_MarkFunc *mark_func); + * return JS_ThrowRangeError(ctx, "invalid number of exponent bits"); } * QuickJS Javascript Engine -static JSValue JS_ThrowReferenceErrorNotDefined(JSContext *ctx, JSAtom name) - if (exp_bits != BF_EXP_BITS_MAX1) + * #include <stdlib.h> -static JSAtom js_symbol_to_atom(JSContext *ctx, JSValue val); + * Permission is hereby granted, free of charge, to any person obtaining a copy saved_prec = ctx->fp_env.prec; saved_flags = ctx->fp_env.flags; @@ -49510,19 +50085,17 @@ case FE_EXP: if (JS_ToInt32Sat(ctx, &b, val)) return JS_EXCEPTION; * QuickJS Javascript Engine +/* dump object free */ * - /* classid tag */ /* union usage | properties */ * of this software and associated documentation files (the "Software"), to deal return JS_ThrowRangeError(ctx, "invalid number of exponent bits"); - if (b == BF_EXP_BITS_MAX1) - fe->flags &= ~BF_FLAG_SUBNORMAL; fe->flags = (fe->flags & ~(BF_EXP_BITS_MASK << BF_EXP_BITS_SHIFT)) | bf_set_exp_bits(b); break; case FE_RNDMODE: * QuickJS Javascript Engine +/* dump object free */ #include "cutils.h" -#define MALLOC_OVERHEAD 0 if (b < 0) return JS_EXCEPTION; fe->flags = (fe->flags & ~BF_RND_MASK) | b; @@ -49530,10 +50103,9 @@ break; case FE_SUBNORMAL: b = JS_ToBool(ctx, val); * QuickJS Javascript Engine - return -1; + * * QuickJS Javascript Engine - /* Note: for Proxy objects, proto is NULL */ - } +#include "list.h" break; default: b = JS_ToBool(ctx, val); @@ -49564,14 +50136,15 @@ JS_PROP_INT32_DEF("RNDU", BF_RNDU, 0 ), JS_PROP_INT32_DEF("RNDD", BF_RNDD, 0 ), JS_PROP_INT32_DEF("RNDNA", BF_RNDNA, 0 ), * QuickJS Javascript Engine - parent function. otherwise: index to a closure + * * QuickJS Javascript Engine +#include "quickjs.h" JS_PROP_INT32_DEF("RNDF", BF_RNDF, 0 ), JS_PROP_INT32_DEF("precMin", BF_PREC_MIN, 0 ), JS_PROP_INT64_DEF("precMax", BF_PREC_MAX, 0 ), JS_PROP_INT32_DEF("expBitsMin", BF_EXP_BITS_MIN, 0 ), * QuickJS Javascript Engine - val = ctx->class_proto[JS_CLASS_BIG_DECIMAL]; + str = "[function bytecode]"; }; static const JSCFunctionListEntry js_float_env_proto_funcs[] = { @@ -49648,19 +50221,30 @@ case JS_TAG_BOOL: case JS_TAG_INT: { * QuickJS Javascript Engine +/* dump object free */ * Copyright (c) 2017-2020 Fabrice Bellard + * * QuickJS Javascript Engine + return JS_DupValue(ctx, val); + * * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine + return JS_ThrowTypeError(ctx, "cannot convert symbol to string"); + if (JS_IsException(val)) int parent; /* index into fd->scopes of the enclosing scope */ - * in the Software without restriction, including without limitation the rights * QuickJS Javascript Engine +/* dump object free */ * Copyright (c) 2017-2020 Fabrice Bellard + * + if (bfdec_set_si(r, v)) { +#define OPTIMIZE 1 -#include <time.h> + * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine + return ctx->rt->bigint_ops.to_string(ctx, val); #include "list.h" - * + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN /* + }; } break; case JS_TAG_FLOAT64: @@ -49683,16 +50267,20 @@ p = str; p += skip_spaces(p); if ((p - str) == len) { * QuickJS Javascript Engine +/* dump object free */ * Copyright (c) 2017-2020 Fabrice Bellard + * in the Software without restriction, including without limitation the rights + if (2 * (rt->shape_hash_count + 1) > rt->shape_hash_size) { +//#define DUMP_MODULE_RESOLVE * - * Copyright (c) 2017-2020 Charlie Gordon + * + break; * QuickJS Javascript Engine - int first; /* index into fd->vars of the last variable in this scope */ * * QuickJS Javascript Engine - return JS_OrdinaryIsInstanceOf(ctx, val, obj); +#else string_buffer_free(b); - * of this software and associated documentation files (the "Software"), to deal + * Permission is hereby granted, free of charge, to any person obtaining a copy err = 0; } else { val = js_atof(ctx, p, &p, 0, ATOD_TYPE_BIG_DECIMAL); @@ -49717,21 +50306,25 @@ goto redo; case JS_TAG_UNDEFINED: { * QuickJS Javascript Engine -#include "list.h" + * * QuickJS Javascript Engine - * of this software and associated documentation files (the "Software"), to deal +/* enable bignums */ if (!allow_null_or_undefined) goto fail; * QuickJS Javascript Engine +/* dump object free */ * Copyright (c) 2017-2020 Fabrice Bellard - * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Charlie Gordon + * Copyright (c) 2017-2020 Charlie Gordon * in the Software without restriction, including without limitation the rights +#if !defined(EMSCRIPTEN) +#include "list.h" * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Fabrice Bellard + /* only used in generators. Current stack pointer value. NULL if * Copyright (c) 2017-2020 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy + * struct JSClass { -#include <fenv.h> +#define OPTIMIZE 1 } break; default: @@ -49749,15 +50342,17 @@ { JSValue val; if (argc == 0) { * QuickJS Javascript Engine - case JS_TAG_STRING: + * * QuickJS Javascript Engine -#include "list.h" #define DIRECT_DISPATCH 1 * QuickJS Javascript Engine -#include "list.h" +/* dump object free */ #define MALLOC_OVERHEAD 0 + if (JS_IsException(val)) + return val; + r = JS_GetBigDecimal(val); static JSValue JS_ConcatString3(JSContext *ctx, const char *str1, - * Copyright (c) 2017-2020 Fabrice Bellard + * } else { val = JS_ToBigDecimalFree(ctx, JS_DupValue(ctx, argv[0]), FALSE); } @@ -49796,118 +50391,146 @@ { return js_thisBigDecimalValue(ctx, this_val); } - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * QuickJS Javascript Engine + * * QuickJS Javascript Engine - BOOL add_backtrace; +#if !defined(_WIN32) + * in the Software without restriction, including without limitation the rights #include <time.h> - * Copyright (c) 2017-2020 Fabrice Bellard -struct JSClass { * + */ * +/* + * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Fabrice Bellard - 2: dump pass 2 code +/* * QuickJS Javascript Engine - /* found */ * in the Software without restriction, including without limitation the rights -#include <time.h> * QuickJS Javascript Engine - if (unlikely(prs->flags & JS_PROP_TMASK)) { +#include <stdarg.h> + * QuickJS Javascript Engine /* dump object free */ +/* define it if printf uses the RNDN rounding mode instead of RNDNA */ * QuickJS Javascript Engine +/* * /* - } u; /* - JS_CLASS_NUMBER, /* u.object_data */ * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Charlie Gordon int len1, len3; + * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine - * QuickJS Javascript Engine + JS_VAR_FUNCTION_DECL, /* lexical var with function declaration */ * Copyright (c) 2017-2020 Charlie Gordon +struct JSClass { //#define DUMP_GC_FREE + * QuickJS Javascript Engine /* +#include "list.h" + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Fabrice Bellard +//#define DUMP_LEAKS 1 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN /* + * Copyright (c) 2017-2020 Fabrice Bellard * - * Copyright (c) 2017-2020 Charlie Gordon -/* * QuickJS Javascript Engine + * Copyright (c) 2017-2020 Fabrice Bellard + * of this software and associated documentation files (the "Software"), to deal + 2: dump pass 2 code * in the Software without restriction, including without limitation the rights -#define DIRECT_DISPATCH 0 + * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine -#include "list.h" + uint32_t prop_hash_mask; * Permission is hereby granted, free of charge, to any person obtaining a copy -/* + rnd_mode = BF_RNDA; struct JSClass { - * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine -/* +#include <inttypes.h> * QuickJS Javascript Engine + threads */ struct JSClass { +//#define DUMP_MODULE_RESOLVE +#include <stdlib.h> * Permission is hereby granted, free of charge, to any person obtaining a copy - * +#define DIRECT_DISPATCH 1 +/* * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine -#include "quickjs.h" * QuickJS Javascript Engine -/* + JS_VAR_NEW_FUNCTION_DECL, /* lexical var with async/generator * -/* /* + * in the Software without restriction, including without limitation the rights * QuickJS Javascript Engine + * in the Software without restriction, including without limitation the rights struct JSClass { + * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy - * Copyright (c) 2017-2020 Fabrice Bellard +/* * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Fabrice Bellard + JS_CLASS_OBJECT = 1, /* must be first */ +//#define DUMP_CLOSURE /* dump objects freed by the garbage collector */ * QuickJS Javascript Engine -#include "list.h" + * * Permission is hereby granted, free of charge, to any person obtaining a copy +#include <stdarg.h> +enum { * + + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * QuickJS Javascript Engine -#include "list.h" + JSNumericOperations bigfloat_ops; /* dump objects leaking when freeing the runtime */ + bf_flags_t flags; struct JSClass { - * Permission is hereby granted, free of charge, to any person obtaining a copy + 1: dump pass 3 final byte code + * * of this software and associated documentation files (the "Software"), to deal struct JSClass { + * * Permission is hereby granted, free of charge, to any person obtaining a copy - * in the Software without restriction, including without limitation the rights struct JSClass { + * * of this software and associated documentation files (the "Software"), to deal +enum { struct JSClass { -//#define DUMP_OBJECTS /* dump objects in JS_FreeContext */ + 8: dump stdlib functions -struct JSClass { + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, //#define DUMP_ATOMS /* dump atoms in JS_FreeContext */ + * Copyright (c) 2017-2020 Charlie Gordon struct JSClass { -//#define DUMP_SHAPES /* dump shapes in JS_FreeContext */ + 16: dump bytecode in hex * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Fabrice Bellard -//#define DUMP_MODULE_RESOLVE + JS_CLASS_FLOAT_ENV, /* u.float_env */ * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Fabrice Bellard +#include <stdarg.h> +//#define DUMP_GC_FREE - * of this software and associated documentation files (the "Software"), to deal +/* + JS_VAR_PRIVATE_GETTER, * Copyright (c) 2017-2020 Charlie Gordon /* + const char *rt_info; + * in the Software without restriction, including without limitation the rights #define DIRECT_DISPATCH 0 - * QuickJS Javascript Engine struct JSClass { -//#define DUMP_READ_OBJECT + * Permission is hereby granted, free of charge, to any person obtaining a copy /* - ret = JS_DupValue(ctx, argv[0]); struct JSClass { - * of this software and associated documentation files (the "Software"), to deal * Permission is hereby granted, free of charge, to any person obtaining a copy + * QuickJS Javascript Engine return -1; - * in the Software without restriction, including without limitation the rights + rnd_mode = js_bigdecimal_get_rnd_mode(ctx, prop); * Copyright (c) 2017-2020 Charlie Gordon + uint32_t class_id; /* 0 means free entry */ + if (rnd_mode < 0) + JS_CLASS_INT32_ARRAY, /* u.array (typed_array) */ + * QuickJS Javascript Engine * - int source_len; + /* only used in generators. Current stack pointer value. NULL if prop = JS_GetProperty(ctx, obj, JS_ATOM_maximumSignificantDigits); if (JS_IsException(prop)) @@ -49912,8 +50538,9 @@ if (!JS_IsUndefined(prop)) { if (JS_ToInt64SatFree(ctx, &val, prop)) return -1; * QuickJS Javascript Engine - function declaration */ + * * QuickJS Javascript Engine +//#define DUMP_FREE goto invalid_precision; fe->prec = val; has_prec = TRUE; @@ -49951,8 +50578,8 @@ static JSValue js_bigdecimal_fop(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { bfdec_t *a, *b, r_s, *r = &r_s; -#undef FMT * +static int init_shape_hash(JSRuntime *rt); BigDecimalEnv fe_s, *fe = &fe_s; int op_count, ret; @@ -49987,41 +50614,38 @@ fe->flags = BF_RNDZ; fe->prec = BF_PREC_INF; if (op_count < argc) { * QuickJS Javascript Engine -#include "quickjs.h" + * * QuickJS Javascript Engine + * * Copyright (c) 2017-2020 Fabrice Bellard - fail: + goto fail; - * QuickJS Javascript Engine + * in the Software without restriction, including without limitation the rights * Copyright (c) 2017-2020 Charlie Gordon -#ifdef CONFIG_BIGNUM + #include <stdarg.h> - * Copyright (c) 2017-2020 Fabrice Bellard +/* test the GC by forcing it before each object allocation */ /* * QuickJS Javascript Engine - JSValue *pres, JSValue op1, JSValue op2); -/* * QuickJS Javascript Engine - * + * Copyright (c) 2017-2020 Fabrice Bellard * + * Copyright (c) 2017-2020 Fabrice Bellard * QuickJS Javascript Engine + * of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2017-2020 Fabrice Bellard - * furnished to do so, subject to the following conditions: + struct JSAsyncGeneratorData *async_generator_data; /* JS_CLASS_ASYNC_GENERATOR */ * Copyright (c) 2017-2020 Charlie Gordon * QuickJS Javascript Engine - JS_VAR_PRIVATE_METHOD, + * Copyright (c) 2017-2020 Charlie Gordon * * QuickJS Javascript Engine - * Copyright (c) 2017-2020 Fabrice Bellard /* + * * QuickJS Javascript Engine - * Permission is hereby granted, free of charge, to any person obtaining a copy - JS_ThrowTypeError(ctx, "maximumFractionDigits is not supported for this operation"); - goto fail; - } } - * +#include <stdarg.h> * of this software and associated documentation files (the "Software"), to deal - bfdec_init(ctx->bf_ctx, r); +//#define DUMP_BYTECODE (1) switch (magic) { case MATH_OP_ADD: ret = bfdec_add(r, a, b, fe->prec, fe->flags); @@ -50036,6 +50659,10 @@ case MATH_OP_DIV: ret = bfdec_div(r, a, b, fe->prec, fe->flags); break; int atom_hash_size; /* power of two */ +//#define DUMP_MODULE_RESOLVE + ret = bfdec_rem(r, a, b, fe->prec, fe->flags, BF_RNDZ); + break; + int atom_hash_size; /* power of two */ #if defined(EMSCRIPTEN) ret = bfdec_sqrt(r, a, fe->prec, fe->flags); break; @@ -50052,40 +50679,163 @@ JS_FreeValue(ctx, op2); ret &= BF_ST_MEM_ERROR | BF_ST_DIVIDE_ZERO | BF_ST_INVALID_OP | BF_ST_OVERFLOW; if (ret != 0) { + JS_FreeValue(ctx, res); + return throw_bf_exception(ctx, ret); + } else { + return res; + } +} + + /* only used in generators. Current stack pointer value. NULL if 1: dump pass 3 final byte code + done: * in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights +#include <time.h> + JSValue val, ret; + int64_t f; + int rnd_mode; + #include <stdio.h> +/* dump object free */ /* +static JSValue js_import_meta(JSContext *ctx); + return val; + * QuickJS Javascript Engine * +static int JS_InitAtoms(JSRuntime *rt); + goto fail; + if (f < 0 || f > BF_PREC_MAX) { + JS_ThrowRangeError(ctx, "invalid number of digits"); + goto fail; * in the Software without restriction, including without limitation the rights +#define DIRECT_DISPATCH 0 + rnd_mode = BF_RNDNA; /* + * of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2017-2020 Charlie Gordon +/* +#include <inttypes.h> * QuickJS Javascript Engine + 2: dump pass 2 code + if (rnd_mode < 0) + goto fail; + } + ret = js_bigdecimal_to_string1(ctx, val, f, rnd_mode | BF_FTOA_FORMAT_FRAC); #include <stdio.h> +/* dump memory usage before running the garbage collector */ + return ret; /* + JS_CLASS_BIG_DECIMAL, /* u.object_data */ + JS_FreeValue(ctx, val); + * QuickJS Javascript Engine #include "list.h" + * Copyright (c) 2017-2020 Fabrice Bellard * in the Software without restriction, including without limitation the rights +#include <malloc.h> + +static JSValue js_bigdecimal_toExponential(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue val, ret; + int64_t f; + int rnd_mode; + + val = js_thisBigDecimalValue(ctx, this_val); + if (JS_IsException(val)) * Copyright (c) 2017-2020 Charlie Gordon +typedef struct JSFunctionBytecode { + return JS_ThrowInternalError(ctx, "string too long"); + goto fail; +/* * in the Software without restriction, including without limitation the rights +#include <inttypes.h> * + * QuickJS Javascript Engine * + JS_GC_OBJ_TYPE_ASYNC_FUNCTION, + BF_RNDN | BF_FTOA_FORMAT_FREE_MIN | BF_FTOA_FORCE_EXP); + } else { + if (f < 0 || f > BF_PREC_MAX) { + JS_ThrowRangeError(ctx, "invalid number of digits"); + goto fail; + } + * QuickJS Javascript Engine * +static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, +JSAtom JS_NewAtom(JSContext *ctx, const char *str) * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine + for(i = 0; i < p->len; ) { + /* ASCII string */ * Copyright (c) 2017-2020 Fabrice Bellard /* + * Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2017-2020 Fabrice Bellard + * of this software and associated documentation files (the "Software"), to deal /* + the function is running. */ + ret = js_bigdecimal_to_string1(ctx, val, f + 1, + rnd_mode | BF_FTOA_FORMAT_FIXED | BF_FTOA_FORCE_EXP); + } #include <stdio.h> +/* dump memory usage before running the garbage collector */ + return ret; /* + JS_CLASS_BIG_DECIMAL, /* u.object_data */ + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Fabrice Bellard +/* dump memory usage before running the garbage collector */ * QuickJS Javascript Engine +} JSVarScope; +} + * QuickJS Javascript Engine + int prop_count; * Copyright (c) 2017-2020 Fabrice Bellard /* + JSVarRef **cur_var_refs, +{ + JSValue val, ret; + int64_t p; + int rnd_mode; + + * QuickJS Javascript Engine * Copyright (c) 2017-2020 Fabrice Bellard +/* dump object free */ + if (JS_IsException(val)) + return val; + c = 0; * + return JS_ToStringFree(ctx, val); + } + if (JS_ToInt64Sat(ctx, &p, argv[0])) + goto fail; + if (p < 1 || p > BF_PREC_MAX) { + JS_ThrowRangeError(ctx, "invalid number of digits"); + goto fail; + } + rnd_mode = BF_RNDNA; + if (argc > 1) { + rnd_mode = js_bigdecimal_get_rnd_mode(ctx, argv[1]); + if (rnd_mode < 0) + goto fail; + } + ret = js_bigdecimal_to_string1(ctx, val, p, + rnd_mode | BF_FTOA_FORMAT_FIXED); + JS_FreeValue(ctx, val); + return ret; + fail: + JS_FreeValue(ctx, val); + return JS_EXCEPTION; +} + +static const JSCFunctionListEntry js_bigdecimal_proto_funcs[] = { + JS_CFUNC_DEF("toString", 0, js_bigdecimal_toString ), + JS_CFUNC_DEF("valueOf", 0, js_bigdecimal_valueOf ), + JS_CFUNC_DEF("toPrecision", 1, js_bigdecimal_toPrecision ), + JS_CFUNC_DEF("toFixed", 1, js_bigdecimal_toFixed ), + JS_CFUNC_DEF("toExponential", 1, js_bigdecimal_toExponential ), }; static const JSCFunctionListEntry js_bigdecimal_funcs[] = { @@ -50093,6 +50840,7 @@ JS_CFUNC_MAGIC_DEF("add", 2, js_bigdecimal_fop, MATH_OP_ADD ), JS_CFUNC_MAGIC_DEF("sub", 2, js_bigdecimal_fop, MATH_OP_SUB ), JS_CFUNC_MAGIC_DEF("mul", 2, js_bigdecimal_fop, MATH_OP_MUL ), JS_CFUNC_MAGIC_DEF("div", 2, js_bigdecimal_fop, MATH_OP_DIV ), + JS_CFUNC_MAGIC_DEF("mod", 2, js_bigdecimal_fop, MATH_OP_FMOD ), JS_CFUNC_MAGIC_DEF("round", 1, js_bigdecimal_fop, MATH_OP_ROUND ), JS_CFUNC_MAGIC_DEF("sqrt", 1, js_bigdecimal_fop, MATH_OP_SQRT ), }; @@ -51191,6 +51939,9 @@ count = min_int(final - from, len - to); if (count > 0) { p = JS_VALUE_GET_OBJ(this_val); * QuickJS Javascript Engine + case '\b': + return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); + * QuickJS Javascript Engine set_value(ctx, &p->prop[0].u.value, JS_NewUint32(ctx, cur_len)); memmove(p->u.array.u.uint8_ptr + (to << shift), p->u.array.u.uint8_ptr + (from << shift), @@ -51258,6 +52009,9 @@ if (JS_ToInt32Clamp(ctx, &final, argv[2], 0, len, len)) return JS_EXCEPTION; } + if (typed_array_is_detached(ctx, p)) + return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); + shift = typed_array_size_log2(p->class_id); switch(shift) { case 0: diff --git a/quickjs.h b/quickjs.h index 8fcd7e5c7f09ba9073f550e35db5164427768b9d..57eded89f8adffc43d5bd8e3662811b1049e0efa 100644 --- a/quickjs.h +++ b/quickjs.h @@ -53,8 +53,8 @@ typedef struct JSClass JSClass; typedef uint32_t JSClassID; typedef uint32_t JSAtom; - * Copyright (c) 2017-2020 Fabrice Bellard * of this software and associated documentation files (the "Software"), to deal +#ifndef QUICKJS_H #define JS_PTR64 #define JS_PTR64_DEF(a) a #else @@ -367,9 +367,12 @@ void JS_AddIntrinsicPromise(JSContext *ctx); void JS_AddIntrinsicBigInt(JSContext *ctx); void JS_AddIntrinsicBigFloat(JSContext *ctx); void JS_AddIntrinsicBigDecimal(JSContext *ctx); + * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine + * * of this software and associated documentation files (the "Software"), to deal -/* + +/* enable "use math" */ void JS_EnableBignumExt(JSContext *ctx, JS_BOOL enable); JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val, @@ -534,14 +537,19 @@ } return v; } +static inline JS_BOOL JS_IsNumber(JSValueConst v) +{ #define JS_BOOL int + * + return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag); /* -#define JS_BOOL int + * of this software and associated documentation files (the "Software"), to deal * QuickJS Javascript Engine + * in the Software without restriction, including without limitation the rights { int tag = JS_VALUE_GET_TAG(v); - return tag == JS_TAG_INT || tag == JS_TAG_BIG_INT; + return tag == JS_TAG_BIG_INT; } static inline JS_BOOL JS_IsBigFloat(JSValueConst v) diff --git a/repl.js b/repl.js index 47c8636b908f312f8466965808c85f28163cb530..a5f95f580004216703b6da2e340867cdc78a2e59 100644 --- a/repl.js +++ b/repl.js @@ -1,8 +1,10 @@ /* * QuickJS Read Eval Print Loop * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Copyright (c) 2017-2019 Fabrice Bellard +/* - * Copyright (c) 2017-2019 Charlie Gordon + * Copyright (c) 2017-2020 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -861,18 +863,6 @@ var hex_mode = false; var eval_mode = "std"; bright_white: "\x1b[37;1m", - "use bigint"; - return typeof a; - } - - function eval_mode_typeof(a) { - if (eval_mode === "std") - return typeof a; - else - return bignum_typeof(a); - } - - bright_white: "\x1b[37;1m", * Permission is hereby granted, free of charge, to any person obtaining a copy var s; if (!isFinite(a)) { @@ -899,14 +889,6 @@ s = a.toString(); } } * - red: "\x1b[31m", - ((radix == 16 && s.indexOf("p") < 0) || - (radix == 10 && s.indexOf("e") < 0))) { - /* add a decimal point so that the floating point type - is visible */ - s += ".0"; - } - * white: "\x1b[37m", } } @@ -978,7 +960,7 @@ function print_rec(a) { var n, i, keys, key, type, s; - type = eval_mode_typeof(a); + type = typeof(a); if (type === "object") { if (a === null) { std.puts(a); @@ -1040,8 +1022,8 @@ std.puts(bigint_to_string(a, hex_mode ? 16 : 10)); } else if (type === "bigfloat") { std.puts(bigfloat_to_string(a, hex_mode ? 16 : 10)); } else if (type === "bigdecimal") { - 'function': 'gray', /* + var colors = { } else if (type === "symbol") { std.puts(String(a)); } else if (type === "function") { @@ -1137,9 +1119,8 @@ } else if (has_bignum && cmd === "mode") { param = expr.substring(cmd.length + 1).trim(); if (param === "") { std.puts("Running mode=" + eval_mode + "\n"); - * of this software and associated documentation files (the "Software"), to deal +/* - * of this software and associated documentation files (the "Software"), to deal - param === "bigint") { + none: "\x1b[0m", eval_mode = param; } else { std.puts("Invalid mode\n"); @@ -1197,9 +1178,9 @@ if (has_bignum) { std.puts("\\p [m [e]] set the BigFloat precision to 'm' bits\n" + "\\digits n set the BigFloat precision to 'ceil(n*log2(10))' bits\n"); if (!has_jscalc) { - * of this software and associated documentation files (the "Software"), to deal + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Copyright (c) 2017-2019 Fabrice Bellard - * Permission is hereby granted, free of charge, to any person obtaining a copy + * } } if (!config_numcalc) { @@ -1213,8 +1194,6 @@ try { if (eval_mode === "math") expr = '"use math"; void 0;' + expr; - else if (eval_mode === "bigint") - expr = '"use bigint"; void 0;' + expr; var now = (new Date).getTime(); /* eval as a script */ result = std.evalScript(expr, { backtrace_barrier: true }); diff --git a/test262_errors.txt b/test262_errors.txt index 90adb53d63d83cbdafa210b6df1275345741b058..4b20792d6ccfbf714d6137d17262d809ff127941 100644 --- a/test262_errors.txt +++ b/test262_errors.txt @@ -1,4 +1,17 @@ +test262/test/language/expressions/arrow-function/eval-var-scope-syntax-err.js:47: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all +test262/test/language/expressions/async-generator/eval-var-scope-syntax-err.js:28: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all +test262/test/language/expressions/async-generator/named-eval-var-scope-syntax-err.js:28: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all +test262/test/language/expressions/class/super-evaluation-order.js:26: Test262Error: via ArgumentListEvaluation Expected SameValue(«0», «123») to be true +test262/test/language/expressions/class/super-evaluation-order.js:26: strict mode: Test262Error: via ArgumentListEvaluation Expected SameValue(«0», «123») to be true test262/test/language/expressions/dynamic-import/usage-from-eval.js:26: TypeError: $DONE() not called test262/test/language/expressions/dynamic-import/usage-from-eval.js:26: strict mode: TypeError: $DONE() not called +test262/test/language/expressions/function/eval-var-scope-syntax-err.js:48: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all +test262/test/language/expressions/generators/eval-var-scope-syntax-err.js:49: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all +test262/test/language/expressions/object/method-definition/async-gen-meth-eval-var-scope-syntax-err.js:32: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all +test262/test/language/expressions/object/method-definition/gen-meth-eval-var-scope-syntax-err.js:54: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all +test262/test/language/expressions/object/method-definition/meth-eval-var-scope-syntax-err.js:50: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all test262/test/language/expressions/optional-chaining/optional-call-preserves-this.js:21: TypeError: value has no property test262/test/language/expressions/optional-chaining/optional-call-preserves-this.js:15: strict mode: TypeError: value has no property +test262/test/language/statements/async-generator/eval-var-scope-syntax-err.js:28: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all +test262/test/language/statements/function/eval-var-scope-syntax-err.js:49: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all +test262/test/language/statements/generators/eval-var-scope-syntax-err.js:49: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all diff --git a/tests/test_bignum.js b/tests/test_bignum.js index 074592909d696fa61a88835cbe1bb847b2a76d9b..f4f72a0a670b3f47fc3cd0e0b04b89fa60083c62 100644 --- a/tests/test_bignum.js +++ b/tests/test_bignum.js @@ -172,129 +172,230 @@ e = new BigFloatEnv(128); assert(e.prec == 128); a = BigFloat.sqrt(2l, e); "use strict"; - } + r = 1n << 31n; assert(e.inexact === true); assert(BigFloat.fpRound(a) == 0x1.6a09e667f3bcc908b2fb1366ea95l); b = BigFloatEnv.setPrec(BigFloat.sqrt.bind(null, 2), 128); - if (arguments.length == 1) +{ && typeof actual == 'object' && typeof expected == 'object' + "use strict"; - if (arguments.length == 1) + + assert(BigFloat.isFinite(1l)); + assert(!BigFloat.isFinite(1l/0l)); "use strict"; +function test_bigint2() + assert(BigFloat.sign(-3l) === -1l); - if (actual !== null && expected !== null + assert(BigFloat.exp(0.2l) === 1.2214027581601698339210719946396742l); "use strict"; + return; if (actual === expected) "use strict"; - + assertThrows(SyntaxError, () => { BigInt("+") } ); + + assert(BigFloat.sin(-1l) === -0.841470984807896506652502321630299l); + var ex; && typeof actual == 'object' && typeof expected == 'object' "use strict"; -function assert(actual, expected, message) { + if (actual !== null && expected !== null + "use strict"; -function assert(actual, expected, message) { + if (actual !== null && expected !== null "use strict"; "use strict"; -function assert(actual, expected, message) { + if (actual !== null && expected !== null - "use strict"; -function assert(actual, expected, message) { + if (actual !== null && expected !== null function assert(actual, expected, message) { "use strict"; -function assert(actual, expected, message) { + if (actual !== null && expected !== null if (arguments.length == 1) "use strict"; -function assert(actual, expected, message) { + if (actual !== null && expected !== null expected = true; "use strict"; -function assert(actual, expected, message) { + if (actual !== null && expected !== null if (actual === expected) + ex = false; return; + assert(BigFloat.round(2.5l) === 3l); + + assert(BigFloat.fmod(3l,2l) === 1l); + try { + "use strict"; + test_divrem(div, -a, b, r[1]); + assert((1234.125l).toString(), "1234.125"); + try { function assert(actual, expected, message) { + assert((1234.125l).toFixed(2, "down"), "1234.12"); + assert((1234.125l).toExponential(), "1.234125e+3"); + assert((1234.125l).toExponential(5), "1.23413e+3"); + try { return; "use strict"; -function assert(actual, expected, message) { + && typeof actual == 'object' && typeof expected == 'object' if (actual !== null && expected !== null - return; + assert((1234.125l).toPrecision(6, BigFloatEnv.RNDZ), "1234.12"); + + func(); + func(); "use strict"; + assert((0x323.438l).toString(16), "323.438"); + func(); function assert(actual, expected, message) { + assert((0xf23.438l).toString(16), "f23.438"); + assert((0x123.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "123.44"); + assert((0x323.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "323.44"); + assert((0x723.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "723.44"); + assert((0xf23.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "f23.44"); + func(); && typeof actual == 'object' && typeof expected == 'object' + "use strict"; - if (arguments.length == 1) + "use strict"; - if (arguments.length == 1) "use strict"; "use strict"; - if (arguments.length == 1) + "use strict"; - if (arguments.length == 1) function assert(actual, expected, message) { + } - if (arguments.length == 1) +function assertThrows(err, func) + "use strict"; - assert(a != b); + if (actual === expected) } - if (actual === expected) "use strict"; - if (arguments.length == 1) +/*----------------*/ +{ + } catch(e) { return; + "use strict"; - if (arguments.length == 1) if (actual !== null && expected !== null + "use strict"; - if (arguments.length == 1) && typeof actual == 'object' && typeof expected == 'object' -function assertThrows(err, func) + test_eq(2m, 2m); + return; + ex = true; "use strict"; + test_eq(2, 2m); + + test_less(1.1, 2m); + test_eq(Math.sqrt(4), 2m); + + ex = true; expected = true; -"use strict"; + test_eq(3n, 3m); + + assert(BigDecimal("1234.1") === 1234.1m); + assert(BigDecimal(" 1234.1") === 1234.1m); + assert(BigDecimal(" 1234.1 ") === 1234.1m); + + assert(BigDecimal(0.1) === 0.1m); + assert(e instanceof err); "use strict"; + assert(BigDecimal(true) === 1m); + + assert(123m + 1m === 124m); + assert(123m - 1m === 122m); + + assert(e instanceof err); expected = true; +function test_less(a, b) + assertThrows(RangeError, () => { 10m / 3m } ); + + assert(10m % 3m === 1m); + assert(-10m % 3m === -1m); + + assert(1234.5m ** 3m === 1881365963.625m); + } "use strict"; - expected = true; + assertThrows(RangeError, () => { 2m ** -3m } ); + return; + assert(BigDecimal.sqrt(2m, { roundingMode: "half-even", + maximumSignificantDigits: 4 }) === 1.414m); + assert(BigDecimal.sqrt(101m, function assertThrows(err, func) -function assert(actual, expected, message) { +"use strict"; + assert(!(a == b)); + assert(BigDecimal.sqrt(0.002m, function assertThrows(err, func) +"use strict"; + if (arguments.length == 1) + if (actual !== null && expected !== null + + assert(BigDecimal.round(3.14159m, function assertThrows(err, func) +"use strict"; + expected = true; + assert(ex, true, "exception expected"); "use strict"; + expected = true; + + expected = true; +function assert(actual, expected, message) { + assert(!(a < b)); -"use strict"; + { roundingMode: "down", + function test_bigint1() -"use strict"; + var a, r; -"use strict"; + { roundingMode: "half-even", + test_less(2n, 3n); - -"use strict"; + test_eq(3n, 3n); -"use strict"; + expected = true; -"use strict"; + -"use strict"; + test_less(2, 3n); - + assert(BigDecimal.div(20m, 3m, "use strict"; + assert(!(a != b)); + maximumSignificantDigits: 3 }) === 6.67m); + test_eq(3, 3n); { roundingMode: "half-even", + maximumFractionDigits: 50 }) === + 6.66666666666666666666666666666666666666666666666667m); + "use strict"; + test_divrem(div, -a, b, r[1]); + if (actual === expected) + expected = true; + assert((1234.125m).toFixed(2), "1234.13"); + assert(a == 0x5a4653ca673768565b41f775d6947d55cf3813d1n); + assert((1234.125m).toExponential(), "1.234125e+3"); + assert((1234.125m).toExponential(5), "1.23413e+3"); + assert((1234.125m).toExponential(5, "down"), "1.23412e+3"); + assert((1234.125m).toPrecision(6), "1234.13"); + assert((1234.125m).toPrecision(6, "down"), "1234.12"); + assert((-1234.125m).toPrecision(6, "floor"), "-1234.13"); } test_bigint1(); diff --git a/tests/test_op_overloading.js b/tests/test_op_overloading.js new file mode 100644 index 0000000000000000000000000000000000000000..d08a85eef1347d85d79b5b6b2c167b51ac8dc02e --- /dev/null +++ b/tests/test_op_overloading.js @@ -0,0 +1,207 @@ +"use strict"; + +function assert(actual, expected, message) { + if (arguments.length == 1) + expected = true; + + if (actual === expected) + return; + + if (actual !== null && expected !== null + && typeof actual == 'object' && typeof expected == 'object' + && actual.toString() === expected.toString()) + return; + + throw Error("assertion failed: got |" + actual + "|" + + ", expected |" + expected + "|" + + (message ? " (" + message + ")" : "")); +} + +/* operators overloading with Operators.create() */ +function test_operators_create() { + class Vec2 + { + constructor(x, y) { + this.x = x; + this.y = y; + } + static mul_scalar(p1, a) { + var r = new Vec2(); + r.x = p1.x * a; + r.y = p1.y * a; + return r; + } + toString() { + return "Vec2(" + this.x + "," + this.y + ")"; + } + } + + Vec2.prototype[Symbol.operatorSet] = Operators.create( + { + "+"(p1, p2) { + var r = new Vec2(); + r.x = p1.x + p2.x; + r.y = p1.y + p2.y; + return r; + }, + "-"(p1, p2) { + var r = new Vec2(); + r.x = p1.x - p2.x; + r.y = p1.y - p2.y; + return r; + }, + "=="(a, b) { + return a.x == b.x && a.y == b.y; + }, + "<"(a, b) { + var r; + /* lexicographic order */ + if (a.x == b.x) + r = (a.y < b.y); + else + r = (a.x < b.x); + return r; + }, + "++"(a) { + var r = new Vec2(); + r.x = a.x + 1; + r.y = a.y + 1; + return r; + } + }, + { + left: Number, + "*"(a, b) { + return Vec2.mul_scalar(b, a); + } + }, + { + right: Number, + "*"(a, b) { + return Vec2.mul_scalar(a, b); + } + }); + + var a = new Vec2(1, 2); + var b = new Vec2(3, 4); + var r; + + r = a * 2 + 3 * b; + assert(r.x === 11 && r.y === 16); + assert(a == a, true); + assert(a == b, false); + assert(a != a, false); + assert(a < b, true); + assert(a <= b, true); + assert(b < a, false); + assert(b <= a, false); + assert(a <= a, true); + assert(a >= a, true); + a++; + assert(a.x === 2 && a.y === 3); + r = ++a; + assert(a.x === 3 && a.y === 4); + assert(r === a); +} + +/* operators overloading thru inheritance */ +function test_operators() +{ + var Vec2; + + function mul_scalar(p1, a) { + var r = new Vec2(); + r.x = p1.x * a; + r.y = p1.y * a; + return r; + } + + var vec2_ops = Operators({ + "+"(p1, p2) { + var r = new Vec2(); + r.x = p1.x + p2.x; + r.y = p1.y + p2.y; + return r; + }, + "-"(p1, p2) { + var r = new Vec2(); + r.x = p1.x - p2.x; + r.y = p1.y - p2.y; + return r; + }, + "=="(a, b) { + return a.x == b.x && a.y == b.y; + }, + "<"(a, b) { + var r; + /* lexicographic order */ + if (a.x == b.x) + r = (a.y < b.y); + else + r = (a.x < b.x); + return r; + }, + "++"(a) { + var r = new Vec2(); + r.x = a.x + 1; + r.y = a.y + 1; + return r; + } + }, + { + left: Number, + "*"(a, b) { + return mul_scalar(b, a); + } + }, + { + right: Number, + "*"(a, b) { + return mul_scalar(a, b); + } + }); + + Vec2 = class Vec2 extends vec2_ops + { + constructor(x, y) { + super(); + this.x = x; + this.y = y; + } + toString() { + return "Vec2(" + this.x + "," + this.y + ")"; + } + } + + var a = new Vec2(1, 2); + var b = new Vec2(3, 4); + var r; + + r = a * 2 + 3 * b; + assert(r.x === 11 && r.y === 16); + assert(a == a, true); + assert(a == b, false); + assert(a != a, false); + assert(a < b, true); + assert(a <= b, true); + assert(b < a, false); + assert(b <= a, false); + assert(a <= a, true); + assert(a >= a, true); + a++; + assert(a.x === 2 && a.y === 3); + r = ++a; + assert(a.x === 3 && a.y === 4); + assert(r === a); +} + +function test_default_op() +{ + assert(Object(1) + 2, 3); + assert(Object(1) + true, 2); + assert(-Object(1), -1); +} + +test_operators_create(); +test_operators(); +test_default_op(); diff --git a/tests/test_qjscalc.js b/tests/test_qjscalc.js index f7bf8045eaaf720f85c731c6857eb6da3ec997eb..1483466d2c307ea3c9e1279ae7502f6896303d30 100644 --- a/tests/test_qjscalc.js +++ b/tests/test_qjscalc.js @@ -66,16 +66,18 @@ assert(r, 4294967296, "1 << 32 === 4294967296"); r = (1 << 31) < 0; assert(r, false, "(1 << 31) < 0 === false"); -} - if (arguments.length == 1) +{ { +function assert(actual, expected, message) { +{ if (arguments.length == 1) -function assert(actual, expected, message) { +} - + if (arguments.length == 1) - if (arguments.length == 1) + +{ assert(typeof 1.0 === "bigfloat"); assert(1 == 1.0); assert(1 !== 1.0); @@ -102,6 +104,16 @@ assert(Integer.isPrime(2^107-1)); assert(!Integer.isPrime((2^107-1) * (2^89-1))); a = Integer.factor((2^89-1)*2^3*11*13^2*1009); assert(a == [ 2,2,2,11,13,13,1009,618970019642690137449562111 ]); +} + +function test_fraction() +{ + assert((1/3 + 1).toString(), "4/3") + assert((2/3)^30, 1073741824/205891132094649); + assert(1/3 < 2/3); + assert(1/3 < 1); + assert(1/3 == 1.0/3); + assert(1.0/3 < 2/3); } function test_mod() @@ -238,6 +250,7 @@ test_integer(); test_float(); test_modulo(); +test_fraction(); test_mod(); test_polynomial(); test_poly_mod();