From b3090678a9d9d1a8bda18a1781557d0547882da9 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Mon, 18 May 2020 16:04:38 +0100 Subject: [PATCH] LibJS: Add Math.clz32() --- Libraries/LibJS/Runtime/MathObject.cpp | 12 +++++++ Libraries/LibJS/Runtime/MathObject.h | 1 + Libraries/LibJS/Tests/Math.clz32.js | 50 ++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 Libraries/LibJS/Tests/Math.clz32.js diff --git a/Libraries/LibJS/Runtime/MathObject.cpp b/Libraries/LibJS/Runtime/MathObject.cpp index 2b173bcc701..73ee7696c0d 100644 --- a/Libraries/LibJS/Runtime/MathObject.cpp +++ b/Libraries/LibJS/Runtime/MathObject.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Andreas Kling + * Copyright (c) 2020, Linus Groh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,6 +54,7 @@ MathObject::MathObject() put_native_function("exp", exp, 1, attr); put_native_function("expm1", expm1, 1, attr); put_native_function("sign", sign, 1, attr); + put_native_function("clz32", clz32, 1, attr); put("E", Value(M_E), 0); put("LN2", Value(M_LN2), 0); @@ -245,4 +247,14 @@ Value MathObject::sign(Interpreter& interpreter) return js_nan(); } +Value MathObject::clz32(Interpreter& interpreter) +{ + auto number = interpreter.argument(0).to_number(interpreter); + if (interpreter.exception()) + return {}; + if (!number.is_finite_number() || (unsigned)number.as_double() == 0) + return Value(32); + return Value(__builtin_clz((unsigned)number.as_double())); +} + } diff --git a/Libraries/LibJS/Runtime/MathObject.h b/Libraries/LibJS/Runtime/MathObject.h index e9902e6d53d..1cd550ca7dc 100644 --- a/Libraries/LibJS/Runtime/MathObject.h +++ b/Libraries/LibJS/Runtime/MathObject.h @@ -54,6 +54,7 @@ private: static Value exp(Interpreter&); static Value expm1(Interpreter&); static Value sign(Interpreter&); + static Value clz32(Interpreter&); }; } diff --git a/Libraries/LibJS/Tests/Math.clz32.js b/Libraries/LibJS/Tests/Math.clz32.js new file mode 100644 index 00000000000..ee37c9212d0 --- /dev/null +++ b/Libraries/LibJS/Tests/Math.clz32.js @@ -0,0 +1,50 @@ +load("test-common.js"); + +try { + assert(Math.clz32.length === 1); + + assert(Math.clz32(0) === 32); + assert(Math.clz32(1) === 31); + assert(Math.clz32(2) === 30); + assert(Math.clz32(3) === 30); + assert(Math.clz32(4) === 29); + assert(Math.clz32(5) === 29); + assert(Math.clz32(-1) === 0); + assert(Math.clz32(-10) === 0); + assert(Math.clz32(-100) === 0); + assert(Math.clz32(-1000) === 0); + assert(Math.clz32(-0.123) === 32); + assert(Math.clz32(0.123) === 32); + assert(Math.clz32(1.23) === 31); + assert(Math.clz32(12) === 28); + assert(Math.clz32(123) === 25); + assert(Math.clz32(1234) === 21); + assert(Math.clz32(12345) === 18); + assert(Math.clz32(123456) === 15); + assert(Math.clz32(1234567) === 11); + assert(Math.clz32(12345678) === 8); + assert(Math.clz32(123456789) === 5); + assert(Math.clz32(999999999) === 2); + assert(Math.clz32(9999999999) === 1); + assert(Math.clz32(99999999999) === 1); + assert(Math.clz32(999999999999) === 0); + assert(Math.clz32(9999999999999) === 1); + assert(Math.clz32(99999999999999) === 3); + assert(Math.clz32(999999999999999) === 0); + + assert(Math.clz32() === 32); + assert(Math.clz32(NaN) === 32); + assert(Math.clz32(Infinity) === 32); + assert(Math.clz32(-Infinity) === 32); + assert(Math.clz32(false) === 32); + assert(Math.clz32(true) === 31); + assert(Math.clz32(null) === 32); + assert(Math.clz32(undefined) === 32); + assert(Math.clz32([]) === 32); + assert(Math.clz32({}) === 32); + assert(Math.clz32("foo") === 32); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}