diff --git a/core/src/avm1/globals/bevel_filter.rs b/core/src/avm1/globals/bevel_filter.rs index fb0c681b5..d6c579ea6 100644 --- a/core/src/avm1/globals/bevel_filter.rs +++ b/core/src/avm1/globals/bevel_filter.rs @@ -5,7 +5,7 @@ use crate::avm1::error::Error; use crate::avm1::object::bevel_filter::{BevelFilterObject, BevelFilterType}; use crate::avm1::property_decl::{define_properties_on, Declaration}; use crate::avm1::{Object, TObject, Value}; -use crate::string::AvmString; +use crate::string::{AvmString, BorrowWStr, WStr}; use gc_arena::MutationContext; const PROTO_DECLS: &[Declaration] = declare_properties! { @@ -378,8 +378,8 @@ pub fn get_type<'gc>( _args: &[Value<'gc>], ) -> Result, Error<'gc>> { if let Some(filter) = this.as_bevel_filter_object() { - let type_: &str = filter.get_type().into(); - return Ok(AvmString::new(activation.context.gc_context, type_.to_string()).into()); + let type_: WStr<'_> = filter.get_type().into(); + return Ok(AvmString::new_ucs2(activation.context.gc_context, type_.into()).into()); } Ok(Value::Undefined) @@ -394,7 +394,7 @@ pub fn set_type<'gc>( .get(0) .unwrap_or(&"inner".into()) .coerce_to_string(activation) - .map(|s| s.as_str().into())?; + .map(|s| s.borrow().into())?; if let Some(filter) = this.as_bevel_filter_object() { filter.set_type(activation.context.gc_context, type_); diff --git a/core/src/avm1/globals/displacement_map_filter.rs b/core/src/avm1/globals/displacement_map_filter.rs index 7d9a30088..63a8ca7ac 100644 --- a/core/src/avm1/globals/displacement_map_filter.rs +++ b/core/src/avm1/globals/displacement_map_filter.rs @@ -5,7 +5,7 @@ use crate::avm1::error::Error; use crate::avm1::object::displacement_map_filter::DisplacementMapFilterObject; use crate::avm1::property_decl::{define_properties_on, Declaration}; use crate::avm1::{Object, TObject, Value}; -use crate::string::AvmString; +use crate::string::{AvmString, BorrowWStr, WStr}; use gc_arena::MutationContext; const PROTO_DECLS: &[Declaration] = declare_properties! { @@ -224,9 +224,8 @@ pub fn mode<'gc>( _args: &[Value<'gc>], ) -> Result, Error<'gc>> { if let Some(object) = this.as_displacement_map_filter_object() { - return Ok( - AvmString::new(activation.context.gc_context, String::from(object.mode())).into(), - ); + let mode: WStr<'_> = object.mode().into(); + return Ok(AvmString::new_ucs2(activation.context.gc_context, mode.into()).into()); } Ok(Value::Undefined) @@ -243,7 +242,7 @@ pub fn set_mode<'gc>( .coerce_to_string(activation)?; if let Some(object) = this.as_displacement_map_filter_object() { - object.set_mode(activation.context.gc_context, mode.as_str().into()); + object.set_mode(activation.context.gc_context, mode.borrow().into()); } Ok(Value::Undefined) diff --git a/core/src/avm1/globals/gradient_bevel_filter.rs b/core/src/avm1/globals/gradient_bevel_filter.rs index a35e94d25..82807a072 100644 --- a/core/src/avm1/globals/gradient_bevel_filter.rs +++ b/core/src/avm1/globals/gradient_bevel_filter.rs @@ -6,7 +6,7 @@ use crate::avm1::object::bevel_filter::BevelFilterType; use crate::avm1::object::gradient_bevel_filter::GradientBevelFilterObject; use crate::avm1::property_decl::{define_properties_on, Declaration}; use crate::avm1::{ArrayObject, Object, TObject, Value}; -use crate::string::AvmString; +use crate::string::{AvmString, BorrowWStr, WStr}; use gc_arena::MutationContext; const PROTO_DECLS: &[Declaration] = declare_properties! { @@ -392,8 +392,8 @@ pub fn get_type<'gc>( _args: &[Value<'gc>], ) -> Result, Error<'gc>> { if let Some(filter) = this.as_gradient_bevel_filter_object() { - let type_: &str = filter.get_type().into(); - return Ok(AvmString::new(activation.context.gc_context, type_.to_string()).into()); + let type_: WStr<'_> = filter.get_type().into(); + return Ok(AvmString::new_ucs2(activation.context.gc_context, type_.into()).into()); } Ok(Value::Undefined) @@ -408,7 +408,7 @@ pub fn set_type<'gc>( .get(0) .unwrap_or(&"inner".into()) .coerce_to_string(activation) - .map(|s| s.as_str().into())?; + .map(|s| s.borrow().into())?; if let Some(filter) = this.as_gradient_bevel_filter_object() { filter.set_type(activation.context.gc_context, type_); diff --git a/core/src/avm1/globals/gradient_glow_filter.rs b/core/src/avm1/globals/gradient_glow_filter.rs index ef3690cdb..083c3f26b 100644 --- a/core/src/avm1/globals/gradient_glow_filter.rs +++ b/core/src/avm1/globals/gradient_glow_filter.rs @@ -6,7 +6,7 @@ use crate::avm1::object::bevel_filter::BevelFilterType; use crate::avm1::object::gradient_glow_filter::GradientGlowFilterObject; use crate::avm1::property_decl::{define_properties_on, Declaration}; use crate::avm1::{ArrayObject, Object, TObject, Value}; -use crate::string::AvmString; +use crate::string::{AvmString, BorrowWStr, WStr}; use gc_arena::MutationContext; const PROTO_DECLS: &[Declaration] = declare_properties! { @@ -392,8 +392,8 @@ pub fn get_type<'gc>( _args: &[Value<'gc>], ) -> Result, Error<'gc>> { if let Some(filter) = this.as_gradient_glow_filter_object() { - let type_: &str = filter.get_type().into(); - return Ok(AvmString::new(activation.context.gc_context, type_.to_string()).into()); + let type_: WStr<'_> = filter.get_type().into(); + return Ok(AvmString::new_ucs2(activation.context.gc_context, type_.into()).into()); } Ok(Value::Undefined) @@ -408,7 +408,7 @@ pub fn set_type<'gc>( .get(0) .unwrap_or(&"inner".into()) .coerce_to_string(activation) - .map(|s| s.as_str().into())?; + .map(|s| s.borrow().into())?; if let Some(filter) = this.as_gradient_glow_filter_object() { filter.set_type(activation.context.gc_context, type_); diff --git a/core/src/avm1/globals/movie_clip.rs b/core/src/avm1/globals/movie_clip.rs index 4b391f758..aea9dfc80 100644 --- a/core/src/avm1/globals/movie_clip.rs +++ b/core/src/avm1/globals/movie_clip.rs @@ -15,7 +15,7 @@ use crate::display_object::{ use crate::ecma_conversions::f64_to_wrapping_i32; use crate::prelude::*; use crate::shape_utils::DrawCommand; -use crate::string::AvmString; +use crate::string::{AvmString, BorrowWStr}; use crate::vminterface::Instantiator; use gc_arena::MutationContext; use std::borrow::Cow; @@ -262,28 +262,31 @@ fn line_style<'gc>( let (allow_scale_x, allow_scale_y) = match args .get(4) .and_then(|v| v.coerce_to_string(activation).ok()) - .as_deref() + .as_ref() + .map(|v| v.borrow()) { - Some("normal") => (true, true), - Some("vertical") => (true, false), - Some("horizontal") => (false, true), + Some(v) if v == b"normal" => (true, true), + Some(v) if v == b"vertical" => (true, false), + Some(v) if v == b"horizontal" => (false, true), _ => (false, false), }; let cap_style = match args .get(5) .and_then(|v| v.coerce_to_string(activation).ok()) - .as_deref() + .as_ref() + .map(|v| v.borrow()) { - Some("square") => LineCapStyle::Square, - Some("none") => LineCapStyle::None, + Some(v) if v == b"square" => LineCapStyle::Square, + Some(v) if v == b"none" => LineCapStyle::None, _ => LineCapStyle::Round, }; let join_style = match args .get(6) .and_then(|v| v.coerce_to_string(activation).ok()) - .as_deref() + .as_ref() + .map(|v| v.borrow()) { - Some("miter") => { + Some(v) if v == b"miter" => { if let Some(limit) = args.get(7) { let limit = limit.coerce_to_f64(activation)?.clamp(0.0, 255.0); LineJoinStyle::Miter(Fixed8::from_f64(limit)) @@ -291,7 +294,7 @@ fn line_style<'gc>( LineJoinStyle::Miter(Fixed8::from_f32(3.0)) } } - Some("bevel") => LineJoinStyle::Bevel, + Some(v) if v == b"bevel" => LineJoinStyle::Bevel, _ => LineJoinStyle::Round, }; movie_clip @@ -468,18 +471,20 @@ fn begin_gradient_fill<'gc>( let spread = match args .get(5) .and_then(|v| v.coerce_to_string(activation).ok()) - .as_deref() + .as_ref() + .map(|v| v.borrow()) { - Some("reflect") => GradientSpread::Reflect, - Some("repeat") => GradientSpread::Repeat, + Some(v) if v == b"reflect" => GradientSpread::Reflect, + Some(v) if v == b"repeat" => GradientSpread::Repeat, _ => GradientSpread::Pad, }; let interpolation = match args .get(6) .and_then(|v| v.coerce_to_string(activation).ok()) - .as_deref() + .as_ref() + .map(|v| v.borrow()) { - Some("linearRGB") => GradientInterpolation::LinearRgb, + Some(v) if v == b"linearRGB" => GradientInterpolation::LinearRgb, _ => GradientInterpolation::Rgb, }; @@ -489,26 +494,24 @@ fn begin_gradient_fill<'gc>( interpolation, records, }; - let style = match method.as_ref() { - "linear" => FillStyle::LinearGradient(gradient), - "radial" => { - if let Some(focal_point) = args.get(7) { - FillStyle::FocalGradient { - gradient, - focal_point: Fixed8::from_f64(focal_point.coerce_to_f64(activation)?), - } - } else { - FillStyle::RadialGradient(gradient) + let style = if method == b"linear" { + FillStyle::LinearGradient(gradient) + } else if method == b"radial" { + if let Some(focal_point) = args.get(7) { + FillStyle::FocalGradient { + gradient, + focal_point: Fixed8::from_f64(focal_point.coerce_to_f64(activation)?), } + } else { + FillStyle::RadialGradient(gradient) } - other => { - avm_warn!( - activation, - "beginGradientFill() received invalid fill type {:?}", - other - ); - return Ok(Value::Undefined); - } + } else { + avm_warn!( + activation, + "beginGradientFill() received invalid fill type {:?}", + method + ); + return Ok(Value::Undefined); }; movie_clip .as_drawing(activation.context.gc_context) @@ -1004,7 +1007,7 @@ pub fn goto_frame<'gc>( activation.resolve_variable_path(movie_clip.into(), &frame_path)? { if let Some(clip) = clip.as_display_object().and_then(|o| o.as_movie_clip()) { - // TODO(moulins): we need Str::parse for avoiding allocation here. + // TODO(moulins): we need WStr::parse for avoiding allocation here. let frame = frame.to_string(); if let Ok(frame) = frame.parse().map(f64_to_wrapping_i32) { // First try to parse as a frame number. diff --git a/core/src/avm1/globals/object.rs b/core/src/avm1/globals/object.rs index 59aced1d0..8bd0d2790 100644 --- a/core/src/avm1/globals/object.rs +++ b/core/src/avm1/globals/object.rs @@ -294,11 +294,14 @@ pub fn as_set_prop_flags<'gc>( ), Some(v) => { let props = v.coerce_to_string(activation)?; - if props.as_str().contains(',') { - for prop_name in props.as_str().split(',') { + if props.contains(b',') { + for prop_name in props.split(b',') { object.set_attributes( activation.context.gc_context, - Some(AvmString::new(activation.context.gc_context, prop_name)), + Some(AvmString::new_ucs2( + activation.context.gc_context, + prop_name.into(), + )), set_attributes, clear_attributes, ) diff --git a/core/src/avm1/object/bevel_filter.rs b/core/src/avm1/object/bevel_filter.rs index 1636d7a8d..6887a9e45 100644 --- a/core/src/avm1/object/bevel_filter.rs +++ b/core/src/avm1/object/bevel_filter.rs @@ -1,6 +1,7 @@ use crate::add_field_accessors; use crate::avm1::{Object, ScriptObject, TObject}; use crate::impl_custom_object; +use crate::string::WStr; use gc_arena::{Collect, GcCell, MutationContext}; use std::fmt; @@ -13,24 +14,26 @@ pub enum BevelFilterType { Full, } -impl From<&str> for BevelFilterType { - fn from(value: &str) -> Self { - match value { - "inner" => BevelFilterType::Inner, - "outer" => BevelFilterType::Outer, - "full" => BevelFilterType::Full, - _ => BevelFilterType::Full, +impl From> for BevelFilterType { + fn from(value: WStr<'_>) -> Self { + if value == b"inner" { + BevelFilterType::Inner + } else if value == b"outer" { + BevelFilterType::Outer + } else { + BevelFilterType::Full } } } -impl From for &str { - fn from(v: BevelFilterType) -> Self { - match v { - BevelFilterType::Inner => "inner", - BevelFilterType::Outer => "outer", - BevelFilterType::Full => "full", - } +impl From for WStr<'static> { + fn from(v: BevelFilterType) -> WStr<'static> { + let s: &[u8] = match v { + BevelFilterType::Inner => b"inner", + BevelFilterType::Outer => b"outer", + BevelFilterType::Full => b"full", + }; + WStr::from_units(s) } } diff --git a/core/src/avm1/object/displacement_map_filter.rs b/core/src/avm1/object/displacement_map_filter.rs index a3ed9a97f..5e4f09590 100644 --- a/core/src/avm1/object/displacement_map_filter.rs +++ b/core/src/avm1/object/displacement_map_filter.rs @@ -1,6 +1,7 @@ use crate::add_field_accessors; use crate::avm1::{Object, ScriptObject, TObject}; use crate::impl_custom_object; +use crate::string::WStr; use gc_arena::{Collect, GcCell, MutationContext}; use std::fmt; @@ -14,32 +15,29 @@ pub enum DisplacementMapFilterMode { Color, } -impl From<&str> for DisplacementMapFilterMode { - fn from(v: &str) -> DisplacementMapFilterMode { - match v { - "wrap" => DisplacementMapFilterMode::Wrap, - "clamp" => DisplacementMapFilterMode::Clamp, - "ignore" => DisplacementMapFilterMode::Ignore, - "color" => DisplacementMapFilterMode::Color, - _ => DisplacementMapFilterMode::Wrap, +impl From> for DisplacementMapFilterMode { + fn from(v: WStr<'_>) -> DisplacementMapFilterMode { + if v == b"clamp" { + DisplacementMapFilterMode::Clamp + } else if v == b"ignore" { + DisplacementMapFilterMode::Ignore + } else if v == b"color" { + DisplacementMapFilterMode::Color + } else { + DisplacementMapFilterMode::Wrap } } } -impl From for &str { +impl From for WStr<'static> { fn from(v: DisplacementMapFilterMode) -> Self { - match v { - DisplacementMapFilterMode::Wrap => "wrap", - DisplacementMapFilterMode::Clamp => "clamp", - DisplacementMapFilterMode::Ignore => "ignore", - DisplacementMapFilterMode::Color => "color", - } - } -} - -impl From for String { - fn from(v: DisplacementMapFilterMode) -> Self { - Into::<&str>::into(v).to_string() + let s: &[u8] = match v { + DisplacementMapFilterMode::Wrap => b"wrap", + DisplacementMapFilterMode::Clamp => b"clamp", + DisplacementMapFilterMode::Ignore => b"ignore", + DisplacementMapFilterMode::Color => b"color", + }; + WStr::from_units(s) } }