Skip to content

Commit

Permalink
Merge branch 'main' into philippe/396-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
philippedistributive authored Jul 30, 2024
2 parents 6561d5a + 8f1ac3c commit 3b02465
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 12 deletions.
18 changes: 18 additions & 0 deletions include/PyBytesProxyHandler.hh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ public:
PyBytesProxyHandler() : PyObjectProxyHandler(&family) {};
static const char family;

/**
* @brief [[Set]]
*
* @param cx pointer to JSContext
* @param proxy The proxy object who's property we wish to set
* @param id Key of the property we wish to set
* @param v Value that we wish to set the property to
* @param receiver The `this` value to use when executing any code
* @param result whether or not the call succeeded
* @return true call succeed
* @return false call failed and an exception has been raised
*/
bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::HandleValue v, JS::HandleValue receiver,
JS::ObjectOpResult &result) const override;
Expand All @@ -33,6 +45,12 @@ public:
JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc
) const override;

/**
* @brief Handles python object reference count when JS Proxy object is finalized
*
* @param gcx pointer to JS::GCContext
* @param proxy the proxy object being finalized
*/
void finalize(JS::GCContext *gcx, JSObject *proxy) const override;
};

Expand Down
11 changes: 9 additions & 2 deletions src/BufferType.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,19 @@
#include <js/experimental/TypedData.h>
#include <js/ScalarType.h>

#include <limits.h>

// JS to Python

/* static */
const char *BufferType::_toPyBufferFormatCode(JS::Scalar::Type subtype) {
// floating point types
if (subtype == JS::Scalar::Float32) {
switch (subtype) {
case JS::Scalar::Float16:
return "e";
case JS::Scalar::Float32:
return "f";
} else if (subtype == JS::Scalar::Float64) {
case JS::Scalar::Float64:
return "d";
}

Expand Down Expand Up @@ -216,8 +220,11 @@ JS::Scalar::Type BufferType::_getPyBufferType(Py_buffer *bufView) {
return JS::Scalar::Float32;
} else if (typeCode == 'd') {
return JS::Scalar::Float64;
} else if (typeCode == 'e') {
return JS::Scalar::Float16;
}


// integer types
// We can't rely on the type codes alone since the typecodes are mapped to C types and would have different sizes on different architectures
// see https://docs.python.org/3.9/library/array.html#module-array
Expand Down
29 changes: 19 additions & 10 deletions src/PyBytesProxyHandler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,27 @@ static bool array_valueOf(JSContext *cx, unsigned argc, JS::Value *vp) {
bool isSharedMemory;
JS::AutoCheckCannotGC autoNoGC(cx);
uint8_t *data = JS::GetArrayBufferData(rootedArrayBuffer, &isSharedMemory, autoNoGC);

std::string valueOfString;

for (Py_ssize_t index = 0; index < byteLength; index++) {
if (index > 0) {
valueOfString += ",";
}

valueOfString += std::to_string(data[index]);

size_t numberOfDigits = 0;
for (size_t i = 0; i < byteLength; i++) {
numberOfDigits += data[i] < 10 ? 1 : data[i] < 100 ? 2 : 3;
}
const size_t STRING_LENGTH = byteLength + numberOfDigits;
JS::Latin1Char* buffer = (JS::Latin1Char *)malloc(sizeof(JS::Latin1Char) * STRING_LENGTH);

size_t charIndex = 0;
sprintf((char*)&buffer[charIndex], "%d", data[0]);
charIndex += data[0] < 10 ? 1 : data[0] < 100 ? 2 : 3;

for (size_t dataIndex = 1; dataIndex < byteLength; dataIndex++) {
buffer[charIndex] = ',';
charIndex++;
sprintf((char*)&buffer[charIndex], "%d", data[dataIndex]);
charIndex += data[dataIndex] < 10 ? 1 : data[dataIndex] < 100 ? 2 : 3;
}

args.rval().setString(JS_NewStringCopyZ(cx, valueOfString.c_str()));
JS::UniqueLatin1Chars str(buffer);
args.rval().setString(JS_NewLatin1String(cx, std::move(str), STRING_LENGTH - 1)); // don't include null byte
return true;
}

Expand Down
2 changes: 2 additions & 0 deletions tests/python/test_buffer_typed_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def assert_js_to_py_memoryview(buf: memoryview):
assert pm.eval("(arr)=>arr instanceof Int16Array")(numpy.array([1], dtype=numpy.int16))
assert pm.eval("(arr)=>arr instanceof Int32Array")(numpy.array([1], dtype=numpy.int32))
assert pm.eval("(arr)=>arr instanceof BigInt64Array")(numpy.array([1], dtype=numpy.int64))
assert pm.eval("(arr)=>arr instanceof Float16Array")(numpy.array([1], dtype=numpy.float16))
assert pm.eval("(arr)=>arr instanceof Float32Array")(numpy.array([1], dtype=numpy.float32))
assert pm.eval("(arr)=>arr instanceof Float64Array")(numpy.array([1], dtype=numpy.float64))
assert pm.eval("new Uint8Array([1])").format == "B"
Expand All @@ -60,6 +61,7 @@ def assert_js_to_py_memoryview(buf: memoryview):
assert pm.eval("new Int16Array([1])").format == "h"
assert pm.eval("new Int32Array([1])").format == "i"
assert pm.eval("new BigInt64Array([1n])").format == "q"
assert pm.eval("new Float16Array([1])").format == "e"
assert pm.eval("new Float32Array([1])").format == "f"
assert pm.eval("new Float64Array([1])").format == "d"

Expand Down

0 comments on commit 3b02465

Please sign in to comment.