Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typed array APIs #72

Closed
9 tasks
dherman opened this issue Apr 21, 2016 · 8 comments
Closed
9 tasks

typed array APIs #72

dherman opened this issue Apr 21, 2016 · 8 comments

Comments

@dherman
Copy link
Collaborator

dherman commented Apr 21, 2016

Create object types for all the typed array types:

  • neon::js::binary::Int8Array
  • neon::js::binary::Uint8Array
  • neon::js::binary::Uint8ClampedArray
  • neon::js::binary::Int16Array
  • neon::js::binary::Uint16Array
  • neon::js::binary::Int32Array
  • neon::js::binary::Uint32Array
  • neon::js::binary::Float32Array
  • neon::js::binary::Float64Array
@bennycode
Copy link

bennycode commented Feb 17, 2017

Hey @dherman, thanks for providing Neon!

At Wire we see high potential in it. However, we are dependent on the Uint8Array type. Do you have an outlook when it will be possible to map this type between Rust and JavaScript?

@dherman
Copy link
Collaborator Author

dherman commented Feb 20, 2017

@bennyn That's great to hear you have use cases for Neon! I'm happy to prioritize adding at least Uint8Array. In the meantime would the JsBuffer type work for you? (AIUI the Buffer class is a subclass of Uint8Array.)

@ffflorian
Copy link
Contributor

ffflorian commented Feb 21, 2017

@dherman
Thank you for the hint. By using the JsBuffer and afterwards converting it to an Uint8Array in JavaScript, we managed to make it work! 🎉

By using neon, our benchmark just got 61.5 times faster!


Here is a code example with gen_keypair() from sodiumoxide:

lib.rs

fn crypto_sign_keypair(call: Call) -> JsResult<JsObject> {
    let scope = call.scope;
    let (kp_public, kp_secret) = ed25519::gen_keypair();

    let mut kp_public_buf = try!(JsBuffer::new(scope, 32));
    utils::buf_copy_from_slice(&kp_public.0, &mut kp_public_buf);

    let mut kp_secret_buf = try!(JsBuffer::new(scope, 64));
    utils::buf_copy_from_slice(&kp_secret.0, &mut kp_secret_buf);

    let js_object: Handle<JsObject> = JsObject::new(scope);
    try!(js_object.set("keyType", JsString::new(scope, "ed25519").unwrap()));
    try!(js_object.set("publicKeyBuffer", kp_public_buf));
    try!(js_object.set("privateKeyBuffer", kp_secret_buf));

    Ok(js_object)
}

index.js

const crypto_sign_keypair = () => {
    const { publicKeyBuffer, privateKeyBuffer, keyType } = sodiumneon.crypto_sign_keypair();

    return {
        publicKey: new Uint8Array(publicKeyBuffer),
        privateKey: new Uint8Array(privateKeyBuffer),
        keyType
    };
};

@dherman
Copy link
Collaborator Author

dherman commented Nov 3, 2017

This deserves an RFC, and we should also think about whether we want to offer a way to get the different typed views on an ArrayBuffer directly within Rust. Right now you can hack your way to doing this with some unsafe Rust skulduggery:

buffer.grab(|mut slice| {
    let len = slice.len();
    let raw = slice.as_mut_ptr();
    let mut slice: CMutSlice<f32> = unsafe { CMutSlice::new(mem::transmute(raw), len / 4) };
    slice[0] = 1.8;
    slice[1] = 13.4;
});

I think it's important to be able to do this with an ArrayBuffer, without having to require the JS to pass you a view of the right type. Maybe the best way to do this is for the Lock implementation not to directly provide a CMutSlice<u8> but instead a custom type that gives you access to CMutSlice<u8>, CMutSlice<i8>, CMutSlice<u16>, CMutSlice<i16>, etc.

@DiThi
Copy link

DiThi commented Dec 11, 2017

@dherman Is there a way to do that from a buffer that was created in JS and passed as argument? At least for reading.

@kjvalencik
Copy link
Member

@ffflorian Excellent work! Isn't that benchmark a little unfair? If I'm reading correctly, you are comparing an ECMAScripten compilation to pure JS against a native implementation.

How does it compare against something that uses native bindings like sodium-native?

@ffflorian
Copy link
Contributor

ffflorian commented Dec 12, 2017

@kjvalencik

How does it compare against something that uses native bindings like sodium-native?

I don't know, back then in February, sodium-native was not usable for us because of several reasons. And since we wanted to switch from pure JS to a Rust implementation, I simply compared the results after switching.

@dherman
Copy link
Collaborator Author

dherman commented Sep 15, 2021

This has been designed and implemented with RFC neon-bindings/rfcs#44! 🎉

@dherman dherman closed this as completed Sep 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants