~ubuntu-branches/ubuntu/saucy/gnash/saucy-proposed

« back to all changes in this revision

Viewing changes to libcore/vm/fn_call.h

  • Committer: Bazaar Package Importer
  • Author(s): Sindhudweep Narayan Sarkar
  • Date: 2009-10-07 00:06:10 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20091007000610-mj9rwqe774gizn1j
Tags: 0.8.6-0ubuntu1
new upstream release 0.8.6 (LP: #435897)

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include "as_environment.h" // for inlines (arg)
26
26
#include "as_object.h" // for dtor visibility by boost::intrusive_ptr
27
27
#include "smart_ptr.h"
 
28
#include "VM.h"
28
29
 
29
30
#include <cassert> // for inlines (arg)
30
31
#include <ostream> // for inlines (dump_args)
41
42
 
42
43
namespace gnash {
43
44
 
 
45
/// A class to contain transferable arguments for a fn_call.
 
46
//
 
47
/// The operators += and , are implemented for intuitive syntax:
 
48
//
 
49
/// FunctionArgs<as_value> args; args += 0.0, "string", NaN.
 
50
//
 
51
/// This may have unexpected side effects if it is used in unexpected ways,
 
52
/// so stick to using such lists, or use operator += repeatedly.
 
53
//
 
54
/// The arguments can be moved to another container, and this happens when
 
55
/// the FunctionArgs object is passed to fn_call. It will still be valid
 
56
/// afterwards, but will contain no arguments.
 
57
template<typename T>
 
58
class FunctionArgs
 
59
{
 
60
public:
 
61
 
 
62
    typedef typename std::vector<T>::size_type size_type;
 
63
    typedef std::vector<T> container_type;
 
64
    typedef T value_type;
 
65
 
 
66
    FunctionArgs() {}
 
67
 
 
68
    FunctionArgs& operator+=(const T& t) {
 
69
        _v.push_back(t);
 
70
        return *this;
 
71
    }
 
72
 
 
73
    FunctionArgs& operator,(const T& t) {
 
74
        _v.push_back(t);
 
75
        return *this;
 
76
    }
 
77
 
 
78
    void swap(std::vector<T>& to) {
 
79
        std::swap(_v, to);
 
80
    }
 
81
 
 
82
    size_type size() const {
 
83
        return _v.size();
 
84
    }
 
85
 
 
86
private:
 
87
    std::vector<T> _v;
 
88
};
 
89
 
44
90
 
45
91
/// \brief
46
92
/// Parameters/environment for builtin or user-defined functions
48
94
class fn_call
49
95
{
50
96
public:
 
97
    typedef FunctionArgs<as_value> Args;
 
98
 
51
99
        /// The as_object (or a pointer derived thereof) on which this call
52
100
        /// is taking place.
53
 
        boost::intrusive_ptr<as_object> this_ptr;
 
101
        as_object* this_ptr;
54
102
 
55
103
        /// The "super" object in this function call context
56
104
        as_object* super;
57
105
 
58
106
        /// Number of arguments to this ActionScript function call.
59
 
        unsigned int nargs;
 
107
    Args::size_type nargs;
60
108
 
61
109
    /// Definition containing caller code. 0 if spontaneous (system event).
62
110
    const movie_definition* callerDef;
67
115
        super(fn.super),
68
116
                nargs(fn.nargs),
69
117
        callerDef(fn.callerDef),
70
 
        _env(fn._env)
 
118
        _new(false),
 
119
        _env(fn._env),
 
120
        _args(fn._args)
71
121
        {
72
 
                if (fn._args.get()) {
73
 
                        _args.reset(new std::vector<as_value>(*fn._args));
74
 
        }
75
122
        }
76
123
 
77
124
        fn_call(const fn_call& fn, as_object* this_in, as_object* sup = 0)
80
127
        super(sup),
81
128
        nargs(fn.nargs),
82
129
        callerDef(fn.callerDef),
83
 
                _env(fn._env)
 
130
        _new(false),
 
131
                _env(fn._env),
 
132
        _args(fn._args)
84
133
        {
85
 
                if (fn._args.get()) {
86
 
                        _args.reset(new std::vector<as_value>(*fn._args));
87
 
        }
88
134
        }
89
135
 
90
 
        fn_call(as_object* this_in, as_environment& env_in,
 
136
        fn_call(as_object* this_in, const as_environment& env_in,
91
137
                        int nargs_in, size_t first_in, as_object* sup = 0)
92
138
                :
93
139
                this_ptr(this_in),
94
140
                super(sup),
95
141
                nargs(nargs_in),
96
142
        callerDef(0),
 
143
        _new(false),
97
144
                _env(env_in)
98
145
        {
99
146
                assert(first_in + 1 == env_in.stack_size());
100
147
                readArgs(env_in, first_in, nargs);
101
148
        }
102
149
 
103
 
        fn_call(as_object* this_in, as_environment& env_in,
104
 
                        std::auto_ptr<std::vector<as_value> > args, as_object* sup = 0)
 
150
        fn_call(as_object* this_in, const as_environment& env_in,
 
151
            Args& args, as_object* sup = 0, bool isNew = false)
105
152
                :
106
153
                this_ptr(this_in),
107
154
                super(sup),
108
 
                nargs(args->size()),
 
155
                nargs(args.size()),
109
156
        callerDef(0),
110
 
                _env(env_in),
111
 
                _args(args)
 
157
        _new(isNew),
 
158
                _env(env_in)
112
159
        {
 
160
        args.swap(_args);
113
161
        }
114
162
 
115
 
        fn_call(as_object* this_in, as_environment& env_in)
 
163
        fn_call(as_object* this_in, const as_environment& env_in)
116
164
                :
117
165
                this_ptr(this_in),
118
166
                super(0),
119
167
                nargs(0),
120
168
        callerDef(0),
121
 
                _env(env_in),
122
 
                _args(0)
 
169
        _new(false),
 
170
                _env(env_in)
123
171
        {
124
172
        }
125
173
 
138
186
                // For the future, we might use an explicit flag instead
139
187
                // as I belive there are some cases in which 'this' is
140
188
                // undefined even in a normal function call.
141
 
                return (this_ptr == 0);
 
189
                return _new;
142
190
        }
143
191
 
144
192
        /// Access a particular argument.
145
 
        const as_value& arg(unsigned int n) const
 
193
        const Args::value_type& arg(unsigned int n) const
146
194
        {
147
195
                assert(n < nargs);
148
 
                return (*_args)[n]; 
 
196
                return _args[n]; 
149
197
        }
150
198
 
151
 
    const std::vector<as_value>& getArgs() const {
152
 
        return *_args;
 
199
    const Args::container_type& getArgs() const {
 
200
        return _args;
153
201
    }
154
202
 
155
203
        void drop_bottom()
156
204
        {
157
 
                assert(_args.get() && !(*_args).empty());
158
 
                for (size_t i=0; i<(*_args).size()-1; ++i)
159
 
                {
160
 
                        (*_args)[i] = (*_args)[i+1];
161
 
                }
162
 
                _args->pop_back();
 
205
                assert(!_args.empty());
 
206
        _args.erase(_args.begin());
163
207
                --nargs;
164
208
        }
165
209
 
166
 
        as_environment& env() const
 
210
        const as_environment& env() const
167
211
        {
168
212
                return _env;
169
213
        }
171
215
        /// Dump arguments to given output stream
172
216
        void dump_args(std::ostream& os) const
173
217
        {
174
 
                for (unsigned int i=0; i<nargs; ++i)
 
218
                for (size_t i = 0; i < nargs; ++i)
175
219
                {
176
220
                        if ( i ) os << ", ";
177
221
                        os << arg(i).toDebugString();
188
232
 
189
233
        void resetArgs()
190
234
        {
191
 
                nargs=0;
192
 
                _args->clear();
 
235
                nargs = 0;
 
236
                _args.clear();
193
237
        }
194
238
 
195
 
        void pushArg(const as_value& arg)
 
239
        void pushArg(const Args::value_type& arg)
196
240
        {
197
 
                nargs++;
198
 
                _args->push_back(arg);
 
241
                ++nargs;
 
242
                _args.push_back(arg);
199
243
        }
200
244
 
201
245
private:
202
246
 
 
247
    bool _new;
 
248
 
203
249
        /// The ActionScript environment in which the function call is taking
204
250
        /// place. This contains, among other things, the function arguments.
205
 
        as_environment& _env;
 
251
        const as_environment& _env;
206
252
 
207
253
        /// The actual arguments
208
 
        std::auto_ptr< std::vector<as_value> > _args;
 
254
    Args::container_type _args;
209
255
 
210
 
        void readArgs(as_environment& env, int first_in, int nargs)
 
256
        void readArgs(const as_environment& env, int first_in, size_t nargs)
211
257
        {
212
 
                _args.reset(new std::vector<as_value>);
213
 
                for (int i=0; i<nargs; ++i)
214
 
                        _args->push_back(env.bottom(first_in - i));
 
258
                _args.clear();
 
259
                for (size_t i = 0; i < nargs; ++i) {
 
260
                        _args.push_back(env.bottom(first_in - i));
 
261
        }
215
262
        }
216
263
 
217
264
};
218
265
 
219
 
/// Signature of a builtin function callable from ActionScript
220
 
typedef as_value (*as_c_function_ptr)(const fn_call& fn);
221
 
 
 
266
/// Check whether the currently executing code is AS3 (ABC)
 
267
//
 
268
/// This is a non-member, non-friend function for better encapsulation.
 
269
/// TODO: drop these when there is a better design!
 
270
inline bool
 
271
isAS3(const fn_call& fn)
 
272
{
 
273
    return fn.getVM().getAVMVersion() == VM::AVM2;
 
274
}
 
275
 
 
276
inline string_table&
 
277
getStringTable(const fn_call& fn)
 
278
{
 
279
    return fn.getVM().getStringTable();
 
280
}
 
281
 
 
282
inline movie_root&
 
283
getRoot(const fn_call& fn)
 
284
{
 
285
    return fn.getVM().getRoot();
 
286
}
 
287
 
 
288
inline int
 
289
getSWFVersion(const fn_call& fn)
 
290
{
 
291
    return fn.getVM().getSWFVersion();
 
292
}
 
293
 
 
294
inline VM&
 
295
getVM(const fn_call& fn)
 
296
{
 
297
    return fn.getVM();
 
298
}
 
299
 
 
300
inline Global_as*
 
301
getGlobal(const fn_call& fn)
 
302
{
 
303
    return fn.getVM().getGlobal();
 
304
}
222
305
 
223
306
} // namespace gnash
224
307
 
225
308
 
226
 
#endif // _GNASH_FN_CALL_H_
 
309
#endif 
227
310
 
228
311
 
229
312
// Local Variables: