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

Protect internal String methods #5503

Closed

Conversation

chastell
Copy link
Contributor

@chastell chastell commented Jan 1, 2018

This makes String#unsafe_byte_at and String#unsafe_byte_slice protected, as per this comment.

src/file.cr Outdated
@@ -469,7 +469,8 @@ class File < IO::FileDescriptor
byte_count -= 1
end

str.write part.unsafe_byte_slice(byte_start, byte_count)
pointer = part.to_unsafe + byte_start
str.write Slice.new(pointer, byte_count, read_only: true)
Copy link
Contributor

Choose a reason for hiding this comment

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

str.write part.to_slice[pointer, byte_count] should work...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, thanks, I’m still learning all of this. 🙂

Unfortunately:

in src/file.cr:472: instantiating 'Slice(UInt8)#[](Pointer(UInt8), Int32)'

        str.write part.to_slice[part.to_unsafe + byte_start, byte_count]
                               ^

in src/slice.cr:195: no overload matches 'Int32#<=' with type Pointer(UInt8)
Overloads are:
 - Int32#<=(other : Int8)
 - Int32#<=(other : Int16)
 - Int32#<=(other : Int32)
 - Int32#<=(other : Int64)
 - Int32#<=(other : Int128)
 - Int32#<=(other : UInt8)
 - Int32#<=(other : UInt16)
 - Int32#<=(other : UInt32)
 - Int32#<=(other : UInt64)
 - Int32#<=(other : UInt128)
 - Int32#<=(other : Float32)
 - Int32#<=(other : Float64)
 - Comparable(T)#<=(other : T)

    unless 0 <= start <= @size
             ^

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, should this be just the below?

str.write part.to_slice[byte_start, byte_count]

src/string.cr Outdated
@@ -900,7 +900,7 @@ class String
end
end

def unsafe_byte_at(index)
protected def unsafe_byte_at(index)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be removed and replaced with just to_unsafe[index] where used.

src/string.cr Outdated
@@ -900,7 +900,7 @@ class String
end
end

def unsafe_byte_at(index)
protected def unsafe_byte_at(index)
Copy link
Member

Choose a reason for hiding this comment

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

When all calls to this method get replaced by to_unsafe[index] it could as well be removed entirely.

Copy link
Member

Choose a reason for hiding this comment

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

I think we should really remove this method.

string.to_unsafe[index]
string.unsafe_byte_at_index(index)

the second is even longer!

Also, I'd like to come back with the idea of having general benchmarks of the whole standard library. Then we could see which places don't need to be "unsafe" and work just fine with safe code.

@chastell chastell force-pushed the protect_internal_String_methods branch from edc0013 to a7680bf Compare January 2, 2018 19:43
@chastell chastell force-pushed the protect_internal_String_methods branch from a7680bf to 7141fa9 Compare January 2, 2018 20:02
@chastell
Copy link
Contributor Author

chastell commented Jan 2, 2018

Addressed the comments, just need a double-check on whether

str.write part.unsafe_byte_slice(byte_start, byte_count)

and

str.write part.to_slice[byte_start, byte_count]

are equivalent (they do look so to me and the tests pass).

@asterite
Copy link
Member

asterite commented Jan 2, 2018

The latter is a bit slower because it has to do index bounds check. I don't know how it affects performance, though. That's why we need #5508 to know if this kind of refactors are OK to merge.

@chastell
Copy link
Contributor Author

chastell commented Jan 2, 2018

The latter is a bit slower because it has to do index bounds check.

Well I did initially go with

pointer = part.to_unsafe + byte_start
str.write Slice.new(pointer, byte_count, read_only: true)

but received a change request for String#to_slice… 😄

@straight-shoota
Copy link
Member

@chastell This needs a rebase.

@Sija
Copy link
Contributor

Sija commented Jan 29, 2019

@chastell Do you still plan working on that PR?

@straight-shoota
Copy link
Member

Closing stale PR.
#unsafe_byte_at has been deprecated in #10559.

#unsafe_byte_slice* is being kept for now. I think there's no need to make it nodoc or protected. Other APIs beside String itself might benefit from more performant string slicing as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants