Skip to content

Introduce the Array Buffer C API #2161

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

Merged
merged 1 commit into from
Jan 11, 2018

Conversation

galpeter
Copy link
Contributor

@galpeter galpeter commented Jan 5, 2018

Add C API to work with Array Buffers.
The following methods are added:

  • jerry_value_is_arraybuffer
  • jerry_create_arraybuffer
  • jerry_arraybuffer_write
  • jerry_arraybuffer_read
  • jerry_get_arraybuffer_byte_length

JerryScript-DCO-1.0-Signed-off-by: Peter Gal [email protected]

@galpeter galpeter added api Related to the public API enhancement An improvement ES2015 Related to ES2015 features labels Jan 5, 2018
@galpeter
Copy link
Contributor Author

galpeter commented Jan 5, 2018

As per #1832 I've created an API proposal for the Array Buffers.

Some notes:

  • The jerry_arraybuffer_map call is a bit dangerous but useful in case we want to reduce memory usage with array buffers. I'm not sure we want this.
  • I was wondering on a way to have the array buffer use an external (non-jerry heap memory) for which we could have the map operation. I'll try to dig around this a bit.
  • The names of the functions was changed a bit, but maybe there are better names.

there is no out of bounds reads or writes.

After using the pointer the [jerry_arraybuffer_unmap][#jerry_arraybuffer_unmap)
function must be called.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong bracket

**Summary**

Release the Array Buffer after a [jerry_arraybuffer_map][#jerry_arraybuffer_map)
function call.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

```c
{
jerry_value_t buffer = jerry_create_arraybuffer (22);
uint8_t * const data = jerry_arraybuffer_map (buffer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put a space only before the asterisk character


ecma_object_t *buffer_p = ecma_get_object_from_value (buffer);
lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p);
return (uint8_t * const) mem_buffer_p;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

// acquire the Array Buffer from somewhere

uint8_t * const data = jerry_arraybuffer_map (array_buffer);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

uint8_t *buf_p,
jerry_length_t buf_size);
jerry_length_t jerry_arraybuffer_get_length (const jerry_value_t value);
uint8_t * jerry_arraybuffer_map (const jerry_value_t value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

TEST_ASSERT (jerry_value_is_arraybuffer (buffer));
TEST_ASSERT (jerry_arraybuffer_get_length (buffer) == 20);

uint8_t * const data = jerry_arraybuffer_map (buffer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Contributor

@robertsipka robertsipka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (informally) after these minor fixes.


jerry_value_t buffer;
// ... create the Array Buffer or acuiqre it from somewhere.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*acquire


**Summary**

The function allows acces to the contents of the Array Buffer directly.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

access

@galpeter
Copy link
Contributor Author

galpeter commented Jan 8, 2018

I've updated the PR with the requested changes. Also I've removed the _map and _unmap functions as they are high-risk functions and I'll will create another PR which introduces ArrayBuffers with external (non Jerry heap) memory usage.


```c
jerry_length_t
jerry_arraybuffer_get_length (const jerry_value_t value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a jerry_get_array_length function already. I am thinking whether this could be combined with it. Maybe just introducing a jerry_get_length() function which works with any special object (list in the comment what types it supports). But that could increase the binary size. I am unsure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The jerry_arraybuffer_get_length returns the byteLength property (which is specified ad construction time) and the arraybuffer does not have a length property. I'm not really sure we should remove this function, but we could change the name to have byte_length suffix?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a name like: jerry_get_arraybuffer_byte_length ? so we'll have a common naming scheme for "getters".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, actually sounds good.


**Summary**

Read the contents of the Array Buffer into a buffer.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy the portion of the Array Buffer into a user provided buffer.


**Summary**

Write the contents of a buffer into the Array Buffer.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy again

jerry_arraybuffer_write (const jerry_value_t value,
jerry_length_t offset,
const uint8_t *buf_p,
jerry_length_t buf_size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong alignment


ecma_object_t *buffer_p = ecma_get_object_from_value (buffer);
jerry_length_t length = ecma_arraybuffer_get_length (buffer_p);
jerry_length_t copy_count = JERRY_MIN (length - offset, buf_size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens it offset > length? In some range, it will be a big number, and the min mitigates the issue, but if offset is 0xffffffff that could be exploited.

I would add an early return if offset >= length.


ecma_object_t *buffer_p = ecma_get_object_from_value (buffer);
jerry_length_t length = ecma_arraybuffer_get_length (buffer_p);
jerry_length_t copy_count = JERRY_MIN (length - offset, buf_size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

offset issue again

@galpeter galpeter force-pushed the c-api-arraybuffer branch 2 times, most recently from d4e26eb to ffea5b8 Compare January 9, 2018 15:16
@galpeter
Copy link
Contributor Author

galpeter commented Jan 9, 2018

@zherczeg I've updated the PR with the requested changes, and also added two new api tests.

Copy link
Member

@zherczeg zherczeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few changes. Patch is close to ready.

jerry_create_arraybuffer (jerry_length_t size);
```

- `size` - size of the ArrayBuffer to create
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

byte size. I think we need to emphasize this.

{
return jerry_create_boolean (true);
}
else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need else after return.

Add C API to work with Array Buffers.
The following methods are added:
- jerry_value_is_arraybuffer
- jerry_create_arraybuffer
- jerry_arraybuffer_write
- jerry_arraybuffer_read
- jerry_get_arraybuffer_byte_length

JerryScript-DCO-1.0-Signed-off-by: Peter Gal [email protected]
@galpeter
Copy link
Contributor Author

@zherczeg updated PR based on requests.

Copy link
Member

@zherczeg zherczeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@martijnthe
Copy link
Contributor

Hey @galpeter, thanks for adding this. Looks great.
The one thing I'm missing is a non-copy read API (basically getting a pointer to the internal buffer).
The need for this was raised by multiple people in the discussion here:
#1832
Fine to add it later, I just wanted to bring it up again and make sure there's nothing in the way to do so later.

@zherczeg
Copy link
Member

Please check #2162 . The idea is that we allow arraybuffer to be created for external byte arrays. This allows communication between jerryscript instances, direct access for screen memory, etc. However there is no plan for accessing data of internally created arraybuffers.

@martijnthe
Copy link
Contributor

@zherczeg got it, makes sense, thanks!

@galpeter
Copy link
Contributor Author

@martijnthe initially I had that non-copy api which returned the internal buffer pointer, but that was to risky so I've changed the logic to external buffers which can be seen in #2162.

Copy link
Contributor

@LaszloLango LaszloLango left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@LaszloLango LaszloLango merged commit ded0d5a into jerryscript-project:master Jan 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api Related to the public API enhancement An improvement ES2015 Related to ES2015 features feature request Requested feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants