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

core/avm1/avm2: Add AvmString::new_ascii_static and use it #19760

Merged
merged 1 commit into from
Mar 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/avm1/activation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
// SWF19: "If A is zero, the result NaN, Infinity, or -Infinity is pushed to the stack in SWF 5 and later.
// In SWF 4, the result is the string #ERROR#."
let result: Value<'gc> = if a == 0.0 && self.swf_version() < 5 {
AvmString::new_utf8(self.gc(), "#ERROR#").into()
AvmString::new_ascii_static(self.gc(), b"#ERROR#").into()
} else {
(b / a).into()
};
Expand Down
4 changes: 2 additions & 2 deletions core/src/avm1/globals/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ fn to_string<'gc>(
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if this.as_executable().is_some() {
Ok(AvmString::new_utf8(activation.gc(), "[type Function]").into())
Ok(AvmString::new_ascii_static(activation.gc(), b"[type Function]").into())
} else {
Ok(AvmString::new_utf8(activation.gc(), "[object Object]").into())
Ok(AvmString::new_ascii_static(activation.gc(), b"[object Object]").into())
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/avm1/globals/system_ime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn get_conversion_mode<'gc>(
_this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
Ok(AvmString::new_utf8(activation.gc(), "KOREAN").into())
Ok(AvmString::new_ascii_static(activation.gc(), b"KOREAN").into())
}

fn get_enabled<'gc>(
Expand Down
4 changes: 2 additions & 2 deletions core/src/avm1/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,9 +423,9 @@ impl<'gc> Value<'gc> {
Value::String(s) => s,
_ => {
if object.as_executable().is_some() {
AvmString::new_utf8(activation.gc(), "[type Function]")
AvmString::new_ascii_static(activation.gc(), b"[type Function]")
} else {
AvmString::new_utf8(activation.gc(), "[type Object]")
AvmString::new_ascii_static(activation.gc(), b"[type Object]")
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/avm2/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ impl<'gc> Domain<'gc> {
activation.gc(),
&name[(start + 2)..(name.len() - 1)],
));
name = AvmString::new_utf8(activation.gc(), "__AS3__.vec::Vector");
name = AvmString::new_ascii_static(activation.gc(), b"__AS3__.vec::Vector");
}
// FIXME - is this the correct api version?
let api_version = activation.avm2().root_api_version;
Expand Down
2 changes: 0 additions & 2 deletions core/src/avm2/globals/Date.as
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ package {
public dynamic class Date {
public static const length:int = 7;

private static const invalidDateStr:String = "Invalid Date";

prototype.valueOf = function():* {
var d:Date = this;
return d.AS3::valueOf();
Expand Down
2 changes: 1 addition & 1 deletion core/src/avm2/globals/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ pub fn create_c_class<'gc>(
let gc_context = activation.gc();
let namespaces = activation.avm2().namespaces;

let class_name = AvmString::new_utf8(gc_context, "Class$");
let class_name = AvmString::new_ascii_static(gc_context, b"Class$");
let class_c_class = Class::custom_new(
QName::new(namespaces.public_all(), class_name),
Some(class_i_class),
Expand Down
12 changes: 6 additions & 6 deletions core/src/avm2/globals/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ pub fn to_string<'gc>(
)
.into())
} else {
Ok(AvmString::new_utf8(activation.gc(), "Invalid Date").into())
Ok(AvmString::new_ascii_static(activation.gc(), b"Invalid Date").into())
}
}

Expand All @@ -955,7 +955,7 @@ pub fn to_utc_string<'gc>(
)
.into())
} else {
Ok(AvmString::new_utf8(activation.gc(), "Invalid Date").into())
Ok(AvmString::new_ascii_static(activation.gc(), b"Invalid Date").into())
}
}

Expand All @@ -979,7 +979,7 @@ pub fn to_locale_string<'gc>(
)
.into())
} else {
Ok(AvmString::new_utf8(activation.gc(), "Invalid Date").into())
Ok(AvmString::new_ascii_static(activation.gc(), b"Invalid Date").into())
}
}

Expand All @@ -999,7 +999,7 @@ pub fn to_time_string<'gc>(
{
Ok(AvmString::new_utf8(activation.gc(), date.format("%T GMT%z").to_string()).into())
} else {
Ok(AvmString::new_utf8(activation.gc(), "Invalid Date").into())
Ok(AvmString::new_ascii_static(activation.gc(), b"Invalid Date").into())
}
}

Expand All @@ -1019,7 +1019,7 @@ pub fn to_locale_time_string<'gc>(
{
Ok(AvmString::new_utf8(activation.gc(), date.format("%T %p").to_string()).into())
} else {
Ok(AvmString::new_utf8(activation.gc(), "Invalid Date").into())
Ok(AvmString::new_ascii_static(activation.gc(), b"Invalid Date").into())
}
}

Expand All @@ -1039,7 +1039,7 @@ pub fn to_date_string<'gc>(
{
Ok(AvmString::new_utf8(activation.gc(), date.format("%a %b %-d %-Y").to_string()).into())
} else {
Ok(AvmString::new_utf8(activation.gc(), "Invalid Date").into())
Ok(AvmString::new_ascii_static(activation.gc(), b"Invalid Date").into())
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/avm2/globals/flash/ui/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub fn get_physical_keyboard_type<'gc>(
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
avm2_stub_getter!(activation, "flash.ui.Keyboard", "physicalKeyboardType");
Ok(AvmString::new_utf8(activation.gc(), "alphanumeric").into())
Ok(AvmString::new_ascii_static(activation.gc(), b"alphanumeric").into())
}

pub fn is_accessible<'gc>(
Expand Down
2 changes: 1 addition & 1 deletion core/src/avm2/globals/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub fn print_with_radix<'gc>(

if number.is_infinite() {
if number < 0.0 {
return Ok(AvmString::new_utf8(activation.gc(), "-Infinity"));
return Ok(AvmString::new_ascii_static(activation.gc(), b"-Infinity"));
} else if number > 0.0 {
return Ok(istr!("Infinity"));
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/avm2/globals/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ pub fn create_c_class<'gc>(
let gc_context = activation.gc();
let namespaces = activation.avm2().namespaces;

let class_name = AvmString::new_utf8(gc_context, "Object$");
let class_name = AvmString::new_ascii_static(gc_context, b"Object$");
let object_c_class = Class::custom_new(
QName::new(namespaces.public_all(), class_name),
Some(class_i_class),
Expand Down
16 changes: 8 additions & 8 deletions core/src/avm2/globals/xml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -866,17 +866,17 @@ pub fn node_kind<'gc>(
let this = this.as_object().unwrap();

let xml = this.as_xml_object().unwrap();
let name = match &*xml.node().kind() {
E4XNodeKind::Text(_) => "text",
E4XNodeKind::CData(_) => "text", // cdata pretends to be text here
E4XNodeKind::Comment(_) => "comment",
E4XNodeKind::ProcessingInstruction(_) => "processing-instruction",
E4XNodeKind::Attribute(_) => "attribute",
E4XNodeKind::Element { .. } => "element",
let name: &'static [u8] = match &*xml.node().kind() {
E4XNodeKind::Text(_) => b"text",
E4XNodeKind::CData(_) => b"text", // cdata pretends to be text here
E4XNodeKind::Comment(_) => b"comment",
E4XNodeKind::ProcessingInstruction(_) => b"processing-instruction",
E4XNodeKind::Attribute(_) => b"attribute",
E4XNodeKind::Element { .. } => b"element",
};

// FIXME should we intern these?
Ok(AvmString::new_utf8(activation.gc(), name).into())
Ok(AvmString::new_ascii_static(activation.gc(), name).into())
}

pub fn append_child<'gc>(
Expand Down
4 changes: 2 additions & 2 deletions core/src/avm2/namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,8 @@ impl<'gc> CommonNamespaces<'gc> {
let empty_string = context.empty();

let as3_namespace_string =
AvmString::new_utf8(context.gc(), "http://adobe.com/AS3/2006/builtin");
let vector_namespace_string = AvmString::new_utf8(context.gc(), "__AS3__.vec");
AvmString::new_ascii_static(context.gc(), b"http://adobe.com/AS3/2006/builtin");
let vector_namespace_string = AvmString::new_ascii_static(context.gc(), b"__AS3__.vec");

Self {
public_namespaces: std::array::from_fn(|val| {
Expand Down
2 changes: 1 addition & 1 deletion core/src/backend/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ impl<'gc> AudioManager<'gc> {

// Fire soundComplete event.
if let Some(root) = context.stage.root_clip() {
let method_name = AvmString::new_utf8(mc, "onSoundComplete");
let method_name = AvmString::new_ascii_static(mc, b"onSoundComplete");

context.action_queue.queue_action(
root,
Expand Down
2 changes: 1 addition & 1 deletion core/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ impl<'gc> UpdateContext<'gc> {
.get_version_string(activation.context.avm1);
object.define_value(
activation.gc(),
AvmString::new_utf8(activation.gc(), "$version"),
AvmString::new_ascii_static(activation.gc(), b"$version"),
AvmString::new_utf8(activation.gc(), version_string).into(),
Attribute::empty(),
);
Expand Down
4 changes: 2 additions & 2 deletions core/src/display_object/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,9 +610,9 @@ pub trait TInteractiveObject<'gc>:
.unwrap_or(Avm1Value::Null);

let method_name = if focused {
AvmString::new_utf8(context.gc(), "onSetFocus")
AvmString::new_ascii_static(context.gc(), b"onSetFocus")
} else {
AvmString::new_utf8(context.gc(), "onKillFocus")
AvmString::new_ascii_static(context.gc(), b"onKillFocus")
};

Avm1::run_stack_frame_for_method(self_do, object, method_name, &[other], context);
Expand Down
2 changes: 1 addition & 1 deletion core/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2531,7 +2531,7 @@ impl<'gc> Loader<'gc> {
match vm_data {
MovieLoaderVMData::Avm1 { broadcaster } => {
if let Some(broadcaster) = broadcaster {
let error_message = AvmString::new_utf8(uc.gc(), "LoadNeverCompleted");
let error_message = AvmString::new_ascii_static(uc.gc(), b"LoadNeverCompleted");

Avm1::run_stack_frame_for_method(
clip,
Expand Down
5 changes: 5 additions & 0 deletions core/src/string/avm_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ impl<'gc> AvmString<'gc> {
}
}

pub fn new_ascii_static(gc_context: &Mutation<'gc>, bytes: &'static [u8]) -> Self {
let repr = AvmStringRepr::from_raw_static(WStr::from_units(bytes), false);
Self(Gc::new(gc_context, repr))
}

pub fn new_utf8<'s, S: Into<Cow<'s, str>>>(gc_context: &Mutation<'gc>, string: S) -> Self {
let buf = match string.into() {
Cow::Owned(utf8) => WString::from_utf8_owned(utf8),
Expand Down