chore: Migrate from enumset to bitflags

This commit is contained in:
relrelb 2021-01-22 02:35:46 +02:00 committed by GitHub
parent 2254589e71
commit b05c6540e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
85 changed files with 1570 additions and 1387 deletions

585
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@ png = { version = "0.16.8" }
puremp3 = { version = "0.1", optional = true } puremp3 = { version = "0.1", optional = true }
ruffle_macros = { path = "macros" } ruffle_macros = { path = "macros" }
swf = { path = "../swf" } swf = { path = "../swf" }
enumset = "1.0.1" bitflags = "1.2.1"
smallvec = "1.6.1" smallvec = "1.6.1"
num_enum = "0.5.1" num_enum = "0.5.1"
quick-xml = "0.20.0" quick-xml = "0.20.0"

View File

@ -22,7 +22,7 @@ mod fscommand;
pub mod function; pub mod function;
pub mod globals; pub mod globals;
pub mod object; pub mod object;
mod property; pub mod property;
mod scope; mod scope;
mod string; mod string;
mod timer; mod timer;

View File

@ -14,7 +14,6 @@ use crate::ecma_conversions::f64_to_wrapping_u32;
use crate::tag_utils::SwfSlice; use crate::tag_utils::SwfSlice;
use crate::vminterface::Instantiator; use crate::vminterface::Instantiator;
use crate::{avm_error, avm_warn}; use crate::{avm_error, avm_warn};
use enumset::EnumSet;
use gc_arena::{Collect, Gc, GcCell, MutationContext}; use gc_arena::{Collect, Gc, GcCell, MutationContext};
use indexmap::IndexMap; use indexmap::IndexMap;
use rand::Rng; use rand::Rng;
@ -1146,16 +1145,16 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
sub_prototype.set_attributes( sub_prototype.set_attributes(
self.context.gc_context, self.context.gc_context,
Some("constructor"), Some("constructor"),
Attribute::DontEnum.into(), Attribute::DONT_ENUM,
EnumSet::empty(), Attribute::empty(),
); );
sub_prototype.set("__constructor__", superclass.into(), self)?; sub_prototype.set("__constructor__", superclass.into(), self)?;
sub_prototype.set_attributes( sub_prototype.set_attributes(
self.context.gc_context, self.context.gc_context,
Some("__constructor__"), Some("__constructor__"),
Attribute::DontEnum.into(), Attribute::DONT_ENUM,
EnumSet::empty(), Attribute::empty(),
); );
subclass.set("prototype", sub_prototype.into(), self)?; subclass.set("prototype", sub_prototype.into(), self)?;

View File

@ -3,13 +3,12 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::object::super_object::SuperObject; use crate::avm1::object::super_object::SuperObject;
use crate::avm1::property::{Attribute, Attribute::*}; use crate::avm1::property::Attribute;
use crate::avm1::scope::Scope; use crate::avm1::scope::Scope;
use crate::avm1::value::Value; use crate::avm1::value::Value;
use crate::avm1::{Object, ObjectPtr, ScriptObject, TObject}; use crate::avm1::{Object, ObjectPtr, ScriptObject, TObject};
use crate::display_object::{DisplayObject, TDisplayObject}; use crate::display_object::{DisplayObject, TDisplayObject};
use crate::tag_utils::SwfSlice; use crate::tag_utils::SwfSlice;
use enumset::EnumSet;
use gc_arena::{Collect, CollectionContext, Gc, GcCell, MutationContext}; use gc_arena::{Collect, CollectionContext, Gc, GcCell, MutationContext};
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt; use std::fmt;
@ -269,14 +268,14 @@ impl<'gc> Executable<'gc> {
activation.context.gc_context, activation.context.gc_context,
"callee", "callee",
callee.into(), callee.into(),
DontEnum.into(), Attribute::DONT_ENUM,
); );
// The caller is the previous callee. // The caller is the previous callee.
arguments.define_value( arguments.define_value(
activation.context.gc_context, activation.context.gc_context,
"caller", "caller",
activation.callee.map(Value::from).unwrap_or(Value::Null), activation.callee.map(Value::from).unwrap_or(Value::Null),
DontEnum.into(), Attribute::DONT_ENUM,
); );
if !af.suppress_arguments { if !af.suppress_arguments {
@ -505,9 +504,9 @@ impl<'gc> FunctionObject<'gc> {
context, context,
"constructor", "constructor",
Value::Object(function), Value::Object(function),
DontEnum.into(), Attribute::DONT_ENUM,
); );
function.define_value(context, "prototype", prototype.into(), EnumSet::empty()); function.define_value(context, "prototype", prototype.into(), Attribute::empty());
function function
} }
@ -594,16 +593,16 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
this.set_attributes( this.set_attributes(
activation.context.gc_context, activation.context.gc_context,
Some("__constructor__"), Some("__constructor__"),
Attribute::DontEnum.into(), Attribute::DONT_ENUM,
EnumSet::empty(), Attribute::empty(),
); );
if activation.current_swf_version() < 7 { if activation.current_swf_version() < 7 {
this.set("constructor", (*self).into(), activation)?; this.set("constructor", (*self).into(), activation)?;
this.set_attributes( this.set_attributes(
activation.context.gc_context, activation.context.gc_context,
Some("constructor"), Some("constructor"),
Attribute::DontEnum.into(), Attribute::DONT_ENUM,
EnumSet::empty(), Attribute::empty(),
); );
} }
if let Some(exec) = &self.data.read().constructor { if let Some(exec) = &self.data.read().constructor {
@ -636,16 +635,16 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
this.set_attributes( this.set_attributes(
activation.context.gc_context, activation.context.gc_context,
Some("__constructor__"), Some("__constructor__"),
Attribute::DontEnum.into(), Attribute::DONT_ENUM,
EnumSet::empty(), Attribute::empty(),
); );
if activation.current_swf_version() < 7 { if activation.current_swf_version() < 7 {
this.set("constructor", (*self).into(), activation)?; this.set("constructor", (*self).into(), activation)?;
this.set_attributes( this.set_attributes(
activation.context.gc_context, activation.context.gc_context,
Some("constructor"), Some("constructor"),
Attribute::DontEnum.into(), Attribute::DONT_ENUM,
EnumSet::empty(), Attribute::empty(),
); );
} }
if let Some(exec) = &self.data.read().constructor { if let Some(exec) = &self.data.read().constructor {
@ -715,7 +714,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: &str, name: &str,
value: Value<'gc>, value: Value<'gc>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.base.define_value(gc_context, name, value, attributes) self.base.define_value(gc_context, name, value, attributes)
} }
@ -724,8 +723,8 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
&self, &self,
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: Option<&str>, name: Option<&str>,
set_attributes: EnumSet<Attribute>, set_attributes: Attribute,
clear_attributes: EnumSet<Attribute>, clear_attributes: Attribute,
) { ) {
self.base self.base
.set_attributes(gc_context, name, set_attributes, clear_attributes) .set_attributes(gc_context, name, set_attributes, clear_attributes)
@ -737,7 +736,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.base self.base
.add_property(gc_context, name, get, set, attributes) .add_property(gc_context, name, get, set, attributes)
@ -750,7 +749,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.base self.base
.add_property_with_case(activation, gc_context, name, get, set, attributes) .add_property_with_case(activation, gc_context, name, get, set, attributes)

View File

@ -1,9 +1,8 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::Collect; use gc_arena::Collect;
use gc_arena::MutationContext; use gc_arena::MutationContext;
use rand::Rng; use rand::Rng;
@ -701,19 +700,29 @@ pub fn create_globals<'gc>(
transform_proto, transform_proto,
); );
flash.define_value(gc_context, "geom", geom.into(), EnumSet::empty()); flash.define_value(gc_context, "geom", geom.into(), Attribute::empty());
flash.define_value(gc_context, "filters", filters.into(), EnumSet::empty()); flash.define_value(gc_context, "filters", filters.into(), Attribute::empty());
flash.define_value(gc_context, "display", display.into(), EnumSet::empty()); flash.define_value(gc_context, "display", display.into(), Attribute::empty());
geom.define_value(gc_context, "Matrix", matrix.into(), EnumSet::empty()); geom.define_value(gc_context, "Matrix", matrix.into(), Attribute::empty());
geom.define_value(gc_context, "Point", point.into(), EnumSet::empty()); geom.define_value(gc_context, "Point", point.into(), Attribute::empty());
geom.define_value(gc_context, "Rectangle", rectangle.into(), EnumSet::empty()); geom.define_value(
gc_context,
"Rectangle",
rectangle.into(),
Attribute::empty(),
);
geom.define_value( geom.define_value(
gc_context, gc_context,
"ColorTransform", "ColorTransform",
color_transform.into(), color_transform.into(),
EnumSet::empty(), Attribute::empty(),
);
geom.define_value(
gc_context,
"Transform",
transform.into(),
Attribute::empty(),
); );
geom.define_value(gc_context, "Transform", transform.into(), EnumSet::empty());
let bitmap_filter_proto = let bitmap_filter_proto =
bitmap_filter::create_proto(gc_context, object_proto, Some(function_proto)); bitmap_filter::create_proto(gc_context, object_proto, Some(function_proto));
@ -819,62 +828,62 @@ pub fn create_globals<'gc>(
gc_context, gc_context,
"BitmapFilter", "BitmapFilter",
bitmap_filter.into(), bitmap_filter.into(),
EnumSet::empty(), Attribute::empty(),
); );
filters.define_value( filters.define_value(
gc_context, gc_context,
"BlurFilter", "BlurFilter",
blur_filter.into(), blur_filter.into(),
EnumSet::empty(), Attribute::empty(),
); );
filters.define_value( filters.define_value(
gc_context, gc_context,
"BevelFilter", "BevelFilter",
bevel_filter.into(), bevel_filter.into(),
EnumSet::empty(), Attribute::empty(),
); );
filters.define_value( filters.define_value(
gc_context, gc_context,
"GlowFilter", "GlowFilter",
glow_filter.into(), glow_filter.into(),
EnumSet::empty(), Attribute::empty(),
); );
filters.define_value( filters.define_value(
gc_context, gc_context,
"DropShadowFilter", "DropShadowFilter",
drop_shadow_filter.into(), drop_shadow_filter.into(),
EnumSet::empty(), Attribute::empty(),
); );
filters.define_value( filters.define_value(
gc_context, gc_context,
"ColorMatrixFilter", "ColorMatrixFilter",
color_matrix_filter.into(), color_matrix_filter.into(),
EnumSet::empty(), Attribute::empty(),
); );
filters.define_value( filters.define_value(
gc_context, gc_context,
"DisplacementMapFilter", "DisplacementMapFilter",
displacement_map_filter.into(), displacement_map_filter.into(),
EnumSet::empty(), Attribute::empty(),
); );
filters.define_value( filters.define_value(
gc_context, gc_context,
"ConvolutionFilter", "ConvolutionFilter",
convolution_filter.into(), convolution_filter.into(),
EnumSet::empty(), Attribute::empty(),
); );
filters.define_value( filters.define_value(
gc_context, gc_context,
"GradientBevelFilter", "GradientBevelFilter",
gradient_bevel_filter.into(), gradient_bevel_filter.into(),
EnumSet::empty(), Attribute::empty(),
); );
filters.define_value( filters.define_value(
gc_context, gc_context,
"GradientGlowFilter", "GradientGlowFilter",
gradient_glow_filter.into(), gradient_glow_filter.into(),
EnumSet::empty(), Attribute::empty(),
); );
let bitmap_data_proto = bitmap_data::create_proto(gc_context, object_proto, function_proto); let bitmap_data_proto = bitmap_data::create_proto(gc_context, object_proto, function_proto);
@ -885,7 +894,7 @@ pub fn create_globals<'gc>(
gc_context, gc_context,
"BitmapData", "BitmapData",
bitmap_data.into(), bitmap_data.into(),
EnumSet::empty(), Attribute::empty(),
); );
let external = ScriptObject::object(gc_context, Some(object_proto)); let external = ScriptObject::object(gc_context, Some(object_proto));
@ -895,12 +904,12 @@ pub fn create_globals<'gc>(
function_proto, function_proto,
); );
flash.define_value(gc_context, "external", external.into(), EnumSet::empty()); flash.define_value(gc_context, "external", external.into(), Attribute::empty());
external.define_value( external.define_value(
gc_context, gc_context,
"ExternalInterface", "ExternalInterface",
external_interface.into(), external_interface.into(),
EnumSet::empty(), Attribute::empty(),
); );
let mut globals = ScriptObject::bare_object(gc_context); let mut globals = ScriptObject::bare_object(gc_context);
@ -908,37 +917,57 @@ pub fn create_globals<'gc>(
gc_context, gc_context,
"AsBroadcaster", "AsBroadcaster",
as_broadcaster.into(), as_broadcaster.into(),
DontEnum.into(), Attribute::DONT_ENUM,
);
globals.define_value(gc_context, "flash", flash.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Array", array.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Button", button.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Color", color.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Error", error.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Object", object.into(), Attribute::DONT_ENUM);
globals.define_value(
gc_context,
"Function",
function.into(),
Attribute::DONT_ENUM,
);
globals.define_value(
gc_context,
"LoadVars",
load_vars.into(),
Attribute::DONT_ENUM,
);
globals.define_value(
gc_context,
"MovieClip",
movie_clip.into(),
Attribute::DONT_ENUM,
); );
globals.define_value(gc_context, "flash", flash.into(), DontEnum.into());
globals.define_value(gc_context, "Array", array.into(), DontEnum.into());
globals.define_value(gc_context, "Button", button.into(), DontEnum.into());
globals.define_value(gc_context, "Color", color.into(), DontEnum.into());
globals.define_value(gc_context, "Error", error.into(), DontEnum.into());
globals.define_value(gc_context, "Object", object.into(), DontEnum.into());
globals.define_value(gc_context, "Function", function.into(), DontEnum.into());
globals.define_value(gc_context, "LoadVars", load_vars.into(), DontEnum.into());
globals.define_value(gc_context, "MovieClip", movie_clip.into(), DontEnum.into());
globals.define_value( globals.define_value(
gc_context, gc_context,
"MovieClipLoader", "MovieClipLoader",
movie_clip_loader.into(), movie_clip_loader.into(),
DontEnum.into(), Attribute::DONT_ENUM,
);
globals.define_value(gc_context, "Sound", sound.into(), Attribute::DONT_ENUM);
globals.define_value(
gc_context,
"TextField",
text_field.into(),
Attribute::DONT_ENUM,
); );
globals.define_value(gc_context, "Sound", sound.into(), DontEnum.into());
globals.define_value(gc_context, "TextField", text_field.into(), DontEnum.into());
globals.define_value( globals.define_value(
gc_context, gc_context,
"TextFormat", "TextFormat",
text_format.into(), text_format.into(),
DontEnum.into(), Attribute::DONT_ENUM,
); );
globals.define_value(gc_context, "XMLNode", xmlnode.into(), DontEnum.into()); globals.define_value(gc_context, "XMLNode", xmlnode.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "XML", xml.into(), DontEnum.into()); globals.define_value(gc_context, "XML", xml.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "String", string.into(), DontEnum.into()); globals.define_value(gc_context, "String", string.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Number", number.into(), DontEnum.into()); globals.define_value(gc_context, "Number", number.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Boolean", boolean.into(), DontEnum.into()); globals.define_value(gc_context, "Boolean", boolean.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Date", date.into(), DontEnum.into()); globals.define_value(gc_context, "Date", date.into(), Attribute::DONT_ENUM);
let shared_object_proto = shared_object::create_proto(gc_context, object_proto, function_proto); let shared_object_proto = shared_object::create_proto(gc_context, object_proto, function_proto);
@ -951,7 +980,7 @@ pub fn create_globals<'gc>(
gc_context, gc_context,
"SharedObject", "SharedObject",
shared_obj.into(), shared_obj.into(),
DontEnum.into(), Attribute::DONT_ENUM,
); );
let context_menu = FunctionObject::constructor( let context_menu = FunctionObject::constructor(
@ -965,7 +994,7 @@ pub fn create_globals<'gc>(
gc_context, gc_context,
"ContextMenu", "ContextMenu",
context_menu.into(), context_menu.into(),
DontEnum.into(), Attribute::DONT_ENUM,
); );
let selection = selection::create_selection_object( let selection = selection::create_selection_object(
@ -975,7 +1004,12 @@ pub fn create_globals<'gc>(
broadcaster_functions, broadcaster_functions,
array_proto, array_proto,
); );
globals.define_value(gc_context, "Selection", selection.into(), DontEnum.into()); globals.define_value(
gc_context,
"Selection",
selection.into(),
Attribute::DONT_ENUM,
);
let context_menu_item = FunctionObject::constructor( let context_menu_item = FunctionObject::constructor(
gc_context, gc_context,
@ -988,7 +1022,7 @@ pub fn create_globals<'gc>(
gc_context, gc_context,
"ContextMenuItem", "ContextMenuItem",
context_menu_item.into(), context_menu_item.into(),
DontEnum.into(), Attribute::DONT_ENUM,
); );
let system_security = system_security::create(gc_context, Some(object_proto), function_proto); let system_security = system_security::create(gc_context, Some(object_proto), function_proto);
@ -1010,7 +1044,7 @@ pub fn create_globals<'gc>(
system_capabilities, system_capabilities,
system_ime, system_ime,
); );
globals.define_value(gc_context, "System", system.into(), DontEnum.into()); globals.define_value(gc_context, "System", system.into(), Attribute::DONT_ENUM);
globals.define_value( globals.define_value(
gc_context, gc_context,
@ -1020,7 +1054,7 @@ pub fn create_globals<'gc>(
Some(object_proto), Some(object_proto),
Some(function_proto), Some(function_proto),
)), )),
DontEnum.into(), Attribute::DONT_ENUM,
); );
globals.define_value( globals.define_value(
gc_context, gc_context,
@ -1032,7 +1066,7 @@ pub fn create_globals<'gc>(
broadcaster_functions, broadcaster_functions,
array_proto, array_proto,
)), )),
DontEnum.into(), Attribute::DONT_ENUM,
); );
globals.define_value( globals.define_value(
gc_context, gc_context,
@ -1044,7 +1078,7 @@ pub fn create_globals<'gc>(
broadcaster_functions, broadcaster_functions,
array_proto, array_proto,
)), )),
DontEnum.into(), Attribute::DONT_ENUM,
); );
globals.define_value( globals.define_value(
gc_context, gc_context,
@ -1056,72 +1090,90 @@ pub fn create_globals<'gc>(
function_proto, function_proto,
broadcaster_functions, broadcaster_functions,
)), )),
DontEnum.into(), Attribute::DONT_ENUM,
); );
globals.force_set_function( globals.force_set_function(
"isFinite", "isFinite",
is_finite, is_finite,
gc_context, gc_context,
DontEnum, Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"isNaN",
is_nan,
gc_context,
Attribute::DONT_ENUM,
Some(function_proto), Some(function_proto),
); );
globals.force_set_function("isNaN", is_nan, gc_context, DontEnum, Some(function_proto));
globals.force_set_function( globals.force_set_function(
"parseInt", "parseInt",
parse_int, parse_int,
gc_context, gc_context,
DontEnum, Attribute::DONT_ENUM,
Some(function_proto), Some(function_proto),
); );
globals.force_set_function( globals.force_set_function(
"parseFloat", "parseFloat",
parse_float, parse_float,
gc_context, gc_context,
DontEnum, Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"random",
random,
gc_context,
Attribute::DONT_ENUM,
Some(function_proto), Some(function_proto),
); );
globals.force_set_function("random", random, gc_context, DontEnum, Some(function_proto));
globals.force_set_function( globals.force_set_function(
"ASSetPropFlags", "ASSetPropFlags",
object::as_set_prop_flags, object::as_set_prop_flags,
gc_context, gc_context,
DontEnum, Attribute::DONT_ENUM,
Some(function_proto), Some(function_proto),
); );
globals.force_set_function( globals.force_set_function(
"clearInterval", "clearInterval",
clear_interval, clear_interval,
gc_context, gc_context,
DontEnum, Attribute::DONT_ENUM,
Some(function_proto), Some(function_proto),
); );
globals.force_set_function( globals.force_set_function(
"setInterval", "setInterval",
set_interval, set_interval,
gc_context, gc_context,
DontEnum, Attribute::DONT_ENUM,
Some(function_proto), Some(function_proto),
); );
globals.force_set_function( globals.force_set_function(
"setTimeout", "setTimeout",
set_timeout, set_timeout,
gc_context, gc_context,
DontEnum, Attribute::DONT_ENUM,
Some(function_proto), Some(function_proto),
); );
globals.force_set_function( globals.force_set_function(
"updateAfterEvent", "updateAfterEvent",
update_after_event, update_after_event,
gc_context, gc_context,
DontEnum, Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"escape",
escape,
gc_context,
Attribute::DONT_ENUM,
Some(function_proto), Some(function_proto),
); );
globals.force_set_function("escape", escape, gc_context, DontEnum, Some(function_proto));
globals.force_set_function( globals.force_set_function(
"unescape", "unescape",
unescape, unescape,
gc_context, gc_context,
DontEnum, Attribute::DONT_ENUM,
Some(function_proto), Some(function_proto),
); );
@ -1135,7 +1187,7 @@ pub fn create_globals<'gc>(
function_proto, function_proto,
), ),
None, None,
DontEnum.into(), Attribute::DONT_ENUM,
); );
globals.add_property( globals.add_property(
gc_context, gc_context,
@ -1147,7 +1199,7 @@ pub fn create_globals<'gc>(
function_proto, function_proto,
), ),
None, None,
DontEnum.into(), Attribute::DONT_ENUM,
); );
( (

View File

@ -46,35 +46,35 @@ pub fn create_array_object<'gc>(
gc_context, gc_context,
"CASEINSENSITIVE", "CASEINSENSITIVE",
1.into(), 1.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_ENUM | Attribute::DONT_DELETE | Attribute::READ_ONLY,
); );
object.define_value( object.define_value(
gc_context, gc_context,
"DESCENDING", "DESCENDING",
2.into(), 2.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_ENUM | Attribute::DONT_DELETE | Attribute::READ_ONLY,
); );
object.define_value( object.define_value(
gc_context, gc_context,
"UNIQUESORT", "UNIQUESORT",
4.into(), 4.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_ENUM | Attribute::DONT_DELETE | Attribute::READ_ONLY,
); );
object.define_value( object.define_value(
gc_context, gc_context,
"RETURNINDEXEDARRAY", "RETURNINDEXEDARRAY",
8.into(), 8.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_ENUM | Attribute::DONT_DELETE | Attribute::READ_ONLY,
); );
object.define_value( object.define_value(
gc_context, gc_context,
"NUMERIC", "NUMERIC",
16.into(), 16.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_ENUM | Attribute::DONT_DELETE | Attribute::READ_ONLY,
); );
array array
@ -663,78 +663,78 @@ pub fn create_proto<'gc>(
"push", "push",
push, push,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"unshift", "unshift",
unshift, unshift,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"shift", "shift",
shift, shift,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("pop", pop, gc_context, Attribute::DontEnum, Some(fn_proto)); object.force_set_function("pop", pop, gc_context, Attribute::DONT_ENUM, Some(fn_proto));
object.force_set_function( object.force_set_function(
"reverse", "reverse",
reverse, reverse,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"join", "join",
join, join,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"slice", "slice",
slice, slice,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"splice", "splice",
splice, splice,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"concat", "concat",
concat, concat,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"toString", "toString",
to_string, to_string,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"sort", "sort",
sort, sort,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"sortOn", "sortOn",
sort_on, sort_on,
gc_context, gc_context,
Attribute::DontEnum, Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -4,7 +4,7 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::TObject; use crate::avm1::object::TObject;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, Value}; use crate::avm1::{Object, ScriptObject, Value};
use gc_arena::{Collect, MutationContext}; use gc_arena::{Collect, MutationContext};
@ -165,27 +165,32 @@ pub fn initialize_internal<'gc>(
) { ) {
let listeners = ScriptObject::array(gc_context, Some(array_proto)); let listeners = ScriptObject::array(gc_context, Some(array_proto));
broadcaster.define_value(gc_context, "_listeners", listeners.into(), DontEnum.into()); broadcaster.define_value(
gc_context,
"_listeners",
listeners.into(),
Attribute::DONT_ENUM,
);
broadcaster.define_value( broadcaster.define_value(
gc_context, gc_context,
"addListener", "addListener",
functions.add_listener.into(), functions.add_listener.into(),
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
broadcaster.define_value( broadcaster.define_value(
gc_context, gc_context,
"removeListener", "removeListener",
functions.remove_listener.into(), functions.remove_listener.into(),
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
broadcaster.define_value( broadcaster.define_value(
gc_context, gc_context,
"broadcastMessage", "broadcastMessage",
functions.broadcast_message.into(), functions.broadcast_message.into(),
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
} }
@ -200,7 +205,7 @@ pub fn create<'gc>(
"initialize", "initialize",
initialize, initialize,
gc_context, gc_context,
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -214,7 +219,7 @@ pub fn create<'gc>(
gc_context, gc_context,
"addListener", "addListener",
add_listener.into(), add_listener.into(),
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
let remove_listener = FunctionObject::function( let remove_listener = FunctionObject::function(
@ -227,7 +232,7 @@ pub fn create<'gc>(
gc_context, gc_context,
"removeListener", "removeListener",
remove_listener.into(), remove_listener.into(),
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
let broadcast_message = FunctionObject::function( let broadcast_message = FunctionObject::function(
@ -240,7 +245,7 @@ pub fn create<'gc>(
gc_context, gc_context,
"broadcastMessage", "broadcastMessage",
broadcast_message.into(), broadcast_message.into(),
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
( (

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::bevel_filter::{BevelFilterObject, BevelFilterType}; use crate::avm1::object::bevel_filter::{BevelFilterObject, BevelFilterType};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value}; use crate::avm1::{AvmString, Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -417,7 +417,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -434,7 +434,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -451,7 +451,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -468,7 +468,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -485,7 +485,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -502,7 +502,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -519,7 +519,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -536,7 +536,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -553,7 +553,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -570,7 +570,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -587,7 +587,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
script_object.add_property( script_object.add_property(
gc_context, gc_context,
@ -604,7 +604,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.into() object.into()
} }

View File

@ -3,11 +3,11 @@
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::bitmap_data::{BitmapDataObject, ChannelOptions, Color}; use crate::avm1::object::bitmap_data::{BitmapDataObject, ChannelOptions, Color};
use crate::avm1::property::Attribute;
use crate::avm1::{activation::Activation, object::bitmap_data::BitmapData}; use crate::avm1::{activation::Activation, object::bitmap_data::BitmapData};
use crate::avm1::{Object, TObject, Value}; use crate::avm1::{Object, TObject, Value};
use crate::character::Character; use crate::character::Character;
use crate::display_object::TDisplayObject; use crate::display_object::TDisplayObject;
use enumset::EnumSet;
use gc_arena::{GcCell, MutationContext}; use gc_arena::{GcCell, MutationContext};
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -847,7 +847,7 @@ pub fn create_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -860,7 +860,7 @@ pub fn create_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -873,7 +873,7 @@ pub fn create_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -886,144 +886,162 @@ pub fn create_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
EnumSet::empty(), Attribute::empty(),
); );
object.force_set_function( object.force_set_function(
"getPixel", "getPixel",
get_pixel, get_pixel,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"getPixel32", "getPixel32",
get_pixel32, get_pixel32,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"setPixel", "setPixel",
set_pixel, set_pixel,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"setPixel32", "setPixel32",
set_pixel32, set_pixel32,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"copyChannel", "copyChannel",
copy_channel, copy_channel,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"fillRect", "fillRect",
fill_rect, fill_rect,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"clone",
clone,
gc_context,
Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function( object.force_set_function(
"dispose", "dispose",
dispose, dispose,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"floodFill", "floodFill",
flood_fill, flood_fill,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"noise",
noise,
gc_context,
Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("noise", noise, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function( object.force_set_function(
"colorTransform", "colorTransform",
color_transform, color_transform,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"getColorBoundsRect", "getColorBoundsRect",
get_color_bounds_rect, get_color_bounds_rect,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"perlinNoise", "perlinNoise",
perlin_noise, perlin_noise,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"applyFilter", "applyFilter",
apply_filter, apply_filter,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("draw", draw, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function("draw", draw, gc_context, Attribute::empty(), Some(fn_proto));
object.force_set_function( object.force_set_function(
"hitTest", "hitTest",
hit_test, hit_test,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"generateFilterRect", "generateFilterRect",
generate_filter_rect, generate_filter_rect,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"copyPixels", "copyPixels",
copy_pixels, copy_pixels,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"merge",
merge,
gc_context,
Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("merge", merge, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function( object.force_set_function(
"paletteMap", "paletteMap",
palette_map, palette_map,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"pixelDissolve", "pixelDissolve",
pixel_dissolve, pixel_dissolve,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"scroll", "scroll",
scroll, scroll,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"threshold", "threshold",
threshold, threshold,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -1092,7 +1110,7 @@ pub fn create_bitmap_data_object<'gc>(
"loadBitmap", "loadBitmap",
load_bitmap, load_bitmap,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
fn_proto, fn_proto,
); );

View File

@ -2,8 +2,8 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value}; use crate::avm1::{Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -275,7 +275,7 @@ pub fn create_proto<'gc>(
) -> Object<'gc> { ) -> Object<'gc> {
let mut object = ScriptObject::object(gc_context, Some(proto)); let mut object = ScriptObject::object(gc_context, Some(proto));
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), fn_proto); object.force_set_function("clone", clone, gc_context, Attribute::empty(), fn_proto);
object.into() object.into()
} }

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::blur_filter::BlurFilterObject; use crate::avm1::object::blur_filter::BlurFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, TObject, Value}; use crate::avm1::{Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -133,7 +133,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -151,7 +151,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -169,7 +169,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
blur_filter.into() blur_filter.into()

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::value_object::ValueObject; use crate::avm1::object::value_object::ValueObject;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value}; use crate::avm1::{AvmString, Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
/// `Boolean` constructor /// `Boolean` constructor
@ -72,14 +72,14 @@ pub fn create_proto<'gc>(
"toString", "toString",
to_string, to_string,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"valueOf", "valueOf",
value_of, value_of,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );

View File

@ -4,7 +4,7 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::display_object; use crate::avm1::globals::display_object;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value}; use crate::avm1::{Object, ScriptObject, TObject, Value};
use crate::display_object::{Button, TDisplayObject}; use crate::display_object::{Button, TDisplayObject};
use gc_arena::MutationContext; use gc_arena::MutationContext;
@ -17,7 +17,7 @@ macro_rules! with_button_props {
$name, $name,
with_button_props!(getter $gc, $fn_proto, $get), with_button_props!(getter $gc, $fn_proto, $get),
with_button_props!(setter $gc, $fn_proto, $($set),*), with_button_props!(setter $gc, $fn_proto, $($set),*),
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
)* )*
}; };

View File

@ -5,10 +5,9 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value}; use crate::avm1::{Object, ScriptObject, TObject, Value};
use crate::display_object::{DisplayObject, TDisplayObject}; use crate::display_object::{DisplayObject, TDisplayObject};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -23,8 +22,8 @@ pub fn constructor<'gc>(
this.set_attributes( this.set_attributes(
activation.context.gc_context, activation.context.gc_context,
Some("target"), Some("target"),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
EnumSet::empty(), Attribute::empty(),
); );
Ok(this.into()) Ok(this.into())
@ -41,7 +40,7 @@ pub fn create_proto<'gc>(
"getRGB", "getRGB",
get_rgb, get_rgb,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -49,7 +48,7 @@ pub fn create_proto<'gc>(
"getTransform", "getTransform",
get_transform, get_transform,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -57,7 +56,7 @@ pub fn create_proto<'gc>(
"setRGB", "setRGB",
set_rgb, set_rgb,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -65,7 +64,7 @@ pub fn create_proto<'gc>(
"setTransform", "setTransform",
set_transform, set_transform,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::color_matrix_filter::ColorMatrixFilterObject; use crate::avm1::object::color_matrix_filter::ColorMatrixFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value}; use crate::avm1::{Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -88,7 +88,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
color_matrix_filter.into() color_matrix_filter.into()

View File

@ -3,8 +3,8 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value}; use crate::avm1::{AvmString, Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
use crate::avm1::object::color_transform_object::ColorTransformObject; use crate::avm1::object::color_transform_object::ColorTransformObject;
@ -19,7 +19,7 @@ macro_rules! with_color_transform {
$name, $name,
FunctionObject::function($gc, Executable::Native($get), Some($fn_proto), $fn_proto), FunctionObject::function($gc, Executable::Native($get), Some($fn_proto), $fn_proto),
Some(FunctionObject::function($gc, Executable::Native($set), Some($fn_proto), $fn_proto)), Some(FunctionObject::function($gc, Executable::Native($set), Some($fn_proto), $fn_proto)),
EnumSet::empty(), Attribute::empty(),
); );
)* )*
} }
@ -260,7 +260,7 @@ pub fn create_proto<'gc>(
"concat", "concat",
concat, concat,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -268,7 +268,7 @@ pub fn create_proto<'gc>(
"toString", "toString",
to_string, to_string,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );

View File

@ -143,7 +143,7 @@ pub fn create_proto<'gc>(
"copy", "copy",
copy, copy,
gc_context, gc_context,
Attribute::DontEnum | Attribute::DontDelete, Attribute::DONT_ENUM | Attribute::DONT_DELETE,
Some(fn_proto), Some(fn_proto),
); );
@ -151,7 +151,7 @@ pub fn create_proto<'gc>(
"hideBuiltInItems", "hideBuiltInItems",
hide_builtin_items, hide_builtin_items,
gc_context, gc_context,
Attribute::DontEnum | Attribute::DontDelete, Attribute::DONT_ENUM | Attribute::DONT_DELETE,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -108,7 +108,7 @@ pub fn create_proto<'gc>(
"copy", "copy",
copy, copy,
gc_context, gc_context,
Attribute::DontEnum | Attribute::DontDelete, Attribute::DONT_ENUM | Attribute::DONT_DELETE,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::convolution_filter::ConvolutionFilterObject; use crate::avm1::object::convolution_filter::ConvolutionFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value}; use crate::avm1::{Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -337,7 +337,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -355,7 +355,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -373,7 +373,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -391,7 +391,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -409,7 +409,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -427,7 +427,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -445,7 +445,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -463,7 +463,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -481,7 +481,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
filter.into() filter.into()

View File

@ -5,7 +5,6 @@ use crate::avm1::object::date_object::DateObject;
use crate::avm1::property::Attribute; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value}; use crate::avm1::{AvmString, Object, TObject, Value};
use chrono::{DateTime, Datelike, Duration, FixedOffset, LocalResult, TimeZone, Timelike, Utc}; use chrono::{DateTime, Datelike, Duration, FixedOffset, LocalResult, TimeZone, Timelike, Utc};
use enumset::EnumSet;
use gc_arena::{Collect, MutationContext}; use gc_arena::{Collect, MutationContext};
use num_traits::ToPrimitive; use num_traits::ToPrimitive;
use std::f64::NAN; use std::f64::NAN;
@ -28,7 +27,7 @@ macro_rules! implement_local_getters {
} }
} as crate::avm1::function::NativeFunction<'gc>, } as crate::avm1::function::NativeFunction<'gc>,
$gc_context, $gc_context,
Attribute::DontDelete | Attribute::ReadOnly | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto $fn_proto
); );
)* )*
@ -48,7 +47,7 @@ macro_rules! implement_methods {
} }
} as crate::avm1::function::NativeFunction<'gc>, } as crate::avm1::function::NativeFunction<'gc>,
$gc_context, $gc_context,
Attribute::DontDelete | Attribute::ReadOnly | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto $fn_proto
); );
)* )*
@ -72,7 +71,7 @@ macro_rules! implement_utc_getters {
} }
} as crate::avm1::function::NativeFunction<'gc>, } as crate::avm1::function::NativeFunction<'gc>,
$gc_context, $gc_context,
Attribute::DontDelete | Attribute::ReadOnly | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto $fn_proto
); );
)* )*
@ -906,7 +905,7 @@ pub fn create_date_object<'gc>(
); );
let mut object = date.as_script_object().unwrap(); let mut object = date.as_script_object().unwrap();
object.force_set_function("UTC", create_utc, gc_context, EnumSet::empty(), fn_proto); object.force_set_function("UTC", create_utc, gc_context, Attribute::empty(), fn_proto);
date date
} }

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::displacement_map_filter::DisplacementMapFilterObject; use crate::avm1::object::displacement_map_filter::DisplacementMapFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value}; use crate::avm1::{AvmString, Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -328,7 +328,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -346,7 +346,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -364,7 +364,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -382,7 +382,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -400,7 +400,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -418,7 +418,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -436,7 +436,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -454,7 +454,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -472,7 +472,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
filter.into() filter.into()

View File

@ -3,10 +3,9 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use crate::display_object::{DisplayObject, TDisplayObject, TDisplayObjectContainer}; use crate::display_object::{DisplayObject, Lists, TDisplayObject, TDisplayObjectContainer};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
/// Depths used/returned by ActionScript are offset by this amount from depths used inside the SWF/by the VM. /// Depths used/returned by ActionScript are offset by this amount from depths used inside the SWF/by the VM.
@ -35,7 +34,7 @@ macro_rules! with_display_object {
Ok(Value::Undefined) Ok(Value::Undefined)
} as crate::avm1::function::NativeFunction<'gc>, } as crate::avm1::function::NativeFunction<'gc>,
$gc_context, $gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto $fn_proto
); );
)* )*
@ -73,7 +72,7 @@ pub fn define_display_object_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.add_property( object.add_property(
@ -91,7 +90,7 @@ pub fn define_display_object_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.add_property( object.add_property(
@ -109,7 +108,7 @@ pub fn define_display_object_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
} }
@ -160,7 +159,7 @@ pub fn overwrite_root<'gc>(
activation.context.gc_context, activation.context.gc_context,
"_root", "_root",
new_val, new_val,
EnumSet::new(), Attribute::empty(),
); );
Ok(Value::Undefined) Ok(Value::Undefined)
@ -179,7 +178,7 @@ pub fn overwrite_global<'gc>(
activation.context.gc_context, activation.context.gc_context,
"_global", "_global",
new_val, new_val,
EnumSet::new(), Attribute::empty(),
); );
Ok(Value::Undefined) Ok(Value::Undefined)
@ -198,7 +197,7 @@ pub fn overwrite_parent<'gc>(
activation.context.gc_context, activation.context.gc_context,
"_parent", "_parent",
new_val, new_val,
EnumSet::new(), Attribute::empty(),
); );
Ok(Value::Undefined) Ok(Value::Undefined)
@ -216,7 +215,7 @@ pub fn remove_display_object<'gc>(
if depth >= AVM_DEPTH_BIAS && depth < AVM_MAX_REMOVE_DEPTH && !this.removed() { if depth >= AVM_DEPTH_BIAS && depth < AVM_MAX_REMOVE_DEPTH && !this.removed() {
// Need a parent to remove from. // Need a parent to remove from.
if let Some(mut parent) = this.parent().and_then(|o| o.as_movie_clip()) { if let Some(mut parent) = this.parent().and_then(|o| o.as_movie_clip()) {
parent.remove_child(&mut activation.context, this, EnumSet::all()); parent.remove_child(&mut activation.context, this, Lists::all());
} }
} }
} }

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::drop_shadow_filter::DropShadowFilterObject; use crate::avm1::object::drop_shadow_filter::DropShadowFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, TObject, Value}; use crate::avm1::{Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -381,7 +381,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -399,7 +399,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -417,7 +417,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -435,7 +435,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -453,7 +453,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -471,7 +471,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -489,7 +489,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -507,7 +507,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -525,7 +525,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -543,7 +543,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -561,7 +561,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
drop_shadow_filter.into() drop_shadow_filter.into()

View File

@ -2,9 +2,8 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -29,14 +28,14 @@ pub fn create_proto<'gc>(
) -> Object<'gc> { ) -> Object<'gc> {
let mut object = ScriptObject::object(gc_context, Some(proto)); let mut object = ScriptObject::object(gc_context, Some(proto));
object.define_value(gc_context, "message", "Error".into(), EnumSet::empty()); object.define_value(gc_context, "message", "Error".into(), Attribute::empty());
object.define_value(gc_context, "name", "Error".into(), EnumSet::empty()); object.define_value(gc_context, "name", "Error".into(), Attribute::empty());
object.force_set_function( object.force_set_function(
"toString", "toString",
to_string, to_string,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -81,14 +81,14 @@ pub fn create_external_interface_object<'gc>(
fn_proto, fn_proto,
), ),
None, None,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.force_set_function( object.force_set_function(
"addCallback", "addCallback",
add_callback, add_callback,
gc_context, gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -96,7 +96,7 @@ pub fn create_external_interface_object<'gc>(
"call", "call",
call, call,
gc_context, gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -3,8 +3,8 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::ExecutionReason; use crate::avm1::function::ExecutionReason;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value}; use crate::avm1::{Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
/// Implements `new Function()` /// Implements `new Function()`
@ -121,15 +121,15 @@ pub fn create_proto<'gc>(gc_context: MutationContext<'gc, '_>, proto: Object<'gc
function_proto function_proto
.as_script_object() .as_script_object()
.unwrap() .unwrap()
.force_set_function("call", call, gc_context, EnumSet::empty(), this); .force_set_function("call", call, gc_context, Attribute::empty(), this);
function_proto function_proto
.as_script_object() .as_script_object()
.unwrap() .unwrap()
.force_set_function("apply", apply, gc_context, EnumSet::empty(), this); .force_set_function("apply", apply, gc_context, Attribute::empty(), this);
function_proto function_proto
.as_script_object() .as_script_object()
.unwrap() .unwrap()
.force_set_function("toString", to_string, gc_context, EnumSet::empty(), this); .force_set_function("toString", to_string, gc_context, Attribute::empty(), this);
function_proto function_proto
} }

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::glow_filter::GlowFilterObject; use crate::avm1::object::glow_filter::GlowFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, TObject, Value}; use crate::avm1::{Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -284,7 +284,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -302,7 +302,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -320,7 +320,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -338,7 +338,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -356,7 +356,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -374,7 +374,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -392,7 +392,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -410,7 +410,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
glow_filter.into() glow_filter.into()

View File

@ -5,8 +5,8 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::bevel_filter::BevelFilterType; use crate::avm1::object::bevel_filter::BevelFilterType;
use crate::avm1::object::gradient_bevel_filter::GradientBevelFilterObject; use crate::avm1::object::gradient_bevel_filter::GradientBevelFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -477,7 +477,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -495,7 +495,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -513,7 +513,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -531,7 +531,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -549,7 +549,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -567,7 +567,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -585,7 +585,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -603,7 +603,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -621,7 +621,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -639,7 +639,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -657,7 +657,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
color_matrix_filter.into() color_matrix_filter.into()

View File

@ -5,8 +5,8 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::bevel_filter::BevelFilterType; use crate::avm1::object::bevel_filter::BevelFilterType;
use crate::avm1::object::gradient_glow_filter::GradientGlowFilterObject; use crate::avm1::object::gradient_glow_filter::GradientGlowFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -477,7 +477,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -495,7 +495,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -513,7 +513,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -531,7 +531,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -549,7 +549,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -567,7 +567,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -585,7 +585,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -603,7 +603,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -621,7 +621,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -639,7 +639,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
object.add_property( object.add_property(
@ -657,7 +657,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
color_matrix_filter.into() color_matrix_filter.into()

View File

@ -56,122 +56,122 @@ pub fn create_key_object<'gc>(
gc_context, gc_context,
"ALT", "ALT",
18.into(), 18.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"BACKSPACE", "BACKSPACE",
8.into(), 8.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"CAPSLOCK", "CAPSLOCK",
20.into(), 20.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"CONTROL", "CONTROL",
17.into(), 17.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"DELETEKEY", "DELETEKEY",
46.into(), 46.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"DOWN", "DOWN",
40.into(), 40.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"END", "END",
35.into(), 35.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"ENTER", "ENTER",
13.into(), 13.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"ESCAPE", "ESCAPE",
27.into(), 27.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"HOME", "HOME",
36.into(), 36.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"INSERT", "INSERT",
45.into(), 45.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"LEFT", "LEFT",
37.into(), 37.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"PGDN", "PGDN",
34.into(), 34.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"PGUP", "PGUP",
33.into(), 33.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"RIGHT", "RIGHT",
39.into(), 39.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"SHIFT", "SHIFT",
16.into(), 16.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"SPACE", "SPACE",
32.into(), 32.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"TAB", "TAB",
9.into(), 9.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.define_value( key.define_value(
gc_context, gc_context,
"UP", "UP",
38.into(), 38.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
key.force_set_function( key.force_set_function(
"isDown", "isDown",
is_down, is_down,
gc_context, gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
@ -179,7 +179,7 @@ pub fn create_key_object<'gc>(
"getAscii", "getAscii",
get_ascii, get_ascii,
gc_context, gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
@ -187,7 +187,7 @@ pub fn create_key_object<'gc>(
"getCode", "getCode",
get_code, get_code,
gc_context, gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );

View File

@ -25,15 +25,13 @@ pub fn create_proto<'gc>(
proto: Object<'gc>, proto: Object<'gc>,
fn_proto: Object<'gc>, fn_proto: Object<'gc>,
) -> Object<'gc> { ) -> Object<'gc> {
use Attribute::*;
let mut object = ScriptObject::object(gc_context, Some(proto)); let mut object = ScriptObject::object(gc_context, Some(proto));
object.force_set_function( object.force_set_function(
"load", "load",
load, load,
gc_context, gc_context,
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -41,7 +39,7 @@ pub fn create_proto<'gc>(
"send", "send",
send, send,
gc_context, gc_context,
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -49,7 +47,7 @@ pub fn create_proto<'gc>(
"sendAndLoad", "sendAndLoad",
send_and_load, send_and_load,
gc_context, gc_context,
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -57,7 +55,7 @@ pub fn create_proto<'gc>(
"decode", "decode",
decode, decode,
gc_context, gc_context,
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -65,7 +63,7 @@ pub fn create_proto<'gc>(
"getBytesLoaded", "getBytesLoaded",
get_bytes_loaded, get_bytes_loaded,
gc_context, gc_context,
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -73,7 +71,7 @@ pub fn create_proto<'gc>(
"getBytesTotal", "getBytesTotal",
get_bytes_total, get_bytes_total,
gc_context, gc_context,
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -81,7 +79,7 @@ pub fn create_proto<'gc>(
"toString", "toString",
to_string, to_string,
gc_context, gc_context,
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -89,14 +87,14 @@ pub fn create_proto<'gc>(
gc_context, gc_context,
"contentType", "contentType",
"application/x-www-form-url-encoded".into(), "application/x-www-form-url-encoded".into(),
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.force_set_function( object.force_set_function(
"onLoad", "onLoad",
on_load, on_load,
gc_context, gc_context,
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -104,7 +102,7 @@ pub fn create_proto<'gc>(
"onData", "onData",
on_data, on_data,
gc_context, gc_context,
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -112,7 +110,7 @@ pub fn create_proto<'gc>(
"addRequestHeader", "addRequestHeader",
add_request_header, add_request_header,
gc_context, gc_context,
DontDelete | DontEnum | ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -343,7 +341,7 @@ fn spawn_load_var_fetch<'gc>(
activation.context.gc_context, activation.context.gc_context,
"_bytesLoaded", "_bytesLoaded",
0.into(), 0.into(),
Attribute::DontDelete | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
} else { } else {
loader_object.set("_bytesLoaded", 0.into(), activation)?; loader_object.set("_bytesLoaded", 0.into(), activation)?;
@ -354,7 +352,7 @@ fn spawn_load_var_fetch<'gc>(
activation.context.gc_context, activation.context.gc_context,
"loaded", "loaded",
false.into(), false.into(),
Attribute::DontDelete | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
} else { } else {
loader_object.set("loaded", false.into(), activation)?; loader_object.set("loaded", false.into(), activation)?;

View File

@ -1,7 +1,7 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::object::Object; use crate::avm1::object::Object;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{ScriptObject, TObject, Value}; use crate::avm1::{ScriptObject, TObject, Value};
use gc_arena::MutationContext; use gc_arena::MutationContext;
use rand::Rng; use rand::Rng;
@ -20,7 +20,7 @@ macro_rules! wrap_std {
} }
}, },
$gc_context, $gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$proto $proto
); );
)* )*
@ -144,49 +144,49 @@ pub fn create<'gc>(
gc_context, gc_context,
"E", "E",
std::f64::consts::E.into(), std::f64::consts::E.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
math.define_value( math.define_value(
gc_context, gc_context,
"LN10", "LN10",
std::f64::consts::LN_10.into(), std::f64::consts::LN_10.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
math.define_value( math.define_value(
gc_context, gc_context,
"LN2", "LN2",
std::f64::consts::LN_2.into(), std::f64::consts::LN_2.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
math.define_value( math.define_value(
gc_context, gc_context,
"LOG10E", "LOG10E",
std::f64::consts::LOG10_E.into(), std::f64::consts::LOG10_E.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
math.define_value( math.define_value(
gc_context, gc_context,
"LOG2E", "LOG2E",
std::f64::consts::LOG2_E.into(), std::f64::consts::LOG2_E.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
math.define_value( math.define_value(
gc_context, gc_context,
"PI", "PI",
std::f64::consts::PI.into(), std::f64::consts::PI.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
math.define_value( math.define_value(
gc_context, gc_context,
"SQRT1_2", "SQRT1_2",
std::f64::consts::FRAC_1_SQRT_2.into(), std::f64::consts::FRAC_1_SQRT_2.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
math.define_value( math.define_value(
gc_context, gc_context,
"SQRT2", "SQRT2",
std::f64::consts::SQRT_2.into(), std::f64::consts::SQRT_2.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
wrap_std!(math, gc_context, fn_proto, wrap_std!(math, gc_context, fn_proto,
@ -208,42 +208,42 @@ pub fn create<'gc>(
"atan2", "atan2",
atan2, atan2,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
math.force_set_function( math.force_set_function(
"pow", "pow",
pow, pow,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
math.force_set_function( math.force_set_function(
"max", "max",
max, max,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
math.force_set_function( math.force_set_function(
"min", "min",
min, min,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
math.force_set_function( math.force_set_function(
"random", "random",
random, random,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
math.force_set_function( math.force_set_function(
"round", "round",
round, round,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::point::{point_to_object, value_to_point}; use crate::avm1::globals::point::{point_to_object, value_to_point};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
use swf::{Matrix, Twips}; use swf::{Matrix, Twips};
@ -427,7 +427,7 @@ pub fn create_proto<'gc>(
"toString", "toString",
to_string, to_string,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -435,19 +435,31 @@ pub fn create_proto<'gc>(
"identity", "identity",
identity, identity,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function(
"clone",
clone,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("scale", scale, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function(
"scale",
scale,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function( object.force_set_function(
"rotate", "rotate",
rotate, rotate,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -455,7 +467,7 @@ pub fn create_proto<'gc>(
"translate", "translate",
translate, translate,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -463,7 +475,7 @@ pub fn create_proto<'gc>(
"concat", "concat",
concat, concat,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -471,7 +483,7 @@ pub fn create_proto<'gc>(
"invert", "invert",
invert, invert,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -479,7 +491,7 @@ pub fn create_proto<'gc>(
"createBox", "createBox",
create_box, create_box,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -487,7 +499,7 @@ pub fn create_proto<'gc>(
"createGradientBox", "createGradientBox",
create_gradient_box, create_gradient_box,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -495,7 +507,7 @@ pub fn create_proto<'gc>(
"transformPoint", "transformPoint",
transform_point, transform_point,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -503,7 +515,7 @@ pub fn create_proto<'gc>(
"deltaTransformPoint", "deltaTransformPoint",
delta_transform_point, delta_transform_point,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );

View File

@ -48,7 +48,7 @@ pub fn create_mouse_object<'gc>(
"show", "show",
show_mouse, show_mouse,
gc_context, gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
@ -56,7 +56,7 @@ pub fn create_mouse_object<'gc>(
"hide", "hide",
hide_mouse, hide_mouse,
gc_context, gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );

View File

@ -5,7 +5,7 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::display_object::{self, AVM_DEPTH_BIAS, AVM_MAX_DEPTH}; use crate::avm1::globals::display_object::{self, AVM_DEPTH_BIAS, AVM_MAX_DEPTH};
use crate::avm1::globals::matrix::gradient_object_to_matrix; use crate::avm1::globals::matrix::gradient_object_to_matrix;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use crate::avm_error; use crate::avm_error;
use crate::avm_warn; use crate::avm_warn;
@ -48,7 +48,7 @@ macro_rules! with_movie_clip {
Ok(Value::Undefined) Ok(Value::Undefined)
} as crate::avm1::function::NativeFunction<'gc>, } as crate::avm1::function::NativeFunction<'gc>,
$gc_context, $gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto $fn_proto
); );
)* )*
@ -63,7 +63,7 @@ macro_rules! with_movie_clip_props {
$name, $name,
with_movie_clip_props!(getter $gc, $fn_proto, $get), with_movie_clip_props!(getter $gc, $fn_proto, $get),
with_movie_clip_props!(setter $gc, $fn_proto, $($set),*), with_movie_clip_props!(setter $gc, $fn_proto, $($set),*),
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
)* )*
}; };
@ -209,7 +209,7 @@ pub fn create_proto<'gc>(
"removeMovieClip", "removeMovieClip",
remove_movie_clip, remove_movie_clip,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -9,7 +9,6 @@ use crate::avm1::property::Attribute;
use crate::avm1::{Object, Value}; use crate::avm1::{Object, Value};
use crate::backend::navigator::RequestOptions; use crate::backend::navigator::RequestOptions;
use crate::display_object::{DisplayObject, TDisplayObject}; use crate::display_object::{DisplayObject, TDisplayObject};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
pub fn constructor<'gc>( pub fn constructor<'gc>(
@ -25,7 +24,7 @@ pub fn constructor<'gc>(
activation.context.gc_context, activation.context.gc_context,
"_listeners", "_listeners",
Value::Object(listeners.into()), Value::Object(listeners.into()),
Attribute::DontEnum.into(), Attribute::DONT_ENUM,
); );
listeners.set_array_element(0, Value::Object(this), activation.context.gc_context); listeners.set_array_element(0, Value::Object(this), activation.context.gc_context);
@ -109,7 +108,7 @@ pub fn get_progress<'gc>(
.movie() .movie()
.map(|mv| (mv.header().uncompressed_length).into()) .map(|mv| (mv.header().uncompressed_length).into())
.unwrap_or(Value::Undefined), .unwrap_or(Value::Undefined),
EnumSet::empty(), Attribute::empty(),
); );
ret_obj.define_value( ret_obj.define_value(
activation.context.gc_context, activation.context.gc_context,
@ -118,7 +117,7 @@ pub fn get_progress<'gc>(
.movie() .movie()
.map(|mv| (mv.header().uncompressed_length).into()) .map(|mv| (mv.header().uncompressed_length).into())
.unwrap_or(Value::Undefined), .unwrap_or(Value::Undefined),
EnumSet::empty(), Attribute::empty(),
); );
return Ok(ret_obj.into()); return Ok(ret_obj.into());
@ -143,21 +142,21 @@ pub fn create_proto<'gc>(
"loadClip", "loadClip",
load_clip, load_clip,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
mcl_proto.as_script_object().unwrap().force_set_function( mcl_proto.as_script_object().unwrap().force_set_function(
"unloadClip", "unloadClip",
unload_clip, unload_clip,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
mcl_proto.as_script_object().unwrap().force_set_function( mcl_proto.as_script_object().unwrap().force_set_function(
"getProgress", "getProgress",
get_progress, get_progress,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );

View File

@ -4,9 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::value_object::ValueObject; use crate::avm1::object::value_object::ValueObject;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value}; use crate::avm1::{AvmString, Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
/// `Number` constructor /// `Number` constructor
@ -63,7 +62,7 @@ pub fn create_number_object<'gc>(
gc_context, gc_context,
"MAX_VALUE", "MAX_VALUE",
std::f64::MAX.into(), std::f64::MAX.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.define_value( object.define_value(
@ -72,28 +71,28 @@ pub fn create_number_object<'gc>(
// Note this is actually the smallest positive denormalized f64. // Note this is actually the smallest positive denormalized f64.
// Rust doesn't provide a constant for this (`MIN_POSITIVE` is a normal f64). // Rust doesn't provide a constant for this (`MIN_POSITIVE` is a normal f64).
Value::Number(f64::from_bits(1)), Value::Number(f64::from_bits(1)),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.define_value( object.define_value(
gc_context, gc_context,
"NaN", "NaN",
std::f64::NAN.into(), std::f64::NAN.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.define_value( object.define_value(
gc_context, gc_context,
"NEGATIVE_INFINITY", "NEGATIVE_INFINITY",
std::f64::NEG_INFINITY.into(), std::f64::NEG_INFINITY.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.define_value( object.define_value(
gc_context, gc_context,
"POSITIVE_INFINITY", "POSITIVE_INFINITY",
std::f64::INFINITY.into(), std::f64::INFINITY.into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
number number
@ -112,14 +111,14 @@ pub fn create_proto<'gc>(
"toString", "toString",
to_string, to_string,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"valueOf", "valueOf",
value_of, value_of,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );

View File

@ -2,11 +2,10 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute::{self, *}; use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value}; use crate::avm1::{Object, ScriptObject, TObject, Value};
use crate::avm_warn; use crate::avm_warn;
use crate::display_object::TDisplayObject; use crate::display_object::TDisplayObject;
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
use std::borrow::Cow; use std::borrow::Cow;
@ -60,7 +59,7 @@ pub fn add_property<'gc>(
&name, &name,
get.to_owned(), get.to_owned(),
Some(set.to_owned()), Some(set.to_owned()),
EnumSet::empty(), Attribute::empty(),
); );
} else if let Value::Null = setter { } else if let Value::Null = setter {
this.add_property_with_case( this.add_property_with_case(
@ -69,7 +68,7 @@ pub fn add_property<'gc>(
&name, &name,
get.to_owned(), get.to_owned(),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
} else { } else {
return Ok(false.into()); return Ok(false.into());
@ -248,56 +247,56 @@ pub fn fill_proto<'gc>(
"addProperty", "addProperty",
add_property, add_property,
gc_context, gc_context,
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object_proto.as_script_object().unwrap().force_set_function( object_proto.as_script_object().unwrap().force_set_function(
"hasOwnProperty", "hasOwnProperty",
has_own_property, has_own_property,
gc_context, gc_context,
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object_proto.as_script_object().unwrap().force_set_function( object_proto.as_script_object().unwrap().force_set_function(
"isPropertyEnumerable", "isPropertyEnumerable",
is_property_enumerable, is_property_enumerable,
gc_context, gc_context,
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object_proto.as_script_object().unwrap().force_set_function( object_proto.as_script_object().unwrap().force_set_function(
"isPrototypeOf", "isPrototypeOf",
is_prototype_of, is_prototype_of,
gc_context, gc_context,
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object_proto.as_script_object().unwrap().force_set_function( object_proto.as_script_object().unwrap().force_set_function(
"toString", "toString",
to_string, to_string,
gc_context, gc_context,
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object_proto.as_script_object().unwrap().force_set_function( object_proto.as_script_object().unwrap().force_set_function(
"valueOf", "valueOf",
value_of, value_of,
gc_context, gc_context,
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object_proto.as_script_object().unwrap().force_set_function( object_proto.as_script_object().unwrap().force_set_function(
"watch", "watch",
watch, watch,
gc_context, gc_context,
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object_proto.as_script_object().unwrap().force_set_function( object_proto.as_script_object().unwrap().force_set_function(
"unwatch", "unwatch",
unwatch, unwatch,
gc_context, gc_context,
DontDelete | DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
} }
@ -349,22 +348,22 @@ pub fn as_set_prop_flags<'gc>(
let set_flags = args let set_flags = args
.get(2) .get(2)
.unwrap_or(&Value::Number(0.0)) .unwrap_or(&Value::Number(0.0))
.coerce_to_f64(activation)? as u128; .coerce_to_f64(activation)? as u8;
let clear_flags = args let set_attributes = Attribute::from_bits_truncate(set_flags);
.get(2)
.unwrap_or(&Value::Number(0.0))
.coerce_to_f64(activation)? as u128;
if set_flags > 0b111 || clear_flags > 0b111 { let clear_flags = args
.get(3)
.unwrap_or(&Value::Number(0.0))
.coerce_to_f64(activation)? as u8;
let clear_attributes = Attribute::from_bits_truncate(clear_flags);
if set_attributes.bits() != set_flags || clear_attributes.bits() != clear_flags {
avm_warn!( avm_warn!(
activation, activation,
"ASSetPropFlags: Unimplemented support for flags > 7" "ASSetPropFlags: Unimplemented support for flags > 7"
); );
} }
let set_attributes = EnumSet::<Attribute>::from_u128(set_flags & 0b111);
let clear_attributes = EnumSet::<Attribute>::from_u128(clear_flags & 0b111);
match properties { match properties {
Some(properties) => { Some(properties) => {
for prop_name in properties { for prop_name in properties {
@ -405,7 +404,7 @@ pub fn create_object_object<'gc>(
"registerClass", "registerClass",
register_class, register_class,
gc_context, gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -5,7 +5,6 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
use std::f64::NAN; use std::f64::NAN;
@ -276,13 +275,19 @@ pub fn create_point_object<'gc>(
); );
let mut object = point.as_script_object().unwrap(); let mut object = point.as_script_object().unwrap();
object.force_set_function("distance", distance, gc_context, EnumSet::empty(), fn_proto); object.force_set_function(
object.force_set_function("polar", polar, gc_context, EnumSet::empty(), fn_proto); "distance",
distance,
gc_context,
Attribute::empty(),
fn_proto,
);
object.force_set_function("polar", polar, gc_context, Attribute::empty(), fn_proto);
object.force_set_function( object.force_set_function(
"interpolate", "interpolate",
interpolate, interpolate,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
fn_proto, fn_proto,
); );
@ -300,27 +305,33 @@ pub fn create_proto<'gc>(
"toString", "toString",
to_string, to_string,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function(
"clone",
clone,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function( object.force_set_function(
"equals", "equals",
equals, equals,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("add", add, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function("add", add, gc_context, Attribute::empty(), Some(fn_proto));
object.force_set_function( object.force_set_function(
"subtract", "subtract",
subtract, subtract,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -328,7 +339,7 @@ pub fn create_proto<'gc>(
"normalize", "normalize",
normalize, normalize,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -336,7 +347,7 @@ pub fn create_proto<'gc>(
"offset", "offset",
offset, offset,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -350,7 +361,7 @@ pub fn create_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
Attribute::ReadOnly.into(), Attribute::READ_ONLY,
); );
object.into() object.into()

View File

@ -6,7 +6,6 @@ use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::point::{construct_new_point, point_to_object, value_to_point}; use crate::avm1::globals::point::{construct_new_point, point_to_object, value_to_point};
use crate::avm1::property::Attribute; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
use std::f64::NAN; use std::f64::NAN;
@ -691,7 +690,7 @@ pub fn create_proto<'gc>(
"toString", "toString",
to_string, to_string,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -699,7 +698,7 @@ pub fn create_proto<'gc>(
"isEmpty", "isEmpty",
is_empty, is_empty,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -707,17 +706,23 @@ pub fn create_proto<'gc>(
"setEmpty", "setEmpty",
set_empty, set_empty,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function(
"clone",
clone,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function( object.force_set_function(
"contains", "contains",
contains, contains,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -725,7 +730,7 @@ pub fn create_proto<'gc>(
"containsPoint", "containsPoint",
contains_point, contains_point,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -733,7 +738,7 @@ pub fn create_proto<'gc>(
"containsRectangle", "containsRectangle",
contains_rectangle, contains_rectangle,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -741,17 +746,23 @@ pub fn create_proto<'gc>(
"intersects", "intersects",
intersects, intersects,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("union", union, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function(
"union",
union,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function( object.force_set_function(
"inflate", "inflate",
inflate, inflate,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -759,7 +770,7 @@ pub fn create_proto<'gc>(
"inflatePoint", "inflatePoint",
inflate_point, inflate_point,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -767,7 +778,7 @@ pub fn create_proto<'gc>(
"offset", "offset",
offset, offset,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -775,7 +786,7 @@ pub fn create_proto<'gc>(
"offsetPoint", "offsetPoint",
offset_point, offset_point,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -783,7 +794,7 @@ pub fn create_proto<'gc>(
"intersection", "intersection",
intersection, intersection,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -791,7 +802,7 @@ pub fn create_proto<'gc>(
"equals", "equals",
equals, equals,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -810,7 +821,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
Attribute::DontDelete | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
object.add_property( object.add_property(
@ -828,7 +839,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
Attribute::DontDelete | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
object.add_property( object.add_property(
@ -846,7 +857,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
Attribute::DontDelete | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
object.add_property( object.add_property(
@ -864,7 +875,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
Attribute::DontDelete | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
object.add_property( object.add_property(
@ -882,7 +893,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
Attribute::DontDelete | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
object.add_property( object.add_property(
@ -900,7 +911,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
Attribute::DontDelete | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
object.add_property( object.add_property(
@ -918,7 +929,7 @@ pub fn create_proto<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
Attribute::DontDelete | Attribute::DontEnum, Attribute::DONT_DELETE | Attribute::DONT_ENUM,
); );
object.into() object.into()

View File

@ -147,7 +147,7 @@ pub fn create_selection_object<'gc>(
"getBeginIndex", "getBeginIndex",
get_begin_index, get_begin_index,
gc_context, gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -155,7 +155,7 @@ pub fn create_selection_object<'gc>(
"getEndIndex", "getEndIndex",
get_end_index, get_end_index,
gc_context, gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -163,7 +163,7 @@ pub fn create_selection_object<'gc>(
"getCaretIndex", "getCaretIndex",
get_caret_index, get_caret_index,
gc_context, gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -171,7 +171,7 @@ pub fn create_selection_object<'gc>(
"setSelection", "setSelection",
set_selection, set_selection,
gc_context, gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -179,7 +179,7 @@ pub fn create_selection_object<'gc>(
"setFocus", "setFocus",
set_focus, set_focus,
gc_context, gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -187,7 +187,7 @@ pub fn create_selection_object<'gc>(
"getFocus", "getFocus",
get_focus, get_focus,
gc_context, gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -1,10 +1,10 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value}; use crate::avm1::{AvmString, Object, TObject, Value};
use crate::avm_warn; use crate::avm_warn;
use crate::display_object::TDisplayObject; use crate::display_object::TDisplayObject;
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
use crate::avm1::object::shared_object::SharedObject; use crate::avm1::object::shared_object::SharedObject;
@ -106,7 +106,7 @@ fn deserialize_object<'gc>(
activation.context.gc_context, activation.context.gc_context,
entry.0, entry.0,
value, value,
EnumSet::empty(), Attribute::empty(),
); );
} }
obj.into() obj.into()
@ -141,7 +141,7 @@ fn deserialize_array<'gc>(
activation.context.gc_context, activation.context.gc_context,
entry.0, entry.0,
value, value,
EnumSet::empty(), Attribute::empty(),
); );
} }
} }
@ -282,7 +282,7 @@ pub fn get_local<'gc>(
activation.context.gc_context, activation.context.gc_context,
"data", "data",
data, data,
EnumSet::empty(), Attribute::empty(),
); );
activation.context.shared_objects.insert(full_name, this); activation.context.shared_objects.insert(full_name, this);
@ -344,7 +344,7 @@ pub fn create_shared_object_object<'gc>(
"deleteAll", "deleteAll",
delete_all, delete_all,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
fn_proto, fn_proto,
); );
@ -352,7 +352,7 @@ pub fn create_shared_object_object<'gc>(
"getDiskUsage", "getDiskUsage",
get_disk_usage, get_disk_usage,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
fn_proto, fn_proto,
); );
@ -360,7 +360,7 @@ pub fn create_shared_object_object<'gc>(
"getLocal", "getLocal",
get_local, get_local,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
fn_proto, fn_proto,
); );
@ -368,7 +368,7 @@ pub fn create_shared_object_object<'gc>(
"getRemote", "getRemote",
get_remote, get_remote,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
fn_proto, fn_proto,
); );
@ -376,7 +376,7 @@ pub fn create_shared_object_object<'gc>(
"getMaxSize", "getMaxSize",
get_max_size, get_max_size,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
fn_proto, fn_proto,
); );
@ -384,7 +384,7 @@ pub fn create_shared_object_object<'gc>(
"addListener", "addListener",
add_listener, add_listener,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
fn_proto, fn_proto,
); );
@ -392,7 +392,7 @@ pub fn create_shared_object_object<'gc>(
"removeListener", "removeListener",
remove_listener, remove_listener,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
fn_proto, fn_proto,
); );
@ -509,35 +509,53 @@ pub fn create_proto<'gc>(
let shared_obj = SharedObject::empty_shared_obj(gc_context, Some(proto)); let shared_obj = SharedObject::empty_shared_obj(gc_context, Some(proto));
let mut object = shared_obj.as_script_object().unwrap(); let mut object = shared_obj.as_script_object().unwrap();
object.force_set_function("clear", clear, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function(
"clear",
clear,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("close", close, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function(
"close",
close,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function( object.force_set_function(
"connect", "connect",
connect, connect,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("flush", flush, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function(
"flush",
flush,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function( object.force_set_function(
"getSize", "getSize",
get_size, get_size,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function("send", send, gc_context, EnumSet::empty(), Some(fn_proto)); object.force_set_function("send", send, gc_context, Attribute::empty(), Some(fn_proto));
object.force_set_function( object.force_set_function(
"setFps", "setFps",
set_fps, set_fps,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -545,7 +563,7 @@ pub fn create_proto<'gc>(
"onStatus", "onStatus",
on_status, on_status,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -553,7 +571,7 @@ pub fn create_proto<'gc>(
"onSync", "onSync",
on_sync, on_sync,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );

View File

@ -4,7 +4,7 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{Object, SoundObject, TObject, Value}; use crate::avm1::{Object, SoundObject, TObject, Value};
use crate::avm_warn; use crate::avm_warn;
use crate::character::Character; use crate::character::Character;
@ -44,7 +44,7 @@ pub fn create_proto<'gc>(
"attachSound", "attachSound",
attach_sound, attach_sound,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -58,7 +58,7 @@ pub fn create_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.add_property( object.add_property(
@ -71,14 +71,14 @@ pub fn create_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.as_script_object().unwrap().force_set_function( object.as_script_object().unwrap().force_set_function(
"getBytesLoaded", "getBytesLoaded",
get_bytes_loaded, get_bytes_loaded,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -86,7 +86,7 @@ pub fn create_proto<'gc>(
"getBytesTotal", "getBytesTotal",
get_bytes_total, get_bytes_total,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -94,7 +94,7 @@ pub fn create_proto<'gc>(
"getPan", "getPan",
get_pan, get_pan,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -102,7 +102,7 @@ pub fn create_proto<'gc>(
"getTransform", "getTransform",
get_transform, get_transform,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -110,7 +110,7 @@ pub fn create_proto<'gc>(
"getVolume", "getVolume",
get_volume, get_volume,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -118,7 +118,7 @@ pub fn create_proto<'gc>(
"loadSound", "loadSound",
load_sound, load_sound,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -132,14 +132,14 @@ pub fn create_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
object.as_script_object().unwrap().force_set_function( object.as_script_object().unwrap().force_set_function(
"setPan", "setPan",
set_pan, set_pan,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -147,7 +147,7 @@ pub fn create_proto<'gc>(
"setTransform", "setTransform",
set_transform, set_transform,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -155,7 +155,7 @@ pub fn create_proto<'gc>(
"setVolume", "setVolume",
set_volume, set_volume,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -163,7 +163,7 @@ pub fn create_proto<'gc>(
"start", "start",
start, start,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -171,7 +171,7 @@ pub fn create_proto<'gc>(
"stop", "stop",
stop, stop,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -36,7 +36,7 @@ pub fn create_stage_object<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
Attribute::DontEnum | Attribute::DontDelete, Attribute::DONT_ENUM | Attribute::DONT_DELETE,
); );
stage.add_property( stage.add_property(
@ -49,7 +49,7 @@ pub fn create_stage_object<'gc>(
fn_proto, fn_proto,
), ),
None, None,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
stage.add_property( stage.add_property(
@ -67,7 +67,7 @@ pub fn create_stage_object<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
Attribute::DontEnum | Attribute::DontDelete, Attribute::DONT_ENUM | Attribute::DONT_DELETE,
); );
stage.add_property( stage.add_property(
@ -85,7 +85,7 @@ pub fn create_stage_object<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
Attribute::DontEnum | Attribute::DontDelete, Attribute::DONT_ENUM | Attribute::DONT_DELETE,
); );
stage.add_property( stage.add_property(
@ -98,7 +98,7 @@ pub fn create_stage_object<'gc>(
fn_proto, fn_proto,
), ),
None, None,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
stage.into() stage.into()

View File

@ -4,10 +4,9 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::value_object::ValueObject; use crate::avm1::object::value_object::ValueObject;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use crate::string_utils; use crate::string_utils;
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
/// `String` constructor /// `String` constructor
@ -64,7 +63,7 @@ pub fn create_string_object<'gc>(
"fromCharCode", "fromCharCode",
from_char_code, from_char_code,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
@ -84,28 +83,28 @@ pub fn create_proto<'gc>(
"toString", "toString",
to_string_value_of, to_string_value_of,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"valueOf", "valueOf",
to_string_value_of, to_string_value_of,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"charAt", "charAt",
char_at, char_at,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
object.force_set_function( object.force_set_function(
"charCodeAt", "charCodeAt",
char_code_at, char_code_at,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -113,7 +112,7 @@ pub fn create_proto<'gc>(
"concat", "concat",
concat, concat,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -121,7 +120,7 @@ pub fn create_proto<'gc>(
"indexOf", "indexOf",
index_of, index_of,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -129,7 +128,7 @@ pub fn create_proto<'gc>(
"lastIndexOf", "lastIndexOf",
last_index_of, last_index_of,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -137,7 +136,7 @@ pub fn create_proto<'gc>(
"slice", "slice",
slice, slice,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -145,7 +144,7 @@ pub fn create_proto<'gc>(
"split", "split",
split, split,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -153,7 +152,7 @@ pub fn create_proto<'gc>(
"substr", "substr",
substr, substr,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -161,7 +160,7 @@ pub fn create_proto<'gc>(
"substring", "substring",
substring, substring,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -169,7 +168,7 @@ pub fn create_proto<'gc>(
"toLowerCase", "toLowerCase",
to_lower_case, to_lower_case,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );
@ -177,7 +176,7 @@ pub fn create_proto<'gc>(
"toUpperCase", "toUpperCase",
to_upper_case, to_upper_case,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto), Some(fn_proto),
); );

View File

@ -2,10 +2,11 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::Object; use crate::avm1::object::Object;
use crate::avm1::property::Attribute;
use crate::avm1::{Avm1, ScriptObject, TObject, Value}; use crate::avm1::{Avm1, ScriptObject, TObject, Value};
use crate::avm_warn; use crate::avm_warn;
use bitflags::bitflags;
use core::fmt; use core::fmt;
use enumset::{EnumSet, EnumSetType};
use gc_arena::MutationContext; use gc_arena::MutationContext;
use num_enum::TryFromPrimitive; use num_enum::TryFromPrimitive;
use std::convert::TryFrom; use std::convert::TryFrom;
@ -214,28 +215,29 @@ enum SettingsPanel {
Camera = 3, Camera = 3,
} }
#[derive(EnumSetType, Debug)] bitflags! {
pub enum SystemCapabilities { pub struct SystemCapabilities: u32 {
AvHardware, const AV_HARDWARE = 1 << 0;
Accessibility, const ACCESSIBILITY = 1 << 1;
Audio, const AUDIO = 1 << 2;
AudioEncoder, const AUDIO_ENCODER = 1 << 3;
EmbeddedVideo, const EMBEDDED_VIDEO = 1 << 4;
IME, const IME = 1 << 5;
MP3, const MP3 = 1 << 6;
Printing, const PRINTING = 1 << 7;
ScreenBroadcast, const SCREEN_BROADCAST = 1 << 8;
ScreenPlayback, const SCREEN_PLAYBACK = 1 << 9;
StreamingAudio, const STREAMING_AUDIO = 1 << 10;
StreamingVideo, const STREAMING_VIDEO = 1 << 11;
VideoEncoder, const VIDEO_ENCODER = 1 << 12;
Debugger, const DEBUGGER = 1 << 13;
LocalFileRead, const LOCAL_FILE_READ = 1 << 14;
Process64Bit, const PROCESS_64_BIT = 1 << 15;
Process32Bit, const PROCESS_32_BIT = 1 << 16;
AcrobatEmbedded, const ACROBAT_EMBEDDED = 1 << 17;
TLS, const TLS = 1 << 18;
WindowLess, const WINDOW_LESS = 1 << 19;
}
} }
/// The properties modified by 'System' /// The properties modified by 'System'
@ -247,7 +249,7 @@ pub struct SystemProperties {
/// If false then unicode should be used /// If false then unicode should be used
pub use_codepage: bool, pub use_codepage: bool,
/// The capabilities of the player /// The capabilities of the player
pub capabilities: EnumSet<SystemCapabilities>, pub capabilities: SystemCapabilities,
/// The type of the player /// The type of the player
pub player_type: PlayerType, pub player_type: PlayerType,
/// The type of screen available to the player /// The type of screen available to the player
@ -307,42 +309,42 @@ impl SystemProperties {
pub fn get_server_string(&self, avm: &mut Avm1) -> String { pub fn get_server_string(&self, avm: &mut Avm1) -> String {
url::form_urlencoded::Serializer::new(String::new()) url::form_urlencoded::Serializer::new(String::new())
.append_pair("A", self.encode_capability(SystemCapabilities::Audio)) .append_pair("A", self.encode_capability(SystemCapabilities::AUDIO))
.append_pair( .append_pair(
"SA", "SA",
self.encode_capability(SystemCapabilities::StreamingAudio), self.encode_capability(SystemCapabilities::STREAMING_AUDIO),
) )
.append_pair( .append_pair(
"SV", "SV",
self.encode_capability(SystemCapabilities::StreamingVideo), self.encode_capability(SystemCapabilities::STREAMING_VIDEO),
) )
.append_pair( .append_pair(
"EV", "EV",
self.encode_capability(SystemCapabilities::EmbeddedVideo), self.encode_capability(SystemCapabilities::EMBEDDED_VIDEO),
) )
.append_pair("MP3", self.encode_capability(SystemCapabilities::MP3)) .append_pair("MP3", self.encode_capability(SystemCapabilities::MP3))
.append_pair( .append_pair(
"AE", "AE",
self.encode_capability(SystemCapabilities::AudioEncoder), self.encode_capability(SystemCapabilities::AUDIO_ENCODER),
) )
.append_pair( .append_pair(
"VE", "VE",
self.encode_capability(SystemCapabilities::VideoEncoder), self.encode_capability(SystemCapabilities::VIDEO_ENCODER),
) )
.append_pair( .append_pair(
"ACC", "ACC",
self.encode_not_capability(SystemCapabilities::Accessibility), self.encode_not_capability(SystemCapabilities::ACCESSIBILITY),
) )
.append_pair("PR", self.encode_capability(SystemCapabilities::Printing)) .append_pair("PR", self.encode_capability(SystemCapabilities::PRINTING))
.append_pair( .append_pair(
"SP", "SP",
self.encode_capability(SystemCapabilities::ScreenPlayback), self.encode_capability(SystemCapabilities::SCREEN_PLAYBACK),
) )
.append_pair( .append_pair(
"SB", "SB",
self.encode_capability(SystemCapabilities::ScreenBroadcast), self.encode_capability(SystemCapabilities::SCREEN_BROADCAST),
) )
.append_pair("DEB", self.encode_capability(SystemCapabilities::Debugger)) .append_pair("DEB", self.encode_capability(SystemCapabilities::DEBUGGER))
.append_pair( .append_pair(
"M", "M",
&self.encode_string( &self.encode_string(
@ -363,11 +365,11 @@ impl SystemProperties {
.append_pair("PT", &self.player_type.to_string()) .append_pair("PT", &self.player_type.to_string())
.append_pair( .append_pair(
"AVD", "AVD",
self.encode_not_capability(SystemCapabilities::AvHardware), self.encode_not_capability(SystemCapabilities::AV_HARDWARE),
) )
.append_pair( .append_pair(
"LFD", "LFD",
self.encode_not_capability(SystemCapabilities::LocalFileRead), self.encode_not_capability(SystemCapabilities::LOCAL_FILE_READ),
) )
.append_pair("DP", &self.dpi.to_string()) .append_pair("DP", &self.dpi.to_string())
.finish() .finish()
@ -381,7 +383,7 @@ impl Default for SystemProperties {
exact_settings: true, exact_settings: true,
//TODO: default to false on fp>=7, true <= 6 //TODO: default to false on fp>=7, true <= 6
use_codepage: false, use_codepage: false,
capabilities: EnumSet::empty(), capabilities: SystemCapabilities::empty(),
player_type: PlayerType::StandAlone, player_type: PlayerType::StandAlone,
screen_color: ScreenColor::Color, screen_color: ScreenColor::Color,
// TODO: note for fp <7 this should be the locale and the ui lang for >= 7, on windows // TODO: note for fp <7 this should be the locale and the ui lang for >= 7, on windows
@ -519,7 +521,7 @@ pub fn create<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
system.add_property( system.add_property(
@ -537,25 +539,25 @@ pub fn create<'gc>(
Some(fn_proto), Some(fn_proto),
fn_proto, fn_proto,
)), )),
EnumSet::empty(), Attribute::empty(),
); );
system.define_value(gc_context, "security", security.into(), EnumSet::empty()); system.define_value(gc_context, "security", security.into(), Attribute::empty());
system.define_value( system.define_value(
gc_context, gc_context,
"capabilities", "capabilities",
capabilities.into(), capabilities.into(),
EnumSet::empty(), Attribute::empty(),
); );
system.define_value(gc_context, "IME", ime.into(), EnumSet::empty()); system.define_value(gc_context, "IME", ime.into(), Attribute::empty());
system.force_set_function( system.force_set_function(
"setClipboard", "setClipboard",
set_clipboard, set_clipboard,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -563,7 +565,7 @@ pub fn create<'gc>(
"showSettings", "showSettings",
show_settings, show_settings,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -572,7 +574,7 @@ pub fn create<'gc>(
"onStatus", "onStatus",
on_status, on_status,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );

View File

@ -3,8 +3,8 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::system::SystemCapabilities; use crate::avm1::globals::system::SystemCapabilities;
use crate::avm1::object::Object; use crate::avm1::object::Object;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
macro_rules! capabilities_func { macro_rules! capabilities_func {
@ -39,39 +39,42 @@ macro_rules! capabilities_prop {
$name, $name,
FunctionObject::function($gc_ctx, Executable::Native($func), Some($fn_proto), $fn_proto), FunctionObject::function($gc_ctx, Executable::Native($func), Some($fn_proto), $fn_proto),
None, None,
EnumSet::empty() Attribute::empty()
); );
)* )*
}}; }};
} }
capabilities_func!(get_has_64_bit_support, SystemCapabilities::Process64Bit); capabilities_func!(get_has_64_bit_support, SystemCapabilities::PROCESS_64_BIT);
capabilities_func!(get_has_32_bit_support, SystemCapabilities::Process32Bit); capabilities_func!(get_has_32_bit_support, SystemCapabilities::PROCESS_32_BIT);
capabilities_func!(get_is_acrobat_embedded, SystemCapabilities::AcrobatEmbedded); capabilities_func!(
get_is_acrobat_embedded,
SystemCapabilities::ACROBAT_EMBEDDED
);
capabilities_func!(get_has_tls, SystemCapabilities::TLS); capabilities_func!(get_has_tls, SystemCapabilities::TLS);
capabilities_func!(get_has_accessibility, SystemCapabilities::Accessibility); capabilities_func!(get_has_accessibility, SystemCapabilities::ACCESSIBILITY);
capabilities_func!(get_has_audio, SystemCapabilities::Audio); capabilities_func!(get_has_audio, SystemCapabilities::AUDIO);
capabilities_func!(get_has_audio_encoder, SystemCapabilities::AudioEncoder); capabilities_func!(get_has_audio_encoder, SystemCapabilities::AUDIO_ENCODER);
capabilities_func!(get_has_embedded_video, SystemCapabilities::EmbeddedVideo); capabilities_func!(get_has_embedded_video, SystemCapabilities::EMBEDDED_VIDEO);
capabilities_func!(get_has_ime, SystemCapabilities::IME); capabilities_func!(get_has_ime, SystemCapabilities::IME);
capabilities_func!(get_has_mp3, SystemCapabilities::MP3); capabilities_func!(get_has_mp3, SystemCapabilities::MP3);
capabilities_func!(get_has_printing, SystemCapabilities::Printing); capabilities_func!(get_has_printing, SystemCapabilities::PRINTING);
capabilities_func!( capabilities_func!(
get_has_screen_broadcast, get_has_screen_broadcast,
SystemCapabilities::ScreenBroadcast SystemCapabilities::SCREEN_BROADCAST
); );
capabilities_func!(get_has_screen_playback, SystemCapabilities::ScreenPlayback); capabilities_func!(get_has_screen_playback, SystemCapabilities::SCREEN_PLAYBACK);
capabilities_func!(get_has_streaming_audio, SystemCapabilities::StreamingAudio); capabilities_func!(get_has_streaming_audio, SystemCapabilities::STREAMING_AUDIO);
capabilities_func!(get_has_streaming_video, SystemCapabilities::StreamingVideo); capabilities_func!(get_has_streaming_video, SystemCapabilities::STREAMING_VIDEO);
capabilities_func!(get_has_video_encoder, SystemCapabilities::VideoEncoder); capabilities_func!(get_has_video_encoder, SystemCapabilities::VIDEO_ENCODER);
capabilities_func!(get_is_debugger, SystemCapabilities::Debugger); capabilities_func!(get_is_debugger, SystemCapabilities::DEBUGGER);
inverse_capabilities_func!( inverse_capabilities_func!(
get_is_local_file_read_disabled, get_is_local_file_read_disabled,
SystemCapabilities::LocalFileRead SystemCapabilities::LOCAL_FILE_READ
); );
inverse_capabilities_func!(get_is_av_hardware_disabled, SystemCapabilities::AvHardware); inverse_capabilities_func!(get_is_av_hardware_disabled, SystemCapabilities::AV_HARDWARE);
inverse_capabilities_func!(get_is_windowless_disabled, SystemCapabilities::WindowLess); inverse_capabilities_func!(get_is_windowless_disabled, SystemCapabilities::WINDOW_LESS);
pub fn get_player_type<'gc>( pub fn get_player_type<'gc>(
activation: &mut Activation<'_, 'gc, '_>, activation: &mut Activation<'_, 'gc, '_>,

View File

@ -3,7 +3,6 @@ use crate::avm1::error::Error;
use crate::avm1::globals::as_broadcaster::BroadcasterFunctions; use crate::avm1::globals::as_broadcaster::BroadcasterFunctions;
use crate::avm1::object::Object; use crate::avm1::object::Object;
use crate::avm1::property::Attribute; use crate::avm1::property::Attribute;
use crate::avm1::property::Attribute::{DontDelete, DontEnum, ReadOnly};
use crate::avm1::{ScriptObject, TObject, Value}; use crate::avm1::{ScriptObject, TObject, Value};
use gc_arena::MutationContext; use gc_arena::MutationContext;
use std::convert::Into; use std::convert::Into;
@ -79,56 +78,56 @@ pub fn create<'gc>(
gc_context, gc_context,
"ALPHANUMERIC_FULL", "ALPHANUMERIC_FULL",
"ALPHANUMERIC_FULL".into(), "ALPHANUMERIC_FULL".into(),
Attribute::DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
ime.define_value( ime.define_value(
gc_context, gc_context,
"ALPHANUMERIC_HALF", "ALPHANUMERIC_HALF",
"ALPHANUMERIC_HALF".into(), "ALPHANUMERIC_HALF".into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
ime.define_value( ime.define_value(
gc_context, gc_context,
"CHINESE", "CHINESE",
"CHINESE".into(), "CHINESE".into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
ime.define_value( ime.define_value(
gc_context, gc_context,
"JAPANESE_HIRAGANA", "JAPANESE_HIRAGANA",
"JAPANESE_HIRAGANA".into(), "JAPANESE_HIRAGANA".into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
ime.define_value( ime.define_value(
gc_context, gc_context,
"JAPANESE_KATAKANA_FULL", "JAPANESE_KATAKANA_FULL",
"JAPANESE_KATAKANA_FULL".into(), "JAPANESE_KATAKANA_FULL".into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
ime.define_value( ime.define_value(
gc_context, gc_context,
"KOREAN", "KOREAN",
"KOREAN".into(), "KOREAN".into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
ime.define_value( ime.define_value(
gc_context, gc_context,
"UNKNOWN", "UNKNOWN",
"UNKNOWN".into(), "UNKNOWN".into(),
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
); );
ime.force_set_function( ime.force_set_function(
"onIMEComposition", "onIMEComposition",
on_ime_composition, on_ime_composition,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
@ -136,7 +135,7 @@ pub fn create<'gc>(
"doConversion", "doConversion",
do_conversion, do_conversion,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
@ -144,7 +143,7 @@ pub fn create<'gc>(
"getConversionMode", "getConversionMode",
get_conversion_mode, get_conversion_mode,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
@ -152,7 +151,7 @@ pub fn create<'gc>(
"getEnabled", "getEnabled",
get_enabled, get_enabled,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
@ -160,7 +159,7 @@ pub fn create<'gc>(
"setCompositionString", "setCompositionString",
set_composition_string, set_composition_string,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
@ -168,7 +167,7 @@ pub fn create<'gc>(
"setConversionMode", "setConversionMode",
set_conversion_mode, set_conversion_mode,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );
@ -176,7 +175,7 @@ pub fn create<'gc>(
"setEnabled", "setEnabled",
set_enabled, set_enabled,
gc_context, gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto, fn_proto,
); );

View File

@ -2,9 +2,9 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::Object; use crate::avm1::object::Object;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, ScriptObject, TObject, Value};
use crate::avm_warn; use crate::avm_warn;
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
use std::convert::Into; use std::convert::Into;
@ -97,7 +97,7 @@ pub fn create<'gc>(
"PolicyFileResolver", "PolicyFileResolver",
policy_file_resolver, policy_file_resolver,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -105,7 +105,7 @@ pub fn create<'gc>(
"allowDomain", "allowDomain",
allow_domain, allow_domain,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -113,7 +113,7 @@ pub fn create<'gc>(
"allowInsecureDomain", "allowInsecureDomain",
allow_insecure_domain, allow_insecure_domain,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -121,7 +121,7 @@ pub fn create<'gc>(
"loadPolicyFile", "loadPolicyFile",
load_policy_file, load_policy_file,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -129,7 +129,7 @@ pub fn create<'gc>(
"escapeDomain", "escapeDomain",
escape_domain, escape_domain,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -143,7 +143,7 @@ pub fn create<'gc>(
fn_proto, fn_proto,
), ),
None, None,
EnumSet::empty(), Attribute::empty(),
); );
security.add_property( security.add_property(
@ -156,7 +156,7 @@ pub fn create<'gc>(
fn_proto, fn_proto,
), ),
None, None,
EnumSet::empty(), Attribute::empty(),
); );
security.into() security.into()

View File

@ -2,7 +2,7 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::display_object; use crate::avm1::globals::display_object;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use crate::avm_error; use crate::avm_error;
use crate::display_object::{AutoSizeMode, EditText, TDisplayObject, TextSelection}; use crate::display_object::{AutoSizeMode, EditText, TDisplayObject, TextSelection};
@ -23,7 +23,7 @@ macro_rules! with_text_field {
Ok(Value::Undefined) Ok(Value::Undefined)
} as crate::avm1::function::NativeFunction<'gc>, } as crate::avm1::function::NativeFunction<'gc>,
$gc_context, $gc_context,
DontDelete | ReadOnly | DontEnum, Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto $fn_proto
); );
)* )*
@ -38,7 +38,7 @@ macro_rules! with_text_field_props {
$name, $name,
with_text_field_props!(getter $gc, $fn_proto, $get), with_text_field_props!(getter $gc, $fn_proto, $get),
with_text_field_props!(setter $gc, $fn_proto, $($set),*), with_text_field_props!(setter $gc, $fn_proto, $($set),*),
Default::default() Attribute::empty()
); );
)* )*
}; };

View File

@ -5,9 +5,9 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::{color_transform, matrix}; use crate::avm1::globals::{color_transform, matrix};
use crate::avm1::object::transform_object::TransformObject; use crate::avm1::object::transform_object::TransformObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, TObject, Value}; use crate::avm1::{Object, TObject, Value};
use crate::display_object::{DisplayObject, MovieClip, TDisplayObject}; use crate::display_object::{DisplayObject, MovieClip, TDisplayObject};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
macro_rules! with_transform_props { macro_rules! with_transform_props {
@ -18,7 +18,7 @@ macro_rules! with_transform_props {
$name, $name,
with_transform_props!(getter $gc, $fn_proto, $get), with_transform_props!(getter $gc, $fn_proto, $get),
with_transform_props!(setter $gc, $fn_proto, $($set),*), with_transform_props!(setter $gc, $fn_proto, $($set),*),
EnumSet::empty(), Attribute::empty(),
); );
)* )*
}; };

View File

@ -5,13 +5,12 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject}; use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::script_object::ScriptObject; use crate::avm1::object::script_object::ScriptObject;
use crate::avm1::object::xml_object::XMLObject; use crate::avm1::object::xml_object::XMLObject;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value}; use crate::avm1::{AvmString, Object, TObject, Value};
use crate::avm_warn; use crate::avm_warn;
use crate::backend::navigator::RequestOptions; use crate::backend::navigator::RequestOptions;
use crate::xml; use crate::xml;
use crate::xml::{XMLDocument, XMLNode}; use crate::xml::{XMLDocument, XMLNode};
use enumset::EnumSet;
use gc_arena::MutationContext; use gc_arena::MutationContext;
use quick_xml::Error as ParseError; use quick_xml::Error as ParseError;
@ -550,7 +549,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -562,7 +561,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -574,7 +573,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -586,7 +585,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -598,7 +597,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -610,7 +609,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -622,7 +621,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -634,7 +633,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -646,7 +645,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -658,7 +657,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -670,7 +669,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -682,7 +681,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto.add_property( xmlnode_proto.add_property(
gc_context, gc_context,
@ -694,7 +693,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xmlnode_proto xmlnode_proto
.as_script_object() .as_script_object()
@ -703,7 +702,7 @@ pub fn create_xmlnode_proto<'gc>(
"appendChild", "appendChild",
xmlnode_append_child, xmlnode_append_child,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xmlnode_proto xmlnode_proto
@ -713,7 +712,7 @@ pub fn create_xmlnode_proto<'gc>(
"insertBefore", "insertBefore",
xmlnode_insert_before, xmlnode_insert_before,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xmlnode_proto xmlnode_proto
@ -723,7 +722,7 @@ pub fn create_xmlnode_proto<'gc>(
"cloneNode", "cloneNode",
xmlnode_clone_node, xmlnode_clone_node,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xmlnode_proto xmlnode_proto
@ -733,7 +732,7 @@ pub fn create_xmlnode_proto<'gc>(
"getNamespaceForPrefix", "getNamespaceForPrefix",
xmlnode_get_namespace_for_prefix, xmlnode_get_namespace_for_prefix,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xmlnode_proto xmlnode_proto
@ -743,7 +742,7 @@ pub fn create_xmlnode_proto<'gc>(
"getPrefixForNamespace", "getPrefixForNamespace",
xmlnode_get_prefix_for_namespace, xmlnode_get_prefix_for_namespace,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xmlnode_proto xmlnode_proto
@ -753,7 +752,7 @@ pub fn create_xmlnode_proto<'gc>(
"hasChildNodes", "hasChildNodes",
xmlnode_has_child_nodes, xmlnode_has_child_nodes,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xmlnode_proto xmlnode_proto
@ -763,7 +762,7 @@ pub fn create_xmlnode_proto<'gc>(
"removeNode", "removeNode",
xmlnode_remove_node, xmlnode_remove_node,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xmlnode_proto xmlnode_proto
@ -773,7 +772,7 @@ pub fn create_xmlnode_proto<'gc>(
"toString", "toString",
xmlnode_to_string, xmlnode_to_string,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
@ -1091,9 +1090,9 @@ pub fn create_xml_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xml_proto.define_value(gc_context, "ignoreWhite", false.into(), EnumSet::empty()); xml_proto.define_value(gc_context, "ignoreWhite", false.into(), Attribute::empty());
xml_proto.add_property( xml_proto.add_property(
gc_context, gc_context,
"xmlDecl", "xmlDecl",
@ -1104,7 +1103,7 @@ pub fn create_xml_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xml_proto.add_property( xml_proto.add_property(
gc_context, gc_context,
@ -1116,7 +1115,7 @@ pub fn create_xml_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xml_proto.add_property( xml_proto.add_property(
gc_context, gc_context,
@ -1128,41 +1127,41 @@ pub fn create_xml_proto<'gc>(
fn_proto, fn_proto,
), ),
None, None,
ReadOnly.into(), Attribute::READ_ONLY,
); );
xml_proto.as_script_object().unwrap().force_set_function( xml_proto.as_script_object().unwrap().force_set_function(
"createElement", "createElement",
xml_create_element, xml_create_element,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xml_proto.as_script_object().unwrap().force_set_function( xml_proto.as_script_object().unwrap().force_set_function(
"createTextNode", "createTextNode",
xml_create_text_node, xml_create_text_node,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xml_proto.as_script_object().unwrap().force_set_function( xml_proto.as_script_object().unwrap().force_set_function(
"parseXML", "parseXML",
xml_parse_xml, xml_parse_xml,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xml_proto.as_script_object().unwrap().force_set_function( xml_proto.as_script_object().unwrap().force_set_function(
"load", "load",
xml_load, xml_load,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );
xml_proto.as_script_object().unwrap().force_set_function( xml_proto.as_script_object().unwrap().force_set_function(
"onData", "onData",
xml_on_data, xml_on_data,
gc_context, gc_context,
EnumSet::empty(), Attribute::empty(),
Some(fn_proto), Some(fn_proto),
); );

View File

@ -28,7 +28,6 @@ use crate::avm1::{ScriptObject, SoundObject, StageObject, Value};
use crate::avm_warn; use crate::avm_warn;
use crate::display_object::DisplayObject; use crate::display_object::DisplayObject;
use crate::xml::XMLNode; use crate::xml::XMLNode;
use enumset::EnumSet;
use gc_arena::{Collect, MutationContext}; use gc_arena::{Collect, MutationContext};
use ruffle_macros::enum_trait_object; use ruffle_macros::enum_trait_object;
use std::borrow::Cow; use std::borrow::Cow;
@ -249,7 +248,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: &str, name: &str,
value: Value<'gc>, value: Value<'gc>,
attributes: EnumSet<Attribute>, attributes: Attribute,
); );
/// Set the attributes of a given property. /// Set the attributes of a given property.
@ -263,8 +262,8 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
&self, &self,
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: Option<&str>, name: Option<&str>,
set_attributes: EnumSet<Attribute>, set_attributes: Attribute,
clear_attributes: EnumSet<Attribute>, clear_attributes: Attribute,
); );
/// Define a virtual property onto a given object. /// Define a virtual property onto a given object.
@ -283,7 +282,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
); );
/// Define a virtual property onto a given object. /// Define a virtual property onto a given object.
@ -303,7 +302,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
); );
/// Set the 'watcher' of a given property. /// Set the 'watcher' of a given property.

View File

@ -58,7 +58,7 @@ macro_rules! impl_custom_object_without_set {
gc_context: gc_arena::MutationContext<'gc, '_>, gc_context: gc_arena::MutationContext<'gc, '_>,
name: &str, name: &str,
value: crate::avm1::Value<'gc>, value: crate::avm1::Value<'gc>,
attributes: enumset::EnumSet<crate::avm1::property::Attribute>, attributes: crate::avm1::property::Attribute,
) { ) {
self.0 self.0
.read() .read()
@ -70,8 +70,8 @@ macro_rules! impl_custom_object_without_set {
&self, &self,
gc_context: gc_arena::MutationContext<'gc, '_>, gc_context: gc_arena::MutationContext<'gc, '_>,
name: Option<&str>, name: Option<&str>,
set_attributes: enumset::EnumSet<crate::avm1::property::Attribute>, set_attributes: crate::avm1::property::Attribute,
clear_attributes: enumset::EnumSet<crate::avm1::property::Attribute>, clear_attributes: crate::avm1::property::Attribute,
) { ) {
self.0.write(gc_context).$field.set_attributes( self.0.write(gc_context).$field.set_attributes(
gc_context, gc_context,
@ -87,7 +87,7 @@ macro_rules! impl_custom_object_without_set {
name: &str, name: &str,
get: crate::avm1::object::Object<'gc>, get: crate::avm1::object::Object<'gc>,
set: Option<crate::avm1::object::Object<'gc>>, set: Option<crate::avm1::object::Object<'gc>>,
attributes: enumset::EnumSet<crate::avm1::property::Attribute>, attributes: crate::avm1::property::Attribute,
) { ) {
self.0 self.0
.read() .read()
@ -102,7 +102,7 @@ macro_rules! impl_custom_object_without_set {
name: &str, name: &str,
get: crate::avm1::object::Object<'gc>, get: crate::avm1::object::Object<'gc>,
set: Option<crate::avm1::object::Object<'gc>>, set: Option<crate::avm1::object::Object<'gc>>,
attributes: enumset::EnumSet<crate::avm1::property::Attribute>, attributes: crate::avm1::property::Attribute,
) { ) {
self.0 self.0
.read() .read()
@ -268,7 +268,6 @@ macro_rules! add_field_accessors {
); );
}; };
($([$var: ident, $type_: ty $(, set => $set_ident: ident)? $(, get => $get_ident: ident)?],)*) => { ($([$var: ident, $type_: ty $(, set => $set_ident: ident)? $(, get => $get_ident: ident)?],)*) => {
$( $(
$( add_field_accessors!([setter_only $set_ident, $var, $type_],); )* $( add_field_accessors!([setter_only $set_ident, $var, $type_],); )*

View File

@ -5,7 +5,6 @@ use crate::avm1::property::{Attribute, Property};
use crate::avm1::{AvmString, Object, ObjectPtr, TObject, Value}; use crate::avm1::{AvmString, Object, ObjectPtr, TObject, Value};
use crate::property_map::{Entry, PropertyMap}; use crate::property_map::{Entry, PropertyMap};
use core::fmt; use core::fmt;
use enumset::EnumSet;
use gc_arena::{Collect, GcCell, MutationContext}; use gc_arena::{Collect, GcCell, MutationContext};
use std::borrow::Cow; use std::borrow::Cow;
@ -185,16 +184,14 @@ impl<'gc> ScriptObject<'gc> {
/// is only possible when defining host functions. User-defined functions /// is only possible when defining host functions. User-defined functions
/// always get a fresh explicit prototype, so you should never force set a /// always get a fresh explicit prototype, so you should never force set a
/// user-defined function. /// user-defined function.
pub fn force_set_function<A>( pub fn force_set_function(
&mut self, &mut self,
name: &str, name: &str,
function: NativeFunction<'gc>, function: NativeFunction<'gc>,
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
attributes: A, attributes: Attribute,
fn_proto: Option<Object<'gc>>, fn_proto: Option<Object<'gc>>,
) where ) {
A: Into<EnumSet<Attribute>>,
{
self.define_value( self.define_value(
gc_context, gc_context,
name, name,
@ -205,7 +202,7 @@ impl<'gc> ScriptObject<'gc> {
fn_proto, fn_proto,
) )
.into(), .into(),
attributes.into(), attributes,
) )
} }
@ -239,9 +236,9 @@ impl<'gc> ScriptObject<'gc> {
entry.insert(Property::Stored { entry.insert(Property::Stored {
value: native_value, value: native_value,
attributes: if is_enumerable { attributes: if is_enumerable {
EnumSet::empty() Attribute::empty()
} else { } else {
Attribute::DontEnum.into() Attribute::DONT_ENUM
}, },
}); });
} }
@ -354,7 +351,7 @@ impl<'gc> ScriptObject<'gc> {
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
entry.insert(Property::Stored { entry.insert(Property::Stored {
value: value.clone(), value: value.clone(),
attributes: Default::default(), attributes: Attribute::empty(),
}); });
None None
@ -529,7 +526,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.0.write(gc_context).values.insert( self.0.write(gc_context).values.insert(
name, name,
@ -549,7 +546,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.0.write(gc_context).values.insert( self.0.write(gc_context).values.insert(
name, name,
@ -596,7 +593,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: &str, name: &str,
value: Value<'gc>, value: Value<'gc>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.0 self.0
.write(gc_context) .write(gc_context)
@ -608,8 +605,8 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
&self, &self,
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: Option<&str>, name: Option<&str>,
set_attributes: EnumSet<Attribute>, set_attributes: Attribute,
clear_attributes: EnumSet<Attribute>, clear_attributes: Attribute,
) { ) {
match name { match name {
None => { None => {
@ -841,7 +838,7 @@ mod tests {
use crate::avm1::activation::ActivationIdentifier; use crate::avm1::activation::ActivationIdentifier;
use crate::avm1::function::Executable; use crate::avm1::function::Executable;
use crate::avm1::globals::system::SystemProperties; use crate::avm1::globals::system::SystemProperties;
use crate::avm1::property::Attribute::*; use crate::avm1::property::Attribute;
use crate::avm1::{Avm1, Timers}; use crate::avm1::{Avm1, Timers};
use crate::avm2::Avm2; use crate::avm2::Avm2;
use crate::backend::audio::NullAudioBackend; use crate::backend::audio::NullAudioBackend;
@ -955,7 +952,7 @@ mod tests {
activation.context.gc_context, activation.context.gc_context,
"forced", "forced",
"forced".into(), "forced".into(),
EnumSet::empty(), Attribute::empty(),
); );
object.set("natural", "natural".into(), activation).unwrap(); object.set("natural", "natural".into(), activation).unwrap();
@ -971,13 +968,13 @@ mod tests {
activation.context.gc_context, activation.context.gc_context,
"normal", "normal",
"initial".into(), "initial".into(),
EnumSet::empty(), Attribute::empty(),
); );
object.as_script_object().unwrap().define_value( object.as_script_object().unwrap().define_value(
activation.context.gc_context, activation.context.gc_context,
"readonly", "readonly",
"initial".into(), "initial".into(),
ReadOnly.into(), Attribute::READ_ONLY,
); );
object.set("normal", "replaced".into(), activation).unwrap(); object.set("normal", "replaced".into(), activation).unwrap();
@ -1000,7 +997,7 @@ mod tests {
activation.context.gc_context, activation.context.gc_context,
"test", "test",
"initial".into(), "initial".into(),
DontDelete.into(), Attribute::DONT_DELETE,
); );
assert_eq!(object.delete(activation, "test"), false); assert_eq!(object.delete(activation, "test"), false);
@ -1032,7 +1029,7 @@ mod tests {
"test", "test",
getter, getter,
None, None,
EnumSet::empty(), Attribute::empty(),
); );
assert_eq!(object.get("test", activation).unwrap(), "Virtual!".into()); assert_eq!(object.get("test", activation).unwrap(), "Virtual!".into());
@ -1058,26 +1055,26 @@ mod tests {
"virtual", "virtual",
getter, getter,
None, None,
EnumSet::empty(), Attribute::empty(),
); );
object.as_script_object().unwrap().add_property( object.as_script_object().unwrap().add_property(
activation.context.gc_context, activation.context.gc_context,
"virtual_un", "virtual_un",
getter, getter,
None, None,
DontDelete.into(), Attribute::DONT_DELETE,
); );
object.as_script_object().unwrap().define_value( object.as_script_object().unwrap().define_value(
activation.context.gc_context, activation.context.gc_context,
"stored", "stored",
"Stored!".into(), "Stored!".into(),
EnumSet::empty(), Attribute::empty(),
); );
object.as_script_object().unwrap().define_value( object.as_script_object().unwrap().define_value(
activation.context.gc_context, activation.context.gc_context,
"stored_un", "stored_un",
"Stored!".into(), "Stored!".into(),
DontDelete.into(), Attribute::DONT_DELETE,
); );
assert_eq!(object.delete(activation, "virtual"), true); assert_eq!(object.delete(activation, "virtual"), true);
@ -1113,27 +1110,27 @@ mod tests {
activation.context.gc_context, activation.context.gc_context,
"stored", "stored",
Value::Null, Value::Null,
EnumSet::empty(), Attribute::empty(),
); );
object.as_script_object().unwrap().define_value( object.as_script_object().unwrap().define_value(
activation.context.gc_context, activation.context.gc_context,
"stored_hidden", "stored_hidden",
Value::Null, Value::Null,
DontEnum.into(), Attribute::DONT_ENUM,
); );
object.as_script_object().unwrap().add_property( object.as_script_object().unwrap().add_property(
activation.context.gc_context, activation.context.gc_context,
"virtual", "virtual",
getter, getter,
None, None,
EnumSet::empty(), Attribute::empty(),
); );
object.as_script_object().unwrap().add_property( object.as_script_object().unwrap().add_property(
activation.context.gc_context, activation.context.gc_context,
"virtual_hidden", "virtual_hidden",
getter, getter,
None, None,
DontEnum.into(), Attribute::DONT_ENUM,
); );
let keys: Vec<_> = object.get_keys(activation); let keys: Vec<_> = object.get_keys(activation);

View File

@ -11,7 +11,6 @@ use crate::context::UpdateContext;
use crate::display_object::{DisplayObject, EditText, MovieClip, TDisplayObjectContainer}; use crate::display_object::{DisplayObject, EditText, MovieClip, TDisplayObjectContainer};
use crate::property_map::PropertyMap; use crate::property_map::PropertyMap;
use crate::types::Percent; use crate::types::Percent;
use enumset::EnumSet;
use gc_arena::{Collect, GcCell, MutationContext}; use gc_arena::{Collect, GcCell, MutationContext};
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt; use std::fmt;
@ -268,7 +267,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: &str, name: &str,
value: Value<'gc>, value: Value<'gc>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.0 self.0
.read() .read()
@ -280,8 +279,8 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
&self, &self,
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: Option<&str>, name: Option<&str>,
set_attributes: EnumSet<Attribute>, set_attributes: Attribute,
clear_attributes: EnumSet<Attribute>, clear_attributes: Attribute,
) { ) {
self.0.write(gc_context).base.set_attributes( self.0.write(gc_context).base.set_attributes(
gc_context, gc_context,
@ -297,7 +296,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.0 self.0
.read() .read()
@ -312,7 +311,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.0 self.0
.read() .read()

View File

@ -9,7 +9,6 @@ use crate::avm1::property::Attribute;
use crate::avm1::{Object, ObjectPtr, ScriptObject, TObject, Value}; use crate::avm1::{Object, ObjectPtr, ScriptObject, TObject, Value};
use crate::avm_warn; use crate::avm_warn;
use crate::display_object::DisplayObject; use crate::display_object::DisplayObject;
use enumset::EnumSet;
use gc_arena::{Collect, GcCell, MutationContext}; use gc_arena::{Collect, GcCell, MutationContext};
use std::borrow::Cow; use std::borrow::Cow;
@ -181,7 +180,7 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
_gc_context: MutationContext<'gc, '_>, _gc_context: MutationContext<'gc, '_>,
_name: &str, _name: &str,
_value: Value<'gc>, _value: Value<'gc>,
_attributes: EnumSet<Attribute>, _attributes: Attribute,
) { ) {
//`super` cannot have values defined on it //`super` cannot have values defined on it
} }
@ -190,8 +189,8 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
&self, &self,
_gc_context: MutationContext<'gc, '_>, _gc_context: MutationContext<'gc, '_>,
_name: Option<&str>, _name: Option<&str>,
_set_attributes: EnumSet<Attribute>, _set_attributes: Attribute,
_clear_attributes: EnumSet<Attribute>, _clear_attributes: Attribute,
) { ) {
//TODO: Does ASSetPropFlags work on `super`? What would it even work on? //TODO: Does ASSetPropFlags work on `super`? What would it even work on?
} }
@ -202,7 +201,7 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
_name: &str, _name: &str,
_get: Object<'gc>, _get: Object<'gc>,
_set: Option<Object<'gc>>, _set: Option<Object<'gc>>,
_attributes: EnumSet<Attribute>, _attributes: Attribute,
) { ) {
//`super` cannot have properties defined on it //`super` cannot have properties defined on it
} }
@ -214,7 +213,7 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
_name: &str, _name: &str,
_get: Object<'gc>, _get: Object<'gc>,
_set: Option<Object<'gc>>, _set: Option<Object<'gc>>,
_attributes: EnumSet<Attribute>, _attributes: Attribute,
) { ) {
//`super` cannot have properties defined on it //`super` cannot have properties defined on it
} }

View File

@ -6,7 +6,6 @@ use crate::avm1::object::{ObjectPtr, TObject};
use crate::avm1::property::Attribute; use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, Value}; use crate::avm1::{AvmString, Object, ScriptObject, Value};
use crate::xml::{XMLName, XMLNode}; use crate::xml::{XMLName, XMLNode};
use enumset::EnumSet;
use gc_arena::{Collect, MutationContext}; use gc_arena::{Collect, MutationContext};
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt; use std::fmt;
@ -126,7 +125,7 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.base() self.base()
.add_property(gc_context, name, get, set, attributes) .add_property(gc_context, name, get, set, attributes)
@ -139,7 +138,7 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.base() self.base()
.add_property_with_case(activation, gc_context, name, get, set, attributes) .add_property_with_case(activation, gc_context, name, get, set, attributes)
@ -171,7 +170,7 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: &str, name: &str,
value: Value<'gc>, value: Value<'gc>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.base() self.base()
.define_value(gc_context, name, value, attributes) .define_value(gc_context, name, value, attributes)
@ -181,8 +180,8 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
&self, &self,
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: Option<&str>, name: Option<&str>,
set_attributes: EnumSet<Attribute>, set_attributes: Attribute,
clear_attributes: EnumSet<Attribute>, clear_attributes: Attribute,
) { ) {
self.base() self.base()
.set_attributes(gc_context, name, set_attributes, clear_attributes) .set_attributes(gc_context, name, set_attributes, clear_attributes)

View File

@ -7,7 +7,6 @@ use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, Value}; use crate::avm1::{Object, ScriptObject, Value};
use crate::avm_warn; use crate::avm_warn;
use crate::xml::{XMLDocument, XMLNode}; use crate::xml::{XMLDocument, XMLNode};
use enumset::EnumSet;
use gc_arena::{Collect, MutationContext}; use gc_arena::{Collect, MutationContext};
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt; use std::fmt;
@ -124,7 +123,7 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.base() self.base()
.add_property(gc_context, name, get, set, attributes) .add_property(gc_context, name, get, set, attributes)
@ -137,7 +136,7 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
name: &str, name: &str,
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.base() self.base()
.add_property_with_case(activation, gc_context, name, get, set, attributes) .add_property_with_case(activation, gc_context, name, get, set, attributes)
@ -169,7 +168,7 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: &str, name: &str,
value: Value<'gc>, value: Value<'gc>,
attributes: EnumSet<Attribute>, attributes: Attribute,
) { ) {
self.base() self.base()
.define_value(gc_context, name, value, attributes) .define_value(gc_context, name, value, attributes)
@ -179,8 +178,8 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
&self, &self,
gc_context: MutationContext<'gc, '_>, gc_context: MutationContext<'gc, '_>,
name: Option<&str>, name: Option<&str>,
set_attributes: EnumSet<Attribute>, set_attributes: Attribute,
clear_attributes: EnumSet<Attribute>, clear_attributes: Attribute,
) { ) {
self.base() self.base()
.set_attributes(gc_context, name, set_attributes, clear_attributes) .set_attributes(gc_context, name, set_attributes, clear_attributes)

View File

@ -1,18 +1,18 @@
//! User-defined properties //! User-defined properties
use self::Attribute::*;
use crate::avm1::object::Object; use crate::avm1::object::Object;
use crate::avm1::Value; use crate::avm1::Value;
use bitflags::bitflags;
use core::fmt; use core::fmt;
use enumset::{EnumSet, EnumSetType};
/// Attributes of properties in the AVM runtime. bitflags! {
/// The order is significant and should match the order used by `object::as_set_prop_flags`. /// Attributes of properties in the AVM runtime.
#[derive(EnumSetType, Debug)] /// The values are significant and should match the order used by `object::as_set_prop_flags`.
pub enum Attribute { pub struct Attribute: u8 {
DontEnum, const DONT_ENUM = 1 << 0;
DontDelete, const DONT_DELETE = 1 << 1;
ReadOnly, const READ_ONLY = 1 << 2;
}
} }
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
@ -21,11 +21,11 @@ pub enum Property<'gc> {
Virtual { Virtual {
get: Object<'gc>, get: Object<'gc>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
}, },
Stored { Stored {
value: Value<'gc>, value: Value<'gc>,
attributes: EnumSet<Attribute>, attributes: Attribute,
}, },
} }
@ -47,7 +47,7 @@ impl<'gc> Property<'gc> {
Property::Stored { Property::Stored {
value, attributes, .. value, attributes, ..
} => { } => {
if !attributes.contains(ReadOnly) { if !attributes.contains(Attribute::READ_ONLY) {
*value = new_value.into(); *value = new_value.into();
} }
@ -57,7 +57,7 @@ impl<'gc> Property<'gc> {
} }
/// List this property's attributes. /// List this property's attributes.
pub fn attributes(&self) -> EnumSet<Attribute> { pub fn attributes(&self) -> Attribute {
match self { match self {
Property::Virtual { attributes, .. } => *attributes, Property::Virtual { attributes, .. } => *attributes,
Property::Stored { attributes, .. } => *attributes, Property::Stored { attributes, .. } => *attributes,
@ -65,7 +65,7 @@ impl<'gc> Property<'gc> {
} }
/// Re-define this property's attributes. /// Re-define this property's attributes.
pub fn set_attributes(&mut self, new_attributes: EnumSet<Attribute>) { pub fn set_attributes(&mut self, new_attributes: Attribute) {
match self { match self {
Property::Virtual { Property::Virtual {
ref mut attributes, .. ref mut attributes, ..
@ -78,15 +78,15 @@ impl<'gc> Property<'gc> {
pub fn can_delete(&self) -> bool { pub fn can_delete(&self) -> bool {
match self { match self {
Property::Virtual { attributes, .. } => !attributes.contains(DontDelete), Property::Virtual { attributes, .. } => !attributes.contains(Attribute::DONT_DELETE),
Property::Stored { attributes, .. } => !attributes.contains(DontDelete), Property::Stored { attributes, .. } => !attributes.contains(Attribute::DONT_DELETE),
} }
} }
pub fn is_enumerable(&self) -> bool { pub fn is_enumerable(&self) -> bool {
match self { match self {
Property::Virtual { attributes, .. } => !attributes.contains(DontEnum), Property::Virtual { attributes, .. } => !attributes.contains(Attribute::DONT_ENUM),
Property::Stored { attributes, .. } => !attributes.contains(DontEnum), Property::Stored { attributes, .. } => !attributes.contains(Attribute::DONT_ENUM),
} }
} }
@ -95,8 +95,8 @@ impl<'gc> Property<'gc> {
match self { match self {
Property::Virtual { Property::Virtual {
attributes, set, .. attributes, set, ..
} => !attributes.contains(ReadOnly) && !set.is_none(), } => !attributes.contains(Attribute::READ_ONLY) && !set.is_none(),
Property::Stored { attributes, .. } => !attributes.contains(ReadOnly), Property::Stored { attributes, .. } => !attributes.contains(Attribute::READ_ONLY),
} }
} }

View File

@ -3,8 +3,8 @@
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
use crate::avm1::callable_value::CallableValue; use crate::avm1::callable_value::CallableValue;
use crate::avm1::error::Error; use crate::avm1::error::Error;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value}; use crate::avm1::{Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::{GcCell, MutationContext}; use gc_arena::{GcCell, MutationContext};
use std::cell::Ref; use std::cell::Ref;
@ -307,7 +307,7 @@ impl<'gc> Scope<'gc> {
/// local object and does not traverse the scope chain. /// local object and does not traverse the scope chain.
pub fn define(&self, name: &str, value: impl Into<Value<'gc>>, mc: MutationContext<'gc, '_>) { pub fn define(&self, name: &str, value: impl Into<Value<'gc>>, mc: MutationContext<'gc, '_>) {
self.locals() self.locals()
.define_value(mc, name, value.into(), EnumSet::empty()); .define_value(mc, name, value.into(), Attribute::empty());
} }
/// Delete a value from scope /// Delete a value from scope

View File

@ -503,9 +503,10 @@ mod test {
use crate::avm1::globals::create_globals; use crate::avm1::globals::create_globals;
use crate::avm1::object::script_object::ScriptObject; use crate::avm1::object::script_object::ScriptObject;
use crate::avm1::object::{Object, TObject}; use crate::avm1::object::{Object, TObject};
use crate::avm1::property::Attribute;
use crate::avm1::test_utils::with_avm; use crate::avm1::test_utils::with_avm;
use crate::avm1::{AvmString, Value}; use crate::avm1::{AvmString, Value};
use enumset::EnumSet;
use std::f64::{INFINITY, NAN, NEG_INFINITY}; use std::f64::{INFINITY, NAN, NEG_INFINITY};
#[test] #[test]
@ -549,7 +550,7 @@ mod test {
activation.context.gc_context, activation.context.gc_context,
"valueOf", "valueOf",
valueof.into(), valueof.into(),
EnumSet::empty(), Attribute::empty(),
); );
assert_eq!( assert_eq!(

View File

@ -7,23 +7,24 @@ use crate::avm2::string::AvmString;
use crate::avm2::traits::{Trait, TraitKind}; use crate::avm2::traits::{Trait, TraitKind};
use crate::avm2::{Avm2, Error}; use crate::avm2::{Avm2, Error};
use crate::collect::CollectWrapper; use crate::collect::CollectWrapper;
use enumset::{EnumSet, EnumSetType}; use bitflags::bitflags;
use gc_arena::{Collect, GcCell, MutationContext}; use gc_arena::{Collect, GcCell, MutationContext};
use swf::avm2::types::{Class as AbcClass, Instance as AbcInstance}; use swf::avm2::types::{Class as AbcClass, Instance as AbcInstance};
/// All possible attributes for a given class. bitflags! {
#[derive(EnumSetType, Debug)] /// All possible attributes for a given class.
pub enum ClassAttributes { pub struct ClassAttributes: u8 {
/// Class is sealed, attempts to set or init dynamic properties on an /// Class is sealed, attempts to set or init dynamic properties on an
/// object will generate a runtime error. /// object will generate a runtime error.
Sealed, const SEALED = 1 << 0;
/// Class is final, attempts to construct child classes from it will /// Class is final, attempts to construct child classes from it will
/// generate a verification error. /// generate a verification error.
Final, const FINAL = 1 << 1;
/// Class is an interface. /// Class is an interface.
Interface, const INTERFACE = 1 << 2;
}
} }
/// A loaded ABC Class which can be used to construct objects with. /// A loaded ABC Class which can be used to construct objects with.
@ -37,7 +38,7 @@ pub struct Class<'gc> {
super_class: Option<Multiname<'gc>>, super_class: Option<Multiname<'gc>>,
/// Attributes of the given class. /// Attributes of the given class.
attributes: CollectWrapper<EnumSet<ClassAttributes>>, attributes: CollectWrapper<ClassAttributes>,
/// The namespace that protected traits of this class are stored into. /// The namespace that protected traits of this class are stored into.
protected_namespace: Option<Namespace<'gc>>, protected_namespace: Option<Namespace<'gc>>,
@ -128,7 +129,7 @@ impl<'gc> Class<'gc> {
Self { Self {
name, name,
super_class, super_class,
attributes: CollectWrapper(EnumSet::empty()), attributes: CollectWrapper(ClassAttributes::empty()),
protected_namespace: None, protected_namespace: None,
interfaces: Vec::new(), interfaces: Vec::new(),
instance_init, instance_init,
@ -141,7 +142,7 @@ impl<'gc> Class<'gc> {
} }
/// Set the attributes of the class (sealed/final/interface status). /// Set the attributes of the class (sealed/final/interface status).
pub fn set_attributes(&mut self, attributes: EnumSet<ClassAttributes>) { pub fn set_attributes(&mut self, attributes: ClassAttributes) {
self.attributes = CollectWrapper(attributes); self.attributes = CollectWrapper(attributes);
} }
@ -202,18 +203,10 @@ impl<'gc> Class<'gc> {
let instance_init = unit.load_method(abc_instance.init_method.0, mc)?; let instance_init = unit.load_method(abc_instance.init_method.0, mc)?;
let class_init = unit.load_method(abc_class.init_method.0, mc)?; let class_init = unit.load_method(abc_class.init_method.0, mc)?;
let mut attributes = EnumSet::new(); let mut attributes = ClassAttributes::empty();
if abc_instance.is_sealed { attributes.set(ClassAttributes::SEALED, abc_instance.is_sealed);
attributes |= ClassAttributes::Sealed; attributes.set(ClassAttributes::FINAL, abc_instance.is_final);
} attributes.set(ClassAttributes::INTERFACE, abc_instance.is_interface);
if abc_instance.is_final {
attributes |= ClassAttributes::Final;
}
if abc_instance.is_interface {
attributes |= ClassAttributes::Interface;
}
Ok(GcCell::allocate( Ok(GcCell::allocate(
mc, mc,
@ -410,6 +403,6 @@ impl<'gc> Class<'gc> {
/// Determine if this class is sealed (no dynamic properties) /// Determine if this class is sealed (no dynamic properties)
pub fn is_sealed(&self) -> bool { pub fn is_sealed(&self) -> bool {
self.attributes.0.contains(ClassAttributes::Sealed) self.attributes.0.contains(ClassAttributes::SEALED)
} }
} }

View File

@ -10,7 +10,7 @@ use crate::avm2::string::AvmString;
use crate::avm2::traits::Trait; use crate::avm2::traits::Trait;
use crate::avm2::value::Value; use crate::avm2::value::Value;
use crate::avm2::Error; use crate::avm2::Error;
use enumset::{EnumSet, EnumSetType}; use bitflags::bitflags;
use gc_arena::{GcCell, MutationContext}; use gc_arena::{GcCell, MutationContext};
use std::cmp::{min, Ordering}; use std::cmp::{min, Ordering};
use std::mem::swap; use std::mem::swap;
@ -775,25 +775,26 @@ pub fn splice<'gc>(
Ok(Value::Undefined) Ok(Value::Undefined)
} }
/// The array options that a given sort operation may use. bitflags! {
/// /// The array options that a given sort operation may use.
/// These are provided as a number by the VM and converted into an enumset. ///
#[derive(EnumSetType)] /// These are provided as a number by the VM and converted into bitflags.
enum SortOptions { struct SortOptions: u8 {
/// Request case-insensitive string value sort. /// Request case-insensitive string value sort.
CaseInsensitive, const CASE_INSENSITIVE = 1 << 0;
/// Reverse the order of sorting. /// Reverse the order of sorting.
Descending, const DESCENDING = 1 << 1;
/// Reject sorting on arrays with multiple equivalent values. /// Reject sorting on arrays with multiple equivalent values.
UniqueSort, const UNIQUE_SORT = 1 << 2;
/// Yield a list of indices rather than sorting the array in-place. /// Yield a list of indices rather than sorting the array in-place.
ReturnIndexedArray, const RETURN_INDEXED_ARRAY = 1 << 3;
/// Request numeric value sort. /// Request numeric value sort.
Numeric, const NUMERIC = 1 << 4;
}
} }
/// Identity closure shim which exists purely to decorate closure types with /// Identity closure shim which exists purely to decorate closure types with
@ -821,7 +822,7 @@ where
fn sort_inner<'a, 'gc, 'ctxt, C>( fn sort_inner<'a, 'gc, 'ctxt, C>(
activation: &mut Activation<'a, 'gc, 'ctxt>, activation: &mut Activation<'a, 'gc, 'ctxt>,
values: &mut [(usize, Value<'gc>)], values: &mut [(usize, Value<'gc>)],
options: EnumSet<SortOptions>, options: SortOptions,
mut sort_func: C, mut sort_func: C,
) -> Result<bool, Error> ) -> Result<bool, Error>
where where
@ -848,7 +849,7 @@ where
unique_sort_satisfied = false; unique_sort_satisfied = false;
Ordering::Equal Ordering::Equal
} }
Ok(v) if options.contains(SortOptions::Descending) => v.reverse(), Ok(v) if options.contains(SortOptions::DESCENDING) => v.reverse(),
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {
error_signal = Err(e); error_signal = Err(e);
@ -859,7 +860,7 @@ where
error_signal?; error_signal?;
Ok(!options.contains(SortOptions::UniqueSort) || unique_sort_satisfied) Ok(!options.contains(SortOptions::UNIQUE_SORT) || unique_sort_satisfied)
} }
fn compare_string_case_sensitive<'gc>( fn compare_string_case_sensitive<'gc>(
@ -907,12 +908,12 @@ fn compare_numeric<'gc>(
fn sort_postprocess<'gc>( fn sort_postprocess<'gc>(
activation: &mut Activation<'_, 'gc, '_>, activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>, this: Object<'gc>,
options: EnumSet<SortOptions>, options: SortOptions,
unique_satisfied: bool, unique_satisfied: bool,
values: Vec<(usize, Value<'gc>)>, values: Vec<(usize, Value<'gc>)>,
) -> Result<Value<'gc>, Error> { ) -> Result<Value<'gc>, Error> {
if unique_satisfied { if unique_satisfied {
if options.contains(SortOptions::ReturnIndexedArray) { if options.contains(SortOptions::RETURN_INDEXED_ARRAY) {
return build_array( return build_array(
activation, activation,
ArrayStorage::from_storage( ArrayStorage::from_storage(
@ -998,18 +999,22 @@ pub fn sort<'gc>(
.unwrap_or(Value::Undefined) .unwrap_or(Value::Undefined)
.coerce_to_object(activation)?, .coerce_to_object(activation)?,
), ),
args.get(1) SortOptions::from_bits_truncate(
.cloned() args.get(1)
.unwrap_or_else(|| 0.into()) .cloned()
.coerce_to_enumset(activation)?, .unwrap_or_else(|| 0.into())
.coerce_to_u32(activation)? as u8,
),
) )
} else { } else {
( (
None, None,
args.get(0) SortOptions::from_bits_truncate(
.cloned() args.get(0)
.unwrap_or_else(|| 0.into()) .cloned()
.coerce_to_enumset(activation)?, .unwrap_or_else(|| 0.into())
.coerce_to_u32(activation)? as u8,
),
) )
}; };
@ -1042,9 +1047,9 @@ pub fn sort<'gc>(
} }
}), }),
)? )?
} else if options.contains(SortOptions::Numeric) { } else if options.contains(SortOptions::NUMERIC) {
sort_inner(activation, &mut values, options, compare_numeric)? sort_inner(activation, &mut values, options, compare_numeric)?
} else if options.contains(SortOptions::CaseInsensitive) { } else if options.contains(SortOptions::CASE_INSENSITIVE) {
sort_inner( sort_inner(
activation, activation,
&mut values, &mut values,
@ -1097,23 +1102,22 @@ fn extract_maybe_array_strings<'gc>(
Ok(out) Ok(out)
} }
/// Given a value, extract its array values and coerce them to enumsets. /// Given a value, extract its array values and coerce them to SortOptions.
/// ///
/// If the value is not an array, it will be returned as if it was present in a /// If the value is not an array, it will be returned as if it was present in a
/// one-element array containing itself. This is intended for use with parsing /// one-element array containing itself. This is intended for use with parsing
/// parameters which are optionally arrays. The returned value will still be /// parameters which are optionally arrays. The returned value will still be
/// coerced into a string in this case. /// coerced into a string in this case.
fn extract_maybe_array_enumsets<'gc, E>( fn extract_maybe_array_sort_options<'gc>(
activation: &mut Activation<'_, 'gc, '_>, activation: &mut Activation<'_, 'gc, '_>,
value: Value<'gc>, value: Value<'gc>,
) -> Result<Vec<EnumSet<E>>, Error> ) -> Result<Vec<SortOptions>, Error> {
where
E: EnumSetType,
{
let mut out = Vec::new(); let mut out = Vec::new();
for value in extract_maybe_array_values(activation, value)? { for value in extract_maybe_array_values(activation, value)? {
out.push(value.coerce_to_enumset(activation)?); out.push(SortOptions::from_bits_truncate(
value.coerce_to_u32(activation)? as u8,
));
} }
Ok(out) Ok(out)
@ -1128,16 +1132,13 @@ pub fn sort_on<'gc>(
if let Some(this) = this { if let Some(this) = this {
if let Some(field_names_value) = args.get(0).cloned() { if let Some(field_names_value) = args.get(0).cloned() {
let field_names = extract_maybe_array_strings(activation, field_names_value)?; let field_names = extract_maybe_array_strings(activation, field_names_value)?;
let mut options = extract_maybe_array_enumsets( let mut options = extract_maybe_array_sort_options(
activation, activation,
args.get(1).cloned().unwrap_or_else(|| 0.into()), args.get(1).cloned().unwrap_or_else(|| 0.into()),
)?; )?;
let first_option = options let first_option = options.get(0).cloned().unwrap_or_else(SortOptions::empty)
.get(0) & (SortOptions::UNIQUE_SORT | SortOptions::RETURN_INDEXED_ARRAY);
.cloned()
.unwrap_or_else(EnumSet::empty)
.intersection(SortOptions::UniqueSort | SortOptions::ReturnIndexedArray);
let mut values = if let Some(values) = extract_array_values(activation, this.into())? { let mut values = if let Some(values) = extract_array_values(activation, this.into())? {
values values
.iter() .iter()
@ -1151,7 +1152,7 @@ pub fn sort_on<'gc>(
if options.len() < field_names.len() { if options.len() < field_names.len() {
options.resize( options.resize(
field_names.len(), field_names.len(),
options.last().cloned().unwrap_or_else(EnumSet::empty), options.last().cloned().unwrap_or_else(SortOptions::empty),
); );
} }
@ -1175,9 +1176,9 @@ pub fn sort_on<'gc>(
activation, activation,
)?; )?;
let ord = if options.contains(SortOptions::Numeric) { let ord = if options.contains(SortOptions::NUMERIC) {
compare_numeric(activation, a_field, b_field)? compare_numeric(activation, a_field, b_field)?
} else if options.contains(SortOptions::CaseInsensitive) { } else if options.contains(SortOptions::CASE_INSENSITIVE) {
compare_string_case_insensitive(activation, a_field, b_field)? compare_string_case_insensitive(activation, a_field, b_field)?
} else { } else {
compare_string_case_sensitive(activation, a_field, b_field)? compare_string_case_sensitive(activation, a_field, b_field)?
@ -1187,7 +1188,7 @@ pub fn sort_on<'gc>(
continue; continue;
} }
if options.contains(SortOptions::Descending) { if options.contains(SortOptions::DESCENDING) {
return Ok(ord.reverse()); return Ok(ord.reverse());
} else { } else {
return Ok(ord); return Ok(ord);
@ -1328,35 +1329,31 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
class.write(mc).define_class_trait(Trait::from_const( class.write(mc).define_class_trait(Trait::from_const(
QName::new(Namespace::public_namespace(), "CASEINSENSITIVE"), QName::new(Namespace::public_namespace(), "CASEINSENSITIVE"),
Multiname::from(QName::new(Namespace::public_namespace(), "uint")), Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
Some(EnumSet::from(SortOptions::CaseInsensitive).as_u32().into()), Some(SortOptions::CASE_INSENSITIVE.bits().into()),
)); ));
class.write(mc).define_class_trait(Trait::from_const( class.write(mc).define_class_trait(Trait::from_const(
QName::new(Namespace::public_namespace(), "DESCENDING"), QName::new(Namespace::public_namespace(), "DESCENDING"),
Multiname::from(QName::new(Namespace::public_namespace(), "uint")), Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
Some(EnumSet::from(SortOptions::Descending).as_u32().into()), Some(SortOptions::DESCENDING.bits().into()),
)); ));
class.write(mc).define_class_trait(Trait::from_const( class.write(mc).define_class_trait(Trait::from_const(
QName::new(Namespace::public_namespace(), "NUMERIC"), QName::new(Namespace::public_namespace(), "NUMERIC"),
Multiname::from(QName::new(Namespace::public_namespace(), "uint")), Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
Some(EnumSet::from(SortOptions::Numeric).as_u32().into()), Some(SortOptions::NUMERIC.bits().into()),
)); ));
class.write(mc).define_class_trait(Trait::from_const( class.write(mc).define_class_trait(Trait::from_const(
QName::new(Namespace::public_namespace(), "RETURNINDEXEDARRAY"), QName::new(Namespace::public_namespace(), "RETURNINDEXEDARRAY"),
Multiname::from(QName::new(Namespace::public_namespace(), "uint")), Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
Some( Some(SortOptions::RETURN_INDEXED_ARRAY.bits().into()),
EnumSet::from(SortOptions::ReturnIndexedArray)
.as_u32()
.into(),
),
)); ));
class.write(mc).define_class_trait(Trait::from_const( class.write(mc).define_class_trait(Trait::from_const(
QName::new(Namespace::public_namespace(), "UNIQUESORT"), QName::new(Namespace::public_namespace(), "UNIQUESORT"),
Multiname::from(QName::new(Namespace::public_namespace(), "uint")), Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
Some(EnumSet::from(SortOptions::UniqueSort).as_u32().into()), Some(SortOptions::UNIQUE_SORT.bits().into()),
)); ));
class class

View File

@ -9,8 +9,7 @@ use crate::avm2::traits::Trait;
use crate::avm2::value::Value; use crate::avm2::value::Value;
use crate::avm2::Error; use crate::avm2::Error;
use crate::context::UpdateContext; use crate::context::UpdateContext;
use crate::display_object::{DisplayObject, TDisplayObject, TDisplayObjectContainer}; use crate::display_object::{DisplayObject, Lists, TDisplayObject, TDisplayObjectContainer};
use enumset::EnumSet;
use gc_arena::{GcCell, MutationContext}; use gc_arena::{GcCell, MutationContext};
use std::cmp::min; use std::cmp::min;
@ -100,7 +99,7 @@ fn remove_child_from_displaylist<'gc>(
) { ) {
if let Some(parent) = child.parent() { if let Some(parent) = child.parent() {
if let Some(mut ctr) = parent.as_container() { if let Some(mut ctr) = parent.as_container() {
ctr.remove_child(context, child, EnumSet::all()); ctr.remove_child(context, child, Lists::all());
} }
} }
} }
@ -353,7 +352,7 @@ pub fn remove_child_at<'gc>(
let child = ctr.child_by_index(target_child as usize).unwrap(); let child = ctr.child_by_index(target_child as usize).unwrap();
ctr.remove_child(&mut activation.context, child, EnumSet::all()); ctr.remove_child(&mut activation.context, child, Lists::all());
return Ok(child.object2()); return Ok(child.object2());
} }

View File

@ -272,7 +272,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
let mut write = class.write(mc); let mut write = class.write(mc);
write.set_attributes(ClassAttributes::Sealed.into()); write.set_attributes(ClassAttributes::SEALED);
write.define_instance_trait(Trait::from_getter( write.define_instance_trait(Trait::from_getter(
QName::new(Namespace::public_namespace(), "bubbles"), QName::new(Namespace::public_namespace(), "bubbles"),

View File

@ -375,7 +375,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
let mut write = class.write(mc); let mut write = class.write(mc);
write.set_attributes(ClassAttributes::Sealed.into()); write.set_attributes(ClassAttributes::SEALED);
write.implements(QName::new(Namespace::package("flash.events"), "IEventDispatcher").into()); write.implements(QName::new(Namespace::package("flash.events"), "IEventDispatcher").into());

View File

@ -40,7 +40,7 @@ pub fn create_interface<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<
let mut write = class.write(mc); let mut write = class.write(mc);
write.set_attributes(ClassAttributes::Interface.into()); write.set_attributes(ClassAttributes::INTERFACE);
write.define_instance_trait(Trait::from_method( write.define_instance_trait(Trait::from_method(
QName::dynamic_name("addEventListener"), QName::dynamic_name("addEventListener"),
Method::from_builtin(bodiless_method), Method::from_builtin(bodiless_method),

View File

@ -84,7 +84,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
); );
let mut write = class.write(mc); let mut write = class.write(mc);
write.set_attributes(ClassAttributes::Final | ClassAttributes::Sealed); write.set_attributes(ClassAttributes::FINAL | ClassAttributes::SEALED);
use std::f64::consts::*; use std::f64::consts::*;
math_constants! { math_constants! {

View File

@ -1,20 +1,20 @@
//! Property data structures //! Property data structures
use self::Attribute::*;
use crate::avm2::object::{Object, TObject}; use crate::avm2::object::{Object, TObject};
use crate::avm2::return_value::ReturnValue; use crate::avm2::return_value::ReturnValue;
use crate::avm2::value::Value; use crate::avm2::value::Value;
use crate::avm2::Error; use crate::avm2::Error;
use enumset::{EnumSet, EnumSetType}; use bitflags::bitflags;
use gc_arena::{Collect, CollectionContext}; use gc_arena::{Collect, CollectionContext};
/// Attributes of properties in the AVM runtime. bitflags! {
/// /// Attributes of properties in the AVM runtime.
/// TODO: Replace with AVM2 properties for traits ///
#[derive(EnumSetType, Debug)] /// TODO: Replace with AVM2 properties for traits
pub enum Attribute { pub struct Attribute: u8 {
DontDelete, const DONT_DELETE = 1 << 0;
ReadOnly, const READ_ONLY = 1 << 1;
}
} }
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
@ -23,15 +23,15 @@ pub enum Property<'gc> {
Virtual { Virtual {
get: Option<Object<'gc>>, get: Option<Object<'gc>>,
set: Option<Object<'gc>>, set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>, attributes: Attribute,
}, },
Stored { Stored {
value: Value<'gc>, value: Value<'gc>,
attributes: EnumSet<Attribute>, attributes: Attribute,
}, },
Slot { Slot {
slot_id: u32, slot_id: u32,
attributes: EnumSet<Attribute>, attributes: Attribute,
}, },
} }
@ -53,7 +53,7 @@ impl<'gc> Property<'gc> {
pub fn new_stored(value: impl Into<Value<'gc>>) -> Self { pub fn new_stored(value: impl Into<Value<'gc>>) -> Self {
Property::Stored { Property::Stored {
value: value.into(), value: value.into(),
attributes: EnumSet::from(Attribute::DontDelete), attributes: Attribute::DONT_DELETE,
} }
} }
@ -61,7 +61,7 @@ impl<'gc> Property<'gc> {
pub fn new_const(value: impl Into<Value<'gc>>) -> Self { pub fn new_const(value: impl Into<Value<'gc>>) -> Self {
Property::Stored { Property::Stored {
value: value.into(), value: value.into(),
attributes: Attribute::ReadOnly | Attribute::DontDelete, attributes: Attribute::DONT_DELETE | Attribute::READ_ONLY,
} }
} }
@ -69,17 +69,17 @@ impl<'gc> Property<'gc> {
pub fn new_dynamic_property(value: impl Into<Value<'gc>>) -> Self { pub fn new_dynamic_property(value: impl Into<Value<'gc>>) -> Self {
Property::Stored { Property::Stored {
value: value.into(), value: value.into(),
attributes: EnumSet::empty(), attributes: Attribute::empty(),
} }
} }
/// Convert a function into a method. /// Convert a function into a method.
/// ///
/// This applies ReadOnly/DontDelete to the property. /// This applies READ_ONLY/DONT_DELETE to the property.
pub fn new_method(fn_obj: Object<'gc>) -> Self { pub fn new_method(fn_obj: Object<'gc>) -> Self {
Property::Stored { Property::Stored {
value: fn_obj.into(), value: fn_obj.into(),
attributes: Attribute::ReadOnly | Attribute::DontDelete, attributes: Attribute::DONT_DELETE | Attribute::READ_ONLY,
} }
} }
@ -88,7 +88,7 @@ impl<'gc> Property<'gc> {
Property::Virtual { Property::Virtual {
get: None, get: None,
set: None, set: None,
attributes: Attribute::ReadOnly | Attribute::DontDelete, attributes: Attribute::DONT_DELETE | Attribute::READ_ONLY,
} }
} }
@ -96,7 +96,7 @@ impl<'gc> Property<'gc> {
pub fn new_slot(slot_id: u32) -> Self { pub fn new_slot(slot_id: u32) -> Self {
Property::Slot { Property::Slot {
slot_id, slot_id,
attributes: EnumSet::from(Attribute::DontDelete), attributes: Attribute::DONT_DELETE,
} }
} }
@ -185,7 +185,7 @@ impl<'gc> Property<'gc> {
Property::Stored { Property::Stored {
value, attributes, .. value, attributes, ..
} => { } => {
if !attributes.contains(ReadOnly) { if !attributes.contains(Attribute::READ_ONLY) {
*value = new_value.into(); *value = new_value.into();
} }
@ -246,20 +246,27 @@ impl<'gc> Property<'gc> {
} }
pub fn can_delete(&self) -> bool { pub fn can_delete(&self) -> bool {
match self { let attributes = match self {
Property::Virtual { attributes, .. } => !attributes.contains(DontDelete), Property::Virtual { attributes, .. } => attributes,
Property::Stored { attributes, .. } => !attributes.contains(DontDelete), Property::Stored { attributes, .. } => attributes,
Property::Slot { attributes, .. } => !attributes.contains(DontDelete), Property::Slot { attributes, .. } => attributes,
} };
!attributes.contains(Attribute::DONT_DELETE)
} }
pub fn is_overwritable(&self) -> bool { pub fn is_overwritable(&self) -> bool {
match self { let attributes = match self {
Property::Virtual { Property::Virtual {
attributes, set, .. attributes, set, ..
} => !attributes.contains(ReadOnly) && !set.is_none(), } => {
Property::Stored { attributes, .. } => !attributes.contains(ReadOnly), if set.is_none() {
Property::Slot { attributes, .. } => !attributes.contains(ReadOnly), return false;
} }
attributes
}
Property::Stored { attributes, .. } => attributes,
Property::Slot { attributes, .. } => attributes,
};
!attributes.contains(Attribute::READ_ONLY)
} }
} }

View File

@ -3,7 +3,6 @@
use crate::avm2::property::Attribute; use crate::avm2::property::Attribute;
use crate::avm2::value::Value; use crate::avm2::value::Value;
use crate::avm2::Error; use crate::avm2::Error;
use enumset::EnumSet;
use gc_arena::{Collect, CollectionContext}; use gc_arena::{Collect, CollectionContext};
/// Represents a single slot on an object. /// Represents a single slot on an object.
@ -20,7 +19,7 @@ pub enum Slot<'gc> {
/// TODO: For some reason, rustc believes this variant is unused. /// TODO: For some reason, rustc believes this variant is unused.
Occupied { Occupied {
value: Value<'gc>, value: Value<'gc>,
attributes: EnumSet<Attribute>, attributes: Attribute,
}, },
} }
@ -44,7 +43,7 @@ impl<'gc> Slot<'gc> {
pub fn new(value: impl Into<Value<'gc>>) -> Self { pub fn new(value: impl Into<Value<'gc>>) -> Self {
Self::Occupied { Self::Occupied {
value: value.into(), value: value.into(),
attributes: EnumSet::empty(), attributes: Attribute::empty(),
} }
} }
@ -52,7 +51,7 @@ impl<'gc> Slot<'gc> {
pub fn new_const(value: impl Into<Value<'gc>>) -> Self { pub fn new_const(value: impl Into<Value<'gc>>) -> Self {
Self::Occupied { Self::Occupied {
value: value.into(), value: value.into(),
attributes: EnumSet::from(Attribute::ReadOnly), attributes: Attribute::READ_ONLY,
} }
} }
@ -69,7 +68,7 @@ impl<'gc> Slot<'gc> {
match self { match self {
Self::Unoccupied => Err("Cannot overwrite unoccupied slot".into()), Self::Unoccupied => Err("Cannot overwrite unoccupied slot".into()),
Self::Occupied { value, attributes } => { Self::Occupied { value, attributes } => {
if attributes.contains(Attribute::ReadOnly) { if attributes.contains(Attribute::READ_ONLY) {
return Err("Cannot overwrite const slot".into()); return Err("Cannot overwrite const slot".into());
} }

View File

@ -7,20 +7,21 @@ use crate::avm2::script::TranslationUnit;
use crate::avm2::value::{abc_default_value, Value}; use crate::avm2::value::{abc_default_value, Value};
use crate::avm2::{Avm2, Error}; use crate::avm2::{Avm2, Error};
use crate::collect::CollectWrapper; use crate::collect::CollectWrapper;
use enumset::{EnumSet, EnumSetType}; use bitflags::bitflags;
use gc_arena::{Collect, GcCell, MutationContext}; use gc_arena::{Collect, GcCell, MutationContext};
use swf::avm2::types::{Trait as AbcTrait, TraitKind as AbcTraitKind}; use swf::avm2::types::{Trait as AbcTrait, TraitKind as AbcTraitKind};
/// All attributes a trait can have. bitflags! {
#[derive(Debug, EnumSetType)] /// All attributes a trait can have.
pub enum TraitAttributes { pub struct TraitAttributes: u8 {
/// Whether or not traits in downstream classes are allowed to override /// Whether or not traits in downstream classes are allowed to override
/// this trait. /// this trait.
Final, const FINAL = 1 << 0;
/// Whether or not this trait is intended to override an upstream class's /// Whether or not this trait is intended to override an upstream class's
/// trait. /// trait.
Override, const OVERRIDE = 1 << 1;
}
} }
/// Represents a trait as loaded into the VM. /// Represents a trait as loaded into the VM.
@ -40,19 +41,17 @@ pub struct Trait<'gc> {
name: QName<'gc>, name: QName<'gc>,
/// The attributes set on this trait. /// The attributes set on this trait.
attributes: CollectWrapper<EnumSet<TraitAttributes>>, attributes: CollectWrapper<TraitAttributes>,
/// The kind of trait in use. /// The kind of trait in use.
kind: TraitKind<'gc>, kind: TraitKind<'gc>,
} }
fn trait_attribs_from_abc_traits(abc_trait: &AbcTrait) -> CollectWrapper<EnumSet<TraitAttributes>> { fn trait_attribs_from_abc_traits(abc_trait: &AbcTrait) -> CollectWrapper<TraitAttributes> {
CollectWrapper(match (abc_trait.is_final, abc_trait.is_override) { let mut attributes = TraitAttributes::empty();
(true, true) => TraitAttributes::Final | TraitAttributes::Override, attributes.set(TraitAttributes::FINAL, abc_trait.is_final);
(true, false) => TraitAttributes::Final.into(), attributes.set(TraitAttributes::OVERRIDE, abc_trait.is_override);
(false, true) => TraitAttributes::Override.into(), CollectWrapper(attributes)
(false, false) => EnumSet::empty(),
})
} }
/// The fields for a particular kind of trait. /// The fields for a particular kind of trait.
@ -104,7 +103,7 @@ impl<'gc> Trait<'gc> {
Trait { Trait {
name, name,
attributes: CollectWrapper(EnumSet::empty()), attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Class { slot_id: 0, class }, kind: TraitKind::Class { slot_id: 0, class },
} }
} }
@ -112,7 +111,7 @@ impl<'gc> Trait<'gc> {
pub fn from_method(name: QName<'gc>, method: Method<'gc>) -> Self { pub fn from_method(name: QName<'gc>, method: Method<'gc>) -> Self {
Trait { Trait {
name, name,
attributes: CollectWrapper(EnumSet::empty()), attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Method { disp_id: 0, method }, kind: TraitKind::Method { disp_id: 0, method },
} }
} }
@ -120,7 +119,7 @@ impl<'gc> Trait<'gc> {
pub fn from_getter(name: QName<'gc>, method: Method<'gc>) -> Self { pub fn from_getter(name: QName<'gc>, method: Method<'gc>) -> Self {
Trait { Trait {
name, name,
attributes: CollectWrapper(EnumSet::empty()), attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Getter { disp_id: 0, method }, kind: TraitKind::Getter { disp_id: 0, method },
} }
} }
@ -128,7 +127,7 @@ impl<'gc> Trait<'gc> {
pub fn from_setter(name: QName<'gc>, method: Method<'gc>) -> Self { pub fn from_setter(name: QName<'gc>, method: Method<'gc>) -> Self {
Trait { Trait {
name, name,
attributes: CollectWrapper(EnumSet::empty()), attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Setter { disp_id: 0, method }, kind: TraitKind::Setter { disp_id: 0, method },
} }
} }
@ -136,7 +135,7 @@ impl<'gc> Trait<'gc> {
pub fn from_function(name: QName<'gc>, function: Method<'gc>) -> Self { pub fn from_function(name: QName<'gc>, function: Method<'gc>) -> Self {
Trait { Trait {
name, name,
attributes: CollectWrapper(EnumSet::empty()), attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Function { kind: TraitKind::Function {
slot_id: 0, slot_id: 0,
function, function,
@ -151,7 +150,7 @@ impl<'gc> Trait<'gc> {
) -> Self { ) -> Self {
Trait { Trait {
name, name,
attributes: CollectWrapper(EnumSet::empty()), attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Slot { kind: TraitKind::Slot {
slot_id: 0, slot_id: 0,
type_name, type_name,
@ -167,7 +166,7 @@ impl<'gc> Trait<'gc> {
) -> Self { ) -> Self {
Trait { Trait {
name, name,
attributes: CollectWrapper(EnumSet::empty()), attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Slot { kind: TraitKind::Slot {
slot_id: 0, slot_id: 0,
type_name, type_name,
@ -280,14 +279,14 @@ impl<'gc> Trait<'gc> {
} }
pub fn is_final(&self) -> bool { pub fn is_final(&self) -> bool {
self.attributes.0.contains(TraitAttributes::Final) self.attributes.0.contains(TraitAttributes::FINAL)
} }
pub fn is_override(&self) -> bool { pub fn is_override(&self) -> bool {
self.attributes.0.contains(TraitAttributes::Override) self.attributes.0.contains(TraitAttributes::OVERRIDE)
} }
pub fn set_attributes(&mut self, attribs: EnumSet<TraitAttributes>) { pub fn set_attributes(&mut self, attribs: TraitAttributes) {
self.attributes.0 = attribs; self.attributes.0 = attribs;
} }

View File

@ -8,7 +8,6 @@ use crate::avm2::script::TranslationUnit;
use crate::avm2::string::AvmString; use crate::avm2::string::AvmString;
use crate::avm2::{Avm2, Error}; use crate::avm2::{Avm2, Error};
use crate::ecma_conversions::{f64_to_wrapping_i32, f64_to_wrapping_u32}; use crate::ecma_conversions::{f64_to_wrapping_i32, f64_to_wrapping_u32};
use enumset::{EnumSet, EnumSetType};
use gc_arena::{Collect, MutationContext}; use gc_arena::{Collect, MutationContext};
use std::cell::Ref; use std::cell::Ref;
use std::f64::NAN; use std::f64::NAN;
@ -446,20 +445,6 @@ impl<'gc> Value<'gc> {
Ok(f64_to_wrapping_i32(self.coerce_to_number(activation)?)) Ok(f64_to_wrapping_i32(self.coerce_to_number(activation)?))
} }
/// Coerce the value to an EnumSet of a particular type.
///
/// This function will ignore invalid bits of the value when interpreting
/// the enum.
pub fn coerce_to_enumset<E>(
&self,
activation: &mut Activation<'_, 'gc, '_>,
) -> Result<EnumSet<E>, Error>
where
E: EnumSetType,
{
Ok(EnumSet::from_u32_truncated(self.coerce_to_u32(activation)?))
}
/// Minimum number of digits after which numbers are formatted as /// Minimum number of digits after which numbers are formatted as
/// exponential strings. /// exponential strings.
const MIN_DIGITS: f64 = -6.0; const MIN_DIGITS: f64 = -6.0;

View File

@ -9,7 +9,7 @@ use crate::tag_utils::SwfMovie;
use crate::transform::Transform; use crate::transform::Transform;
use crate::types::{Degrees, Percent}; use crate::types::{Degrees, Percent};
use crate::vminterface::Instantiator; use crate::vminterface::Instantiator;
use enumset::{EnumSet, EnumSetType}; use bitflags::bitflags;
use gc_arena::{Collect, MutationContext}; use gc_arena::{Collect, MutationContext};
use ruffle_macros::enum_trait_object; use ruffle_macros::enum_trait_object;
use std::cell::{Ref, RefMut}; use std::cell::{Ref, RefMut};
@ -68,7 +68,7 @@ pub struct DisplayObjectBase<'gc> {
next_sibling: Option<DisplayObject<'gc>>, next_sibling: Option<DisplayObject<'gc>>,
/// Bit flags for various display object properites. /// Bit flags for various display object properites.
flags: EnumSet<DisplayObjectFlags>, flags: DisplayObjectFlags,
} }
impl<'gc> Default for DisplayObjectBase<'gc> { impl<'gc> Default for DisplayObjectBase<'gc> {
@ -86,7 +86,7 @@ impl<'gc> Default for DisplayObjectBase<'gc> {
skew: 0.0, skew: 0.0,
prev_sibling: None, prev_sibling: None,
next_sibling: None, next_sibling: None,
flags: DisplayObjectFlags::Visible.into(), flags: DisplayObjectFlags::VISIBLE,
} }
} }
} }
@ -104,28 +104,30 @@ unsafe impl<'gc> Collect for DisplayObjectBase<'gc> {
impl<'gc> DisplayObjectBase<'gc> { impl<'gc> DisplayObjectBase<'gc> {
/// Reset all properties that would be adjusted by a movie load. /// Reset all properties that would be adjusted by a movie load.
fn reset_for_movie_load(&mut self) { fn reset_for_movie_load(&mut self) {
let flags_to_keep = self let flags_to_keep = self.flags & DisplayObjectFlags::LOCK_ROOT;
.flags self.flags = flags_to_keep | DisplayObjectFlags::VISIBLE;
.intersection(EnumSet::from(DisplayObjectFlags::LockRoot));
self.flags = DisplayObjectFlags::Visible.into();
self.flags.insert_all(flags_to_keep);
} }
fn id(&self) -> CharacterId { fn id(&self) -> CharacterId {
0 0
} }
fn depth(&self) -> Depth { fn depth(&self) -> Depth {
self.depth self.depth
} }
fn set_depth(&mut self, depth: Depth) { fn set_depth(&mut self, depth: Depth) {
self.depth = depth; self.depth = depth;
} }
fn place_frame(&self) -> u16 { fn place_frame(&self) -> u16 {
self.place_frame self.place_frame
} }
fn set_place_frame(&mut self, _context: MutationContext<'gc, '_>, frame: u16) { fn set_place_frame(&mut self, _context: MutationContext<'gc, '_>, frame: u16) {
self.place_frame = frame; self.place_frame = frame;
} }
fn transform(&self) -> &Transform { fn transform(&self) -> &Transform {
&self.transform &self.transform
} }
@ -133,19 +135,24 @@ impl<'gc> DisplayObjectBase<'gc> {
fn matrix(&self) -> &Matrix { fn matrix(&self) -> &Matrix {
&self.transform.matrix &self.transform.matrix
} }
fn matrix_mut(&mut self, _context: MutationContext<'gc, '_>) -> &mut Matrix { fn matrix_mut(&mut self, _context: MutationContext<'gc, '_>) -> &mut Matrix {
&mut self.transform.matrix &mut self.transform.matrix
} }
fn set_matrix(&mut self, _context: MutationContext<'gc, '_>, matrix: &Matrix) { fn set_matrix(&mut self, _context: MutationContext<'gc, '_>, matrix: &Matrix) {
self.transform.matrix = *matrix; self.transform.matrix = *matrix;
self.flags.remove(DisplayObjectFlags::ScaleRotationCached); self.flags -= DisplayObjectFlags::SCALE_ROTATION_CACHED;
} }
fn color_transform(&self) -> &ColorTransform { fn color_transform(&self) -> &ColorTransform {
&self.transform.color_transform &self.transform.color_transform
} }
fn color_transform_mut(&mut self) -> &mut ColorTransform { fn color_transform_mut(&mut self) -> &mut ColorTransform {
&mut self.transform.color_transform &mut self.transform.color_transform
} }
fn set_color_transform( fn set_color_transform(
&mut self, &mut self,
_context: MutationContext<'gc, '_>, _context: MutationContext<'gc, '_>,
@ -153,16 +160,20 @@ impl<'gc> DisplayObjectBase<'gc> {
) { ) {
self.transform.color_transform = *color_transform; self.transform.color_transform = *color_transform;
} }
fn x(&self) -> f64 { fn x(&self) -> f64 {
self.transform.matrix.tx.to_pixels() self.transform.matrix.tx.to_pixels()
} }
fn set_x(&mut self, value: f64) { fn set_x(&mut self, value: f64) {
self.set_transformed_by_script(true); self.set_transformed_by_script(true);
self.transform.matrix.tx = Twips::from_pixels(value) self.transform.matrix.tx = Twips::from_pixels(value)
} }
fn y(&self) -> f64 { fn y(&self) -> f64 {
self.transform.matrix.ty.to_pixels() self.transform.matrix.ty.to_pixels()
} }
fn set_y(&mut self, value: f64) { fn set_y(&mut self, value: f64) {
self.set_transformed_by_script(true); self.set_transformed_by_script(true);
self.transform.matrix.ty = Twips::from_pixels(value) self.transform.matrix.ty = Twips::from_pixels(value)
@ -172,7 +183,10 @@ impl<'gc> DisplayObjectBase<'gc> {
/// Calculating these requires heavy trig ops, so we only do it when `_xscale`, `_yscale` or /// Calculating these requires heavy trig ops, so we only do it when `_xscale`, `_yscale` or
/// `_rotation` is accessed. /// `_rotation` is accessed.
fn cache_scale_rotation(&mut self) { fn cache_scale_rotation(&mut self) {
if !self.flags.contains(DisplayObjectFlags::ScaleRotationCached) { if !self
.flags
.contains(DisplayObjectFlags::SCALE_ROTATION_CACHED)
{
let (a, b, c, d) = ( let (a, b, c, d) = (
f64::from(self.transform.matrix.a), f64::from(self.transform.matrix.a),
f64::from(self.transform.matrix.b), f64::from(self.transform.matrix.b),
@ -201,7 +215,7 @@ impl<'gc> DisplayObjectBase<'gc> {
self.scale_x = Percent::from_unit(scale_x); self.scale_x = Percent::from_unit(scale_x);
self.scale_y = Percent::from_unit(scale_y); self.scale_y = Percent::from_unit(scale_y);
self.skew = rotation_y - rotation_x; self.skew = rotation_y - rotation_x;
self.flags.insert(DisplayObjectFlags::ScaleRotationCached); self.flags |= DisplayObjectFlags::SCALE_ROTATION_CACHED;
} }
} }
@ -224,6 +238,7 @@ impl<'gc> DisplayObjectBase<'gc> {
self.cache_scale_rotation(); self.cache_scale_rotation();
self.rotation self.rotation
} }
fn set_rotation(&mut self, degrees: Degrees) { fn set_rotation(&mut self, degrees: Degrees) {
self.set_transformed_by_script(true); self.set_transformed_by_script(true);
self.cache_scale_rotation(); self.cache_scale_rotation();
@ -238,10 +253,12 @@ impl<'gc> DisplayObjectBase<'gc> {
matrix.c = (self.scale_y.into_unit() * -sin_y) as f32; matrix.c = (self.scale_y.into_unit() * -sin_y) as f32;
matrix.d = (self.scale_y.into_unit() * cos_y) as f32; matrix.d = (self.scale_y.into_unit() * cos_y) as f32;
} }
fn scale_x(&mut self) -> Percent { fn scale_x(&mut self) -> Percent {
self.cache_scale_rotation(); self.cache_scale_rotation();
self.scale_x self.scale_x
} }
fn set_scale_x(&mut self, value: Percent) { fn set_scale_x(&mut self, value: Percent) {
self.set_transformed_by_script(true); self.set_transformed_by_script(true);
self.cache_scale_rotation(); self.cache_scale_rotation();
@ -252,10 +269,12 @@ impl<'gc> DisplayObjectBase<'gc> {
matrix.a = (cos * value.into_unit()) as f32; matrix.a = (cos * value.into_unit()) as f32;
matrix.b = (sin * value.into_unit()) as f32; matrix.b = (sin * value.into_unit()) as f32;
} }
fn scale_y(&mut self) -> Percent { fn scale_y(&mut self) -> Percent {
self.cache_scale_rotation(); self.cache_scale_rotation();
self.scale_y self.scale_y
} }
fn set_scale_y(&mut self, value: Percent) { fn set_scale_y(&mut self, value: Percent) {
self.set_transformed_by_script(true); self.set_transformed_by_script(true);
self.cache_scale_rotation(); self.cache_scale_rotation();
@ -270,25 +289,32 @@ impl<'gc> DisplayObjectBase<'gc> {
fn name(&self) -> &str { fn name(&self) -> &str {
&self.name &self.name
} }
fn set_name(&mut self, _context: MutationContext<'gc, '_>, name: &str) { fn set_name(&mut self, _context: MutationContext<'gc, '_>, name: &str) {
self.name = name.to_string(); self.name = name.to_string();
} }
fn alpha(&self) -> f64 { fn alpha(&self) -> f64 {
f64::from(self.color_transform().a_mult) f64::from(self.color_transform().a_mult)
} }
fn set_alpha(&mut self, value: f64) { fn set_alpha(&mut self, value: f64) {
self.set_transformed_by_script(true); self.set_transformed_by_script(true);
self.color_transform_mut().a_mult = value as f32 self.color_transform_mut().a_mult = value as f32
} }
fn clip_depth(&self) -> Depth { fn clip_depth(&self) -> Depth {
self.clip_depth self.clip_depth
} }
fn set_clip_depth(&mut self, _context: MutationContext<'gc, '_>, depth: Depth) { fn set_clip_depth(&mut self, _context: MutationContext<'gc, '_>, depth: Depth) {
self.clip_depth = depth; self.clip_depth = depth;
} }
fn parent(&self) -> Option<DisplayObject<'gc>> { fn parent(&self) -> Option<DisplayObject<'gc>> {
self.parent self.parent
} }
fn set_parent( fn set_parent(
&mut self, &mut self,
_context: MutationContext<'gc, '_>, _context: MutationContext<'gc, '_>,
@ -296,9 +322,11 @@ impl<'gc> DisplayObjectBase<'gc> {
) { ) {
self.parent = parent; self.parent = parent;
} }
fn prev_sibling(&self) -> Option<DisplayObject<'gc>> { fn prev_sibling(&self) -> Option<DisplayObject<'gc>> {
self.prev_sibling self.prev_sibling
} }
fn set_prev_sibling( fn set_prev_sibling(
&mut self, &mut self,
_context: MutationContext<'gc, '_>, _context: MutationContext<'gc, '_>,
@ -306,9 +334,11 @@ impl<'gc> DisplayObjectBase<'gc> {
) { ) {
self.prev_sibling = node; self.prev_sibling = node;
} }
fn next_sibling(&self) -> Option<DisplayObject<'gc>> { fn next_sibling(&self) -> Option<DisplayObject<'gc>> {
self.next_sibling self.next_sibling
} }
fn set_next_sibling( fn set_next_sibling(
&mut self, &mut self,
_context: MutationContext<'gc, '_>, _context: MutationContext<'gc, '_>,
@ -316,77 +346,78 @@ impl<'gc> DisplayObjectBase<'gc> {
) { ) {
self.next_sibling = node; self.next_sibling = node;
} }
fn removed(&self) -> bool { fn removed(&self) -> bool {
self.flags.contains(DisplayObjectFlags::Removed) self.flags.contains(DisplayObjectFlags::REMOVED)
} }
fn set_removed(&mut self, value: bool) { fn set_removed(&mut self, value: bool) {
if value { if value {
self.flags.insert(DisplayObjectFlags::Removed); self.flags |= DisplayObjectFlags::REMOVED;
} else { } else {
self.flags.remove(DisplayObjectFlags::Removed); self.flags -= DisplayObjectFlags::REMOVED;
} }
} }
fn visible(&self) -> bool { fn visible(&self) -> bool {
self.flags.contains(DisplayObjectFlags::Visible) self.flags.contains(DisplayObjectFlags::VISIBLE)
} }
fn set_visible(&mut self, value: bool) { fn set_visible(&mut self, value: bool) {
if value { if value {
self.flags.insert(DisplayObjectFlags::Visible); self.flags |= DisplayObjectFlags::VISIBLE;
} else { } else {
self.flags.remove(DisplayObjectFlags::Visible); self.flags -= DisplayObjectFlags::VISIBLE;
} }
} }
fn lock_root(&self) -> bool { fn lock_root(&self) -> bool {
self.flags.contains(DisplayObjectFlags::LockRoot) self.flags.contains(DisplayObjectFlags::LOCK_ROOT)
} }
fn set_lock_root(&mut self, value: bool) { fn set_lock_root(&mut self, value: bool) {
if value { if value {
self.flags.insert(DisplayObjectFlags::LockRoot); self.flags |= DisplayObjectFlags::LOCK_ROOT;
} else { } else {
self.flags.remove(DisplayObjectFlags::LockRoot); self.flags -= DisplayObjectFlags::LOCK_ROOT;
} }
} }
fn transformed_by_script(&self) -> bool { fn transformed_by_script(&self) -> bool {
self.flags.contains(DisplayObjectFlags::TransformedByScript) self.flags
.contains(DisplayObjectFlags::TRANSFORMED_BY_SCRIPT)
} }
fn set_transformed_by_script(&mut self, value: bool) { fn set_transformed_by_script(&mut self, value: bool) {
if value { if value {
self.flags.insert(DisplayObjectFlags::TransformedByScript); self.flags |= DisplayObjectFlags::TRANSFORMED_BY_SCRIPT;
} else { } else {
self.flags.remove(DisplayObjectFlags::TransformedByScript); self.flags -= DisplayObjectFlags::TRANSFORMED_BY_SCRIPT;
} }
} }
fn placed_by_script(&self) -> bool { fn placed_by_script(&self) -> bool {
self.flags.contains(DisplayObjectFlags::PlacedByScript) self.flags.contains(DisplayObjectFlags::PLACED_BY_SCRIPT)
} }
fn set_placed_by_script(&mut self, value: bool) { fn set_placed_by_script(&mut self, value: bool) {
if value { if value {
self.flags.insert(DisplayObjectFlags::PlacedByScript); self.flags |= DisplayObjectFlags::PLACED_BY_SCRIPT;
} else { } else {
self.flags.remove(DisplayObjectFlags::PlacedByScript); self.flags -= DisplayObjectFlags::PLACED_BY_SCRIPT;
} }
} }
fn instantiated_by_timeline(&self) -> bool { fn instantiated_by_timeline(&self) -> bool {
self.flags self.flags
.contains(DisplayObjectFlags::InstantiatedByTimeline) .contains(DisplayObjectFlags::INSTANTIATED_BY_TIMELINE)
} }
fn set_instantiated_by_timeline(&mut self, value: bool) { fn set_instantiated_by_timeline(&mut self, value: bool) {
if value { if value {
self.flags self.flags |= DisplayObjectFlags::INSTANTIATED_BY_TIMELINE;
.insert(DisplayObjectFlags::InstantiatedByTimeline);
} else { } else {
self.flags self.flags -= DisplayObjectFlags::INSTANTIATED_BY_TIMELINE;
.remove(DisplayObjectFlags::InstantiatedByTimeline);
} }
} }
@ -1268,33 +1299,35 @@ impl<'gc> DisplayObject<'gc> {
} }
} }
/// Bit flags used by `DisplayObject`. bitflags! {
#[derive(Collect, EnumSetType, Debug)] /// Bit flags used by `DisplayObject`.
#[collect(no_drop)] #[derive(Collect)]
enum DisplayObjectFlags { #[collect(no_drop)]
/// Whether this object has been removed from the display list. struct DisplayObjectFlags: u8 {
/// Necessary in AVM1 to throw away queued actions from removed movie clips. /// Whether this object has been removed from the display list.
Removed, /// Necessary in AVM1 to throw away queued actions from removed movie clips.
const REMOVED = 1 << 0;
/// If this object is visible (`_visible` property). /// If this object is visible (`_visible` property).
Visible, const VISIBLE = 1 << 1;
/// Whether the `_xscale`, `_yscale` and `_rotation` of the object have been calculated and cached. /// Whether the `_xscale`, `_yscale` and `_rotation` of the object have been calculated and cached.
ScaleRotationCached, const SCALE_ROTATION_CACHED = 1 << 2;
/// Whether this object has been transformed by ActionScript. /// Whether this object has been transformed by ActionScript.
/// When this flag is set, changes from SWF `PlaceObject` tags are ignored. /// When this flag is set, changes from SWF `PlaceObject` tags are ignored.
TransformedByScript, const TRANSFORMED_BY_SCRIPT = 1 << 3;
/// Whether this object has been placed in a container by ActionScript 3. /// Whether this object has been placed in a container by ActionScript 3.
/// When this flag is set, changes from SWF `RemoveObject` tags are ignored. /// When this flag is set, changes from SWF `RemoveObject` tags are ignored.
PlacedByScript, const PLACED_BY_SCRIPT = 1 << 4;
/// Whether this object has been instantiated by a SWF tag. /// Whether this object has been instantiated by a SWF tag.
/// When this flag is set, changes from SWF `RemoveObject` tags are ignored. /// When this flag is set, changes from SWF `RemoveObject` tags are ignored.
InstantiatedByTimeline, const INSTANTIATED_BY_TIMELINE = 1 << 5;
/// Whether this object has `_lockroot` set to true, in which case /// Whether this object has `_lockroot` set to true, in which case
/// it becomes the _root of itself and of any children /// it becomes the _root of itself and of any children
LockRoot, const LOCK_ROOT = 1 << 6;
}
} }

View File

@ -181,7 +181,7 @@ impl<'gc> Button<'gc> {
// Kill children that no longer exist in this state. // Kill children that no longer exist in this state.
for depth in removed_depths { for depth in removed_depths {
if let Some(child) = self.child_by_depth(depth) { if let Some(child) = self.child_by_depth(depth) {
self.remove_child(context, child, EnumSet::all()); self.remove_child(context, child, Lists::all());
} }
} }

View File

@ -5,7 +5,7 @@ use crate::display_object::button::Button;
use crate::display_object::movie_clip::MovieClip; use crate::display_object::movie_clip::MovieClip;
use crate::display_object::{Depth, DisplayObject, TDisplayObject}; use crate::display_object::{Depth, DisplayObject, TDisplayObject};
use crate::string_utils::swf_string_eq_ignore_case; use crate::string_utils::swf_string_eq_ignore_case;
use enumset::{EnumSet, EnumSetType}; use bitflags::bitflags;
use gc_arena::{Collect, MutationContext}; use gc_arena::{Collect, MutationContext};
use ruffle_macros::enum_trait_object; use ruffle_macros::enum_trait_object;
use std::cmp::Ordering; use std::cmp::Ordering;
@ -13,24 +13,25 @@ use std::collections::BTreeMap;
use std::fmt::Debug; use std::fmt::Debug;
use std::ops::RangeBounds; use std::ops::RangeBounds;
/// The three lists that a display object container is supposed to maintain. bitflags! {
#[derive(EnumSetType)] /// The three lists that a display object container is supposed to maintain.
pub enum Lists { pub struct Lists: u8 {
/// The list that determines the order in which children are rendered. /// The list that determines the order in which children are rendered.
/// ///
/// This is directly manipulated by AVM2 code. /// This is directly manipulated by AVM2 code.
Render, const RENDER = 1 << 0;
/// The list that determines the identity of children according to the /// The list that determines the identity of children according to the
/// timeline and AVM1 code. /// timeline and AVM1 code.
/// ///
/// Manipulations of the depth list are generally propagated to the render /// Manipulations of the depth list are generally propagated to the render
/// list, except in cases where children have been reordered by AVM2. /// list, except in cases where children have been reordered by AVM2.
Depth, const DEPTH = 1 << 1;
/// The list that determines the order in which childrens' actions are /// The list that determines the order in which childrens' actions are
/// executed. /// executed.
Execution, const EXECUTION = 1 << 2;
}
} }
#[enum_trait_object( #[enum_trait_object(
@ -149,7 +150,7 @@ pub trait TDisplayObjectContainer<'gc>:
&mut self, &mut self,
context: &mut UpdateContext<'_, 'gc, '_>, context: &mut UpdateContext<'_, 'gc, '_>,
child: DisplayObject<'gc>, child: DisplayObject<'gc>,
from_lists: EnumSet<Lists>, from_lists: Lists,
) -> bool; ) -> bool;
/// Remove a set of children identified by their render list indicies from /// Remove a set of children identified by their render list indicies from
@ -365,7 +366,7 @@ macro_rules! impl_display_object_container {
if let Some(old_parent) = child.parent() { if let Some(old_parent) = child.parent() {
if !DisplayObject::ptr_eq(old_parent, (*self).into()) { if !DisplayObject::ptr_eq(old_parent, (*self).into()) {
if let Some(mut old_parent) = old_parent.as_container() { if let Some(mut old_parent) = old_parent.as_container() {
old_parent.remove_child(context, child, EnumSet::all()); old_parent.remove_child(context, child, Lists::all());
} }
} }
} }
@ -395,7 +396,7 @@ macro_rules! impl_display_object_container {
&mut self, &mut self,
context: &mut UpdateContext<'_, 'gc, '_>, context: &mut UpdateContext<'_, 'gc, '_>,
child: DisplayObject<'gc>, child: DisplayObject<'gc>,
from_lists: EnumSet<Lists>, from_lists: Lists,
) -> bool { ) -> bool {
debug_assert!(DisplayObject::ptr_eq( debug_assert!(DisplayObject::ptr_eq(
child.parent().unwrap(), child.parent().unwrap(),
@ -404,11 +405,11 @@ macro_rules! impl_display_object_container {
let mut write = self.0.write(context.gc_context); let mut write = self.0.write(context.gc_context);
let removed_from_depth_list = from_lists.contains(Lists::Depth) let removed_from_depth_list = from_lists.contains(Lists::DEPTH)
&& write.$field.remove_child_from_depth_list(child); && write.$field.remove_child_from_depth_list(child);
let removed_from_render_list = from_lists.contains(Lists::Render) let removed_from_render_list = from_lists.contains(Lists::RENDER)
&& write.$field.remove_child_from_render_list(child); && write.$field.remove_child_from_render_list(child);
let removed_from_execution_list = from_lists.contains(Lists::Execution) let removed_from_execution_list = from_lists.contains(Lists::EXECUTION)
&& write.$field.remove_child_from_exec_list(context, child); && write.$field.remove_child_from_exec_list(context, child);
drop(write); drop(write);

View File

@ -8,6 +8,7 @@ use crate::avm2::{
StageObject as Avm2StageObject, TObject as Avm2TObject, Value as Avm2Value, StageObject as Avm2StageObject, TObject as Avm2TObject, Value as Avm2Value,
}; };
use crate::backend::audio::AudioStreamHandle; use crate::backend::audio::AudioStreamHandle;
use bitflags::bitflags;
use crate::avm1::activation::{Activation as Avm1Activation, ActivationIdentifier}; use crate::avm1::activation::{Activation as Avm1Activation, ActivationIdentifier};
use crate::character::Character; use crate::character::Character;
@ -24,7 +25,6 @@ use crate::shape_utils::DrawCommand;
use crate::tag_utils::{self, DecodeResult, SwfMovie, SwfSlice, SwfStream}; use crate::tag_utils::{self, DecodeResult, SwfMovie, SwfSlice, SwfStream};
use crate::types::{Degrees, Percent}; use crate::types::{Degrees, Percent};
use crate::vminterface::{AvmObject, AvmType, Instantiator}; use crate::vminterface::{AvmObject, AvmType, Instantiator};
use enumset::{EnumSet, EnumSetType};
use gc_arena::{Collect, Gc, GcCell, MutationContext}; use gc_arena::{Collect, Gc, GcCell, MutationContext};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::cell::{Ref, RefCell}; use std::cell::{Ref, RefCell};
@ -57,7 +57,7 @@ pub struct MovieClipData<'gc> {
clip_actions: Vec<ClipAction>, clip_actions: Vec<ClipAction>,
frame_scripts: Vec<Avm2FrameScript<'gc>>, frame_scripts: Vec<Avm2FrameScript<'gc>>,
has_button_clip_event: bool, has_button_clip_event: bool,
flags: EnumSet<MovieClipFlags>, flags: MovieClipFlags,
avm2_constructor: Option<Avm2Object<'gc>>, avm2_constructor: Option<Avm2Object<'gc>>,
drawing: Drawing, drawing: Drawing,
is_focusable: bool, is_focusable: bool,
@ -93,7 +93,7 @@ impl<'gc> MovieClip<'gc> {
clip_actions: Vec::new(), clip_actions: Vec::new(),
frame_scripts: Vec::new(), frame_scripts: Vec::new(),
has_button_clip_event: false, has_button_clip_event: false,
flags: EnumSet::empty(), flags: MovieClipFlags::empty(),
avm2_constructor: None, avm2_constructor: None,
drawing: Drawing::new(), drawing: Drawing::new(),
is_focusable: false, is_focusable: false,
@ -125,7 +125,7 @@ impl<'gc> MovieClip<'gc> {
clip_actions: Vec::new(), clip_actions: Vec::new(),
frame_scripts: Vec::new(), frame_scripts: Vec::new(),
has_button_clip_event: false, has_button_clip_event: false,
flags: MovieClipFlags::Playing.into(), flags: MovieClipFlags::PLAYING,
avm2_constructor: None, avm2_constructor: None,
drawing: Drawing::new(), drawing: Drawing::new(),
is_focusable: false, is_focusable: false,
@ -1159,9 +1159,9 @@ impl<'gc> MovieClip<'gc> {
.collect(); .collect();
for (_depth, child) in children { for (_depth, child) in children {
if !child.placed_by_script() { if !child.placed_by_script() {
self.remove_child(context, child, EnumSet::all()); self.remove_child(context, child, Lists::all());
} else { } else {
self.remove_child(context, child, Lists::Depth.into()); self.remove_child(context, child, Lists::DEPTH);
} }
} }
true true
@ -1533,10 +1533,10 @@ impl<'gc> MovieClip<'gc> {
if let Some(child) = read.container.get_depth(depth) { if let Some(child) = read.container.get_depth(depth) {
if !child.placed_by_script() { if !child.placed_by_script() {
drop(read); drop(read);
self.remove_child(context, child, EnumSet::all()); self.remove_child(context, child, Lists::all());
} else { } else {
drop(read); drop(read);
self.remove_child(context, child, Lists::Depth.into()); self.remove_child(context, child, Lists::DEPTH);
} }
} }
} }
@ -1826,7 +1826,7 @@ impl<'gc> MovieClipData<'gc> {
MovieClipStatic::with_data(0, movie.into(), total_frames), MovieClipStatic::with_data(0, movie.into(), total_frames),
); );
self.tag_stream_pos = 0; self.tag_stream_pos = 0;
self.flags = MovieClipFlags::Playing.into(); self.flags = MovieClipFlags::PLAYING;
self.current_frame = 0; self.current_frame = 0;
self.audio_stream = None; self.audio_stream = None;
self.container = ChildContainer::new(); self.container = ChildContainer::new();
@ -1845,23 +1845,23 @@ impl<'gc> MovieClipData<'gc> {
} }
fn playing(&self) -> bool { fn playing(&self) -> bool {
self.flags.contains(MovieClipFlags::Playing) self.flags.contains(MovieClipFlags::PLAYING)
} }
fn set_playing(&mut self, value: bool) { fn set_playing(&mut self, value: bool) {
if value { if value {
self.flags.insert(MovieClipFlags::Playing); self.flags |= MovieClipFlags::PLAYING;
} else { } else {
self.flags.remove(MovieClipFlags::Playing); self.flags -= MovieClipFlags::PLAYING;
} }
} }
fn programmatically_played(&self) -> bool { fn programmatically_played(&self) -> bool {
self.flags.contains(MovieClipFlags::ProgrammaticallyPlayed) self.flags.contains(MovieClipFlags::PROGRAMMATICALLY_PLAYED)
} }
fn set_programmatically_played(&mut self) { fn set_programmatically_played(&mut self) {
self.flags.insert(MovieClipFlags::ProgrammaticallyPlayed); self.flags |= MovieClipFlags::PROGRAMMATICALLY_PLAYED;
} }
fn play(&mut self) { fn play(&mut self) {
@ -2000,15 +2000,17 @@ impl<'gc> MovieClipData<'gc> {
} }
fn initialized(&self) -> bool { fn initialized(&self) -> bool {
self.flags.contains(MovieClipFlags::Initialized) self.flags.contains(MovieClipFlags::INITIALIZED)
} }
fn set_initialized(&mut self, value: bool) -> bool { fn set_initialized(&mut self, value: bool) -> bool {
let ret = self.flags.contains(MovieClipFlags::INITIALIZED);
if value { if value {
self.flags.insert(MovieClipFlags::Initialized) self.flags |= MovieClipFlags::INITIALIZED;
} else { } else {
self.flags.remove(MovieClipFlags::Initialized) self.flags -= MovieClipFlags::INITIALIZED;
} }
!ret
} }
/// Stops the audio stream if one is playing. /// Stops the audio stream if one is playing.
@ -2808,9 +2810,9 @@ impl<'gc, 'a> MovieClip<'gc> {
if let Some(child) = self.child_by_depth(remove_object.depth.into()) { if let Some(child) = self.child_by_depth(remove_object.depth.into()) {
if !child.placed_by_script() { if !child.placed_by_script() {
self.remove_child(context, child, EnumSet::all()); self.remove_child(context, child, Lists::all());
} else { } else {
self.remove_child(context, child, Lists::Depth.into()); self.remove_child(context, child, Lists::DEPTH);
} }
} }
@ -3061,20 +3063,21 @@ impl<'a> GotoPlaceObject<'a> {
} }
} }
/// Boolean state flags used by `MovieClip`. bitflags! {
#[derive(Debug, EnumSetType)] /// Boolean state flags used by `MovieClip`.
enum MovieClipFlags { struct MovieClipFlags: u8 {
/// Whether this `MovieClip` has run its initial frame. /// Whether this `MovieClip` has run its initial frame.
Initialized, const INITIALIZED = 1 << 0;
/// Whether this `MovieClip` is playing or stopped. /// Whether this `MovieClip` is playing or stopped.
Playing, const PLAYING = 1 << 1;
/// Whether this `MovieClip` has been played as a result of an AS3 command. /// Whether this `MovieClip` has been played as a result of an AS3 command.
/// ///
/// The AS3 `isPlaying` property is broken and yields false until you first /// The AS3 `isPlaying` property is broken and yields false until you first
/// call `play` to unbreak it. This flag tracks that bug. /// call `play` to unbreak it. This flag tracks that bug.
ProgrammaticallyPlayed, const PROGRAMMATICALLY_PLAYED = 1 << 2;
}
} }
/// Actions that are attached to a `MovieClip` event in /// Actions that are attached to a `MovieClip` event in
@ -3105,31 +3108,42 @@ impl ClipAction {
let action_data = SwfSlice::from(movie) let action_data = SwfSlice::from(movie)
.to_unbounded_subslice(other.action_data) .to_unbounded_subslice(other.action_data)
.unwrap(); .unwrap();
other.events.into_iter().map(move |event| Self {
let mut events = Vec::new();
let flags = other.events.bits();
let mut bit = 1u32;
while flags & !(bit - 1) != 0 {
if (flags & bit) != 0 {
events.push(ClipEventFlag::from_bits_truncate(bit));
}
bit <<= 1;
}
events.into_iter().map(move |event| Self {
event: match event { event: match event {
ClipEventFlag::Construct => ClipEvent::Construct, ClipEventFlag::CONSTRUCT => ClipEvent::Construct,
ClipEventFlag::Data => ClipEvent::Data, ClipEventFlag::DATA => ClipEvent::Data,
ClipEventFlag::DragOut => ClipEvent::DragOut, ClipEventFlag::DRAG_OUT => ClipEvent::DragOut,
ClipEventFlag::DragOver => ClipEvent::DragOver, ClipEventFlag::DRAG_OVER => ClipEvent::DragOver,
ClipEventFlag::EnterFrame => ClipEvent::EnterFrame, ClipEventFlag::ENTER_FRAME => ClipEvent::EnterFrame,
ClipEventFlag::Initialize => ClipEvent::Initialize, ClipEventFlag::INITIALIZE => ClipEvent::Initialize,
ClipEventFlag::KeyUp => ClipEvent::KeyUp, ClipEventFlag::KEY_UP => ClipEvent::KeyUp,
ClipEventFlag::KeyDown => ClipEvent::KeyDown, ClipEventFlag::KEY_DOWN => ClipEvent::KeyDown,
ClipEventFlag::KeyPress => ClipEvent::KeyPress { ClipEventFlag::KEY_PRESS => ClipEvent::KeyPress {
key_code: key_code key_code: key_code
.and_then(|k| ButtonKeyCode::try_from(k).ok()) .and_then(|k| ButtonKeyCode::try_from(k).ok())
.unwrap_or(ButtonKeyCode::Unknown), .unwrap_or(ButtonKeyCode::Unknown),
}, },
ClipEventFlag::Load => ClipEvent::Load, ClipEventFlag::LOAD => ClipEvent::Load,
ClipEventFlag::MouseUp => ClipEvent::MouseUp, ClipEventFlag::MOUSE_UP => ClipEvent::MouseUp,
ClipEventFlag::MouseDown => ClipEvent::MouseDown, ClipEventFlag::MOUSE_DOWN => ClipEvent::MouseDown,
ClipEventFlag::MouseMove => ClipEvent::MouseMove, ClipEventFlag::MOUSE_MOVE => ClipEvent::MouseMove,
ClipEventFlag::Press => ClipEvent::Press, ClipEventFlag::PRESS => ClipEvent::Press,
ClipEventFlag::RollOut => ClipEvent::RollOut, ClipEventFlag::ROLL_OUT => ClipEvent::RollOut,
ClipEventFlag::RollOver => ClipEvent::RollOver, ClipEventFlag::ROLL_OVER => ClipEvent::RollOver,
ClipEventFlag::Release => ClipEvent::Release, ClipEventFlag::RELEASE => ClipEvent::Release,
ClipEventFlag::ReleaseOutside => ClipEvent::ReleaseOutside, ClipEventFlag::RELEASE_OUTSIDE => ClipEvent::ReleaseOutside,
ClipEventFlag::Unload => ClipEvent::Unload, ClipEventFlag::UNLOAD => ClipEvent::Unload,
_ => unreachable!(),
}, },
action_data: action_data.clone(), action_data: action_data.clone(),
}) })

View File

@ -2,6 +2,7 @@ use crate::avm1::activation::{Activation, ActivationIdentifier};
use crate::avm1::debug::VariableDumper; use crate::avm1::debug::VariableDumper;
use crate::avm1::globals::system::SystemProperties; use crate::avm1::globals::system::SystemProperties;
use crate::avm1::object::Object; use crate::avm1::object::Object;
use crate::avm1::property::Attribute;
use crate::avm1::{Avm1, AvmString, ScriptObject, TObject, Timers, Value}; use crate::avm1::{Avm1, AvmString, ScriptObject, TObject, Timers, Value};
use crate::avm2::{Avm2, Domain as Avm2Domain}; use crate::avm2::{Avm2, Domain as Avm2Domain};
use crate::backend::input::{InputBackend, MouseCursor}; use crate::backend::input::{InputBackend, MouseCursor};
@ -23,7 +24,6 @@ use crate::property_map::PropertyMap;
use crate::tag_utils::SwfMovie; use crate::tag_utils::SwfMovie;
use crate::transform::TransformStack; use crate::transform::TransformStack;
use crate::vminterface::{AvmType, Instantiator}; use crate::vminterface::{AvmType, Instantiator};
use enumset::EnumSet;
use gc_arena::{make_arena, ArenaParameters, Collect, GcCell}; use gc_arena::{make_arena, ArenaParameters, Collect, GcCell};
use instant::Instant; use instant::Instant;
use log::info; use log::info;
@ -388,7 +388,7 @@ impl Player {
context.gc_context, context.gc_context,
key, key,
AvmString::new(context.gc_context, value).into(), AvmString::new(context.gc_context, value).into(),
EnumSet::empty(), Attribute::empty(),
); );
} }
Some(object.into()) Some(object.into())
@ -426,7 +426,7 @@ impl Player {
activation.context.gc_context, activation.context.gc_context,
"$version", "$version",
AvmString::new(activation.context.gc_context, version_string).into(), AvmString::new(activation.context.gc_context, version_string).into(),
EnumSet::empty(), Attribute::empty(),
); );
}); });

View File

@ -7,7 +7,6 @@ pub use crate::display_object::{
pub use crate::{ pub use crate::{
impl_display_object, impl_display_object_container, impl_display_object_sansbounds, impl_display_object, impl_display_object_container, impl_display_object_sansbounds,
}; };
pub use enumset::EnumSet;
pub use log::{error, info, trace, warn}; pub use log::{error, info, trace, warn};
pub use std::ops::{Bound, RangeBounds}; pub use std::ops::{Bound, RangeBounds};
pub use swf::Matrix; pub use swf::Matrix;

View File

@ -10,10 +10,10 @@ readme = "README.md"
description = "Read and write the Adobe Flash SWF file format." description = "Read and write the Adobe Flash SWF file format."
[dependencies] [dependencies]
bitflags = "1.2.1"
bitstream-io = "1.0.0" bitstream-io = "1.0.0"
byteorder = "1.4" byteorder = "1.4"
encoding_rs = "0.8.26" encoding_rs = "0.8.26"
enumset = "1.0.1"
num-derive = "0.3" num-derive = "0.3"
num-traits = "0.2" num-traits = "0.2"
libflate = {version = "1.0", optional = true} libflate = {version = "1.0", optional = true}

View File

@ -13,7 +13,6 @@ use crate::{
}; };
use bitstream_io::BitRead; use bitstream_io::BitRead;
use byteorder::{LittleEndian, ReadBytesExt}; use byteorder::{LittleEndian, ReadBytesExt};
use enumset::EnumSet;
use std::collections::HashSet; use std::collections::HashSet;
use std::io::{self, Read}; use std::io::{self, Read};
@ -2198,7 +2197,7 @@ impl<'a> Reader<'a> {
Ok(None) Ok(None)
} else { } else {
let mut length = self.read_u32()?; let mut length = self.read_u32()?;
let key_code = if events.contains(ClipEventFlag::KeyPress) { let key_code = if events.contains(ClipEventFlag::KEY_PRESS) {
// ActionData length includes the 1 byte key code. // ActionData length includes the 1 byte key code.
length -= 1; length -= 1;
Some(self.read_u8()?) Some(self.read_u8()?)
@ -2215,83 +2214,46 @@ impl<'a> Reader<'a> {
} }
} }
fn read_clip_event_flags(&mut self) -> Result<EnumSet<ClipEventFlag>> { fn read_clip_event_flags(&mut self) -> Result<ClipEventFlag> {
// TODO: Switch to a bitset. // TODO: Switch to a bitset.
let mut event_list = EnumSet::new(); let mut event_list = ClipEventFlag::empty();
let flags = self.read_u8()?; let flags = self.read_u8()?;
if flags & 0b1000_0000 != 0 { event_list.set(ClipEventFlag::KEY_UP, flags & 0b1000_0000 != 0);
event_list.insert(ClipEventFlag::KeyUp); event_list.set(ClipEventFlag::KEY_DOWN, flags & 0b0100_0000 != 0);
} event_list.set(ClipEventFlag::MOUSE_UP, flags & 0b0010_0000 != 0);
if flags & 0b0100_0000 != 0 { event_list.set(ClipEventFlag::MOUSE_DOWN, flags & 0b0001_0000 != 0);
event_list.insert(ClipEventFlag::KeyDown); event_list.set(ClipEventFlag::MOUSE_MOVE, flags & 0b0000_1000 != 0);
} event_list.set(ClipEventFlag::UNLOAD, flags & 0b0000_0100 != 0);
if flags & 0b0010_0000 != 0 { event_list.set(ClipEventFlag::ENTER_FRAME, flags & 0b0000_0010 != 0);
event_list.insert(ClipEventFlag::MouseUp); event_list.set(ClipEventFlag::LOAD, flags & 0b0000_0001 != 0);
}
if flags & 0b0001_0000 != 0 { if self.version > 5 {
event_list.insert(ClipEventFlag::MouseDown); let flags = self.read_u8()?;
} event_list.set(ClipEventFlag::DRAG_OVER, flags & 0b1000_0000 != 0);
if flags & 0b0000_1000 != 0 { event_list.set(ClipEventFlag::ROLL_OUT, flags & 0b0100_0000 != 0);
event_list.insert(ClipEventFlag::MouseMove); event_list.set(ClipEventFlag::ROLL_OVER, flags & 0b0010_0000 != 0);
} event_list.set(ClipEventFlag::RELEASE_OUTSIDE, flags & 0b0001_0000 != 0);
if flags & 0b0000_0100 != 0 { event_list.set(ClipEventFlag::RELEASE, flags & 0b0000_1000 != 0);
event_list.insert(ClipEventFlag::Unload); event_list.set(ClipEventFlag::PRESS, flags & 0b0000_0100 != 0);
} event_list.set(ClipEventFlag::INITIALIZE, flags & 0b0000_0010 != 0);
if flags & 0b0000_0010 != 0 { event_list.set(ClipEventFlag::DATA, flags & 0b0000_0001 != 0);
event_list.insert(ClipEventFlag::EnterFrame);
} let flags = self.read_u8()?;
if flags & 0b0000_0001 != 0 { // Construct was only added in SWF7, but it's not version-gated;
event_list.insert(ClipEventFlag::Load); // Construct events will still fire in SWF6 in a v7+ player. (#1424)
} event_list.set(ClipEventFlag::CONSTRUCT, flags & 0b0000_0100 != 0);
if self.version < 6 { event_list.set(ClipEventFlag::KEY_PRESS, flags & 0b0000_0010 != 0);
event_list.set(ClipEventFlag::DRAG_OUT, flags & 0b0000_0001 != 0);
self.read_u8()?;
} else {
// SWF19 pp. 48-50: For SWFv5, the ClipEventFlags only had 2 bytes of flags, // SWF19 pp. 48-50: For SWFv5, the ClipEventFlags only had 2 bytes of flags,
// with the 2nd byte reserved (all 0). // with the 2nd byte reserved (all 0).
// This was expanded to 4 bytes in SWFv6. // This was expanded to 4 bytes in SWFv6.
self.read_u8()?; self.read_u8()?;
} else {
let flags = self.read_u8()?;
if flags & 0b1000_0000 != 0 {
event_list.insert(ClipEventFlag::DragOver);
}
if flags & 0b0100_0000 != 0 {
event_list.insert(ClipEventFlag::RollOut);
}
if flags & 0b0010_0000 != 0 {
event_list.insert(ClipEventFlag::RollOver);
}
if flags & 0b0001_0000 != 0 {
event_list.insert(ClipEventFlag::ReleaseOutside);
}
if flags & 0b0000_1000 != 0 {
event_list.insert(ClipEventFlag::Release);
}
if flags & 0b0000_0100 != 0 {
event_list.insert(ClipEventFlag::Press);
}
if flags & 0b0000_0010 != 0 {
event_list.insert(ClipEventFlag::Initialize);
}
if flags & 0b0000_0001 != 0 {
event_list.insert(ClipEventFlag::Data);
}
if self.version < 6 {
self.read_u16()?;
} else {
let flags = self.read_u8()?;
if flags & 0b0000_0100 != 0 {
// Construct was only added in SWF7, but it's not version-gated;
// Construct events will still fire in SWF6 in a v7+ player. (#1424)
event_list.insert(ClipEventFlag::Construct);
}
if flags & 0b0000_0010 != 0 {
event_list.insert(ClipEventFlag::KeyPress);
}
if flags & 0b0000_0001 != 0 {
event_list.insert(ClipEventFlag::DragOut);
}
self.read_u8()?;
}
} }
Ok(event_list) Ok(event_list)
} }

View File

@ -2125,7 +2125,7 @@ pub fn tag_tests() -> Vec<TagTestData> {
background_color: None, background_color: None,
blend_mode: None, blend_mode: None,
clip_actions: Some(vec![ClipAction { clip_actions: Some(vec![ClipAction {
events: ClipEventFlag::EnterFrame.into(), events: ClipEventFlag::ENTER_FRAME,
key_code: None, key_code: None,
action_data: &[150, 6, 0, 0, 99, 108, 105, 112, 0, 38, 0], action_data: &[150, 6, 0, 0, 99, 108, 105, 112, 0, 38, 0],
}]), }]),
@ -2156,17 +2156,17 @@ pub fn tag_tests() -> Vec<TagTestData> {
blend_mode: None, blend_mode: None,
clip_actions: Some(vec![ clip_actions: Some(vec![
ClipAction { ClipAction {
events: ClipEventFlag::Press | ClipEventFlag::Release, events: ClipEventFlag::PRESS | ClipEventFlag::RELEASE,
key_code: None, key_code: None,
action_data: &[150, 3, 0, 0, 65, 0, 38, 0], action_data: &[150, 3, 0, 0, 65, 0, 38, 0],
}, },
ClipAction { ClipAction {
events: ClipEventFlag::KeyPress.into(), events: ClipEventFlag::KEY_PRESS,
key_code: Some(99), key_code: Some(99),
action_data: &[150, 3, 0, 0, 66, 0, 38, 0], action_data: &[150, 3, 0, 0, 66, 0, 38, 0],
}, },
ClipAction { ClipAction {
events: ClipEventFlag::EnterFrame.into(), events: ClipEventFlag::ENTER_FRAME,
key_code: None, key_code: None,
action_data: &[150, 3, 0, 0, 67, 0, 38, 0], action_data: &[150, 3, 0, 0, 67, 0, 38, 0],
}, },
@ -2326,12 +2326,12 @@ pub fn tag_tests() -> Vec<TagTestData> {
blend_mode: Some(BlendMode::Difference), blend_mode: Some(BlendMode::Difference),
clip_actions: Some(vec![ clip_actions: Some(vec![
ClipAction { ClipAction {
events: ClipEventFlag::ReleaseOutside | ClipEventFlag::RollOver, events: ClipEventFlag::RELEASE_OUTSIDE | ClipEventFlag::ROLL_OVER,
key_code: None, key_code: None,
action_data: &[0], action_data: &[0],
}, },
ClipAction { ClipAction {
events: ClipEventFlag::Data.into(), events: ClipEventFlag::DATA,
key_code: None, key_code: None,
action_data: &[150, 3, 0, 0, 66, 0, 38, 0], action_data: &[150, 3, 0, 0, 66, 0, 38, 0],
}, },

View File

@ -4,7 +4,7 @@
//! version 19 (henceforth SWF19): //! version 19 (henceforth SWF19):
//! https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf //! https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf
use crate::string::SwfStr; use crate::string::SwfStr;
use enumset::{EnumSet, EnumSetType}; use bitflags::bitflags;
use std::collections::HashSet; use std::collections::HashSet;
mod matrix; mod matrix;
@ -418,39 +418,40 @@ pub enum BlendMode {
/// An clip action (a.k.a. clip event) placed on a movieclip instance. /// An clip action (a.k.a. clip event) placed on a movieclip instance.
/// Created in the Flash IDE using `onClipEvent` or `on` blocks. /// Created in the Flash IDE using `onClipEvent` or `on` blocks.
/// ///
/// [SWF19 pp.37-38 ClipActionRecord](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=37) /// [SWF19 pp.37-38 ClipActionRecord](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=39)
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct ClipAction<'a> { pub struct ClipAction<'a> {
pub events: EnumSet<ClipEventFlag>, pub events: ClipEventFlag,
pub key_code: Option<KeyCode>, pub key_code: Option<KeyCode>,
pub action_data: &'a [u8], pub action_data: &'a [u8],
} }
/// An event that can be attached to a movieclip instance using bitflags! {
/// an `onClipEvent` or `on` block. /// An event that can be attached to a movieclip instance using
/// /// an `onClipEvent` or `on` block.
/// [SWF19 pp.48-50 ClipEvent](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=38) ///
#[derive(Debug, EnumSetType)] /// [SWF19 pp.48-50 ClipEvent](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=50)
pub enum ClipEventFlag { pub struct ClipEventFlag: u32 {
Construct, const CONSTRUCT = 1 << 0;
Data, const DATA = 1 << 1;
DragOut, const DRAG_OUT = 1 << 2;
DragOver, const DRAG_OVER = 1 << 3;
EnterFrame, const ENTER_FRAME = 1 << 4;
Initialize, const INITIALIZE = 1 << 5;
KeyUp, const KEY_UP = 1 << 6;
KeyDown, const KEY_DOWN = 1 << 7;
KeyPress, const KEY_PRESS = 1 << 8;
Load, const LOAD = 1 << 9;
MouseUp, const MOUSE_UP = 1 << 10;
MouseDown, const MOUSE_DOWN = 1 << 11;
MouseMove, const MOUSE_MOVE = 1 << 12;
Press, const PRESS = 1 << 13;
RollOut, const ROLL_OUT = 1 << 14;
RollOver, const ROLL_OVER = 1 << 15;
Release, const RELEASE = 1 << 16;
ReleaseOutside, const RELEASE_OUTSIDE = 1 << 17;
Unload, const UNLOAD = 1 << 18;
}
} }
/// A key code used in `ButtonAction` and `ClipAction` key press events. /// A key code used in `ButtonAction` and `ClipAction` key press events.

View File

@ -13,7 +13,6 @@ use crate::{
}; };
use bitstream_io::BitWrite; use bitstream_io::BitWrite;
use byteorder::{LittleEndian, WriteBytesExt}; use byteorder::{LittleEndian, WriteBytesExt};
use enumset::EnumSet;
use std::cmp::max; use std::cmp::max;
use std::io::{self, Write}; use std::io::{self, Write};
@ -2176,7 +2175,7 @@ impl<W: Write> Writer<W> {
fn write_clip_actions(&mut self, clip_actions: &[ClipAction]) -> Result<()> { fn write_clip_actions(&mut self, clip_actions: &[ClipAction]) -> Result<()> {
self.write_u16(0)?; // Reserved self.write_u16(0)?; // Reserved
{ {
let mut all_events = EnumSet::new(); let mut all_events = ClipEventFlag::empty();
for action in clip_actions { for action in clip_actions {
all_events |= action.events; all_events |= action.events;
} }
@ -2200,31 +2199,31 @@ impl<W: Write> Writer<W> {
Ok(()) Ok(())
} }
fn write_clip_event_flags(&mut self, clip_events: EnumSet<ClipEventFlag>) -> Result<()> { fn write_clip_event_flags(&mut self, clip_events: ClipEventFlag) -> Result<()> {
// TODO: Assert proper version. // TODO: Assert proper version.
let version = self.version; let version = self.version;
let mut bits = self.bits(); let mut bits = self.bits();
bits.write_bit(clip_events.contains(ClipEventFlag::KeyUp))?; bits.write_bit(clip_events.contains(ClipEventFlag::KEY_UP))?;
bits.write_bit(clip_events.contains(ClipEventFlag::KeyDown))?; bits.write_bit(clip_events.contains(ClipEventFlag::KEY_DOWN))?;
bits.write_bit(clip_events.contains(ClipEventFlag::MouseUp))?; bits.write_bit(clip_events.contains(ClipEventFlag::MOUSE_UP))?;
bits.write_bit(clip_events.contains(ClipEventFlag::MouseDown))?; bits.write_bit(clip_events.contains(ClipEventFlag::MOUSE_DOWN))?;
bits.write_bit(clip_events.contains(ClipEventFlag::MouseMove))?; bits.write_bit(clip_events.contains(ClipEventFlag::MOUSE_MOVE))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Unload))?; bits.write_bit(clip_events.contains(ClipEventFlag::UNLOAD))?;
bits.write_bit(clip_events.contains(ClipEventFlag::EnterFrame))?; bits.write_bit(clip_events.contains(ClipEventFlag::ENTER_FRAME))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Load))?; bits.write_bit(clip_events.contains(ClipEventFlag::LOAD))?;
bits.write_bit(clip_events.contains(ClipEventFlag::DragOver))?; bits.write_bit(clip_events.contains(ClipEventFlag::DRAG_OVER))?;
bits.write_bit(clip_events.contains(ClipEventFlag::RollOut))?; bits.write_bit(clip_events.contains(ClipEventFlag::ROLL_OUT))?;
bits.write_bit(clip_events.contains(ClipEventFlag::RollOver))?; bits.write_bit(clip_events.contains(ClipEventFlag::ROLL_OVER))?;
bits.write_bit(clip_events.contains(ClipEventFlag::ReleaseOutside))?; bits.write_bit(clip_events.contains(ClipEventFlag::RELEASE_OUTSIDE))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Release))?; bits.write_bit(clip_events.contains(ClipEventFlag::RELEASE))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Press))?; bits.write_bit(clip_events.contains(ClipEventFlag::PRESS))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Initialize))?; bits.write_bit(clip_events.contains(ClipEventFlag::INITIALIZE))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Data))?; bits.write_bit(clip_events.contains(ClipEventFlag::DATA))?;
if version >= 6 { if version >= 6 {
bits.write_ubits(5, 0)?; bits.write_ubits(5, 0)?;
bits.write_bit(clip_events.contains(ClipEventFlag::Construct))?; bits.write_bit(clip_events.contains(ClipEventFlag::CONSTRUCT))?;
bits.write_bit(clip_events.contains(ClipEventFlag::KeyPress))?; bits.write_bit(clip_events.contains(ClipEventFlag::KEY_PRESS))?;
bits.write_bit(clip_events.contains(ClipEventFlag::DragOut))?; bits.write_bit(clip_events.contains(ClipEventFlag::DRAG_OUT))?;
bits.write_ubits(8, 0)?; bits.write_ubits(8, 0)?;
} }
Ok(()) Ok(())