Unverified Commit b378b8eb authored by Robert's avatar Robert Committed by GitHub

Fix create_vector_of_strings to use the stack, and test it. (#5074)

parent 9635d494
...@@ -29,6 +29,8 @@ use vtable::{VTable, field_index_to_field_offset}; ...@@ -29,6 +29,8 @@ use vtable::{VTable, field_index_to_field_offset};
use vtable_writer::VTableWriter; use vtable_writer::VTableWriter;
use vector::{SafeSliceAccess, Vector}; use vector::{SafeSliceAccess, Vector};
pub const N_SMALLVEC_STRING_VECTOR_CAPACITY: usize = 16;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
struct FieldLoc { struct FieldLoc {
off: UOffsetT, off: UOffsetT,
...@@ -268,10 +270,12 @@ impl<'fbb> FlatBufferBuilder<'fbb> { ...@@ -268,10 +270,12 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
#[inline] #[inline]
pub fn create_vector_of_strings<'a, 'b>(&'a mut self, xs: &'b [&'b str]) -> WIPOffset<Vector<'fbb, ForwardsUOffset<&'fbb str>>> { pub fn create_vector_of_strings<'a, 'b>(&'a mut self, xs: &'b [&'b str]) -> WIPOffset<Vector<'fbb, ForwardsUOffset<&'fbb str>>> {
self.assert_not_nested("create_vector_of_strings can not be called when a table or vector is under construction"); self.assert_not_nested("create_vector_of_strings can not be called when a table or vector is under construction");
// internally, smallvec can be a stack-allocated or heap-allocated vector. // internally, smallvec can be a stack-allocated or heap-allocated vector:
// we expect it to usually be stack-allocated. // if xs.len() > N_SMALLVEC_STRING_VECTOR_CAPACITY then it will overflow to the heap.
let mut offsets: smallvec::SmallVec<[WIPOffset<&str>; 0]> = smallvec::SmallVec::with_capacity(xs.len()); let mut offsets: smallvec::SmallVec<[WIPOffset<&str>; N_SMALLVEC_STRING_VECTOR_CAPACITY]> = smallvec::SmallVec::with_capacity(xs.len());
unsafe { offsets.set_len(xs.len()); } unsafe { offsets.set_len(xs.len()); }
// note that this happens in reverse, because the buffer is built back-to-front:
for (i, &s) in xs.iter().enumerate().rev() { for (i, &s) in xs.iter().enumerate().rev() {
let o = self.create_string(s); let o = self.create_string(s);
offsets[i] = o; offsets[i] = o;
......
...@@ -35,6 +35,8 @@ pub use monster_test_generated::my_game; ...@@ -35,6 +35,8 @@ pub use monster_test_generated::my_game;
// verbatim from the test suite: // verbatim from the test suite:
fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder) { fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder) {
let mon = { let mon = {
let _ = builder.create_vector_of_strings(&["these", "unused", "strings", "check", "the", "create_vector_of_strings", "function"]);
let s0 = builder.create_string("test1"); let s0 = builder.create_string("test1");
let s1 = builder.create_string("test2"); let s1 = builder.create_string("test2");
let fred_name = builder.create_string("Fred"); let fred_name = builder.create_string("Fred");
...@@ -79,7 +81,7 @@ fn main() { ...@@ -79,7 +81,7 @@ fn main() {
create_serialized_example_with_generated_code(builder); create_serialized_example_with_generated_code(builder);
} }
// reset the builder, clearing its heap-allocted memory: // reset the builder, clearing its heap-allocated memory:
builder.reset(); builder.reset();
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment