Skip to content

Commit

Permalink
Refactor String header layout reflection (#13335)
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota authored Apr 20, 2023
1 parent d3f5d75 commit 061dc10
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 11 deletions.
22 changes: 15 additions & 7 deletions src/string.cr
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,9 @@ require "c/string"
# remove the offending byte sequences first.
class String
# :nodoc:
TYPE_ID = "".crystal_type_id

# :nodoc:
HEADER_SIZE = sizeof({Int32, Int32, Int32})
#
# Holds the offset to the first character byte.
HEADER_SIZE = offsetof(String, @c)

include Comparable(self)

Expand Down Expand Up @@ -266,9 +265,18 @@ class String
str = GC.realloc(str, bytesize.to_u32 + HEADER_SIZE + 1)
end

str_header = str.as({Int32, Int32, Int32}*)
str_header.value = {TYPE_ID, bytesize.to_i, size.to_i}
str.as(String)
set_crystal_type_id(str)
str = str.as(String)
str.initialize_header(bytesize.to_i, size.to_i)
str
end

# :nodoc:
#
# Initializes the header information of a `String` instance.
# The actual character content at `@c` is expected to be already filled and is
# unaffected by this method.
def initialize_header(@bytesize : Int32, @length : Int32 = 0)
end

# Builds a `String` by creating a `String::Builder` with the given initial capacity, yielding
Expand Down
8 changes: 4 additions & 4 deletions src/string/builder.cr
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class String::Builder < IO
# Make sure to also be able to hold
# the header size plus the trailing zero byte
capacity += String::HEADER_SIZE + 1
String.check_capacity_in_bounds(capacity)

@buffer = GC.malloc_atomic(capacity.to_u32).as(UInt8*)
@bytesize = 0
Expand Down Expand Up @@ -117,9 +116,10 @@ class String::Builder < IO
resize_to_capacity(real_bytesize)
end

header = @buffer.as({Int32, Int32, Int32}*)
header.value = {String::TYPE_ID, @bytesize - 1, 0}
@buffer.as(String)
String.set_crystal_type_id(@buffer)
str = @buffer.as(String)
str.initialize_header((bytesize - 1).to_i)
str
end

private def real_bytesize
Expand Down

0 comments on commit 061dc10

Please sign in to comment.