avm2: Introduce ActionScript entry-points

Previously all the `.as` files compiled into `playerglobal.swf`
were detected automatically using `walkdir`. While this might be
convenient, it can cause unexpected results when untracked `.as`
files exist. So instead, introduce two entry points - `stubs.as`
and `globals.as`, which include all stub ActionScript definitions,
and actual class implementations, respectively. This also simplifies
the `playerglobal.swf` build script a bit.
This commit is contained in:
relrelb 2022-06-17 16:25:47 +03:00 committed by relrelb
parent 4978158638
commit 786e8d92fb
10 changed files with 42 additions and 60 deletions

1
Cargo.lock generated
View File

@ -256,7 +256,6 @@ name = "build_playerglobal"
version = "0.1.0"
dependencies = [
"swf",
"walkdir",
]
[[package]]

View File

@ -3,8 +3,5 @@ name = "build_playerglobal"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
swf = { path = "../../swf" }
walkdir = "2.3.2"

View File

@ -8,7 +8,6 @@ use swf::DoAbc;
use swf::Header;
use swf::SwfStr;
use swf::Tag;
use walkdir::WalkDir;
/// If successful, returns a list of paths that were used. If this is run
/// from a build script, these paths should be printed with
@ -24,42 +23,21 @@ pub fn build_playerglobal(
// This will create 'playerglobal.abc', 'playerglobal.cpp', and 'playerglobal.h'
// in `out_dir`
let mut cmd = Command::new("java");
cmd.args(&[
"-classpath",
&asc_path.to_string_lossy(),
"macromedia.asc.embedding.ScriptCompiler",
"-optimize",
"-outdir",
&out_dir.to_string_lossy(),
"-out",
"playerglobal",
]);
for entry in WalkDir::new(&classes_dir) {
let entry = entry?;
if entry.path().extension().and_then(|e| e.to_str()) != Some("as") {
continue;
}
// Files like `uint.stub.as` are stubs - they're referenced by
// other classes that we need to compile, but the real definition
// is in Ruffle itself (in Rust code).
// As a result, we don't emit them into the final SWF (but we do
// provide them to asc.jar with '-import' to link against).
if entry
.path()
.file_stem()
.unwrap()
.to_string_lossy()
.ends_with(".stub")
{
cmd.arg("-import");
}
cmd.arg(entry.path());
}
println!("Compiling: {:?}", cmd);
let code = cmd.status()?;
let code = Command::new("java")
.args(&[
"-classpath",
&asc_path.to_string_lossy(),
"macromedia.asc.embedding.ScriptCompiler",
"-optimize",
"-outdir",
&out_dir.to_string_lossy(),
"-out",
"playerglobal",
"-import",
&classes_dir.join("stubs.as").to_string_lossy(),
&classes_dir.join("globals.as").to_string_lossy(),
])
.status()?;
if !code.success() {
return Err(format!("Compiling failed with code {:?}", code).into());
}

View File

@ -1,7 +1,7 @@
# Ruffle AVM2 globals
# AVM2 globals
This directory contains implementations of Flash global
definitions (e.g. `Object`, `flash.geom.Point`, `flash.utils.getDefinitionByName`)
This directory contains implementations of global definitions
(e.g. `Object`, `flash.geom.Point`, `flash.utils.getDefinitionByName`).
WARNING: Do *not* implement classes by copying their (decompiled) ActionScript
from the Adobe Flash `playerglobal.swf`. This would violate copyright by making
@ -10,17 +10,15 @@ Adobe's `playerglobal.swf` uses native methods that Ruffle doesn't implement).
Currently, globals are implemented in one of two ways:
1) As pure-Rust code in files like `system.rs`. These are normal Rust
modules, and are used from `core/src/avm2/global.rs`
2) As ActionScript class definitions like `flash/geom/Point.as`.
These files are automatically compiled into a `playerglobal.swf`
file at build time, which is included into the final Ruffle binary
modules, and are used from `core/src/avm2/global.rs`.
2) As ActionScript code like `flash/geom/Point.as`.
The files included from `globals.as` are compiled into a `playerglobal.swf`
file at build time, which is included in the final Ruffle binary
and loaded during player initialization.
ActionScript files can be marked as 'stubs' by giving them the suffix
'.stub.as' instead of '.as' (e.g. 'Number.stub.as'). Stub classes
can be referenced from other '.as' files, but they will not be included
in the final 'playerglobal.swf'. This is useful when you need to write
a '.as' file that references a class defined in Rust - you can create
ActionScript files included from `stubs.as` can be referenced from other `.as` files,
but they will not be included in the final `playerglobal.swf`. This is useful when you need to write
an `.as` file that references a class defined in Rust - you can create
a stub class without needing to port the entire pre-existing class
to ActionScript.
@ -38,7 +36,7 @@ by the Flash VM, which Ruffle does not implement.
Java must be installed for the build process to complete.
ActionScript classes are processed by the `core/build\_playerglobal`
ActionScript classes are processed by the `core/build_playerglobal`
The tool first uses 'asc.jar'
from the Flex SDK to compile these ActionScript files into
@ -50,15 +48,15 @@ The produced ABC files are then combined into the final
`playerglobal.swf` (which is written out into the build directory,
and not checked in to Git).
The `core/build\_playerglobal` tool is automatically run by `core`'s build script
The `core/build_playerglobal` tool is automatically run by `core`'s build script
when any of our ActionScript classes are changed.
## Limitations
* Only pure ActionScript classes are currently supported. Classes with
'native' methods are not yet supported.
* 'Special' classes which are loaded early during Ruffle initialization
(e.g. 'Object', 'Function', 'Class') cannot currently
be implemented in 'playerglobal', since Ruffle initializes them in a special
way. However, virtually all classes in the 'flash' package are initialized
in a 'normal' way, and are eligible for implementation in 'playerglobal'
* 'Special' classes which are loaded early during player initialization
(e.g. `Object`, `Function`, `Class`) cannot currently
be implemented in `playerglobal`, since they are initialized in a special
way. However, virtually all classes in the `flash` package are initialized
in a 'normal' way, and are eligible for implementation in `playerglobal`.

View File

@ -0,0 +1,3 @@
include "flash/geom/Point.as"
include "flash/geom/Rectangle.as"
include "flash/text/AntiAliasType.as"

View File

@ -0,0 +1,7 @@
// These are stubs - the actual classes are defined in Rust.
// `Object.as` must come first since the other classes depend on it.
include "Object.as"
include "Boolean.as"
include "Number.as"
include "String.as"