From b41c0f432b9a48288406a3b177caea3ee5023b81 Mon Sep 17 00:00:00 2001 From: Luis Finke Date: Fri, 24 Oct 2014 17:41:33 -0400 Subject: [PATCH 01/11] Added (optional) protection against divide by zero exceptions defining the preprocessor CHAISCRIPT_PROTECT_DIVIDEBYZERO adds checking of right side values before division arithmetic, allowing the user to safely catch a divide by zero error, rather than dealing with a SIGFPE and having the entire program exit without a choice --- .../chaiscript/dispatchkit/boxed_number.hpp | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index f3d2838..74de1e5 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -22,6 +22,22 @@ namespace chaiscript { class Dynamic_Cast_Conversions; } // namespace chaiscript +namespace chaiscript +{ + namespace exception + { + struct arithmetic_error : public std::runtime_error + { + std::string reason; + + arithmetic_error(const std::string& reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} + arithmetic_error(const char* reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} + virtual ~arithmetic_error() {} + }; +#define CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(T, n) if(std::is_arithmetic::value) if(n==0) throw chaiscript::exception::arithmetic_error("divide by zero"); + } +} + namespace chaiscript { @@ -89,6 +105,9 @@ namespace chaiscript t += u; break; case Operators::assign_quotient: + #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) + #endif t /= u; break; case Operators::assign_difference: @@ -122,6 +141,9 @@ namespace chaiscript t >>= u; break; case Operators::assign_remainder: + #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) + #endif t %= u; break; case Operators::assign_bitwise_xor: @@ -146,6 +168,9 @@ namespace chaiscript case Operators::shift_right: return const_var(t >> u); case Operators::remainder: + #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) + #endif return const_var(t % u); case Operators::bitwise_and: return const_var(t & u); @@ -171,6 +196,9 @@ namespace chaiscript case Operators::sum: return const_var(t + u); case Operators::quotient: + #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) + #endif return const_var(t / u); case Operators::product: return const_var(t * u); From de0948935545195d177dc771a5d33b8d8dde36f4 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 19:02:56 -0700 Subject: [PATCH 02/11] Fix formatting (tabs vs spaces) in divide/0 protection --- .../chaiscript/dispatchkit/boxed_number.hpp | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index ed74855..1eefcc9 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -24,18 +24,18 @@ class Type_Conversions; namespace chaiscript { - namespace exception - { - struct arithmetic_error : public std::runtime_error - { - std::string reason; + namespace exception + { + struct arithmetic_error : public std::runtime_error + { + std::string reason; - arithmetic_error(const std::string& reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} - arithmetic_error(const char* reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} - virtual ~arithmetic_error() {} - }; + arithmetic_error(const std::string& reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} + arithmetic_error(const char* reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} + virtual ~arithmetic_error() {} + }; #define CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(T, n) if(std::is_arithmetic::value) if(n==0) throw chaiscript::exception::arithmetic_error("divide by zero"); - } + } } namespace chaiscript @@ -105,10 +105,10 @@ namespace chaiscript t += u; break; case Operators::assign_quotient: - #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) - #endif - t /= u; +#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) +#endif + t /= u; break; case Operators::assign_difference: t -= u; @@ -141,9 +141,9 @@ namespace chaiscript t >>= u; break; case Operators::assign_remainder: - #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) - #endif +#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) +#endif t %= u; break; case Operators::assign_bitwise_xor: @@ -168,10 +168,10 @@ namespace chaiscript case Operators::shift_right: return const_var(t >> u); case Operators::remainder: - #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) - #endif - return const_var(t % u); +#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) +#endif + return const_var(t % u); case Operators::bitwise_and: return const_var(t & u); case Operators::bitwise_or: @@ -196,10 +196,10 @@ namespace chaiscript case Operators::sum: return const_var(t + u); case Operators::quotient: - #ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) - #endif - return const_var(t / u); +#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) +#endif + return const_var(t / u); case Operators::product: return const_var(t * u); case Operators::difference: From 1a4dec0df070de2ce9e6297a9f859da64fc5ba3d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 19:06:08 -0700 Subject: [PATCH 03/11] Remove redundant/unnecessary constructors and object copies. --- include/chaiscript/dispatchkit/boxed_number.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 1eefcc9..16022ca 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -28,10 +28,7 @@ namespace chaiscript { struct arithmetic_error : public std::runtime_error { - std::string reason; - - arithmetic_error(const std::string& reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} - arithmetic_error(const char* reason) : std::runtime_error(std::string("Arithmetic error: ").append(reason)), reason(reason) {} + arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {} virtual ~arithmetic_error() {} }; #define CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(T, n) if(std::is_arithmetic::value) if(n==0) throw chaiscript::exception::arithmetic_error("divide by zero"); From 0695eec3caf108756fc615596f48b9c8a6c73c33 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 19:30:28 -0700 Subject: [PATCH 04/11] Limit scope of #ifdefs, remove macros Macros do not fit within the ChaiScript coding standards because they do not respect namespaces and are more difficult to debug of something goes wrong. --- .../chaiscript/dispatchkit/boxed_number.hpp | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 16022ca..87d0cb3 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -31,7 +31,6 @@ namespace chaiscript arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {} virtual ~arithmetic_error() {} }; -#define CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(T, n) if(std::is_arithmetic::value) if(n==0) throw chaiscript::exception::arithmetic_error("divide by zero"); } } @@ -50,6 +49,19 @@ namespace chaiscript class Boxed_Number { private: +#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO + template + static void check_divide_by_zero(T t) + { + if(std::is_arithmetic::value) if(t==0) throw chaiscript::exception::arithmetic_error("divide by zero"); + } +#else + template + static void check_divide_by_zero(T) + { + } +#endif + struct boolean { @@ -74,7 +86,7 @@ namespace chaiscript case Operators::not_equal: return const_var(t != u); default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -102,16 +114,14 @@ namespace chaiscript t += u; break; case Operators::assign_quotient: -#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) -#endif - t /= u; + check_divide_by_zero(u); + t /= u; break; case Operators::assign_difference: t -= u; break; default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } return t_lhs; @@ -138,16 +148,14 @@ namespace chaiscript t >>= u; break; case Operators::assign_remainder: -#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) -#endif + check_divide_by_zero(u); t %= u; break; case Operators::assign_bitwise_xor: t ^= u; break; default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } return t_lhs; } @@ -165,10 +173,8 @@ namespace chaiscript case Operators::shift_right: return const_var(t >> u); case Operators::remainder: -#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) -#endif - return const_var(t % u); + check_divide_by_zero(u); + return const_var(t % u); case Operators::bitwise_and: return const_var(t & u); case Operators::bitwise_or: @@ -178,7 +184,7 @@ namespace chaiscript case Operators::bitwise_complement: return const_var(~t); default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -193,10 +199,8 @@ namespace chaiscript case Operators::sum: return const_var(t + u); case Operators::quotient: -#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO - CHAISCRIPT_ARITHMETIC_CHECKDIVIDEBYZERO(U, u) -#endif - return const_var(t / u); + check_divide_by_zero(u); + return const_var(t / u); case Operators::product: return const_var(t * u); case Operators::difference: @@ -206,7 +210,7 @@ namespace chaiscript case Operators::unary_plus: return const_var(+t); default: - throw chaiscript::detail::exception::bad_any_cast(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; @@ -352,7 +356,6 @@ namespace chaiscript return oss.str(); } - public: Boxed_Number() : bv(Boxed_Value(0)) @@ -868,12 +871,12 @@ namespace chaiscript struct Cast_Helper : Cast_Helper { }; - + /// Cast_Helper for converting from Boxed_Value to Boxed_Number template<> struct Cast_Helper : Cast_Helper { - }; + }; } #ifdef CHAISCRIPT_MSVC From 8746a9eea52e805f47f48d3679ca72077d284e40 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 19:38:27 -0700 Subject: [PATCH 05/11] Make divide by zero protection the default --- include/chaiscript/dispatchkit/boxed_number.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 87d0cb3..69cfefa 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -49,7 +49,7 @@ namespace chaiscript class Boxed_Number { private: -#ifdef CHAISCRIPT_PROTECT_DIVIDEBYZERO +#ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO template static void check_divide_by_zero(T t) { From 25b15a3449c39589855eb10a134e664082600902 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 20:06:04 -0700 Subject: [PATCH 06/11] Only apply divide by zero protection to integers Also allow arithmetic error to bubble up to the caller. --- include/chaiscript/dispatchkit/bootstrap.hpp | 10 +++++++--- include/chaiscript/dispatchkit/boxed_number.hpp | 4 +++- include/chaiscript/language/chaiscript_eval.hpp | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 3e88daf..579b6ee 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -396,10 +396,9 @@ namespace chaiscript m->add(user_type(), "runtime_error"); m->add(chaiscript::base_class()); - m->add(constructor(), "runtime_error"); - m->add(fun(std::function(&what)), "what"); + m->add(fun(std::function(&what)), "what"); m->add(user_type(), "Dynamic_Object"); m->add(constructor(), "Dynamic_Object"); @@ -487,7 +486,12 @@ namespace chaiscript m->add(chaiscript::fun(&has_parse_tree), "has_parse_tree"); m->add(chaiscript::fun(&get_parse_tree), "get_parse_tree"); - m->add(chaiscript::base_class()); + m->add(chaiscript::user_type("eval_error")); + m->add(chaiscript::base_class()); + + m->add(chaiscript::user_type("arithmetic_error")); + m->add(chaiscript::base_class()); + // chaiscript::bootstrap::standard_library::vector_type > >("AST_NodeVector", m); diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 69cfefa..150e76c 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -53,7 +53,9 @@ namespace chaiscript template static void check_divide_by_zero(T t) { - if(std::is_arithmetic::value) if(t==0) throw chaiscript::exception::arithmetic_error("divide by zero"); + if(std::is_integral::value && std::is_arithmetic::value && t==0) { + throw chaiscript::exception::arithmetic_error("divide by zero"); + } } #else template diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index be9aabc..eafb84b 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -93,6 +93,8 @@ namespace chaiscript // If it's an arithmetic operation we want to short circuit dispatch try{ return Boxed_Number::do_oper(t_oper, t_lhs, t_rhs); + } catch (const chaiscript::exception::arithmetic_error &) { + throw; } catch (...) { throw exception::eval_error("Error with numeric operator calling: " + t_oper_string); } From 576816e3b11d6fb04f09fa810144a0c418454c62 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 20:17:20 -0700 Subject: [PATCH 07/11] Add unit test for divide by zero protection --- include/chaiscript/dispatchkit/bootstrap.hpp | 4 ++-- unittests/divide_by_zero_protection.chai | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 unittests/divide_by_zero_protection.chai diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 579b6ee..dd1f880 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -486,10 +486,10 @@ namespace chaiscript m->add(chaiscript::fun(&has_parse_tree), "has_parse_tree"); m->add(chaiscript::fun(&get_parse_tree), "get_parse_tree"); - m->add(chaiscript::user_type("eval_error")); + m->add(chaiscript::user_type(), "eval_error"); m->add(chaiscript::base_class()); - m->add(chaiscript::user_type("arithmetic_error")); + m->add(chaiscript::user_type(), "arithmetic_error"); m->add(chaiscript::base_class()); diff --git a/unittests/divide_by_zero_protection.chai b/unittests/divide_by_zero_protection.chai new file mode 100644 index 0000000..ba40a43 --- /dev/null +++ b/unittests/divide_by_zero_protection.chai @@ -0,0 +1,7 @@ +try { + 3/0 + assert_true(false); // should never get here +} catch (e) { + assert_equal("Arithmetic error: divide by zero", e.what()) +} + From 420ba68b94a23fb4b02a7aa8bd6e3d433e22ce54 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 20:20:38 -0700 Subject: [PATCH 08/11] Make sure floating point returns Infinity --- unittests/divide_by_zero_protection.chai | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unittests/divide_by_zero_protection.chai b/unittests/divide_by_zero_protection.chai index ba40a43..db648fc 100644 --- a/unittests/divide_by_zero_protection.chai +++ b/unittests/divide_by_zero_protection.chai @@ -5,3 +5,5 @@ try { assert_equal("Arithmetic error: divide by zero", e.what()) } +assert_equal(3/0.0, Infinity) + From 2f90b3ae6bec2b77f1f9d7bf98212c001230305c Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Jan 2015 20:31:40 -0700 Subject: [PATCH 09/11] Correct exception specifier for arithmetic_error --- include/chaiscript/dispatchkit/boxed_number.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 150e76c..6000468 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -29,7 +29,7 @@ namespace chaiscript struct arithmetic_error : public std::runtime_error { arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {} - virtual ~arithmetic_error() {} + virtual ~arithmetic_error() CHAISCRIPT_NOEXCEPT {} }; } } From 9b3bb493e9df44c1abd4a6dc609899f502ace8ec Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 10 Jan 2015 07:18:10 -0700 Subject: [PATCH 10/11] Clean up some MSVC warnings --- include/chaiscript/dispatchkit/boxed_number.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 6000468..c00911c 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -53,9 +53,21 @@ namespace chaiscript template static void check_divide_by_zero(T t) { + +#ifdef CHAISCRIPT_MSVC + // MSVC complains that this expression is both constant and the value t is unused + // in the cases of integral expressions. Seems a bit overzealous to me, the parameter + // is only unreferenced because they are eliminating the dead code. +#pragma warning(push) +#pragma warning(disable : 4100 4127) +#endif if(std::is_integral::value && std::is_arithmetic::value && t==0) { throw chaiscript::exception::arithmetic_error("divide by zero"); } +#ifdef CHAISCRIPT_MSVC +#pragma warning(pop) +#endif + } #else template From 31ef683cedd35fb0ff10094f7c7649b97832b86d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 12 Jan 2015 10:06:42 -0700 Subject: [PATCH 11/11] Use SFINAE to clean up divide by zero protection --- .../chaiscript/dispatchkit/boxed_number.hpp | 22 +++++-------------- unittests/future.chai | 6 ++--- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index c00911c..a0ad6aa 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -49,32 +49,20 @@ namespace chaiscript class Boxed_Number { private: -#ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO template - static void check_divide_by_zero(T t) + static void check_divide_by_zero(T t, typename std::enable_if::value>::type* = 0) { - -#ifdef CHAISCRIPT_MSVC - // MSVC complains that this expression is both constant and the value t is unused - // in the cases of integral expressions. Seems a bit overzealous to me, the parameter - // is only unreferenced because they are eliminating the dead code. -#pragma warning(push) -#pragma warning(disable : 4100 4127) -#endif - if(std::is_integral::value && std::is_arithmetic::value && t==0) { +#ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO + if (t == 0) { throw chaiscript::exception::arithmetic_error("divide by zero"); } -#ifdef CHAISCRIPT_MSVC -#pragma warning(pop) #endif - } -#else + template - static void check_divide_by_zero(T) + static void check_divide_by_zero(T, typename std::enable_if::value>::type* = 0) { } -#endif struct boolean { diff --git a/unittests/future.chai b/unittests/future.chai index afb9afe..750c27d 100644 --- a/unittests/future.chai +++ b/unittests/future.chai @@ -1,6 +1,6 @@ var func = fun(){ var ret = 0; - for (var i = 0; i < 1000000; ++i) { + for (var i = 0; i < 50000; ++i) { ret += i; } return ret; @@ -9,9 +9,7 @@ var func = fun(){ var fut1 := async(func); var fut2 := async(func); -var fut3 := async(func); -var fut4 := async(func); // simply executing without crashing is good enough for this test -print(" ${fut1.get()} ${fut2.get()} ${fut3.get()} ${fut4.get()}") +print(" ${fut1.get()} ${fut2.get()} ")