avm2: Fix avmplus.describeTypeJSON bugs and add test
This commit is contained in:
parent
34fb2e4f48
commit
981dedafd2
|
@ -7,6 +7,7 @@ use crate::avm2::property::Property;
|
|||
use crate::avm2::ClassObject;
|
||||
|
||||
use crate::avm2::{Activation, Error, Object, Value};
|
||||
use crate::avm2_stub_method;
|
||||
|
||||
// Implements `avmplus.describeTypeJSON`
|
||||
pub fn describe_type_json<'gc>(
|
||||
|
@ -54,12 +55,17 @@ pub fn describe_type_json<'gc>(
|
|||
object.set_public_property("isStatic", is_static.into(), activation)?;
|
||||
|
||||
let traits = describe_internal_body(activation, class_obj, is_static, flags)?;
|
||||
object.set_public_property("traits", traits.into(), activation)?;
|
||||
if flags.contains(DescribeTypeFlags::INCLUDE_TRAITS) {
|
||||
object.set_public_property("traits", traits.into(), activation)?;
|
||||
} else {
|
||||
object.set_public_property("traits", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
Ok(object.into())
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct DescribeTypeFlags: u32 {
|
||||
const HIDE_NSURI_METHODS = 1 << 0;
|
||||
const INCLUDE_BASES = 1 << 1;
|
||||
|
@ -92,20 +98,40 @@ fn describe_internal_body<'gc>(
|
|||
.construct(activation, &[])?;
|
||||
|
||||
let bases = ArrayObject::empty(activation)?.as_array_object().unwrap();
|
||||
|
||||
let interfaces = ArrayObject::empty(activation)?.as_array_object().unwrap();
|
||||
|
||||
let variables = ArrayObject::empty(activation)?.as_array_object().unwrap();
|
||||
|
||||
let accessors = ArrayObject::empty(activation)?.as_array_object().unwrap();
|
||||
|
||||
let methods = ArrayObject::empty(activation)?.as_array_object().unwrap();
|
||||
|
||||
traits.set_public_property("bases", bases.into(), activation)?;
|
||||
traits.set_public_property("interfaces", interfaces.into(), activation)?;
|
||||
traits.set_public_property("variables", variables.into(), activation)?;
|
||||
traits.set_public_property("accessors", accessors.into(), activation)?;
|
||||
traits.set_public_property("methods", methods.into(), activation)?;
|
||||
if flags.contains(DescribeTypeFlags::INCLUDE_BASES) {
|
||||
traits.set_public_property("bases", bases.into(), activation)?;
|
||||
} else {
|
||||
traits.set_public_property("bases", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
if flags.contains(DescribeTypeFlags::INCLUDE_INTERFACES) {
|
||||
traits.set_public_property("interfaces", interfaces.into(), activation)?;
|
||||
} else {
|
||||
traits.set_public_property("interfaces", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
if flags.contains(DescribeTypeFlags::INCLUDE_VARIABLES) {
|
||||
traits.set_public_property("variables", variables.into(), activation)?;
|
||||
} else {
|
||||
traits.set_public_property("variables", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
if flags.contains(DescribeTypeFlags::INCLUDE_ACCESSORS) {
|
||||
traits.set_public_property("accessors", accessors.into(), activation)?;
|
||||
} else {
|
||||
traits.set_public_property("accessors", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
if flags.contains(DescribeTypeFlags::INCLUDE_METHODS) {
|
||||
traits.set_public_property("methods", methods.into(), activation)?;
|
||||
} else {
|
||||
traits.set_public_property("methods", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
let mut bases_array = bases
|
||||
.as_array_storage_mut(activation.context.gc_context)
|
||||
|
@ -140,8 +166,6 @@ fn describe_internal_body<'gc>(
|
|||
bases_array.push(super_name.into());
|
||||
current_super_obj = super_obj.superclass_object();
|
||||
}
|
||||
} else {
|
||||
traits.set_public_property("bases", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
// When we're describing a Class object, we use the class vtable (which hides instance properties)
|
||||
|
@ -165,8 +189,6 @@ fn describe_internal_body<'gc>(
|
|||
.to_qualified_name(activation.context.gc_context);
|
||||
interfaces_array.push(interface_name.into());
|
||||
}
|
||||
} else {
|
||||
traits.set_public_property("interfaces", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
// Implement the weird 'HIDE_NSURI_METHODS' behavior from avmplus:
|
||||
|
@ -246,6 +268,9 @@ fn describe_internal_body<'gc>(
|
|||
|
||||
match prop {
|
||||
Property::ConstSlot { slot_id } | Property::Slot { slot_id } => {
|
||||
if !flags.contains(DescribeTypeFlags::INCLUDE_VARIABLES) {
|
||||
continue;
|
||||
}
|
||||
let prop_class_name = vtable
|
||||
.slot_class_name(*slot_id, activation.context.gc_context)?
|
||||
.to_qualified_name_or_star(activation.context.gc_context);
|
||||
|
@ -266,15 +291,28 @@ fn describe_internal_body<'gc>(
|
|||
variable.set_public_property("name", prop_name.into(), activation)?;
|
||||
variable.set_public_property("type", prop_class_name.into(), activation)?;
|
||||
variable.set_public_property("access", access.into(), activation)?;
|
||||
variable.set_public_property(
|
||||
"uri",
|
||||
uri.map_or(Value::Null, |u| u.into()),
|
||||
activation,
|
||||
)?;
|
||||
|
||||
if let Some(metadata) = trait_metadata {
|
||||
variable.set_public_property("metadata", Value::Null, activation)?;
|
||||
|
||||
if flags.contains(DescribeTypeFlags::INCLUDE_METADATA) {
|
||||
let metadata_object = ArrayObject::empty(activation)?;
|
||||
write_metadata(metadata_object, &metadata, activation)?;
|
||||
if let Some(metadata) = trait_metadata {
|
||||
write_metadata(metadata_object, &metadata, activation)?;
|
||||
}
|
||||
variable.set_public_property("metadata", metadata_object.into(), activation)?;
|
||||
}
|
||||
|
||||
variables_array.push(variable.into());
|
||||
}
|
||||
Property::Method { disp_id } => {
|
||||
if !flags.contains(DescribeTypeFlags::INCLUDE_METHODS) {
|
||||
continue;
|
||||
}
|
||||
let method = vtable
|
||||
.get_full_method(*disp_id)
|
||||
.unwrap_or_else(|| panic!("Missing method for id {disp_id:?}"));
|
||||
|
@ -316,15 +354,22 @@ fn describe_internal_body<'gc>(
|
|||
activation,
|
||||
)?;
|
||||
|
||||
if let Some(uri) = uri {
|
||||
method_obj.set_public_property("uri", uri.into(), activation)?;
|
||||
}
|
||||
method_obj.set_public_property(
|
||||
"uri",
|
||||
uri.map_or(Value::Null, |u| u.into()),
|
||||
activation,
|
||||
)?;
|
||||
|
||||
let params = write_params(&method.method, activation)?;
|
||||
method_obj.set_public_property("parameters", params.into(), activation)?;
|
||||
if let Some(metadata) = trait_metadata {
|
||||
|
||||
method_obj.set_public_property("metadata", Value::Null, activation)?;
|
||||
|
||||
if flags.contains(DescribeTypeFlags::INCLUDE_METADATA) {
|
||||
let metadata_object = ArrayObject::empty(activation)?;
|
||||
write_metadata(metadata_object, &metadata, activation)?;
|
||||
if let Some(metadata) = trait_metadata {
|
||||
write_metadata(metadata_object, &metadata, activation)?;
|
||||
}
|
||||
method_obj.set_public_property(
|
||||
"metadata",
|
||||
metadata_object.into(),
|
||||
|
@ -334,6 +379,9 @@ fn describe_internal_body<'gc>(
|
|||
methods_array.push(method_obj.into());
|
||||
}
|
||||
Property::Virtual { get, set } => {
|
||||
if !flags.contains(DescribeTypeFlags::INCLUDE_ACCESSORS) {
|
||||
continue;
|
||||
}
|
||||
let access = match (get, set) {
|
||||
(Some(_), Some(_)) => "readwrite",
|
||||
(Some(_), None) => "readonly",
|
||||
|
@ -383,9 +431,11 @@ fn describe_internal_body<'gc>(
|
|||
accessor_obj.set_public_property("access", access.into(), activation)?;
|
||||
accessor_obj.set_public_property("type", accessor_type.into(), activation)?;
|
||||
accessor_obj.set_public_property("declaredBy", declared_by.into(), activation)?;
|
||||
if let Some(uri) = uri {
|
||||
accessor_obj.set_public_property("uri", uri.into(), activation)?;
|
||||
}
|
||||
accessor_obj.set_public_property(
|
||||
"uri",
|
||||
uri.map_or(Value::Null, |u| u.into()),
|
||||
activation,
|
||||
)?;
|
||||
|
||||
let metadata_object = ArrayObject::empty(activation)?;
|
||||
|
||||
|
@ -401,12 +451,16 @@ fn describe_internal_body<'gc>(
|
|||
}
|
||||
}
|
||||
|
||||
if metadata_object.as_array_storage().unwrap().length() > 0 {
|
||||
if flags.contains(DescribeTypeFlags::INCLUDE_METADATA)
|
||||
&& metadata_object.as_array_storage().unwrap().length() > 0
|
||||
{
|
||||
accessor_obj.set_public_property(
|
||||
"metadata",
|
||||
metadata_object.into(),
|
||||
activation,
|
||||
)?;
|
||||
} else {
|
||||
accessor_obj.set_public_property("metadata", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
accessors_array.push(accessor_obj.into());
|
||||
|
@ -427,6 +481,14 @@ fn describe_internal_body<'gc>(
|
|||
traits.set_public_property("constructor", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
if flags.contains(DescribeTypeFlags::INCLUDE_METADATA) {
|
||||
avm2_stub_method!(activation, "avmplus.describeTypeJSON", "top-level metadata");
|
||||
let metadata_object = ArrayObject::empty(activation)?;
|
||||
traits.set_public_property("metadata", metadata_object.into(), activation)?;
|
||||
} else {
|
||||
traits.set_public_property("metadata", Value::Null, activation)?;
|
||||
}
|
||||
|
||||
Ok(traits)
|
||||
}
|
||||
|
||||
|
@ -438,8 +500,7 @@ fn write_params<'gc>(
|
|||
let mut params_array = params
|
||||
.as_array_storage_mut(activation.context.gc_context)
|
||||
.unwrap();
|
||||
for (i, param) in method.signature().iter().enumerate() {
|
||||
let index = i + 1;
|
||||
for param in method.signature() {
|
||||
let param_type_name = param
|
||||
.param_type_name
|
||||
.to_qualified_name_or_star(activation.context.gc_context);
|
||||
|
@ -449,7 +510,6 @@ fn write_params<'gc>(
|
|||
.classes()
|
||||
.object
|
||||
.construct(activation, &[])?;
|
||||
param_obj.set_public_property("index", index.into(), activation)?;
|
||||
param_obj.set_public_property("type", param_type_name.into(), activation)?;
|
||||
param_obj.set_public_property("optional", optional.into(), activation)?;
|
||||
params_array.push(param_obj.into());
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package {
|
||||
public class Test {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
import com.ruffle.RuffleTest;
|
||||
import flash.utils.getDefinitionByName;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.system.System;
|
||||
import avmplus.MyHelper;
|
||||
|
||||
var allFlags = [
|
||||
0,
|
||||
avmplus.INCLUDE_TRAITS | avmplus.HIDE_NSURI_METHODS,
|
||||
avmplus.INCLUDE_TRAITS | avmplus.INCLUDE_BASES,
|
||||
avmplus.INCLUDE_TRAITS | avmplus.INCLUDE_INTERFACES,
|
||||
avmplus.INCLUDE_TRAITS | avmplus.INCLUDE_VARIABLES,
|
||||
avmplus.INCLUDE_TRAITS | avmplus.INCLUDE_ACCESSORS,
|
||||
avmplus.INCLUDE_TRAITS | avmplus.INCLUDE_METHODS,
|
||||
avmplus.INCLUDE_TRAITS | avmplus.INCLUDE_METADATA,
|
||||
avmplus.INCLUDE_TRAITS | avmplus.INCLUDE_CONSTRUCTOR,
|
||||
avmplus.INCLUDE_TRAITS,
|
||||
avmplus.INCLUDE_TRAITS | avmplus.USE_ITRAITS,
|
||||
avmplus.INCLUDE_TRAITS | avmplus.HIDE_OBJECT
|
||||
];
|
||||
|
||||
for each (var flags in allFlags) {
|
||||
trace("Describing with flags: " + flags);
|
||||
printObject(MyHelper.descType(new RuffleTest("first", false), flags));
|
||||
trace();
|
||||
}
|
||||
|
||||
function printObject(obj:Object, numTabs:int = 0):void {
|
||||
var tabs:String = "";
|
||||
for (var i:int = 0; i < numTabs; ++i) {
|
||||
tabs += "\t";
|
||||
}
|
||||
var keys = [];
|
||||
for (var k:* in obj) {
|
||||
keys.push(k);
|
||||
}
|
||||
keys.sort();
|
||||
for each (var key in keys) {
|
||||
var v:* = obj[key];
|
||||
row(tabs + key + " = " + v);
|
||||
if (v) {
|
||||
if (key == "methods" || key == "accessors" || key == "variables") {
|
||||
v.sort(function(m1, m2) {
|
||||
if (m1.name < m2.name) {
|
||||
return -1;
|
||||
|
||||
}
|
||||
else if (m1.name > m2.name) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
printObject(v, numTabs + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function row(...cols):void {
|
||||
trace(cols.join(","));
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package avmplus {
|
||||
public class MyHelper {
|
||||
public static function descType(param1:*, param2:uint) : Object
|
||||
{
|
||||
return describeTypeJSON(param1,param2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package com.ruffle {
|
||||
public interface MyInterface {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.ruffle {
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class RuffleBase {
|
||||
public function RuffleBase() {
|
||||
}
|
||||
|
||||
public var baseMyVar;
|
||||
public const baseMyConst;
|
||||
|
||||
[BaseMyCustomMeta]
|
||||
public function get baseGetterOnly():String {
|
||||
return "";
|
||||
};
|
||||
public function set baseSetterOnly(val:Boolean) {
|
||||
}
|
||||
|
||||
public function get baseGetterAndSetter():Boolean {
|
||||
return true;
|
||||
}
|
||||
public function set baseGetterandSetter(val:Boolean) {
|
||||
}
|
||||
|
||||
public function baseMyMethod() {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.ruffle {
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class RuffleTest extends RuffleBase implements MyInterface {
|
||||
public function RuffleTest(first:String, second:Boolean) {
|
||||
}
|
||||
|
||||
public var myVar;
|
||||
public const myConst;
|
||||
|
||||
[MyCustomMeta]
|
||||
public function get getterOnly():String {
|
||||
return "";
|
||||
};
|
||||
public function set setterOnly(val:Boolean) {
|
||||
}
|
||||
|
||||
public function get getterAndSetter():Boolean {
|
||||
return true;
|
||||
}
|
||||
public function set getterandSetter(val:Boolean) {
|
||||
}
|
||||
|
||||
public function myMethod(first:String, second:ByteArray) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,288 @@
|
|||
Describing with flags: 0
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = null
|
||||
|
||||
Describing with flags: 257
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = [object Object]
|
||||
accessors = null
|
||||
bases = null
|
||||
constructor = null
|
||||
interfaces = null
|
||||
metadata = null
|
||||
methods = null
|
||||
variables = null
|
||||
|
||||
Describing with flags: 258
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = [object Object]
|
||||
accessors = null
|
||||
bases = com.ruffle::RuffleBase,Object
|
||||
0 = com.ruffle::RuffleBase
|
||||
1 = Object
|
||||
constructor = null
|
||||
interfaces = null
|
||||
metadata = null
|
||||
methods = null
|
||||
variables = null
|
||||
|
||||
Describing with flags: 260
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = [object Object]
|
||||
accessors = null
|
||||
bases = null
|
||||
constructor = null
|
||||
interfaces = com.ruffle::MyInterface
|
||||
0 = com.ruffle::MyInterface
|
||||
metadata = null
|
||||
methods = null
|
||||
variables = null
|
||||
|
||||
Describing with flags: 264
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = [object Object]
|
||||
accessors = null
|
||||
bases = null
|
||||
constructor = null
|
||||
interfaces = null
|
||||
metadata = null
|
||||
methods = null
|
||||
variables = [object Object],[object Object],[object Object],[object Object]
|
||||
0 = [object Object]
|
||||
access = readonly
|
||||
metadata = null
|
||||
name = baseMyConst
|
||||
type = *
|
||||
uri = null
|
||||
1 = [object Object]
|
||||
access = readwrite
|
||||
metadata = null
|
||||
name = baseMyVar
|
||||
type = *
|
||||
uri = null
|
||||
2 = [object Object]
|
||||
access = readonly
|
||||
metadata = null
|
||||
name = myConst
|
||||
type = *
|
||||
uri = null
|
||||
3 = [object Object]
|
||||
access = readwrite
|
||||
metadata = null
|
||||
name = myVar
|
||||
type = *
|
||||
uri = null
|
||||
|
||||
Describing with flags: 272
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = [object Object]
|
||||
accessors = [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
|
||||
0 = [object Object]
|
||||
access = readonly
|
||||
declaredBy = com.ruffle::RuffleBase
|
||||
metadata = null
|
||||
name = baseGetterAndSetter
|
||||
type = Boolean
|
||||
uri = null
|
||||
1 = [object Object]
|
||||
access = readonly
|
||||
declaredBy = com.ruffle::RuffleBase
|
||||
metadata = null
|
||||
name = baseGetterOnly
|
||||
type = String
|
||||
uri = null
|
||||
2 = [object Object]
|
||||
access = writeonly
|
||||
declaredBy = com.ruffle::RuffleBase
|
||||
metadata = null
|
||||
name = baseGetterandSetter
|
||||
type = Boolean
|
||||
uri = null
|
||||
3 = [object Object]
|
||||
access = writeonly
|
||||
declaredBy = com.ruffle::RuffleBase
|
||||
metadata = null
|
||||
name = baseSetterOnly
|
||||
type = Boolean
|
||||
uri = null
|
||||
4 = [object Object]
|
||||
access = readonly
|
||||
declaredBy = com.ruffle::RuffleTest
|
||||
metadata = null
|
||||
name = getterAndSetter
|
||||
type = Boolean
|
||||
uri = null
|
||||
5 = [object Object]
|
||||
access = readonly
|
||||
declaredBy = com.ruffle::RuffleTest
|
||||
metadata = null
|
||||
name = getterOnly
|
||||
type = String
|
||||
uri = null
|
||||
6 = [object Object]
|
||||
access = writeonly
|
||||
declaredBy = com.ruffle::RuffleTest
|
||||
metadata = null
|
||||
name = getterandSetter
|
||||
type = Boolean
|
||||
uri = null
|
||||
7 = [object Object]
|
||||
access = writeonly
|
||||
declaredBy = com.ruffle::RuffleTest
|
||||
metadata = null
|
||||
name = setterOnly
|
||||
type = Boolean
|
||||
uri = null
|
||||
bases = null
|
||||
constructor = null
|
||||
interfaces = null
|
||||
metadata = null
|
||||
methods = null
|
||||
variables = null
|
||||
|
||||
Describing with flags: 288
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = [object Object]
|
||||
accessors = null
|
||||
bases = null
|
||||
constructor = null
|
||||
interfaces = null
|
||||
metadata = null
|
||||
methods = [object Object],[object Object],[object Object],[object Object],[object Object]
|
||||
0 = [object Object]
|
||||
declaredBy = com.ruffle::RuffleBase
|
||||
metadata = null
|
||||
name = baseMyMethod
|
||||
parameters =
|
||||
returnType = *
|
||||
uri = null
|
||||
1 = [object Object]
|
||||
declaredBy = Object
|
||||
metadata = null
|
||||
name = hasOwnProperty
|
||||
parameters = [object Object]
|
||||
0 = [object Object]
|
||||
optional = true
|
||||
type = *
|
||||
returnType = Boolean
|
||||
uri = http://adobe.com/AS3/2006/builtin
|
||||
2 = [object Object]
|
||||
declaredBy = Object
|
||||
metadata = null
|
||||
name = isPrototypeOf
|
||||
parameters = [object Object]
|
||||
0 = [object Object]
|
||||
optional = true
|
||||
type = *
|
||||
returnType = Boolean
|
||||
uri = http://adobe.com/AS3/2006/builtin
|
||||
3 = [object Object]
|
||||
declaredBy = com.ruffle::RuffleTest
|
||||
metadata = null
|
||||
name = myMethod
|
||||
parameters = [object Object],[object Object]
|
||||
0 = [object Object]
|
||||
optional = false
|
||||
type = String
|
||||
1 = [object Object]
|
||||
optional = false
|
||||
type = flash.utils::ByteArray
|
||||
returnType = *
|
||||
uri = null
|
||||
4 = [object Object]
|
||||
declaredBy = Object
|
||||
metadata = null
|
||||
name = propertyIsEnumerable
|
||||
parameters = [object Object]
|
||||
0 = [object Object]
|
||||
optional = true
|
||||
type = *
|
||||
returnType = Boolean
|
||||
uri = http://adobe.com/AS3/2006/builtin
|
||||
variables = null
|
||||
|
||||
Describing with flags: 320
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = [object Object]
|
||||
accessors = null
|
||||
bases = null
|
||||
constructor = null
|
||||
interfaces = null
|
||||
metadata =
|
||||
methods = null
|
||||
variables = null
|
||||
|
||||
Describing with flags: 384
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = [object Object]
|
||||
accessors = null
|
||||
bases = null
|
||||
constructor = [object Object],[object Object]
|
||||
0 = [object Object]
|
||||
optional = false
|
||||
type = String
|
||||
1 = [object Object]
|
||||
optional = false
|
||||
type = Boolean
|
||||
interfaces = null
|
||||
metadata = null
|
||||
methods = null
|
||||
variables = null
|
||||
|
||||
Describing with flags: 256
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = [object Object]
|
||||
accessors = null
|
||||
bases = null
|
||||
constructor = null
|
||||
interfaces = null
|
||||
metadata = null
|
||||
methods = null
|
||||
variables = null
|
||||
|
||||
Describing with flags: 768
|
||||
|
||||
Describing with flags: 1280
|
||||
isDynamic = false
|
||||
isFinal = false
|
||||
isStatic = false
|
||||
name = com.ruffle::RuffleTest
|
||||
traits = [object Object]
|
||||
accessors = null
|
||||
bases = null
|
||||
constructor = null
|
||||
interfaces = null
|
||||
metadata = null
|
||||
methods = null
|
||||
variables = null
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
num_ticks = 1
|
Loading…
Reference in New Issue