@@ -8,40 +8,16 @@ use crate::string::{AvmAtom, AvmStringRepr};
88
99#[ derive( Clone , Copy , Collect ) ]
1010#[ collect( no_drop) ]
11- enum Source < ' gc > {
12- Managed ( Gc < ' gc , AvmStringRepr < ' gc > > ) ,
13- Static ( & ' static WStr ) ,
14- }
15-
16- #[ derive( Clone , Copy , Collect ) ]
17- #[ collect( no_drop) ]
18- pub struct AvmString < ' gc > {
19- source : Source < ' gc > ,
20- }
11+ pub struct AvmString < ' gc > ( Gc < ' gc , AvmStringRepr < ' gc > > ) ;
2112
2213impl < ' gc > AvmString < ' gc > {
2314 /// Turns a string to a fully owned (non-dependent) managed string.
2415 pub ( super ) fn to_fully_owned ( self , mc : & Mutation < ' gc > ) -> Gc < ' gc , AvmStringRepr < ' gc > > {
25- match self . source {
26- Source :: Managed ( s) => {
27- if s. is_dependent ( ) {
28- let repr = AvmStringRepr :: from_raw ( WString :: from ( self . as_wstr ( ) ) , false ) ;
29- Gc :: new ( mc, repr)
30- } else {
31- s
32- }
33- }
34- Source :: Static ( s) => {
35- let repr = AvmStringRepr :: from_raw_static ( s, false ) ;
36- Gc :: new ( mc, repr)
37- }
38- }
39- }
40-
41- pub fn as_managed ( self ) -> Option < Gc < ' gc , AvmStringRepr < ' gc > > > {
42- match self . source {
43- Source :: Managed ( s) => Some ( s) ,
44- Source :: Static ( _) => None ,
16+ if self . 0 . is_dependent ( ) {
17+ let repr = AvmStringRepr :: from_raw ( WString :: from ( self . as_wstr ( ) ) , false ) ;
18+ Gc :: new ( mc, repr)
19+ } else {
20+ self . 0
4521 }
4622 }
4723
@@ -51,9 +27,7 @@ impl<'gc> AvmString<'gc> {
5127 Cow :: Borrowed ( utf8) => WString :: from_utf8 ( utf8) ,
5228 } ;
5329 let repr = AvmStringRepr :: from_raw ( buf, false ) ;
54- Self {
55- source : Source :: Managed ( Gc :: new ( gc_context, repr) ) ,
56- }
30+ Self ( Gc :: new ( gc_context, repr) )
5731 }
5832
5933 pub fn new_utf8_bytes ( gc_context : & Mutation < ' gc > , bytes : & [ u8 ] ) -> Self {
@@ -63,43 +37,27 @@ impl<'gc> AvmString<'gc> {
6337
6438 pub fn new < S : Into < WString > > ( gc_context : & Mutation < ' gc > , string : S ) -> Self {
6539 let repr = AvmStringRepr :: from_raw ( string. into ( ) , false ) ;
66- Self {
67- source : Source :: Managed ( Gc :: new ( gc_context, repr) ) ,
68- }
40+ Self ( Gc :: new ( gc_context, repr) )
6941 }
7042
7143 pub fn substring ( mc : & Mutation < ' gc > , string : AvmString < ' gc > , start : usize , end : usize ) -> Self {
72- match string. source {
73- Source :: Managed ( repr) => {
74- let repr = AvmStringRepr :: new_dependent ( repr, start, end) ;
75- Self {
76- source : Source :: Managed ( Gc :: new ( mc, repr) ) ,
77- }
78- }
79- Source :: Static ( s) => Self {
80- source : Source :: Static ( & s[ start..end] ) ,
81- } ,
82- }
44+ let repr = AvmStringRepr :: new_dependent ( string. 0 , start, end) ;
45+ Self ( Gc :: new ( mc, repr) )
8346 }
8447
8548 pub fn is_dependent ( & self ) -> bool {
86- match & self . source {
87- Source :: Managed ( s) => s. is_dependent ( ) ,
88- Source :: Static ( _) => false ,
89- }
49+ self . 0 . is_dependent ( )
9050 }
9151
9252 pub fn as_wstr ( & self ) -> & ' gc WStr {
93- match self . source {
94- Source :: Managed ( s) => Gc :: as_ref ( s) . as_wstr ( ) ,
95- Source :: Static ( s) => s,
96- }
53+ Gc :: as_ref ( self . 0 ) . as_wstr ( )
9754 }
9855
9956 pub fn as_interned ( & self ) -> Option < AvmAtom < ' gc > > {
100- match self . source {
101- Source :: Managed ( s) if s. is_interned ( ) => Some ( AvmAtom ( s) ) ,
102- _ => None ,
57+ if self . 0 . is_interned ( ) {
58+ Some ( AvmAtom ( self . 0 ) )
59+ } else {
60+ None
10361 }
10462 }
10563
@@ -112,13 +70,8 @@ impl<'gc> AvmString<'gc> {
11270 right
11371 } else if right. is_empty ( ) {
11472 left
115- } else if let Some ( repr) = left
116- . as_managed ( )
117- . and_then ( |l| AvmStringRepr :: try_append_inline ( l, & right) )
118- {
119- Self {
120- source : Source :: Managed ( Gc :: new ( mc, repr) ) ,
121- }
73+ } else if let Some ( repr) = AvmStringRepr :: try_append_inline ( left. 0 , & right) {
74+ Self ( Gc :: new ( mc, repr) )
12275 } else {
12376 // When doing a non-in-place append,
12477 // Overallocate a bit so that further appends can be in-place.
@@ -150,28 +103,14 @@ impl<'gc> AvmString<'gc> {
150103impl < ' gc > From < AvmAtom < ' gc > > for AvmString < ' gc > {
151104 #[ inline]
152105 fn from ( atom : AvmAtom < ' gc > ) -> Self {
153- Self {
154- source : Source :: Managed ( atom. 0 ) ,
155- }
106+ Self ( atom. 0 )
156107 }
157108}
158109
159110impl < ' gc > From < Gc < ' gc , AvmStringRepr < ' gc > > > for AvmString < ' gc > {
160111 #[ inline]
161112 fn from ( repr : Gc < ' gc , AvmStringRepr < ' gc > > ) -> Self {
162- Self {
163- source : Source :: Managed ( repr) ,
164- }
165- }
166- }
167-
168- impl From < & ' static str > for AvmString < ' _ > {
169- #[ inline]
170- fn from ( str : & ' static str ) -> Self {
171- // TODO(moulins): actually check that `str` is valid ASCII.
172- Self {
173- source : Source :: Static ( WStr :: from_units ( str. as_bytes ( ) ) ) ,
174- }
113+ Self ( repr)
175114 }
176115}
177116
@@ -186,18 +125,16 @@ impl Deref for AvmString<'_> {
186125// Manual equality implementation with fast paths for owned strings.
187126impl PartialEq for AvmString < ' _ > {
188127 fn eq ( & self , other : & Self ) -> bool {
189- if let ( Source :: Managed ( left ) , Source :: Managed ( right ) ) = ( self . source , other. source ) {
128+ if Gc :: ptr_eq ( self . 0 , other. 0 ) {
190129 // Fast accept for identical strings.
191- if Gc :: ptr_eq ( left , right ) {
192- return true ;
130+ return true ;
131+ } else if self . 0 . is_interned ( ) && other . 0 . is_interned ( ) {
193132 // Fast reject for distinct interned strings.
194- } else if left. is_interned ( ) && right. is_interned ( ) {
195- return false ;
196- }
133+ return false ;
134+ } else {
135+ // Fallback case.
136+ self . as_wstr ( ) == other. as_wstr ( )
197137 }
198-
199- // Fallback case.
200- self . as_wstr ( ) == other. as_wstr ( )
201138 }
202139}
203140
0 commit comments