2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "action_buffer.h"
26 #include "ActionExec.h"
28 #include "NativeFunction.h"
29 #include "Global_as.h"
30 #include "namedStrings.h"
31 #include "CallStack.h"
32 #include "DisplayObject.h"
36 Function::Function(const action_buffer
& ab
, as_environment
& env
,
37 size_t start
, const ScopeStack
& scopeStack
)
39 UserFunction(getGlobal(env
)),
42 _scopeStack(scopeStack
),
46 assert( _startPC
< _action_buffer
.size() );
49 TargetGuard::TargetGuard(as_environment
& e
, DisplayObject
* ch
,
54 from_orig(env
.get_original_target())
57 env
.set_original_target(och
);
61 TargetGuard::~TargetGuard()
64 env
.set_original_target(from_orig
);
69 Function::call(const fn_call
& fn
)
71 // Extract caller before pushing ourself on the call stack
74 as_object
* caller
= vm
.calling() ? &vm
.currentCall().function() : 0;
76 // Set up local stack frame, for parameters and locals.
77 FrameGuard
guard(getVM(fn
), *this);
78 CallFrame
& cf
= guard
.callFrame();
80 DisplayObject
* target
= _env
.target();
81 DisplayObject
* orig_target
= _env
.get_original_target();
83 // Some features are version-dependant.
84 const int swfversion
= getSWFVersion(fn
);
87 // In SWF5, when 'this' is a DisplayObject it becomes
88 // the target for this function call.
89 // See actionscript.all/setProperty.as
90 DisplayObject
* ch
= get
<DisplayObject
>(fn
.this_ptr
);
97 /// This is only needed for SWF5 (temp switch of target)
98 /// We do always and base 'target' value on SWF version.
99 /// TODO: simplify code by maybe using a custom as_environment
100 /// instead, so to get an "original" target being
101 /// the one set now (rather then the really original one)
102 /// TODO: test scope when calling functions defined in another timeline
103 /// (target, in particular).
104 TargetGuard
targetGuard(_env
, target
, orig_target
);
106 // Push the arguments onto the local frame.
107 for (size_t i
= 0, n
= _args
.size(); i
< n
; ++i
) {
109 assert(_args
[i
].reg
== 0);
111 setLocal(cf
, _args
[i
].name
, fn
.arg(i
));
114 // Still declare named arguments, even if
115 // they are not passed from caller
117 declareLocal(cf
, _args
[i
].name
);
122 setLocal(cf
, NSV::PROP_THIS
, fn
.this_ptr
? fn
.this_ptr
: as_value());
124 as_object
* super
= fn
.super
? fn
.super
:
125 fn
.this_ptr
? fn
.this_ptr
->get_super() : 0;
127 // Add 'super' (SWF6+ only)
128 if (super
&& swfversion
> 5) {
129 setLocal(cf
, NSV::PROP_SUPER
, super
);
133 as_object
* args
= getGlobal(fn
).createArray();
135 // Put 'arguments' in a local var.
136 setLocal(cf
, NSV::PROP_ARGUMENTS
, getArguments(*this, *args
, fn
, caller
));
138 // Execute the actions.
140 ActionExec(*this, _env
, &result
, fn
.this_ptr
)();
145 Function::setLength(size_t len
)
147 assert(_startPC
+ len
<= _action_buffer
.size());
152 Function::markReachableResources() const
154 std::for_each(_scopeStack
.begin(), _scopeStack
.end(),
155 std::mem_fun(&as_object::setReachable
));
157 _env
.markReachableResources();
159 // Invoke parent class marker
160 as_object::markReachableResources();
164 getArguments(Function
& callee
, as_object
& args
, const fn_call
& fn
,
168 for (size_t i
= 0; i
< fn
.nargs
; ++i
) {
169 callMethod(&args
, NSV::PROP_PUSH
, fn
.arg(i
));
172 args
.init_member(NSV::PROP_CALLEE
, &callee
);
173 args
.init_member(NSV::PROP_CALLER
, caller
);
178 } // end of gnash namespace