[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r12334: Code cleanups and rearrangem
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r12334: Code cleanups and rearrangements to simplify design. |
Date: |
Sat, 24 Jul 2010 19:32:46 +0200 |
User-agent: |
Bazaar (2.0.3) |
------------------------------------------------------------
revno: 12334 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Sat 2010-07-24 19:32:46 +0200
message:
Code cleanups and rearrangements to simplify design.
Split swf_function into Function and Function2 but preserve same
functionality.
Documentation.
No new features or functional changes.
added:
libcore/Function2.cpp
libcore/Function2.h
renamed:
libcore/swf_function.cpp => libcore/Function.cpp
libcore/swf_function.h => libcore/Function.h
modified:
libcore/Makefile.am
libcore/UserFunction.h
libcore/builtin_function.h
libcore/parser/action_buffer.cpp
libcore/swf/SWF.cpp
libcore/swf/SWF.h
libcore/swf/tag_loaders.cpp
libcore/vm/ASHandlers.cpp
libcore/vm/ASHandlers.h
libcore/vm/ActionExec.cpp
libcore/vm/ActionExec.h
libcore/Function.cpp
libcore/Function.h
=== renamed file 'libcore/swf_function.cpp' => 'libcore/Function.cpp'
--- a/libcore/swf_function.cpp 2010-07-23 08:10:09 +0000
+++ b/libcore/Function.cpp 2010-07-24 15:35:06 +0000
@@ -17,92 +17,53 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "log.h"
-#include "swf_function.h"
+#include "Function.h"
#include "fn_call.h"
-#include "MovieClip.h"
#include "action_buffer.h"
-#include "ActionExec.h" // for operator()
+#include "ActionExec.h"
#include "VM.h"
#include "NativeFunction.h"
#include "Global_as.h"
#include "namedStrings.h"
#include "CallStack.h"
-#include <typeinfo>
-#include <iostream>
-#include <string>
+#include "DisplayObject.h"
namespace gnash {
-namespace {
-
- /// Add properties to an 'arguments' object.
- //
- /// The 'arguments' variable is an array with an additional
- /// 'callee' member, set to the function being called.
- as_object* getArguments(swf_function& callee, as_object& args,
- const fn_call& fn, as_object* caller);
-}
-
-swf_function::swf_function(const action_buffer& ab, as_environment& env,
+Function::Function(const action_buffer& ab, as_environment& env,
size_t start, const ScopeStack& scopeStack)
:
UserFunction(getGlobal(env)),
- m_action_buffer(ab),
_env(env),
+ _action_buffer(ab),
_scopeStack(scopeStack),
_startPC(start),
- _length(0),
- _isFunction2(false),
- _registerCount(0),
- _function2Flags(0)
-{
- assert( _startPC < m_action_buffer.size() );
-
- // We're stuck initializing our own prototype at the moment.
- as_object* proto = getGlobal(env).createObject();
- proto->init_member(NSV::PROP_CONSTRUCTOR, this);
- init_member(NSV::PROP_PROTOTYPE, proto);
- init_member(NSV::PROP_CONSTRUCTOR,
as_function::getFunctionConstructor());
-}
-
-
-/// Exception safe (scoped) as_environment's target changer
-//
-/// This class partially helps fixing an SWF5 scoping issue.
-/// Completing the fix would likely reduce complexity of the
-/// code too, in particular the concept of an 'original target'
-/// in as_environment seems bogus, see setProperty.as, the
-/// failure of setTarget("") construct in SWF5.
-///
-struct TargetGuard
-{
- as_environment& env;
- DisplayObject* from;
- DisplayObject* from_orig;
-
- // @param ch : target to set temporarely
- // @param och : original target to set temporarily
- TargetGuard(as_environment& e, DisplayObject* ch, DisplayObject* och)
- :
- env(e),
- from(env.get_target()),
- from_orig(env.get_original_target())
- {
- env.set_target(ch);
- env.set_original_target(och);
- }
-
-
- ~TargetGuard()
- {
- env.set_target(from);
- env.set_original_target(from_orig);
- }
-};
+ _length(0)
+{
+ assert( _startPC < _action_buffer.size() );
+}
+
+TargetGuard::TargetGuard(as_environment& e, DisplayObject* ch,
+ DisplayObject* och)
+ :
+ env(e),
+ from(env.get_target()),
+ from_orig(env.get_original_target())
+{
+ env.set_target(ch);
+ env.set_original_target(och);
+}
+
+
+TargetGuard::~TargetGuard()
+{
+ env.set_target(from);
+ env.set_original_target(from_orig);
+}
// Dispatch.
as_value
-swf_function::call(const fn_call& fn)
+Function::call(const fn_call& fn)
{
// Extract caller before pushing ourself on the call stack
VM& vm = getVM(fn);
@@ -142,173 +103,40 @@
/// (target, in particular).
TargetGuard targetGuard(_env, target, orig_target);
- if (!_isFunction2) {
-
- // Conventional function.
-
- // Push the arguments onto the local frame.
- for (size_t i=0, n=_args.size(); i<n; ++i)
- {
- assert(_args[i].reg == 0);
- if (i < fn.nargs) {
- setLocal(cf, _args[i].name, fn.arg(i));
- }
- else {
- // Still declare named arguments, even if
- // they are not passed from caller
- // See bug #22203
- declareLocal(cf, _args[i].name);
- }
- }
-
- // Add 'this'
- setLocal(cf, NSV::PROP_THIS, fn.this_ptr ? fn.this_ptr : as_value());
-
- as_object* super = fn.super ? fn.super :
- fn.this_ptr ? fn.this_ptr->get_super() : 0;
-
- // Add 'super' (SWF6+ only)
- if (super && swfversion > 5) {
- setLocal(cf, NSV::PROP_SUPER, super);
- }
-
- // Add 'arguments'
- as_object* args = getGlobal(fn).createArray();
- string_table& st = getStringTable(fn);
- // Put 'arguments' in a local var.
- setLocal(cf, st.find("arguments"),
- getArguments(*this, *args, fn, caller));
- }
- else
- {
- // function2: most args go in registers; any others get pushed.
-
- // Handle the implicit args.
- // @@ why start at 1 ? Note that starting at 0 makes
- // intro.swf movie fail to play correctly.
- size_t current_reg(1);
-
- // This is us. TODO: why do we have to query the VM to get
- // what are effectively our own resources?
-
- // If this is not suppressed it is either placed in a register
- // or set as a local variable, but not both.
- if (!(_function2Flags & SUPPRESS_THIS)) {
- if (_function2Flags & PRELOAD_THIS) {
- // preload 'this' into a register.
- // TODO: check whether it should be undefined or null
- // if this_ptr is null.
- cf.setLocalRegister(current_reg, fn.this_ptr);
- ++current_reg;
- }
- else {
- // Put 'this' in a local var.
- setLocal(cf, NSV::PROP_THIS,
- fn.this_ptr ? fn.this_ptr : as_value());
- }
- }
-
- // This works slightly differently from 'super' and 'this'. The
- // arguments are only ever either placed in the register or a
- // local variable, but if both preload and suppress arguments flags
- // are set, an empty array is still placed to the register.
- // This seems like a bug in the reference player.
- if (!(_function2Flags & SUPPRESS_ARGUMENTS) ||
- (_function2Flags & PRELOAD_ARGUMENTS)) {
-
- as_object* args = getGlobal(fn).createArray();
-
- if (!(_function2Flags & SUPPRESS_ARGUMENTS)) {
- getArguments(*this, *args, fn, caller);
- }
-
- if (_function2Flags & PRELOAD_ARGUMENTS) {
- // preload 'arguments' into a register.
- cf.setLocalRegister(current_reg, args);
- ++current_reg;
- }
- else {
- string_table& st = getStringTable(fn);
- // Put 'arguments' in a local var.
- setLocal(cf, st.find("arguments"), args);
- }
-
- }
-
- // If super is not suppressed it is either placed in a register
- // or set as a local variable, but not both.
- if (swfversion > 5 && !(_function2Flags & SUPPRESS_SUPER)) {
-
- // Put 'super' in a register (SWF6+ only).
- // TOCHECK: should we still set it if not available ?
- as_object* super = fn.super ? fn.super :
- fn.this_ptr ? fn.this_ptr->get_super() : 0;
-
- if (super && (_function2Flags & PRELOAD_SUPER)) {
- cf.setLocalRegister(current_reg, super);
- current_reg++;
- }
- else if (super) {
- setLocal(cf, NSV::PROP_SUPER, super);
- }
- }
-
- if (_function2Flags & PRELOAD_ROOT) {
- // Put '_root' (if any) in a register.
- DisplayObject* tgtch = _env.get_target();
- if (tgtch) {
- // NOTE: _lockroot will be handled by
getAsRoot()
- as_object* r = getObject(tgtch->getAsRoot());
- cf.setLocalRegister(current_reg, r);
- ++current_reg;
- }
- }
-
- if (_function2Flags & PRELOAD_PARENT) {
- DisplayObject* tgtch = _env.get_target();
- if (tgtch) {
- as_object* parent = getObject(tgtch->get_parent());
- cf.setLocalRegister(current_reg, parent);
- ++current_reg;
- }
- }
-
- if (_function2Flags & PRELOAD_GLOBAL) {
- // Put '_global' in a register.
- as_object* global = vm.getGlobal();
- cf.setLocalRegister(current_reg, global);
- ++current_reg;
- }
-
- // Handle the explicit args.
- // This must be done after implicit ones,
- // as the explicit override the implicits:
- // see swfdec/definefunction2-override
- for (size_t i = 0, n = _args.size(); i < n; ++i) {
- // not a register, declare as local
- if (!_args[i].reg) {
- if (i < fn.nargs) {
- // Conventional arg passing: create a
local var.
- setLocal(cf, _args[i].name, fn.arg(i));
- }
- else {
- // Still declare named arguments, even
if
- // they are not passed from caller
- // See bug #22203
- declareLocal(cf, _args[i].name);
- }
- }
- else {
- if (i < fn.nargs) {
- // Pass argument into a register.
- const int reg = _args[i].reg;
- cf.setLocalRegister(reg, fn.arg(i));
- }
- // If no argument was passed, no need to setup a register
- // I guess.
- }
- }
- }
+ // Conventional function.
+
+ // Push the arguments onto the local frame.
+ for (size_t i=0, n=_args.size(); i<n; ++i)
+ {
+ assert(_args[i].reg == 0);
+ if (i < fn.nargs) {
+ setLocal(cf, _args[i].name, fn.arg(i));
+ }
+ else {
+ // Still declare named arguments, even if
+ // they are not passed from caller
+ // See bug #22203
+ declareLocal(cf, _args[i].name);
+ }
+ }
+
+ // Add 'this'
+ setLocal(cf, NSV::PROP_THIS, fn.this_ptr ? fn.this_ptr : as_value());
+
+ as_object* super = fn.super ? fn.super :
+ fn.this_ptr ? fn.this_ptr->get_super() : 0;
+
+ // Add 'super' (SWF6+ only)
+ if (super && swfversion > 5) {
+ setLocal(cf, NSV::PROP_SUPER, super);
+ }
+
+ // Add 'arguments'
+ as_object* args = getGlobal(fn).createArray();
+ string_table& st = getStringTable(fn);
+
+ // Put 'arguments' in a local var.
+ setLocal(cf, st.find("arguments"), getArguments(*this, *args, fn, caller));
// Execute the actions.
// Do this in a try block to proper drop the pushed call frame
@@ -325,16 +153,14 @@
}
void
-swf_function::set_length(int len)
+Function::setLength(size_t len)
{
- assert(len >= 0);
- assert(_startPC+len <= m_action_buffer.size());
+ assert(_startPC + len <= _action_buffer.size());
_length = len;
}
-#ifdef GNASH_USE_GC
void
-swf_function::markReachableResources() const
+Function::markReachableResources() const
{
// Mark scope stack objects
for (ScopeStack::const_iterator i = _scopeStack.begin(),
@@ -348,12 +174,9 @@
// Invoke parent class marker
markAsObjectReachable();
}
-#endif // GNASH_USE_GC
-
-namespace {
as_object*
-getArguments(swf_function& callee, as_object& args, const fn_call& fn,
+getArguments(Function& callee, as_object& args, const fn_call& fn,
as_object* caller)
{
@@ -367,6 +190,5 @@
}
-}
} // end of gnash namespace
=== renamed file 'libcore/swf_function.h' => 'libcore/Function.h'
--- a/libcore/swf_function.h 2010-07-23 13:16:23 +0000
+++ b/libcore/Function.h 2010-07-24 15:35:06 +0000
@@ -34,102 +34,85 @@
namespace gnash {
-/// SWF-defined Function
-class swf_function : public UserFunction
+class TargetGuard
+{
+public:
+
+ // @param ch : target to set temporarely
+ // @param och : original target to set temporarily
+ TargetGuard(as_environment& e, DisplayObject* ch, DisplayObject* och);
+ ~TargetGuard();
+
+private:
+
+ as_environment& env;
+ DisplayObject* from;
+ DisplayObject* from_orig;
+
+};
+
+/// A simple SWF-defined Function
+//
+/// This represents a callable Function defined in a SWF. The basic version
+/// creates a scope in which and 'arguments' array, 'this', 'super', and the
+/// expected argument names are defined.
+//
+/// For a more advanced function, see Function2.
+class Function : public UserFunction
{
public:
typedef std::vector<as_object*> ScopeStack;
- enum SWFDefineFunction2Flags
- {
- /// Bind one register to "this"
- PRELOAD_THIS = 0x01, // 1
-
- /// No "this" variable accessible by-name
- SUPPRESS_THIS = 0x02, // 2
-
- /// Bind one register to "arguments"
- PRELOAD_ARGUMENTS = 0x04, // 4
-
- /// No "argument" variable accessible by-name
- SUPPRESS_ARGUMENTS = 0x08, // 8
-
- /// Bind one register to "super"
- PRELOAD_SUPER = 0x10, // 16
-
- /// No "super" variable accessible by-name
- SUPPRESS_SUPER = 0x20, // 32
-
- /// Bind one register to "_root"
- PRELOAD_ROOT = 0x40, // 64
-
- /// Bind one register to "_parent"
- PRELOAD_PARENT = 0x80, // 128
-
- /// Bind one register to "_global"
- //
- /// TODO: check this.
- /// See:
- /// http://www.m2osw.com/swf_alexref.html#action_declare_function2
- /// Looks like flags would look swapped
- PRELOAD_GLOBAL = 256 // 0x100
-
- };
-
/// \brief
/// Create an ActionScript function as defined in an
/// action_buffer starting at offset 'start'
//
- swf_function(const action_buffer& ab, as_environment& env, size_t start,
+ Function(const action_buffer& ab, as_environment& env, size_t start,
const ScopeStack& with_stack);
- virtual ~swf_function() {}
+ virtual ~Function() {}
- const ScopeStack& getScopeStack() const
- {
+ const ScopeStack& getScopeStack() const {
return _scopeStack;
}
- const action_buffer& getActionBuffer() const
- {
- return m_action_buffer;
+ const action_buffer& getActionBuffer() const {
+ return _action_buffer;
}
- size_t getStartPC() const
- {
+ size_t getStartPC() const {
return _startPC;
}
- size_t getLength() const
- {
+ size_t getLength() const {
return _length;
}
- void set_is_function2() { _isFunction2 = true; }
-
- size_t registers() const {
- return _registerCount;
- }
-
- void set_local_register_count(boost::uint8_t ct) {
- assert(_isFunction2);
- _registerCount = ct;
- }
-
- void set_function2_flags(boost::uint16_t flags) {
- assert(_isFunction2);
- _function2Flags = flags;
- }
-
- void add_arg(boost::uint8_t arg_register, string_table::key name)
- {
- assert(arg_register == 0 || _isFunction2 == true);
- _args.push_back(Argument(arg_register, name));
+ /// Get the number of registers required for function execution.
+ //
+ /// For ordinary Functions this is always 0.
+ virtual boost::uint8_t registers() const {
+ return 0;
+ }
+
+ /// Add an expected argument for the function.
+ //
+ /// For ordinary Functions the register is disregarded. This is only
+ /// relevant for Function2s.
+ //
+ /// All argument names are declared as variables in the function scope,
+ /// whether the argument is passed or not.
+ //
+ /// @param reg The register for the argument.
+ /// @param name The name of the argument.
+ void add_arg(boost::uint8_t reg, string_table::key name) {
+ _args.push_back(Argument(reg, name));
}
- void set_length(int len);
+ /// Set the length in bytes of the function code.
+ void setLength(size_t len);
/// Dispatch.
virtual as_value call(const fn_call& fn);
@@ -143,14 +126,25 @@
virtual void markReachableResources() const;
#endif // GNASH_USE_GC
-private:
+protected:
+
+ struct Argument
+ {
+ Argument(boost::uint8_t r, string_table::key n) : reg(r), name(n) {}
+ boost::uint8_t reg;
+ string_table::key name;
+ };
- /// Action buffer containing the function definition
- const action_buffer& m_action_buffer;
+ std::vector<Argument> _args;
/// @@ might need some kind of ref count here, but beware cycles
as_environment& _env;
+private:
+
+ /// Action buffer containing the function definition
+ const action_buffer& _action_buffer;
+
/// Scope stack on function definition.
ScopeStack _scopeStack;
@@ -166,25 +160,16 @@
/// to a DoAction block
size_t _length;
- struct Argument
- {
- Argument(boost::uint8_t r, string_table::key n) : reg(r), name(n) {}
- boost::uint8_t reg;
- string_table::key name;
- };
-
- std::vector<Argument> _args;
- bool _isFunction2;
- boost::uint8_t _registerCount;
-
- /// used by function2 to control implicit arg register assignments
- //
- /// See
- /// http://sswf.sourceforge.net/SWFalexref.html#action_declare_function2
- boost::uint16_t _function2Flags;
};
+/// Add properties to an 'arguments' object.
+//
+/// The 'arguments' variable is an array with an additional
+/// 'callee' member, set to the function being called.
+as_object* getArguments(Function& callee, as_object& args,
+ const fn_call& fn, as_object* caller);
+
} // end of gnash namespace
=== added file 'libcore/Function2.cpp'
--- a/libcore/Function2.cpp 1970-01-01 00:00:00 +0000
+++ b/libcore/Function2.cpp 2010-07-24 13:44:22 +0000
@@ -0,0 +1,229 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+// Foundation, Inc
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "Function2.h"
+
+#include "log.h"
+#include "fn_call.h"
+#include "action_buffer.h"
+#include "ActionExec.h"
+#include "VM.h"
+#include "NativeFunction.h"
+#include "Global_as.h"
+#include "namedStrings.h"
+#include "CallStack.h"
+#include "MovieClip.h"
+#include "DisplayObject.h"
+
+namespace gnash {
+
+Function2::Function2(const action_buffer& ab, as_environment& env,
+ size_t start, const ScopeStack& scopeStack)
+ :
+ Function(ab, env, start, scopeStack),
+ _registerCount(0),
+ _function2Flags(0)
+{
+}
+
+// Dispatch.
+as_value
+Function2::call(const fn_call& fn)
+{
+ // Extract caller before pushing ourself on the call stack
+ VM& vm = getVM(fn);
+
+ as_object* caller = vm.calling() ? &vm.currentCall().function() : 0;
+
+ // Set up local stack frame, for parameters and locals.
+ FrameGuard guard(getVM(fn), *this);
+ CallFrame& cf = guard.callFrame();
+
+ DisplayObject* target = _env.get_target();
+ DisplayObject* orig_target = _env.get_original_target();
+
+ // Some features are version-dependant.
+ const int swfversion = getSWFVersion(fn);
+
+ if (swfversion < 6) {
+ // In SWF5, when 'this' is a DisplayObject it becomes
+ // the target for this function call.
+ // See actionscript.all/setProperty.as
+ //
+ if (fn.this_ptr) {
+ DisplayObject* ch = get<DisplayObject>(fn.this_ptr);
+ if (ch) {
+ target = ch;
+ orig_target = ch;
+ }
+ }
+ }
+
+ /// This is only needed for SWF5 (temp switch of target)
+ /// We do always and base 'target' value on SWF version.
+ /// TODO: simplify code by maybe using a custom as_environment
+ /// instead, so to get an "original" target being
+ /// the one set now (rather then the really original one)
+ /// TODO: test scope when calling functions defined in another timeline
+ /// (target, in particular).
+ TargetGuard targetGuard(_env, target, orig_target);
+
+ // function2: most args go in registers; any others get pushed.
+
+ // Handle the implicit args.
+ // @@ why start at 1 ? Note that starting at 0 makes
+ // intro.swf movie fail to play correctly.
+ size_t current_reg(1);
+
+ // This is us. TODO: why do we have to query the VM to get
+ // what are effectively our own resources?
+
+ // If this is not suppressed it is either placed in a register
+ // or set as a local variable, but not both.
+ if (!(_function2Flags & SUPPRESS_THIS)) {
+ if (_function2Flags & PRELOAD_THIS) {
+ // preload 'this' into a register.
+ // TODO: check whether it should be undefined or null
+ // if this_ptr is null.
+ cf.setLocalRegister(current_reg, fn.this_ptr);
+ ++current_reg;
+ }
+ else {
+ // Put 'this' in a local var.
+ setLocal(cf, NSV::PROP_THIS,
+ fn.this_ptr ? fn.this_ptr : as_value());
+ }
+ }
+
+ // This works slightly differently from 'super' and 'this'. The
+ // arguments are only ever either placed in the register or a
+ // local variable, but if both preload and suppress arguments flags
+ // are set, an empty array is still placed to the register.
+ // This seems like a bug in the reference player.
+ if (!(_function2Flags & SUPPRESS_ARGUMENTS) ||
+ (_function2Flags & PRELOAD_ARGUMENTS)) {
+
+ as_object* args = getGlobal(fn).createArray();
+
+ if (!(_function2Flags & SUPPRESS_ARGUMENTS)) {
+ getArguments(*this, *args, fn, caller);
+ }
+
+ if (_function2Flags & PRELOAD_ARGUMENTS) {
+ // preload 'arguments' into a register.
+ cf.setLocalRegister(current_reg, args);
+ ++current_reg;
+ }
+ else {
+ string_table& st = getStringTable(fn);
+ // Put 'arguments' in a local var.
+ setLocal(cf, st.find("arguments"), args);
+ }
+
+ }
+
+ // If super is not suppressed it is either placed in a register
+ // or set as a local variable, but not both.
+ if (swfversion > 5 && !(_function2Flags & SUPPRESS_SUPER)) {
+
+ // Put 'super' in a register (SWF6+ only).
+ // TOCHECK: should we still set it if not available ?
+ as_object* super = fn.super ? fn.super :
+ fn.this_ptr ? fn.this_ptr->get_super() : 0;
+
+ if (super && (_function2Flags & PRELOAD_SUPER)) {
+ cf.setLocalRegister(current_reg, super);
+ current_reg++;
+ }
+ else if (super) {
+ setLocal(cf, NSV::PROP_SUPER, super);
+ }
+ }
+
+ if (_function2Flags & PRELOAD_ROOT) {
+ // Put '_root' (if any) in a register.
+ DisplayObject* tgtch = _env.get_target();
+ if (tgtch) {
+ // NOTE: _lockroot will be handled by getAsRoot()
+ as_object* r = getObject(tgtch->getAsRoot());
+ cf.setLocalRegister(current_reg, r);
+ ++current_reg;
+ }
+ }
+
+ if (_function2Flags & PRELOAD_PARENT) {
+ DisplayObject* tgtch = _env.get_target();
+ if (tgtch) {
+ as_object* parent = getObject(tgtch->get_parent());
+ cf.setLocalRegister(current_reg, parent);
+ ++current_reg;
+ }
+ }
+
+ if (_function2Flags & PRELOAD_GLOBAL) {
+ // Put '_global' in a register.
+ as_object* global = vm.getGlobal();
+ cf.setLocalRegister(current_reg, global);
+ ++current_reg;
+ }
+
+ // Handle the explicit args.
+ // This must be done after implicit ones,
+ // as the explicit override the implicits:
+ // see swfdec/definefunction2-override
+ for (size_t i = 0, n = _args.size(); i < n; ++i) {
+ // not a register, declare as local
+ if (!_args[i].reg) {
+ if (i < fn.nargs) {
+ // Conventional arg passing: create a local var.
+ setLocal(cf, _args[i].name, fn.arg(i));
+ }
+ else {
+ // Still declare named arguments, even if
+ // they are not passed from caller
+ // See bug #22203
+ declareLocal(cf, _args[i].name);
+ }
+ }
+ else {
+ if (i < fn.nargs) {
+ // Pass argument into a register.
+ const int reg = _args[i].reg;
+ cf.setLocalRegister(reg, fn.arg(i));
+ }
+ // If no argument was passed, no need to setup a register
+ // I guess.
+ }
+ }
+
+ // Execute the actions.
+ // Do this in a try block to proper drop the pushed call frame
+ // in case of problems (most interesting action limits)
+ try {
+ as_value result;
+ ActionExec exec(*this, _env, &result, fn.this_ptr);
+ exec();
+ return result;
+ }
+ catch (ActionLimitException& ale) {
+ throw;
+ }
+}
+
+} // end of gnash namespace
+
=== added file 'libcore/Function2.h'
--- a/libcore/Function2.h 1970-01-01 00:00:00 +0000
+++ b/libcore/Function2.h 2010-07-24 13:44:22 +0000
@@ -0,0 +1,116 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+// Foundation, Inc
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef GNASH_FUNCTION2_H
+#define GNASH_FUNCTION2_H
+
+#include <vector>
+#include <cassert>
+#include <string>
+
+#include "Function.h"
+#include "smart_ptr.h"
+
+// Forward declarations
+namespace gnash {
+ class action_buffer;
+ class as_object;
+}
+
+namespace gnash {
+
+/// Function2 adds extra sauce to ordinary Functions.
+//
+/// The Function2 was introduced in version 6 of the player. Differences from
+/// ordinary functions are:
+/// 1. Up to 256 local registers.
+/// 2. Ability to suppress super, this, arguments
+/// 3. Ability to store super, this, arguments, _global, _root, and _parent
+/// in registers.
+class Function2 : public Function
+{
+
+public:
+
+ enum DefineFunction2Flags
+ {
+ /// Bind one register to "this"
+ PRELOAD_THIS = 0x01,
+
+ /// No "this" variable accessible by name
+ SUPPRESS_THIS = 0x02,
+
+ /// Bind one register to "arguments"
+ PRELOAD_ARGUMENTS = 0x04,
+
+ /// No "argument" variable accessible by name
+ SUPPRESS_ARGUMENTS = 0x08,
+
+ /// Bind one register to "super"
+ PRELOAD_SUPER = 0x10,
+
+ /// No "super" variable accessible by name
+ SUPPRESS_SUPER = 0x20,
+
+ /// Bind one register to "_root"
+ PRELOAD_ROOT = 0x40,
+
+ /// Bind one register to "_parent"
+ PRELOAD_PARENT = 0x80,
+
+ /// Bind one register to "_global"
+ PRELOAD_GLOBAL = 256
+ };
+
+ // Create a function defined in a DefineFunction2 opcode.
+ Function2(const action_buffer& ab, as_environment& env, size_t start,
+ const ScopeStack& with_stack);
+
+ virtual ~Function2() {}
+
+ /// Return the number of registers to allocate for this function.
+ virtual boost::uint8_t registers() const {
+ return _registerCount;
+ }
+
+ void setRegisterCount(boost::uint8_t ct) {
+ _registerCount = ct;
+ }
+
+ void setFlags(boost::uint16_t flags) {
+ _function2Flags = flags;
+ }
+
+ /// Dispatch.
+ virtual as_value call(const fn_call& fn);
+
+private:
+
+ /// The number of registers required.
+ boost::uint8_t _registerCount;
+
+ /// Used to control implicit arg register assignments
+ boost::uint16_t _function2Flags;
+
+};
+
+
+} // end of gnash namespace
+
+#endif
+
=== modified file 'libcore/Makefile.am'
--- a/libcore/Makefile.am 2010-07-23 12:49:43 +0000
+++ b/libcore/Makefile.am 2010-07-24 13:44:22 +0000
@@ -118,7 +118,8 @@
swf/StartSoundTag.cpp \
swf/SetTabIndexTag.cpp \
swf/StreamSoundBlockTag.cpp \
- swf_function.cpp \
+ Function.cpp \
+ Function2.cpp \
Video.cpp \
StreamProvider.cpp \
Button.cpp \
@@ -213,7 +214,8 @@
swf/StreamSoundBlockTag.h \
swf/ScriptLimitsTag.h \
swf_event.h \
- swf_function.h \
+ Function.h \
+ Function2.h \
Timers.h \
Video.h \
MovieLoader.h \
=== modified file 'libcore/UserFunction.h'
--- a/libcore/UserFunction.h 2010-07-23 07:18:03 +0000
+++ b/libcore/UserFunction.h 2010-07-24 13:44:22 +0000
@@ -30,7 +30,7 @@
//
/// Gnash has two types of UserFunction:
//
-/// 1. swf_function: functions parsed from a SWF
+/// 1. Function: functions parsed from a SWF
/// 2. builtin_function: functions implemented in C++ as though they were
/// These are used to implement what the API functions that the proprietary
/// player implements in a startup script.
@@ -42,7 +42,7 @@
//
/// Only Function2 functions require local registers; for all others
/// the value should be 0.
- virtual size_t registers() const = 0;
+ virtual boost::uint8_t registers() const = 0;
protected:
=== modified file 'libcore/builtin_function.h'
--- a/libcore/builtin_function.h 2010-07-22 12:37:56 +0000
+++ b/libcore/builtin_function.h 2010-07-24 13:44:22 +0000
@@ -59,7 +59,7 @@
/// Return the number of registers required for function execution
//
/// Gnash's C++ implementations of AS functions don't need any registers!
- virtual size_t registers() const {
+ virtual boost::uint8_t registers() const {
return 0;
}
=== modified file 'libcore/parser/action_buffer.cpp'
--- a/libcore/parser/action_buffer.cpp 2010-02-08 08:00:15 +0000
+++ b/libcore/parser/action_buffer.cpp 2010-07-24 14:38:36 +0000
@@ -180,7 +180,7 @@
ss << "<unknown>[0x]" << action_id << endl;
}
else {
- ss << ash[action_id].getName();
+ ss << ash[action_id].getType();
}
// Show instruction argument(s).
=== modified file 'libcore/swf/SWF.cpp'
--- a/libcore/swf/SWF.cpp 2010-01-11 06:41:38 +0000
+++ b/libcore/swf/SWF.cpp 2010-07-24 14:38:36 +0000
@@ -20,10 +20,123 @@
#include <iostream>
namespace gnash {
-namespace SWF { // gnash::SWF
-
-std::ostream&
-operator<< (std::ostream& os, const abc_action_type& opcode)
+namespace SWF {
+
+std::ostream&
+operator<<(std::ostream& o, ActionType a)
+{
+ switch (a) {
+ case ACTION_END: return o << "End";
+ case ACTION_NEXTFRAME: return o << "NextFrame";
+ case ACTION_PREVFRAME: return o << "PreviousFrame";
+ case ACTION_PLAY: return o << "Play";
+ case ACTION_STOP: return o << "Stop";
+ case ACTION_TOGGLEQUALITY: return o << "ToggleQuality";
+ case ACTION_STOPSOUNDS: return o << "StopSounds";
+ case ACTION_GOTOFRAME: return o << "GotoFrame";
+ case ACTION_GETURL: return o << "GetUrl";
+ case ACTION_WAITFORFRAME: return o << "WaitForFrame";
+ case ACTION_SETTARGET: return o << "SetTarget";
+ case ACTION_GOTOLABEL: return o << "GotoLabel";
+ case ACTION_ADD: return o << "Add";
+ case ACTION_SUBTRACT: return o << "Subtract";
+ case ACTION_MULTIPLY: return o << "Multiply";
+ case ACTION_DIVIDE: return o << "Divide";
+ case ACTION_EQUAL: return o << "Equal";
+ case ACTION_LESSTHAN: return o << "LessThan";
+ case ACTION_LOGICALAND: return o << "LogicalAnd";
+ case ACTION_LOGICALOR: return o << "LogicalOr";
+ case ACTION_LOGICALNOT: return o << "LogicalNot";
+ case ACTION_STRINGEQ: return o << "StringEq";
+ case ACTION_STRINGLENGTH: return o << "ActionStringLength";
+ case ACTION_SUBSTRING: return o << "ActionSubString";
+ case ACTION_POP: return o << "ActionPop";
+ case ACTION_INT: return o << "ActionInt";
+ case ACTION_GETVARIABLE: return o << "ActionGetVariable";
+ case ACTION_SETVARIABLE: return o << "ActionSetVariable";
+ case ACTION_SETTARGETEXPRESSION:
+ return o << "ActionSetTargetExpression";
+ case ACTION_STRINGCONCAT: return o << "ActionStringConcat";
+ case ACTION_GETPROPERTY: return o << "ActionGetProperty";
+ case ACTION_SETPROPERTY: return o << "ActionSetProperty";
+ case ACTION_DUPLICATECLIP: return o << "ActionDuplicateClip";
+ case ACTION_REMOVECLIP: return o << "ActionRemoveClip";
+ case ACTION_TRACE: return o << "ActionTrace";
+ case ACTION_STARTDRAGMOVIE: return o << "ActionStartDragMovie";
+ case ACTION_STOPDRAGMOVIE: return o << "ActionStopDragMovie";
+ case ACTION_STRINGCOMPARE: return o << "ActionStringCompare";
+ case ACTION_THROW: return o << "ActionThrow";
+ case ACTION_CASTOP: return o << "ActionCastOp";
+ case ACTION_IMPLEMENTSOP: return o << "ActionImplementsOp";
+ case ACTION_FSCOMMAND2: return o << "ActionFscommand2";
+ case ACTION_RANDOM: return o << "ActionRandom";
+ case ACTION_MBLENGTH: return o << "ActionMbLength";
+ case ACTION_ORD: return o << "ActionOrd";
+ case ACTION_CHR: return o << "ActionChr";
+ case ACTION_GETTIMER: return o << "ActionGetTimer";
+ case ACTION_MBSUBSTRING: return o << "ActionMbSubString";
+ case ACTION_MBORD: return o << "ActionMbOrd";
+ case ACTION_MBCHR: return o << "ActionMbChr";
+ case ACTION_STRICTMODE: return o << "ActionStrictMode";
+ case ACTION_WAITFORFRAMEEXPRESSION:
+ return o << "ActionWaitForFrameExpression";
+ case ACTION_PUSHDATA: return o << "ActionPushData";
+ case ACTION_BRANCHALWAYS: return o << "ActionBranchAlways";
+ case ACTION_GETURL2: return o << "ActionGetUrl2";
+ case ACTION_BRANCHIFTRUE: return o << "ActionBranchIfTrue";
+ case ACTION_CALLFRAME: return o << "ActionCallFrame";
+ case ACTION_GOTOEXPRESSION: return o << "ActionGotoExpression";
+ case ACTION_DELETE: return o << "ActionDelete";
+ case ACTION_DELETE2: return o << "ActionDelete2";
+ case ACTION_VAREQUALS: return o << "ActionVarEquals";
+ case ACTION_CALLFUNCTION: return o << "ActionCallFunction";
+ case ACTION_RETURN: return o << "ActionReturn";
+ case ACTION_MODULO: return o << "ActionModulo";
+ case ACTION_NEW: return o << "ActionNew";
+ case ACTION_VAR: return o << "ActionVar";
+ case ACTION_INITARRAY: return o << "ActionInitArray";
+ case ACTION_INITOBJECT: return o << "ActionInitObject";
+ case ACTION_TYPEOF: return o << "ActionTypeOf";
+ case ACTION_TARGETPATH: return o << "ActionTargetPath";
+ case ACTION_ENUMERATE: return o << "ActionEnumerate";
+ case ACTION_NEWADD: return o << "ActionNewAdd";
+ case ACTION_NEWLESSTHAN: return o << "ActionNewLessThan";
+ case ACTION_NEWEQUALS: return o << "ActionNewEquals";
+ case ACTION_TONUMBER: return o << "ActionToNumber";
+ case ACTION_TOSTRING: return o << "ActionToString";
+ case ACTION_DUP: return o << "ActionDup";
+ case ACTION_SWAP: return o << "ActionSwap";
+ case ACTION_GETMEMBER: return o << "ActionGetMember";
+ case ACTION_SETMEMBER: return o << "ActionSetMember";
+ case ACTION_INCREMENT: return o << "ActionIncrement";
+ case ACTION_DECREMENT: return o << "ActionDecrement";
+ case ACTION_CALLMETHOD: return o << "ActionCallMethod";
+ case ACTION_NEWMETHOD: return o << "ActionNewMethod";
+ case ACTION_INSTANCEOF: return o << "ActionInstanceOf";
+ case ACTION_ENUM2: return o << "ActionEnum2";
+ case ACTION_BITWISEAND: return o << "ActionBitwiseAnd";
+ case ACTION_BITWISEOR: return o << "ActionBitwiseOr";
+ case ACTION_BITWISEXOR: return o << "ActionBitwiseXor";
+ case ACTION_SHIFTLEFT: return o << "ActionShiftLeft";
+ case ACTION_SHIFTRIGHT: return o << "ActionShiftRight";
+ case ACTION_SHIFTRIGHT2: return o << "ActionShiftRight2";
+ case ACTION_STRICTEQ: return o << "ActionStrictEq";
+ case ACTION_GREATER: return o << "ActionGreater";
+ case ACTION_STRINGGREATER: return o << "ActionStringGreater";
+ case ACTION_EXTENDS: return o << "ActionExtends";
+ case ACTION_CONSTANTPOOL: return o << "ActionConstantPool";
+ case ACTION_DEFINEFUNCTION2: return o << "ActionDefineFunction2";
+ case ACTION_TRY: return o << "ActionTry";
+ case ACTION_WITH: return o << "ActionWith";
+ case ACTION_DEFINEFUNCTION: return o << "ActionDefineFunction";
+ case ACTION_SETREGISTER: return o << "ActionSetRegister";
+ default: return o << "Unknown ActionType";
+ }
+ return o;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const abc_action_type& opcode)
{
switch (opcode)
{
=== modified file 'libcore/swf/SWF.h'
--- a/libcore/swf/SWF.h 2010-03-14 02:24:15 +0000
+++ b/libcore/swf/SWF.h 2010-07-24 14:38:36 +0000
@@ -330,6 +330,8 @@
};
+std::ostream& operator<<(std::ostream& o, ActionType a);
+
enum abc_action_type
{
/// AS3 Actions go below here.
=== modified file 'libcore/swf/tag_loaders.cpp'
--- a/libcore/swf/tag_loaders.cpp 2010-07-14 10:47:13 +0000
+++ b/libcore/swf/tag_loaders.cpp 2010-07-24 13:44:22 +0000
@@ -35,7 +35,7 @@
#include "zlib_adapter.h"
#include "sprite_definition.h"
#include "MovieClip.h"
-#include "swf_function.h"
+#include "Function.h"
#include "as_function.h"
#include "SWFMovieDefinition.h"
#include "SWF.h"
=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2010-07-23 14:12:47 +0000
+++ b/libcore/vm/ASHandlers.cpp 2010-07-24 15:35:00 +0000
@@ -29,8 +29,10 @@
#include "rc.h"
#include "ASHandlers.h"
#include "movie_definition.h"
-#include "swf_function.h"
+#include "NativeFunction.h"
+#include "Function.h"
#include "as_function.h"
+#include "Function2.h"
#include "fn_call.h"
#include "ActionExec.h"
#include "MovieClip.h"
@@ -221,42 +223,19 @@
}
namespace SWF {
+
ActionHandler::ActionHandler()
:
- _name("unsupported"),
_callback(ActionUnsupported),
- _debug(false),
- _arg_format(ARG_NONE)
-{
-}
-
-ActionHandler::ActionHandler(ActionType type, ActionCallback func)
- :
- _type(type),
- _callback(func),
- _debug(false),
- _arg_format(ARG_NONE)
-{
-}
-
-ActionHandler::ActionHandler(ActionType type, std::string name,
- ActionCallback func)
- :
- _type(type),
- _name(name),
- _callback(func),
- _debug(false),
- _arg_format(ARG_NONE)
-{
-}
-
-ActionHandler::ActionHandler(ActionType type, std::string name,
- ActionCallback func, ArgumentType format)
- :
- _type(type),
- _name(name),
- _callback(func),
- _debug(false),
+ _arg_format(ARG_NONE)
+{
+}
+
+ActionHandler::ActionHandler(ActionType type, ActionCallback func,
+ ArgumentType format)
+ :
+ _type(type),
+ _callback(func),
_arg_format(format)
{
}
@@ -268,236 +247,184 @@
}
SWFHandlers::SWFHandlers()
+ :
+ _handlers(255)
{
- container_type & handlers = get_handlers();
-
- handlers[ACTION_END] = ActionHandler(ACTION_END,
- "End", ActionEnd);
- handlers[ACTION_NEXTFRAME] = ActionHandler(ACTION_NEXTFRAME,
- "NextFrame", ActionNextFrame);
- handlers[ACTION_PREVFRAME] = ActionHandler(ACTION_PREVFRAME,
- "PreviousFrame", ActionPrevFrame);
- handlers[ACTION_PLAY] = ActionHandler(ACTION_PLAY,
- "Play", ActionPlay);
- handlers[ACTION_STOP] = ActionHandler(ACTION_STOP,
- "Stop", ActionStop);
- handlers[ACTION_TOGGLEQUALITY] = ActionHandler(ACTION_TOGGLEQUALITY,
- "ToggleQuality", ActionToggleQuality);
- handlers[ACTION_STOPSOUNDS] = ActionHandler(ACTION_STOPSOUNDS,
- "StopSounds", ActionStopSounds);
- handlers[ACTION_GOTOFRAME] = ActionHandler(ACTION_GOTOFRAME,
- "GotoFrame", ActionGotoFrame, ARG_U16);
- handlers[ACTION_GETURL] = ActionHandler(ACTION_GETURL,
- "GetUrl", ActionGetUrl, ARG_STR);
- handlers[ACTION_WAITFORFRAME] = ActionHandler(ACTION_WAITFORFRAME,
- "WaitForFrame", ActionWaitForFrame, ARG_HEX);
- handlers[ACTION_SETTARGET] = ActionHandler(ACTION_SETTARGET,
- "SetTarget", ActionSetTarget, ARG_STR);
- handlers[ACTION_GOTOLABEL] = ActionHandler(ACTION_GOTOLABEL,
- "GotoLabel", ActionGotoLabel, ARG_STR);
- handlers[ACTION_ADD] = ActionHandler(ACTION_ADD,
- "Add", ActionAdd);
- handlers[ACTION_SUBTRACT] = ActionHandler(ACTION_SUBTRACT,
- "Subtract", ActionSubtract);
- handlers[ACTION_MULTIPLY] = ActionHandler(ACTION_MULTIPLY,
- "Multiply", ActionMultiply);
- handlers[ACTION_DIVIDE] = ActionHandler(ACTION_DIVIDE,
- "Divide", ActionDivide);
- handlers[ACTION_EQUAL] = ActionHandler(ACTION_EQUAL,
- "Equal", ActionEqual);
- handlers[ACTION_LESSTHAN] = ActionHandler(ACTION_LESSTHAN,
- "LessThan", ActionLessThan);
- handlers[ACTION_LOGICALAND] = ActionHandler(ACTION_LOGICALAND,
- "LogicalAnd", ActionLogicalAnd);
- handlers[ACTION_LOGICALOR] = ActionHandler(ACTION_LOGICALOR,
- "LogicalOr", ActionLogicalOr);
- handlers[ACTION_LOGICALNOT] = ActionHandler(ACTION_LOGICALNOT,
- "LogicalNot", ActionLogicalNot);
- handlers[ACTION_STRINGEQ] = ActionHandler(ACTION_STRINGEQ,
- "StringEq", ActionStringEq);
- handlers[ACTION_STRINGLENGTH] = ActionHandler(ACTION_STRINGLENGTH,
- "ActionStringLength", ActionStringLength);
- handlers[ACTION_SUBSTRING] = ActionHandler(ACTION_SUBSTRING,
- "ActionSubString", ActionSubString);
- handlers[ACTION_POP] = ActionHandler(ACTION_POP,
- "ActionPop", ActionPop);
- handlers[ACTION_INT] = ActionHandler(ACTION_INT,
- "ActionInt", ActionInt);
- handlers[ACTION_GETVARIABLE] = ActionHandler(ACTION_GETVARIABLE,
- "ActionGetVariable", ActionGetVariable);
- handlers[ACTION_SETVARIABLE] = ActionHandler(ACTION_SETVARIABLE,
- "ActionSetVariable", ActionSetVariable);
- handlers[ACTION_SETTARGETEXPRESSION] =
- ActionHandler(ACTION_SETTARGETEXPRESSION,
- "ActionSetTargetExpression",
+ _handlers[ACTION_END] = ActionHandler(ACTION_END, ActionEnd);
+ _handlers[ACTION_NEXTFRAME] = ActionHandler(ACTION_NEXTFRAME,
+ ActionNextFrame);
+ _handlers[ACTION_PREVFRAME] = ActionHandler(ACTION_PREVFRAME,
+ ActionPrevFrame);
+ _handlers[ACTION_PLAY] = ActionHandler(ACTION_PLAY, ActionPlay);
+ _handlers[ACTION_STOP] = ActionHandler(ACTION_STOP, ActionStop);
+ _handlers[ACTION_TOGGLEQUALITY] = ActionHandler(ACTION_TOGGLEQUALITY,
+ ActionToggleQuality);
+ _handlers[ACTION_STOPSOUNDS] = ActionHandler(ACTION_STOPSOUNDS,
+ ActionStopSounds);
+ _handlers[ACTION_GOTOFRAME] = ActionHandler(ACTION_GOTOFRAME,
+ ActionGotoFrame, ARG_U16);
+ _handlers[ACTION_GETURL] = ActionHandler(ACTION_GETURL,
+ ActionGetUrl, ARG_STR);
+ _handlers[ACTION_WAITFORFRAME] = ActionHandler(ACTION_WAITFORFRAME,
+ ActionWaitForFrame, ARG_HEX);
+ _handlers[ACTION_SETTARGET] = ActionHandler(ACTION_SETTARGET,
+ ActionSetTarget, ARG_STR);
+ _handlers[ACTION_GOTOLABEL] = ActionHandler(ACTION_GOTOLABEL,
+ ActionGotoLabel, ARG_STR);
+ _handlers[ACTION_ADD] = ActionHandler(ACTION_ADD, ActionAdd);
+ _handlers[ACTION_SUBTRACT] = ActionHandler(ACTION_SUBTRACT,
ActionSubtract);
+ _handlers[ACTION_MULTIPLY] = ActionHandler(ACTION_MULTIPLY,
ActionMultiply);
+ _handlers[ACTION_DIVIDE] = ActionHandler(ACTION_DIVIDE, ActionDivide);
+ _handlers[ACTION_EQUAL] = ActionHandler(ACTION_EQUAL, ActionEqual);
+ _handlers[ACTION_LESSTHAN] = ActionHandler(ACTION_LESSTHAN,
ActionLessThan);
+ _handlers[ACTION_LOGICALAND] = ActionHandler(ACTION_LOGICALAND,
+ ActionLogicalAnd);
+ _handlers[ACTION_LOGICALOR] = ActionHandler(ACTION_LOGICALOR,
+ ActionLogicalOr);
+ _handlers[ACTION_LOGICALNOT] = ActionHandler(ACTION_LOGICALNOT,
+ ActionLogicalNot);
+ _handlers[ACTION_STRINGEQ] = ActionHandler(ACTION_STRINGEQ,
+ ActionStringEq);
+ _handlers[ACTION_STRINGLENGTH] = ActionHandler(ACTION_STRINGLENGTH,
+ ActionStringLength);
+ _handlers[ACTION_SUBSTRING] = ActionHandler(ACTION_SUBSTRING,
+ ActionSubString);
+ _handlers[ACTION_POP] = ActionHandler(ACTION_POP, ActionPop);
+ _handlers[ACTION_INT] = ActionHandler(ACTION_INT, ActionInt);
+ _handlers[ACTION_GETVARIABLE] = ActionHandler(ACTION_GETVARIABLE,
+ ActionGetVariable);
+ _handlers[ACTION_SETVARIABLE] = ActionHandler(ACTION_SETVARIABLE,
+ ActionSetVariable);
+ _handlers[ACTION_SETTARGETEXPRESSION] =
+ ActionHandler(ACTION_SETTARGETEXPRESSION,
ActionSetTargetExpression);
- handlers[ACTION_STRINGCONCAT] = ActionHandler(ACTION_STRINGCONCAT,
- "ActionStringConcat", ActionStringConcat);
- handlers[ACTION_GETPROPERTY] = ActionHandler(ACTION_GETPROPERTY,
- "ActionGetProperty", ActionGetProperty);
- handlers[ACTION_SETPROPERTY] = ActionHandler(ACTION_SETPROPERTY,
- "ActionSetProperty", ActionSetProperty);
- handlers[ACTION_DUPLICATECLIP] = ActionHandler(ACTION_DUPLICATECLIP,
- "ActionDuplicateClip", ActionDuplicateClip);
- handlers[ACTION_REMOVECLIP] = ActionHandler(ACTION_REMOVECLIP,
- "ActionRemoveClip", ActionRemoveClip);
- handlers[ACTION_TRACE] = ActionHandler(ACTION_TRACE,
- "ActionTrace", ActionTrace);
- handlers[ACTION_STARTDRAGMOVIE] = ActionHandler(ACTION_STARTDRAGMOVIE,
- "ActionStartDragMovie", ActionStartDragMovie);
- handlers[ACTION_STOPDRAGMOVIE] = ActionHandler(ACTION_STOPDRAGMOVIE,
- "ActionStopDragMovie", ActionStopDragMovie);
- handlers[ACTION_STRINGCOMPARE] = ActionHandler(ACTION_STRINGCOMPARE,
- "ActionStringCompare", ActionStringCompare);
- handlers[ACTION_THROW] = ActionHandler(ACTION_THROW,
- "ActionThrow", ActionThrow);
- handlers[ACTION_CASTOP] = ActionHandler(ACTION_CASTOP,
- "ActionCastOp", ActionCastOp);
- handlers[ACTION_IMPLEMENTSOP] = ActionHandler(ACTION_IMPLEMENTSOP,
- "ActionImplementsOp", ActionImplementsOp);
- handlers[ACTION_FSCOMMAND2] = ActionHandler(ACTION_FSCOMMAND2,
- "ActionFscommand2", ActionFscommand2);
- handlers[ACTION_RANDOM] = ActionHandler(ACTION_RANDOM,
- "ActionRandom", ActionRandom);
- handlers[ACTION_MBLENGTH] = ActionHandler(ACTION_MBLENGTH,
- "ActionMbLength", ActionMbLength);
- handlers[ACTION_ORD] = ActionHandler(ACTION_ORD,
- "ActionOrd", ActionOrd);
- handlers[ACTION_CHR] = ActionHandler(ACTION_CHR,
- "ActionChr", ActionChr);
- handlers[ACTION_GETTIMER] = ActionHandler(ACTION_GETTIMER,
- "ActionGetTimer", ActionGetTimer);
- handlers[ACTION_MBSUBSTRING] = ActionHandler(ACTION_MBSUBSTRING,
- "ActionMbSubString", ActionMbSubString);
- handlers[ACTION_MBORD] = ActionHandler(ACTION_MBORD,
- "ActionMbOrd", ActionMbOrd);
- handlers[ACTION_MBCHR] = ActionHandler(ACTION_MBCHR,
- "ActionMbChr", ActionMbChr);
- handlers[ACTION_STRICTMODE] = ActionHandler(ACTION_STRICTMODE,
- "ActionStrictMode", ActionStrictMode, ARG_U8);
- handlers[ACTION_WAITFORFRAMEEXPRESSION] =
+ _handlers[ACTION_STRINGCONCAT] = ActionHandler(ACTION_STRINGCONCAT,
+ ActionStringConcat);
+ _handlers[ACTION_GETPROPERTY] = ActionHandler(ACTION_GETPROPERTY,
+ ActionGetProperty);
+ _handlers[ACTION_SETPROPERTY] = ActionHandler(ACTION_SETPROPERTY,
+ ActionSetProperty);
+ _handlers[ACTION_DUPLICATECLIP] = ActionHandler(ACTION_DUPLICATECLIP,
+ ActionDuplicateClip);
+ _handlers[ACTION_REMOVECLIP] = ActionHandler(ACTION_REMOVECLIP,
+ ActionRemoveClip);
+ _handlers[ACTION_TRACE] = ActionHandler(ACTION_TRACE, ActionTrace);
+ _handlers[ACTION_STARTDRAGMOVIE] = ActionHandler(ACTION_STARTDRAGMOVIE,
+ ActionStartDragMovie);
+ _handlers[ACTION_STOPDRAGMOVIE] = ActionHandler(ACTION_STOPDRAGMOVIE,
+ ActionStopDragMovie);
+ _handlers[ACTION_STRINGCOMPARE] = ActionHandler(ACTION_STRINGCOMPARE,
+ ActionStringCompare);
+ _handlers[ACTION_THROW] = ActionHandler(ACTION_THROW, ActionThrow);
+ _handlers[ACTION_CASTOP] = ActionHandler(ACTION_CASTOP, ActionCastOp);
+ _handlers[ACTION_IMPLEMENTSOP] = ActionHandler(ACTION_IMPLEMENTSOP,
+ ActionImplementsOp);
+ _handlers[ACTION_FSCOMMAND2] = ActionHandler(ACTION_FSCOMMAND2,
+ ActionFscommand2);
+ _handlers[ACTION_RANDOM] = ActionHandler(ACTION_RANDOM, ActionRandom);
+ _handlers[ACTION_MBLENGTH] = ActionHandler(ACTION_MBLENGTH,
ActionMbLength);
+ _handlers[ACTION_ORD] = ActionHandler(ACTION_ORD, ActionOrd);
+ _handlers[ACTION_CHR] = ActionHandler(ACTION_CHR, ActionChr);
+ _handlers[ACTION_GETTIMER] = ActionHandler(ACTION_GETTIMER,
ActionGetTimer);
+ _handlers[ACTION_MBSUBSTRING] = ActionHandler(ACTION_MBSUBSTRING,
+ ActionMbSubString);
+ _handlers[ACTION_MBORD] = ActionHandler(ACTION_MBORD, ActionMbOrd);
+ _handlers[ACTION_MBCHR] = ActionHandler(ACTION_MBCHR, ActionMbChr);
+ _handlers[ACTION_STRICTMODE] = ActionHandler(ACTION_STRICTMODE,
+ ActionStrictMode, ARG_U8);
+ _handlers[ACTION_WAITFORFRAMEEXPRESSION] =
ActionHandler(ACTION_WAITFORFRAMEEXPRESSION,
- "ActionWaitForFrameExpression",
ActionWaitForFrameExpression, ARG_HEX);
- handlers[ACTION_PUSHDATA] = ActionHandler(ACTION_PUSHDATA,
- "ActionPushData", ActionPushData, ARG_PUSH_DATA);
- handlers[ACTION_BRANCHALWAYS] = ActionHandler(ACTION_BRANCHALWAYS,
- "ActionBranchAlways", ActionBranchAlways, ARG_S16);
- handlers[ACTION_GETURL2] = ActionHandler(ACTION_GETURL2,
- "ActionGetUrl2", ActionGetUrl2, ARG_HEX);
- handlers[ACTION_BRANCHIFTRUE] = ActionHandler(ACTION_BRANCHIFTRUE,
- "ActionBranchIfTrue", ActionBranchIfTrue, ARG_S16);
- handlers[ACTION_CALLFRAME] = ActionHandler(ACTION_CALLFRAME,
- "ActionCallFrame", ActionCallFrame, ARG_HEX);
- handlers[ACTION_GOTOEXPRESSION] = ActionHandler(ACTION_GOTOEXPRESSION,
- "ActionGotoExpression",
- ActionGotoExpression, ARG_HEX);
- handlers[ACTION_DELETE] = ActionHandler(ACTION_DELETE,
- "ActionDelete", ActionDelete);
- handlers[ACTION_DELETE2] = ActionHandler(ACTION_DELETE2,
- "ActionDelete2", ActionDelete2);
- handlers[ACTION_VAREQUALS] = ActionHandler(ACTION_VAREQUALS,
- "ActionVarEquals", ActionVarEquals);
- handlers[ACTION_CALLFUNCTION] = ActionHandler(ACTION_CALLFUNCTION,
- "ActionCallFunction", ActionCallFunction);
- handlers[ACTION_RETURN] = ActionHandler(ACTION_RETURN,
- "ActionReturn", ActionReturn);
- handlers[ACTION_MODULO] = ActionHandler(ACTION_MODULO,
- "ActionModulo", ActionModulo);
- handlers[ACTION_NEW] = ActionHandler(ACTION_NEW,
- "ActionNew", ActionNew);
- handlers[ACTION_VAR] = ActionHandler(ACTION_VAR,
- "ActionVar", ActionVar);
- handlers[ACTION_INITARRAY] = ActionHandler(ACTION_INITARRAY,
- "ActionInitArray", ActionInitArray);
- handlers[ACTION_INITOBJECT] = ActionHandler(ACTION_INITOBJECT,
- "ActionInitObject", ActionInitObject);
- handlers[ACTION_TYPEOF] = ActionHandler(ACTION_TYPEOF,
- "ActionTypeOf", ActionTypeOf);
- handlers[ACTION_TARGETPATH] = ActionHandler(ACTION_TARGETPATH,
- "ActionTargetPath", ActionTargetPath);
- handlers[ACTION_ENUMERATE] = ActionHandler(ACTION_ENUMERATE,
- "ActionEnumerate", ActionEnumerate);
- handlers[ACTION_NEWADD] = ActionHandler(ACTION_NEWADD,
- "ActionNewAdd", ActionNewAdd);
- handlers[ACTION_NEWLESSTHAN] = ActionHandler(ACTION_NEWLESSTHAN,
- "ActionNewLessThan", ActionNewLessThan);
- handlers[ACTION_NEWEQUALS] = ActionHandler(ACTION_NEWEQUALS,
- "ActionNewEquals", ActionNewEquals);
- handlers[ACTION_TONUMBER] = ActionHandler(ACTION_TONUMBER,
- "ActionToNumber", ActionToNumber);
- handlers[ACTION_TOSTRING] = ActionHandler(ACTION_TOSTRING,
- "ActionToString", ActionToString);
- handlers[ACTION_DUP] = ActionHandler(ACTION_DUP,
- "ActionDup", ActionDup);
- handlers[ACTION_SWAP] = ActionHandler(ACTION_SWAP,
- "ActionSwap", ActionSwap);
- handlers[ACTION_GETMEMBER] = ActionHandler(ACTION_GETMEMBER,
- "ActionGetMember", ActionGetMember);
- handlers[ACTION_SETMEMBER] = ActionHandler(ACTION_SETMEMBER,
- "ActionSetMember", ActionSetMember);
- handlers[ACTION_INCREMENT] = ActionHandler(ACTION_INCREMENT,
- "ActionIncrement", ActionIncrement);
- handlers[ACTION_DECREMENT] = ActionHandler(ACTION_DECREMENT,
- "ActionDecrement", ActionDecrement);
- handlers[ACTION_CALLMETHOD] = ActionHandler(ACTION_CALLMETHOD,
- "ActionCallMethod", ActionCallMethod);
- handlers[ACTION_NEWMETHOD] = ActionHandler(ACTION_NEWMETHOD,
- "ActionNewMethod", ActionNewMethod);
- handlers[ACTION_INSTANCEOF] = ActionHandler(ACTION_INSTANCEOF,
- "ActionInstanceOf", ActionInstanceOf);
- handlers[ACTION_ENUM2] = ActionHandler(ACTION_ENUM2,
- "ActionEnum2", ActionEnum2);
- handlers[ACTION_BITWISEAND] = ActionHandler(ACTION_BITWISEAND,
- "ActionBitwiseAnd", ActionBitwiseAnd);
- handlers[ACTION_BITWISEOR] = ActionHandler(ACTION_BITWISEOR,
- "ActionBitwiseOr", ActionBitwiseOr);
- handlers[ACTION_BITWISEXOR] = ActionHandler(ACTION_BITWISEXOR,
- "ActionBitwiseXor", ActionBitwiseXor);
- handlers[ACTION_SHIFTLEFT] = ActionHandler(ACTION_SHIFTLEFT,
- "ActionShiftLeft", ActionShiftLeft);
- handlers[ACTION_SHIFTRIGHT] = ActionHandler(ACTION_SHIFTRIGHT,
- "ActionShiftRight", ActionShiftRight);
- handlers[ACTION_SHIFTRIGHT2] = ActionHandler(ACTION_SHIFTRIGHT2,
- "ActionShiftRight2", ActionShiftRight2);
- handlers[ACTION_STRICTEQ] = ActionHandler(ACTION_STRICTEQ,
- "ActionStrictEq", ActionStrictEq);
- handlers[ACTION_GREATER] = ActionHandler(ACTION_GREATER,
- "ActionGreater", ActionGreater);
- handlers[ACTION_STRINGGREATER] = ActionHandler(ACTION_STRINGGREATER,
- "ActionStringGreater", ActionStringGreater);
- handlers[ACTION_EXTENDS] = ActionHandler(ACTION_EXTENDS,
- "ActionExtends", ActionExtends);
- handlers[ACTION_CONSTANTPOOL] = ActionHandler(ACTION_CONSTANTPOOL,
- "ActionConstantPool", ActionConstantPool,
- ARG_DECL_DICT);
- handlers[ACTION_DEFINEFUNCTION2] = ActionHandler(ACTION_DEFINEFUNCTION2,
- "ActionDefineFunction2", ActionDefineFunction2,
- ARG_FUNCTION2);
- handlers[ACTION_TRY] = ActionHandler(ACTION_TRY,
- "ActionTry", ActionTry, ARG_FUNCTION2);
- handlers[ACTION_WITH] = ActionHandler(ACTION_WITH,
- "ActionWith", ActionWith, ARG_U16);
- handlers[ACTION_DEFINEFUNCTION] = ActionHandler(ACTION_DEFINEFUNCTION,
- "ActionDefineFunction", ActionDefineFunction,
- ARG_HEX);
- handlers[ACTION_SETREGISTER] = ActionHandler(ACTION_SETREGISTER,
- "ActionSetRegister", ActionSetRegister, ARG_U8);
+ _handlers[ACTION_PUSHDATA] = ActionHandler(ACTION_PUSHDATA, ActionPushData,
+ ARG_PUSH_DATA);
+ _handlers[ACTION_BRANCHALWAYS] = ActionHandler(ACTION_BRANCHALWAYS,
+ ActionBranchAlways, ARG_S16);
+ _handlers[ACTION_GETURL2] = ActionHandler(ACTION_GETURL2, ActionGetUrl2,
+ ARG_HEX);
+ _handlers[ACTION_BRANCHIFTRUE] = ActionHandler(ACTION_BRANCHIFTRUE,
+ ActionBranchIfTrue, ARG_S16);
+ _handlers[ACTION_CALLFRAME] = ActionHandler(ACTION_CALLFRAME,
+ ActionCallFrame, ARG_HEX);
+ _handlers[ACTION_GOTOEXPRESSION] = ActionHandler(ACTION_GOTOEXPRESSION,
+ ActionGotoExpression, ARG_HEX);
+ _handlers[ACTION_DELETE] = ActionHandler(ACTION_DELETE, ActionDelete);
+ _handlers[ACTION_DELETE2] = ActionHandler(ACTION_DELETE2, ActionDelete2);
+ _handlers[ACTION_VAREQUALS] = ActionHandler(ACTION_VAREQUALS,
+ ActionVarEquals);
+ _handlers[ACTION_CALLFUNCTION] = ActionHandler(ACTION_CALLFUNCTION,
+ ActionCallFunction);
+ _handlers[ACTION_RETURN] = ActionHandler(ACTION_RETURN, ActionReturn);
+ _handlers[ACTION_MODULO] = ActionHandler(ACTION_MODULO, ActionModulo);
+ _handlers[ACTION_NEW] = ActionHandler(ACTION_NEW, ActionNew);
+ _handlers[ACTION_VAR] = ActionHandler(ACTION_VAR, ActionVar);
+ _handlers[ACTION_INITARRAY] = ActionHandler(ACTION_INITARRAY,
+ ActionInitArray);
+ _handlers[ACTION_INITOBJECT] = ActionHandler(ACTION_INITOBJECT,
+ ActionInitObject);
+ _handlers[ACTION_TYPEOF] = ActionHandler(ACTION_TYPEOF, ActionTypeOf);
+ _handlers[ACTION_TARGETPATH] = ActionHandler(ACTION_TARGETPATH,
+ ActionTargetPath);
+ _handlers[ACTION_ENUMERATE] = ActionHandler(ACTION_ENUMERATE,
+ ActionEnumerate);
+ _handlers[ACTION_NEWADD] = ActionHandler(ACTION_NEWADD, ActionNewAdd);
+ _handlers[ACTION_NEWLESSTHAN] = ActionHandler(ACTION_NEWLESSTHAN,
+ ActionNewLessThan);
+ _handlers[ACTION_NEWEQUALS] = ActionHandler(ACTION_NEWEQUALS,
+ ActionNewEquals);
+ _handlers[ACTION_TONUMBER] = ActionHandler(ACTION_TONUMBER,
ActionToNumber);
+ _handlers[ACTION_TOSTRING] = ActionHandler(ACTION_TOSTRING,
ActionToString);
+ _handlers[ACTION_DUP] = ActionHandler(ACTION_DUP, ActionDup);
+ _handlers[ACTION_SWAP] = ActionHandler(ACTION_SWAP, ActionSwap);
+ _handlers[ACTION_GETMEMBER] = ActionHandler(ACTION_GETMEMBER,
+ ActionGetMember);
+ _handlers[ACTION_SETMEMBER] = ActionHandler(ACTION_SETMEMBER,
+ ActionSetMember);
+ _handlers[ACTION_INCREMENT] = ActionHandler(ACTION_INCREMENT,
+ ActionIncrement);
+ _handlers[ACTION_DECREMENT] = ActionHandler(ACTION_DECREMENT,
+ ActionDecrement);
+ _handlers[ACTION_CALLMETHOD] = ActionHandler(ACTION_CALLMETHOD,
+ ActionCallMethod);
+ _handlers[ACTION_NEWMETHOD] = ActionHandler(ACTION_NEWMETHOD,
+ ActionNewMethod);
+ _handlers[ACTION_INSTANCEOF] = ActionHandler(ACTION_INSTANCEOF,
+ ActionInstanceOf);
+ _handlers[ACTION_ENUM2] = ActionHandler(ACTION_ENUM2, ActionEnum2);
+ _handlers[ACTION_BITWISEAND] = ActionHandler(ACTION_BITWISEAND,
+ ActionBitwiseAnd);
+ _handlers[ACTION_BITWISEOR] = ActionHandler(ACTION_BITWISEOR,
+ ActionBitwiseOr);
+ _handlers[ACTION_BITWISEXOR] = ActionHandler(ACTION_BITWISEXOR,
+ ActionBitwiseXor);
+ _handlers[ACTION_SHIFTLEFT] = ActionHandler(ACTION_SHIFTLEFT,
+ ActionShiftLeft);
+ _handlers[ACTION_SHIFTRIGHT] = ActionHandler(ACTION_SHIFTRIGHT,
+ ActionShiftRight);
+ _handlers[ACTION_SHIFTRIGHT2] = ActionHandler(ACTION_SHIFTRIGHT2,
+ ActionShiftRight2);
+ _handlers[ACTION_STRICTEQ] = ActionHandler(ACTION_STRICTEQ,
ActionStrictEq);
+ _handlers[ACTION_GREATER] = ActionHandler(ACTION_GREATER, ActionGreater);
+ _handlers[ACTION_STRINGGREATER] = ActionHandler(ACTION_STRINGGREATER,
+ ActionStringGreater);
+ _handlers[ACTION_EXTENDS] = ActionHandler(ACTION_EXTENDS, ActionExtends);
+ _handlers[ACTION_CONSTANTPOOL] = ActionHandler(ACTION_CONSTANTPOOL,
+ ActionConstantPool, ARG_DECL_DICT);
+ _handlers[ACTION_DEFINEFUNCTION2] = ActionHandler(ACTION_DEFINEFUNCTION2,
+ ActionDefineFunction2, ARG_FUNCTION2);
+ _handlers[ACTION_TRY] = ActionHandler(ACTION_TRY, ActionTry,
ARG_FUNCTION2);
+ _handlers[ACTION_WITH] = ActionHandler(ACTION_WITH,
+ ActionWith, ARG_U16);
+ _handlers[ACTION_DEFINEFUNCTION] = ActionHandler(ACTION_DEFINEFUNCTION,
+ ActionDefineFunction, ARG_HEX);
+ _handlers[ACTION_SETREGISTER] = ActionHandler(ACTION_SETREGISTER,
+ ActionSetRegister, ARG_U8);
}
SWFHandlers::~SWFHandlers()
{
}
-
-std::vector<ActionHandler> &
-SWFHandlers::get_handlers()
-{
- static container_type handlers(255);
- return handlers;
-}
-
const SWFHandlers&
SWFHandlers::instance()
{
@@ -509,7 +436,7 @@
SWFHandlers::execute(ActionType type, ActionExec& thread) const
{
try {
- get_handlers()[type].execute(thread);
+ _handlers[type].execute(thread);
}
catch (ActionParserException& e) {
log_swferror(_("Malformed action code: %s"), e.what());
@@ -520,23 +447,6 @@
}
}
-const char*
-SWFHandlers::action_name(ActionType x) const
-{
- if (static_cast<size_t>(x) > get_handlers().size())
- {
- log_error(_("at SWFHandlers::action_name(%d) call time, "
- "_handlers size is %d"),
- x, get_handlers().size());
- return NULL;
- }
- else
- {
- return get_handlers()[x].getName().c_str();
- }
-}
-
-
} // namespace SWF
@@ -760,9 +670,7 @@
// Actually *wait* for target frame, and never skip any action
size_t lastloaded = target_sprite->get_loaded_frames();
- if ( lastloaded < framenum )
- {
- //log_debug(_("%s: frame %u not reached yet (loaded %u for sprite %s),
skipping next %u actions"), __FUNCTION__, framenum, lastloaded,
target_sprite->getTarget(), skip);
+ if (lastloaded < framenum) {
// better delegate this to ActionExec
thread.skip_actions(skip);
}
@@ -772,7 +680,6 @@
void
ActionSetTarget(ActionExec& thread)
{
-
const action_buffer& code = thread.code;
size_t pc = thread.getCurrentPC();
@@ -781,7 +688,7 @@
#endif
// Change the movie we're working on.
- std::string target_name ( code.read_string(pc+3) );
+ const std::string target_name(code.read_string(pc+3));
commonSetTarget(thread, target_name);
}
@@ -789,20 +696,17 @@
void
ActionGotoLabel(ActionExec& thread)
{
-
as_environment& env = thread.env;
const action_buffer& code = thread.code;
const char* frame_label = code.read_string(thread.getCurrentPC()+3);
DisplayObject *target = env.get_target();
MovieClip *target_sprite = target ? target->to_movie() : 0;
- if ( ! target_sprite )
- {
- log_error(_("%s: environment target is null or not a MovieClip"),
- __FUNCTION__);
+ if (!target_sprite) {
+ log_error(_("GotoLabel: environment target is null or not a "
+ "MovieClip"));
}
- else
- {
+ else {
target_sprite->goto_labeled_frame(frame_label);
}
}
@@ -810,7 +714,6 @@
void
ActionAdd(ActionExec& thread)
{
-
as_environment& env = thread.env;
const double operand2 = env.top(0).to_number();
@@ -830,7 +733,6 @@
void
ActionMultiply(ActionExec& thread)
{
-
as_environment& env = thread.env;
const double operand2 = env.top(0).to_number();
@@ -847,14 +749,12 @@
void
ActionDivide(ActionExec& thread)
{
-
as_environment& env = thread.env;
const double operand2 = env.top(0).to_number();
const double operand1 = env.top(1).to_number();
- if (operand2 == 0)
- {
+ if (operand2 == 0) {
if (env.get_version() < 5) {
env.top(1).set_string("#ERROR#");
}
@@ -872,8 +772,7 @@
}
}
- else
- {
+ else {
env.top(1) = operand1 / operand2;
}
env.drop(1);
@@ -882,7 +781,6 @@
void
ActionEqual(ActionExec& thread)
{
-
as_environment& env = thread.env;
#if GNASH_PARANOIA_LEVEL > 1
@@ -912,7 +810,7 @@
env.top(1).set_bool(d2 < d1);
// Flash4 used 1 and 0 as return from this tag
- if ( env.get_version() < 5 ) convertToNumber(env.top(1), getVM(env));
+ if (env.get_version() < 5) convertToNumber(env.top(1), getVM(env));
env.drop(1);
}
@@ -940,7 +838,6 @@
void
ActionLogicalNot(ActionExec& thread)
{
-
as_environment& env = thread.env;
env.top(0).set_bool(! env.top(0).to_bool());
@@ -952,7 +849,6 @@
void
ActionStringEq(ActionExec& thread)
{
-
as_environment& env = thread.env;
const int version = env.get_version();
@@ -987,7 +883,6 @@
void
ActionSubString(ActionExec& thread)
{
-
// substring("string", base, size)
// SWF4 function, deprecated in favour of String.substring.
// 1-based (String object methods are 0-based).
@@ -1004,9 +899,7 @@
const std::wstring wstr = utf8::decodeCanonicalString(
strval.to_string(version), version);
-
- if (size < 0)
- {
+ if (size < 0) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Negative size passed to ActionSubString, "
"taking as whole length"));
@@ -1023,8 +916,7 @@
// TODO: if 'start' or 'size' do not evaluate to numbers return
// the empty string (how do we check if they evaluate ??)
- if ( start < 1 )
- {
+ if (start < 1) {
IF_VERBOSE_ASCODING_ERRORS (
log_aserror(_("Start is less then 1 in ActionSubString, "
"setting to 1."));
@@ -1034,8 +926,7 @@
// If start is longer than the string length, return empty
// string
- else if (static_cast<unsigned int>(start) > wstr.length() )
- {
+ else if (static_cast<unsigned int>(start) > wstr.length() ) {
IF_VERBOSE_ASCODING_ERRORS (
log_aserror(_("Start goes beyond input string in ActionSubString, "
"returning the empty string."));
@@ -1048,11 +939,10 @@
// Adjust the start for our own use.
--start;
- if (static_cast<unsigned int>(start + size) > wstr.length())
- {
+ if (static_cast<unsigned int>(start + size) > wstr.length()) {
IF_VERBOSE_ASCODING_ERRORS (
- log_aserror(_("start + size goes beyond input string in
ActionSubString, "
- "adjusting size"));
+ log_aserror(_("start + size goes beyond input string in "
+ "ActionSubString, adjusting size"));
);
size = wstr.length() - start;
}
@@ -1071,10 +961,7 @@
void
ActionPop(ActionExec& thread)
{
-
as_environment& env = thread.env;
- // this is an overhead only if SWF is malformed.
-
env.drop(1);
}
@@ -1088,7 +975,6 @@
void
ActionGetVariable(ActionExec& thread)
{
-
as_environment& env = thread.env;
as_value& top_value = env.top(0);
@@ -1125,7 +1011,6 @@
void
ActionSetVariable(ActionExec& thread)
{
-
as_environment& env = thread.env;
const std::string& name = env.top(1).to_string();
@@ -1153,11 +1038,9 @@
env.drop(2);
}
-// See: http://sswf.sourceforge.net/SWFalexref.html#action_get_dynamic
void
ActionSetTargetExpression(ActionExec& thread)
{
-
as_environment& env = thread.env;
// we don't ues the target sprite directly, instead we fetch the
@@ -1190,22 +1073,19 @@
void
ActionGetProperty(ActionExec& thread)
{
-
as_environment& env = thread.env;
as_value& tgt_val = env.top(1);
std::string tgt_str = tgt_val.to_string();
DisplayObject *target = NULL;
- if ( tgt_str.empty() )
- {
+ if (tgt_str.empty()) {
target = get<DisplayObject>(thread.getTarget());
if (!target) {
log_error(_("ActionGetProperty(<empty>) called, but current "
"target is not a DisplayObject"));
}
}
- else
- {
+ else {
target = env.find_target(tgt_str);
}
@@ -1217,12 +1097,11 @@
if (target) {
getIndexedProperty(prop_number, *target, env.top(1));
}
- else
- {
+ else {
// ASCODING error ? (well, last time it was a gnash error ;)
- IF_VERBOSE_ASCODING_ERRORS (
- log_aserror(_("Could not find GetProperty target (%s)"),
- tgt_val);
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror(_("Could not find GetProperty target (%s)"),
+ tgt_val);
);
env.top(1) = as_value();
}
@@ -1232,7 +1111,6 @@
void
ActionSetProperty(ActionExec& thread)
{
-
as_environment& env = thread.env;
DisplayObject *target = env.find_target(env.top(2).to_string());
@@ -1245,11 +1123,10 @@
if (target) {
setIndexedProperty(prop_number, *target, prop_val);
}
- else
- {
- IF_VERBOSE_ASCODING_ERRORS (
- log_aserror(_("ActionSetProperty: can't find target %s for setting
property %s"),
- env.top(2), prop_number);
+ else {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror(_("ActionSetProperty: can't find target %s for "
+ "setting property %s"), env.top(2), prop_number);
)
}
env.drop(3);
@@ -1258,20 +1135,21 @@
void
ActionDuplicateClip(ActionExec& thread)
{
- //GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
// Movies should be attachable from -16384 to 2130690044. See
// Tests in misc-ming.all/DepthLimitsTest.c.
- const double depth = env.top(0).to_number() +
DisplayObject::staticDepthOffset;
+ const double depth = env.top(0).to_number() +
+ DisplayObject::staticDepthOffset;
// This also checks for overflow, as both numbers are expressible as
// boost::int32_t.
if (depth < DisplayObject::lowerAccessibleBound ||
- depth > DisplayObject::upperAccessibleBound)
- {
+ depth > DisplayObject::upperAccessibleBound) {
+
IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("duplicateMovieClip: invalid depth %d passed; not
duplicating"), depth);
+ log_aserror(_("duplicateMovieClip: invalid depth %d passed; "
+ "not duplicating"), depth);
);
env.drop(3);
return;
@@ -1283,10 +1161,10 @@
const std::string& path = env.top(2).to_string();
DisplayObject* ch = env.find_target(path);
- if ( ! ch )
- {
+ if (!ch) {
IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("Path given to duplicateMovieClip(%s) doesn't point
to a DisplayObject"),
+ log_aserror(_("Path given to duplicateMovieClip(%s) doesn't "
+ "point to a DisplayObject"),
path);
);
env.drop(3);
@@ -1294,8 +1172,7 @@
}
MovieClip* sprite = ch->to_movie();
- if ( ! sprite )
- {
+ if (!sprite) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Path given to duplicateMovieClip(%s) is not a sprite"),
path);
@@ -1311,31 +1188,28 @@
void
ActionRemoveClip(ActionExec& thread)
{
-
as_environment& env = thread.env;
const std::string path = env.pop().to_string();
DisplayObject* ch = env.find_target(path);
- if ( ! ch )
- {
+ if (!ch) {
IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("Path given to removeMovieClip(%s) doesn't point to a
DisplayObject"),
- path);
+ log_aserror(_("Path given to removeMovieClip(%s) doesn't "
+ "point to a DisplayObject"),
+ path);
);
return;
}
MovieClip* sprite = ch->to_movie();
- if ( ! sprite )
- {
+ if (!sprite) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Path given to removeMovieClip(%s) is not a sprite"),
path);
);
return;
}
-
sprite->removeMovieClip();
}
@@ -1343,9 +1217,7 @@
void
ActionTrace(ActionExec& thread)
{
-
as_environment& env = thread.env;
-
const std::string val = env.pop().to_string();
// Logging with a std::string here fails the swfdec testsuite,
@@ -1365,69 +1237,56 @@
assert(thread.atActionTag(SWF::ACTION_STARTDRAGMOVIE));
#endif
-
-
drag_state st;
-
DisplayObject* tgt = env.find_target(env.top(0).to_string());
- if ( tgt )
- {
+ if (tgt) {
// mark this DisplayObject as script transformed.
tgt->transformedByScript();
st.setCharacter( tgt );
}
- else
- {
+ else {
IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("startDrag: unknown target '%s'"),
- env.top(0));
+ log_aserror(_("startDrag: unknown target '%s'"), env.top(0));
);
}
- st.setLockCentered( env.top(1).to_bool() );
- if ( env.top(2).to_bool() ) // has bounds !
- {
+ st.setLockCentered(env.top(1).to_bool());
+
+ // Handle bounds.
+ if (env.top(2).to_bool()) {
// strk: this works if we didn't drop any before, in
// a contrary case (if we used pop(), which I suggest)
// we must remember to updated this as required
-
-
boost::int32_t y1 = pixelsToTwips(env.top(3).to_number());
boost::int32_t x1 = pixelsToTwips(env.top(4).to_number());
boost::int32_t y0 = pixelsToTwips(env.top(5).to_number());
boost::int32_t x0 = pixelsToTwips(env.top(6).to_number());
// check for swapped values
- if ( y1 < y0 )
- {
+ if (y1 < y0) {
IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("Y values in ActionStartDrag swapped, fixing"));
+ log_swferror(_("Y values in ActionStartDrag swapped, fixing"));
);
std::swap(y1, y0);
}
- if ( x1 < x0 )
- {
+ if (x1 < x0) {
IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("X values in ActionStartDrag swapped, fixing"));
+ log_swferror(_("X values in ActionStartDrag swapped, fixing"));
);
std::swap(x1, x0);
}
-
- SWFRect bounds(x0, y0, x1, y1);
+ const SWFRect bounds(x0, y0, x1, y1);
st.setBounds(bounds);
-
env.drop(4);
}
env.drop(3);
- if (tgt)
- {
+ if (tgt) {
VM& vm = getVM(env);
vm.getRoot().set_drag_state(st);
}
-
}
void
@@ -1822,8 +1681,6 @@
size = length - start;
}
- //log_debug("Adjusted start:%d size:%d", start, size);
-
if (encoding == ENCGUESS_OTHER)
{
env.top(0).set_string(str.substr(start, size));
@@ -3195,13 +3052,11 @@
env.push(as_value());
return;
}
-
}
void
ActionInstanceOf(ActionExec& thread)
{
-
as_environment& env = thread.env;
// Get the "super" function
@@ -3231,7 +3086,6 @@
void
ActionEnum2(ActionExec& thread)
{
-
as_environment& env = thread.env;
// Get the object.
@@ -3260,8 +3114,8 @@
{
as_environment& env = thread.env;
- int operand1 = toInt(env.top(1));
- int operand2 = toInt(env.top(0));
+ const int operand1 = toInt(env.top(1));
+ const int operand2 = toInt(env.top(0));
env.top(1) = operand1 & operand2;
env.drop(1);
@@ -3270,11 +3124,10 @@
void
ActionBitwiseOr(ActionExec& thread)
{
-
as_environment& env = thread.env;
- int operand1 = toInt(env.top(1));
- int operand2 = toInt(env.top(0));
+ const int operand1 = toInt(env.top(1));
+ const int operand2 = toInt(env.top(0));
env.top(1) = operand1|operand2;
env.drop(1);
@@ -3283,11 +3136,10 @@
void
ActionBitwiseXor(ActionExec& thread)
{
-
as_environment& env = thread.env;
- int operand1 = toInt(env.top(1));
- int operand2 = toInt(env.top(0));
+ const int operand1 = toInt(env.top(1));
+ const int operand2 = toInt(env.top(0));
env.top(1) = operand1^operand2;
env.drop(1);
@@ -3331,7 +3183,6 @@
void
ActionShiftRight2(ActionExec& thread)
{
-
as_environment& env = thread.env;
boost::uint32_t amount = toInt(env.top(0));
@@ -3350,7 +3201,7 @@
as_environment& env = thread.env;
env.top(1).set_bool(env.top(1).strictly_equals(env.top(0)));
- env.drop(1);
+ env.drop(1);
}
void
@@ -3429,39 +3280,43 @@
// Code starts at thread.getNextPC() as the DefineFunction tag
// contains name and args, while next tag is first tag
// of the function body.
- swf_function* func = new swf_function(code, env, thread.getNextPC(),
+ Function2* func = new Function2(code, env, thread.getNextPC(),
thread.getScopeStack());
- func->set_is_function2();
+ // We're stuck initializing our own prototype at the moment.
+ as_object* proto = getGlobal(env).createObject();
+ proto->init_member(NSV::PROP_CONSTRUCTOR, func);
+ func->init_member(NSV::PROP_PROTOTYPE, proto);
+ func->init_member(NSV::PROP_CONSTRUCTOR,
+ as_function::getFunctionConstructor());
size_t i = thread.getCurrentPC() + 3; // skip tag id and length
// Extract name.
// @@ security: watch out for possible missing terminator here!
- std::string name = code.read_string(i);
+ const std::string name = code.read_string(i);
i += name.length() + 1; // add NULL-termination
// Get number of arguments.
- const unsigned nargs = code.read_int16(i);
+ const boost::uint16_t nargs = code.read_uint16(i);
i += 2;
// Get the count of local registers used by this function.
- boost::uint8_t register_count = code[i];
- i++;
+ const boost::uint8_t register_count = code[i];
+ ++i;
- func->set_local_register_count(register_count);
+ func->setRegisterCount(register_count);
// Flags, for controlling register assignment of implicit args.
- boost::uint16_t flags = code.read_int16(i);
+ const boost::uint16_t flags = code.read_uint16(i);
i += 2;
- func->set_function2_flags(flags);
+ func->setFlags(flags);
string_table& st = getStringTable(env);
// Get the register assignments and names of the arguments.
- for (unsigned n = 0; n < nargs; n++)
- {
+ for (size_t n = 0; n < nargs; ++n) {
boost::uint8_t arg_register = code[i];
++i;
@@ -3476,9 +3331,8 @@
boost::uint16_t code_size = code.read_int16(i);
// Check code_size value consistency
- size_t actionbuf_size = thread.code.size();
- if ( thread.getNextPC() + code_size > actionbuf_size )
- {
+ const size_t actionbuf_size = thread.code.size();
+ if (thread.getNextPC() + code_size > actionbuf_size) {
IF_VERBOSE_MALFORMED_SWF(
log_swferror(_("function2 code len (%u) "
"overflows DOACTION tag boundaries "
@@ -3492,7 +3346,7 @@
}
i += 2;
- func->set_length(code_size);
+ func->setLength(code_size);
// Skip the function body (don't interpret it now).
thread.adjustNextPC(code_size);
@@ -3500,8 +3354,7 @@
// If we have a name, then save the function in this
// environment under that name.
as_value function_value(func);
- if (!name.empty())
- {
+ if (!name.empty()) {
IF_VERBOSE_ACTION(
log_action(_("DefineFunction2: named function '%s' "
"starts at PC %d"), name, func->getStartPC());
@@ -3511,22 +3364,13 @@
}
// Otherwise push the function literal on the stack
- else
- {
+ else {
IF_VERBOSE_ACTION(
log_action(_("DefineFunction2: anonymous function starts at "
"PC %d"), func->getStartPC());
);
env.push(function_value);
}
-#ifdef USE_DEBUGGER
- // WARNING: toObject(getGlobal(thread.env), function_value) can return a
newly allocated
- // thing into the intrusive_ptr, so the debugger
- // will be left with a deleted object !!
- // Rob: we don't want to use void pointers here..
- boost::intrusive_ptr<as_object> o = toObject(getGlobal(thread.env),
function_value);
- debugger.addSymbol(o.get(), name);
-#endif
}
void
@@ -3648,7 +3492,6 @@
void
ActionDefineFunction(ActionExec& thread)
{
-
as_environment& env = thread.env;
const action_buffer& code = thread.code;
@@ -3658,42 +3501,44 @@
assert( length >= 0 );
#endif
- // Create a new swf_function
+ // Create a new Function
// Code starts at thread.getNextPC() as the DefineFunction tag
// contains name and args, while next tag is first tag
// of the function body.
- swf_function* func = new swf_function(code, env, thread.getNextPC(),
+ Function* func = new Function(code, env, thread.getNextPC(),
thread.getScopeStack());
+
+ // We're stuck initializing our own prototype at the moment.
+ as_object* proto = getGlobal(env).createObject();
+ proto->init_member(NSV::PROP_CONSTRUCTOR, func);
+ func->init_member(NSV::PROP_PROTOTYPE, proto);
+ func->init_member(NSV::PROP_CONSTRUCTOR,
+ as_function::getFunctionConstructor());
size_t i = thread.getCurrentPC() + 3;
// Extract name.
// @@ security: watch out for possible missing terminator here!
- std::string name = code.read_string(i);
+ const std::string name = code.read_string(i);
i += name.length() + 1;
// Get number of arguments.
- unsigned nargs = code.read_int16(i);
+ const size_t nargs = code.read_uint16(i);
i += 2;
string_table& st = getStringTable(env);
// Get the names of the arguments.
- for (unsigned n = 0; n < nargs; n++)
- {
+ for (size_t n = 0; n < nargs; ++n) {
const std::string arg(code.read_string(i));
-
- // @@ security: watch out for possible missing terminator here!
func->add_arg(0, st.find(arg));
- // wouldn't it be simpler to use strlen(arg)+1 ?
i += arg.size() + 1;
}
// Get the length of the actual function code.
- boost::int16_t code_size = code.read_int16(i);
-
- func->set_length(code_size);
-
+ const boost::uint16_t code_size = code.read_uint16(i);
+
+ func->setLength(code_size);
// Skip the function body (don't interpret it now).
// getNextPC() is assumed to point to first action of
@@ -3703,7 +3548,7 @@
// If we have a name, then save the function in this
// environment under that name.
- as_value function_value(func);
+ as_value function_value(func);
if (!name.empty())
{
IF_VERBOSE_ACTION(
@@ -3736,14 +3581,11 @@
env.push(function_value);
}
-
- //env.dump_stack();
}
void
ActionSetRegister(ActionExec& thread)
{
-
as_environment& env = thread.env;
const action_buffer& code = thread.code;
=== modified file 'libcore/vm/ASHandlers.h'
--- a/libcore/vm/ASHandlers.h 2010-03-12 03:52:58 +0000
+++ b/libcore/vm/ASHandlers.h 2010-07-24 14:38:36 +0000
@@ -53,25 +53,19 @@
public:
ActionHandler();
- ActionHandler(ActionType type, ActionCallback func);
- ActionHandler(ActionType type, std::string name,
- ActionCallback func);
- ActionHandler(ActionType type, std::string name,
- ActionCallback func, ArgumentType format);
+ ActionHandler(ActionType type, ActionCallback func,
+ ArgumentType format = ARG_NONE);
/// Execute the action
void execute(ActionExec& thread) const;
- void toggleDebug(bool state) const { _debug = state; }
ActionType getType() const { return _type; }
- std::string getName() const { return _name; }
ArgumentType getArgFormat() const { return _arg_format; }
private:
+
ActionType _type;
- std::string _name;
ActionCallback _callback;
- mutable bool _debug;
ArgumentType _arg_format;
};
@@ -80,42 +74,34 @@
{
public:
- // Indexed by action id
- typedef std::vector<ActionHandler> container_type;
-
/// Return the singleton instance of SWFHandlers class
static const SWFHandlers& instance();
/// Execute the action identified by 'type' action type
void execute(ActionType type, ActionExec& thread) const;
- void toggleDebug(bool state) { _debug = state; }
-
- size_t size() const { return get_handlers().size(); }
-
- ActionType lastType() const
- {
+ size_t size() const { return _handlers.size(); }
+
+ ActionType lastType() const {
return ACTION_GOTOEXPRESSION;
}
- const ActionHandler &operator[] (ActionType x) const
- {
- return get_handlers()[x];
+ const ActionHandler& operator[](ActionType x) const {
+ return _handlers[x];
}
- const char* action_name(ActionType x) const;
-
private:
- static container_type & get_handlers();
-
- bool _debug;
-
// Use the ::instance() method to get a reference
SWFHandlers();
// You won't destroy a singleton
~SWFHandlers();
+
+ // Indexed by action id
+ typedef std::vector<ActionHandler> container_type;
+
+ container_type _handlers;
};
=== modified file 'libcore/vm/ActionExec.cpp'
--- a/libcore/vm/ActionExec.cpp 2010-07-24 12:51:39 +0000
+++ b/libcore/vm/ActionExec.cpp 2010-07-24 13:44:22 +0000
@@ -25,7 +25,7 @@
#include "ActionExec.h"
#include "action_buffer.h"
-#include "swf_function.h"
+#include "Function.h"
#include "log.h"
#include "VM.h"
#include "GnashException.h"
@@ -67,7 +67,7 @@
static Debugger& debugger = Debugger::getDefaultInstance();
#endif
-ActionExec::ActionExec(const swf_function& func, as_environment& newEnv,
+ActionExec::ActionExec(const Function& func, as_environment& newEnv,
as_value* nRetVal, as_object* this_ptr)
:
code(func.getActionBuffer()),
@@ -101,7 +101,7 @@
// push 'i' getvariable
// get var: i=[undefined]
if (code.getDefinitionVersion() > 5) {
- // We assume that the swf_function () operator already initialized
+ // We assume that the Function () operator already initialized
// its environment so that its activation object is now in the
// top element of the CallFrame stack
CallFrame& topFrame = getVM(newEnv).currentCall();
=== modified file 'libcore/vm/ActionExec.h'
--- a/libcore/vm/ActionExec.h 2010-07-24 12:51:39 +0000
+++ b/libcore/vm/ActionExec.h 2010-07-24 13:44:22 +0000
@@ -31,7 +31,7 @@
// Forward declarations
namespace gnash {
class as_value;
- class swf_function;
+ class Function;
class ActionExec;
}
@@ -142,7 +142,7 @@
/// @param newEnv The execution environment (variables scope, stack
etc.)
/// @param nRetval Where to return a value. If NULL any return will
/// be discarded.
- ActionExec(const swf_function& func, as_environment& newEnv,
+ ActionExec(const Function& func, as_environment& newEnv,
as_value* nRetVal, as_object* this_ptr);
/// \brief
@@ -345,7 +345,7 @@
/// structure including return address
/// and maintained in a stack (the call stack)
///
- const swf_function* _func;
+ const Function* _func;
/// The 'this' pointer, if this is a function call
as_object* _this_ptr;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r12334: Code cleanups and rearrangements to simplify design.,
Benjamin Wolsey <=