Skip to content

Commit 2fbdff6

Browse files
Lord-McSweeneyLord-McSweeney
Lord-McSweeney
authored and
Lord-McSweeney
committed
avm1/avm2: Remove AvmString::Static variant
1 parent e6a05ea commit 2fbdff6

File tree

4 files changed

+28
-104
lines changed

4 files changed

+28
-104
lines changed

core/src/avm1/value.rs

-5
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,8 @@ pub enum Value<'gc> {
2929
}
3030

3131
// This type is used very frequently, so make sure it doesn't unexpectedly grow.
32-
// On 32-bit x86 Android, it's 12 bytes. On most other 32-bit platforms it's 16.
33-
#[cfg(target_pointer_width = "32")]
3432
const _: () = assert!(size_of::<Value<'_>>() <= 16);
3533

36-
#[cfg(target_pointer_width = "64")]
37-
const _: () = assert!(size_of::<Value<'_>>() == 24);
38-
3934
impl<'gc> From<AvmString<'gc>> for Value<'gc> {
4035
fn from(string: AvmString<'gc>) -> Self {
4136
Value::String(string)

core/src/avm2/error.rs

-4
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,8 @@ impl Debug for Error<'_> {
3838
}
3939

4040
// This type is used very frequently, so make sure it doesn't unexpectedly grow.
41-
#[cfg(target_family = "wasm")]
4241
const _: () = assert!(size_of::<Result<Value<'_>, Error<'_>>>() == 24);
4342

44-
#[cfg(target_pointer_width = "64")]
45-
const _: () = assert!(size_of::<Result<Value<'_>, Error<'_>>>() == 32);
46-
4743
#[inline(never)]
4844
#[cold]
4945
pub fn make_null_or_undefined_error<'gc>(

core/src/avm2/value.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,7 @@ pub enum Value<'gc> {
5151
}
5252

5353
// This type is used very frequently, so make sure it doesn't unexpectedly grow.
54-
#[cfg(target_family = "wasm")]
55-
const _: () = assert!(size_of::<Value<'_>>() == 16);
56-
57-
#[cfg(target_pointer_width = "64")]
58-
const _: () = assert!(size_of::<Value<'_>>() == 24);
54+
const _: () = assert!(size_of::<Value<'_>>() <= 16);
5955

6056
impl<'gc> From<AvmString<'gc>> for Value<'gc> {
6157
fn from(string: AvmString<'gc>) -> Self {

core/src/string/avm_string.rs

+27-90
Original file line numberDiff line numberDiff line change
@@ -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

2213
impl<'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> {
150103
impl<'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

159110
impl<'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.
187126
impl 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

Comments
 (0)