d0aebc06e0
This CL adds support in TurboFan for passing JSArrays as arguments to fast API callbacks. It also extends the v8::Array class with a CopyAndConvertArrayToCppBuffer method to allow the embedder to perform quick conversions of their JSArrays to a C++ buffer. The CL also adds tests in d8. Design doc: https://docs.google.com/document/d/1BNKKZNgrGYafx8kqSfNEQqQYY5n4A6mGufss_Vz-h-4/edit#heading=h.c0kgf82jnlpp Bug: chromium:1052746, chromium:715122 Change-Id: If47ac60d9ebe6462bbf3adff002e2da8e14e8fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2940900 Commit-Queue: Maya Lekova <mslekova@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/master@{#75333}
140 lines
4.1 KiB
C++
140 lines
4.1 KiB
C++
// Copyright 2016 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "src/numbers/conversions.h"
|
|
|
|
#include "src/codegen/source-position.h"
|
|
#include "src/init/v8.h"
|
|
#include "test/unittests/test-utils.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
namespace interpreter {
|
|
|
|
class ConversionsTest : public ::testing::Test {
|
|
public:
|
|
ConversionsTest() = default;
|
|
~ConversionsTest() override = default;
|
|
|
|
SourcePosition toPos(int offset) {
|
|
return SourcePosition(offset, offset % 10 - 1);
|
|
}
|
|
};
|
|
|
|
// Some random offsets, mostly at 'suspicious' bit boundaries.
|
|
|
|
struct IntStringPair {
|
|
int integer;
|
|
std::string string;
|
|
};
|
|
|
|
static IntStringPair int_pairs[] = {{0, "0"},
|
|
{101, "101"},
|
|
{-1, "-1"},
|
|
{1024, "1024"},
|
|
{200000, "200000"},
|
|
{-1024, "-1024"},
|
|
{-200000, "-200000"},
|
|
{kMinInt, "-2147483648"},
|
|
{kMaxInt, "2147483647"}};
|
|
|
|
TEST_F(ConversionsTest, IntToCString) {
|
|
std::unique_ptr<char[]> buf(new char[4096]);
|
|
|
|
for (size_t i = 0; i < arraysize(int_pairs); i++) {
|
|
ASSERT_STREQ(IntToCString(int_pairs[i].integer, {buf.get(), 4096}),
|
|
int_pairs[i].string.c_str());
|
|
}
|
|
}
|
|
|
|
struct DoubleStringPair {
|
|
double number;
|
|
std::string string;
|
|
};
|
|
|
|
static DoubleStringPair double_pairs[] = {
|
|
{0.0, "0"},
|
|
{kMinInt, "-2147483648"},
|
|
{kMaxInt, "2147483647"},
|
|
// ES section 7.1.12.1 #sec-tostring-applied-to-the-number-type:
|
|
// -0.0 is stringified to "0".
|
|
{-0.0, "0"},
|
|
{1.1, "1.1"},
|
|
{0.1, "0.1"}};
|
|
|
|
TEST_F(ConversionsTest, DoubleToCString) {
|
|
std::unique_ptr<char[]> buf(new char[4096]);
|
|
|
|
for (size_t i = 0; i < arraysize(double_pairs); i++) {
|
|
ASSERT_STREQ(DoubleToCString(double_pairs[i].number, {buf.get(), 4096}),
|
|
double_pairs[i].string.c_str());
|
|
}
|
|
}
|
|
|
|
struct DoubleInt32Pair {
|
|
double number;
|
|
int integer;
|
|
};
|
|
|
|
static DoubleInt32Pair double_int32_pairs[] = {
|
|
{0.0, 0},
|
|
{-0.0, 0},
|
|
{std::numeric_limits<double>::quiet_NaN(), 0},
|
|
{std::numeric_limits<double>::infinity(), 0},
|
|
{-std::numeric_limits<double>::infinity(), 0},
|
|
{3.14, 3},
|
|
{1.99, 1},
|
|
{-1.99, -1},
|
|
{static_cast<double>(kMinInt), kMinInt},
|
|
{static_cast<double>(kMaxInt), kMaxInt},
|
|
{kMaxSafeInteger, -1},
|
|
{kMinSafeInteger, 1},
|
|
{kMaxSafeInteger + 1, 0},
|
|
{kMinSafeInteger - 1, 0},
|
|
};
|
|
|
|
TEST_F(ConversionsTest, DoubleToInt32) {
|
|
for (size_t i = 0; i < arraysize(double_int32_pairs); i++) {
|
|
ASSERT_EQ(DoubleToInt32(double_int32_pairs[i].number),
|
|
double_int32_pairs[i].integer);
|
|
}
|
|
}
|
|
|
|
struct DoubleInt64Pair {
|
|
double number;
|
|
int64_t integer;
|
|
};
|
|
|
|
static DoubleInt64Pair double_int64_pairs[] = {
|
|
{0.0, 0},
|
|
{-0.0, 0},
|
|
{std::numeric_limits<double>::quiet_NaN(), 0},
|
|
{std::numeric_limits<double>::infinity(), 0},
|
|
{-std::numeric_limits<double>::infinity(), 0},
|
|
{3.14, 3},
|
|
{1.99, 1},
|
|
{-1.99, -1},
|
|
{kMinSafeInteger, static_cast<int64_t>(kMinSafeInteger)},
|
|
{kMaxSafeInteger, static_cast<int64_t>(kMaxSafeIntegerUint64)},
|
|
{kMinSafeInteger - 1, static_cast<int64_t>(kMinSafeInteger) - 1},
|
|
{kMaxSafeInteger + 1, static_cast<int64_t>(kMaxSafeIntegerUint64) + 1},
|
|
{static_cast<double>(std::numeric_limits<int64_t>::min()),
|
|
std::numeric_limits<int64_t>::min()},
|
|
// Max int64_t is not representable as a double, the closest is -2^63.
|
|
{static_cast<double>(std::numeric_limits<int64_t>::max()),
|
|
std::numeric_limits<int64_t>::min()},
|
|
// So we test for a smaller number, representable as a double.
|
|
{static_cast<double>((1ull << 63) - 1024), (1ull << 63) - 1024}};
|
|
|
|
TEST_F(ConversionsTest, DoubleToWebIDLInt64) {
|
|
for (size_t i = 0; i < arraysize(double_int64_pairs); i++) {
|
|
ASSERT_EQ(DoubleToWebIDLInt64(double_int64_pairs[i].number),
|
|
double_int64_pairs[i].integer);
|
|
}
|
|
}
|
|
|
|
} // namespace interpreter
|
|
} // namespace internal
|
|
} // namespace v8
|