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

« back to all changes in this revision

Viewing changes to libcore/asobj/ClassHierarchy.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2008-10-13 14:29:49 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20081013142949-f6qdvnu4mn05ltdc
Tags: 0.8.4~~bzr9980-0ubuntu1
* new upstream release 0.8.4 (LP: #240325)
* ship new lib usr/lib/gnash/libmozsdk.so.* in mozilla-plugin-gnash
  - update debian/mozilla-plugin-gnash.install
* ship new lib usr/lib/gnash/libgnashnet.so.* in gnash-common
  - update debian/gnash-common.install
* add basic debian/build_head script to build latest CVS head packages.
  - add debian/build_head
* new sound architecture requires build depend on libsdl1.2-dev
  - update debian/control
* head build script now has been completely migrated to bzr (upstream +
  ubuntu)
  - update debian/build_head
* disable kde gui until klash/qt4 has been fixed; keep kde packages as empty
  packages for now.
  - update debian/rules
  - debian/klash.install
  - debian/klash.links
  - debian/klash.manpages
  - debian/konqueror-plugin-gnash.install
* drop libkonq5-dev build dependency accordingly
  - update debian/control
* don't install headers manually anymore. gnash doesnt provide a -dev
  package after all
  - update debian/rules
* update libs installed in gnash-common; libgnashserver-*.so is not available
  anymore (removed); in turn we add the new libgnashcore-*.so
  - update debian/gnash-common.install
* use -Os for optimization and properly pass CXXFLAGS=$(CFLAGS) to configure
  - update debian/rules
* touch firefox .autoreg in postinst of mozilla plugin
  - update debian/mozilla-plugin-gnash.postinst
* link gnash in ubufox plugins directory for the plugin alternative switcher
  - add debian/mozilla-plugin-gnash.links
* suggest ubufox accordingly
  - update debian/control
* add new required build-depends on libgif-dev
  - update debian/control
* add Xb-Npp-Description and Xb-Npp-File as new plugin database meta data
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
//   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
 
3
//
 
4
// This program is free software; you can redistribute it and/or modify
 
5
// it under the terms of the GNU General Public License as published by
 
6
// the Free Software Foundation; either version 3 of the License, or
 
7
// (at your option) any later version.
 
8
//
 
9
// This program is distributed in the hope that it will be useful,
 
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
// GNU General Public License for more details.
 
13
//
 
14
// You should have received a copy of the GNU General Public License
 
15
// along with this program; if not, write to the Free Software
 
16
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
17
//
 
18
 
 
19
#include "as_object.h"
 
20
#include "as_prop_flags.h"
 
21
#include "as_value.h"
 
22
#include "as_function.h" // for function_class_init
 
23
#include "button_character_instance.h"
 
24
#include "array.h"
 
25
#include "AsBroadcaster.h"
 
26
#include "Accessibility_as.h"
 
27
#include "Boolean.h"
 
28
#include "Camera.h"
 
29
#include "Color.h"
 
30
#include "ContextMenu.h"
 
31
#include "CustomActions.h"
 
32
#include "Date.h"
 
33
#include "Error_as.h"
 
34
#include "Global.h"
 
35
#include "String_as.h"
 
36
#include "Key.h"
 
37
#include "LoadVars_as.h"
 
38
#include "LocalConnection.h"
 
39
#include "Microphone.h"
 
40
#include "Number.h"
 
41
#include "Object.h"
 
42
#include "Math_as.h"
 
43
#include "Mouse.h"
 
44
#include "MovieClipLoader.h"
 
45
#include "movie_definition.h"
 
46
#include "NetConnection.h"
 
47
#include "NetStream.h"
 
48
#include "Selection.h"
 
49
#include "SharedObject.h"
 
50
#include "Sound.h"
 
51
#include "Stage.h"
 
52
#include "System_as.h"
 
53
#include "TextSnapshot.h"
 
54
#include "TextFormat.h"
 
55
#include "video_stream_instance.h"
 
56
#include "extension.h"
 
57
#include "VM.h"
 
58
#include "timers.h"
 
59
#include "URL.h" // for URL::encode and URL::decode (escape/unescape)
 
60
#include "builtin_function.h"
 
61
#include "edit_text_character.h"
 
62
#include "namedStrings.h"
 
63
#include "ClassHierarchy.h"
 
64
#include "builtin_function.h"
 
65
#include "XMLSocket_as.h"
 
66
#include "XML_as.h"
 
67
#include "xmlnode.h"
 
68
#include "asClass.h"
 
69
 
 
70
namespace gnash {
 
71
 
 
72
namespace { // anonymous namespace
 
73
 
 
74
class declare_extension_function : public as_function
 
75
{
 
76
private:
 
77
        ClassHierarchy::extensionClass mDeclaration;
 
78
        as_object *mTarget;
 
79
        Extension *mExtension;
 
80
 
 
81
public:
 
82
        bool isBuiltin() { return true; }
 
83
 
 
84
        declare_extension_function(ClassHierarchy::extensionClass &c,
 
85
                as_object *g, Extension* e) :
 
86
                as_function(getObjectInterface()),
 
87
                mDeclaration(c), mTarget(g), mExtension(e)
 
88
        {
 
89
                init_member("constructor", as_function::getFunctionConstructor().get());
 
90
        }
 
91
 
 
92
        virtual as_value operator()(const fn_call& /*fn*/)
 
93
        {
 
94
                string_table& st = VM::get().getStringTable();
 
95
                log_debug("Loading extension class %s", st.value(mDeclaration.name));
 
96
 
 
97
                as_value super;
 
98
                if (mDeclaration.super_name)
 
99
                {
 
100
                        // Check to be sure our super exists.
 
101
                        // This will trigger its instantiation if necessary.
 
102
                        if (!mTarget->get_member(mDeclaration.super_name, &super))
 
103
                        {
 
104
                                // Error here -- doesn't exist.
 
105
                                log_error("Can't find %s (Superclass of %s)",
 
106
                                        st.value(mDeclaration.super_name),
 
107
                                        st.value(mDeclaration.name));
 
108
                                super.set_undefined();
 
109
                                return super;
 
110
                        }
 
111
                        if (!super.is_as_function())
 
112
                        {
 
113
                                // Error here -- not an object.
 
114
                                log_error("%s (Superclass of %s) is not a function (%s)",
 
115
                                        st.value(mDeclaration.super_name),
 
116
                                        st.value(mDeclaration.name), super);
 
117
                                super.set_undefined();
 
118
                                return super;
 
119
                        }
 
120
                }
 
121
                if (mExtension->initModuleWithFunc(mDeclaration.file_name,
 
122
                        mDeclaration.init_name, *mTarget))
 
123
                {
 
124
                        // Successfully loaded it, now find it, set its proto, and return.
 
125
                        as_value us;
 
126
                        mTarget->get_member(mDeclaration.name, &us);
 
127
                        if (mDeclaration.super_name && !us.to_object()->hasOwnProperty(NSV::PROP_uuPROTOuu))
 
128
                        {
 
129
                                us.to_object()->set_prototype(super.to_as_function()->getPrototype());
 
130
                        }
 
131
                        return us;
 
132
                }
 
133
                // Error here -- not successful in loading.
 
134
                log_error("Could not load class %s", st.value(mDeclaration.name));
 
135
                super.set_undefined();
 
136
                return super;
 
137
        }
 
138
};
 
139
 
 
140
class declare_native_function : public as_function
 
141
{
 
142
private:
 
143
        ClassHierarchy::nativeClass mDeclaration;
 
144
        as_object *mTarget;
 
145
        Extension *mExtension;
 
146
 
 
147
public:
 
148
        bool isBuiltin() { return true; }
 
149
 
 
150
        declare_native_function(const ClassHierarchy::nativeClass &c,
 
151
                as_object *g, Extension *e) :
 
152
                as_function(getObjectInterface()),
 
153
                mDeclaration(c), mTarget(g), mExtension(e)
 
154
        {
 
155
                // does it make any sense to set a 'constructor' here ??
 
156
                //init_member("constructor", this);
 
157
                //init_member("constructor", as_function::getFunctionConstructor().get());
 
158
        }
 
159
 
 
160
        virtual as_value operator()(const fn_call& /*fn*/)
 
161
        {
 
162
                string_table& st = VM::get().getStringTable();
 
163
                log_debug("Loading native class %s", st.value(mDeclaration.name));
 
164
 
 
165
                mDeclaration.initializer(*mTarget);
 
166
                // Successfully loaded it, now find it, set its proto, and return.
 
167
                as_value us;
 
168
                if ( mTarget->get_member(mDeclaration.name, &us) )
 
169
                {
 
170
                        as_value super;
 
171
                        if (mDeclaration.super_name)
 
172
                        {
 
173
                                // Check to be sure our super exists.
 
174
                                // This will trigger its instantiation if necessary.
 
175
                                if (!mTarget->get_member(mDeclaration.super_name, &super))
 
176
                                {
 
177
                                        // Error here -- doesn't exist.
 
178
                                        log_error("Can't find %s (Superclass of %s)",
 
179
                                                st.value(mDeclaration.super_name),
 
180
                                                st.value(mDeclaration.name));
 
181
                                        super.set_undefined();
 
182
                                        return super;
 
183
                                }
 
184
                                if (!super.is_as_function())
 
185
                                {
 
186
                                        // Error here -- not an object.
 
187
                                        log_error("%s (Superclass of %s) is not a function (%s)",
 
188
                                                st.value(mDeclaration.super_name),
 
189
                                                st.value(mDeclaration.name), super);
 
190
                                        super.set_undefined();
 
191
                                        return super;
 
192
                                }
 
193
                                assert(super.to_as_function());
 
194
                        }
 
195
                        if ( ! us.to_object() )
 
196
                        {
 
197
                                log_error("Native class %s is not an object after initialization (%s)",
 
198
                                        st.value(mDeclaration.name), us);
 
199
                        }
 
200
                        if (mDeclaration.super_name && !us.to_object()->hasOwnProperty(NSV::PROP_uuPROTOuu))
 
201
                        {
 
202
                                us.to_object()->set_prototype(super.to_as_function()->getPrototype());
 
203
                        }
 
204
                }
 
205
                else
 
206
                {
 
207
                        log_error("Native class %s is not found after initialization", 
 
208
                                st.value(mDeclaration.name));
 
209
                }
 
210
                return us;
 
211
        }
 
212
};
 
213
 
 
214
} // end anonymous namespace
 
215
 
 
216
ClassHierarchy::~ClassHierarchy()
 
217
{
 
218
}
 
219
 
 
220
bool
 
221
ClassHierarchy::declareClass(extensionClass& c)
 
222
{
 
223
        if (mExtension == NULL)
 
224
                return false; // Extensions can't be loaded.
 
225
 
 
226
        mGlobalNamespace->stubPrototype(c.name);
 
227
        mGlobalNamespace->getClass(c.name)->setDeclared();
 
228
        mGlobalNamespace->getClass(c.name)->setSystem();
 
229
 
 
230
        boost::intrusive_ptr<as_function> getter =
 
231
                new declare_extension_function(c, mGlobal, mExtension);
 
232
 
 
233
        return mGlobal->init_destructive_property(c.name, *getter);
 
234
}
 
235
 
 
236
bool
 
237
ClassHierarchy::declareClass(const nativeClass& c)
 
238
{
 
239
        // For AS2 and below, registering with mGlobal _should_ make it equivalent
 
240
        // to being in the global namespace, since everything is global there.
 
241
        asNamespace *nso = findNamespace(c.namespace_name);
 
242
        if (!nso)
 
243
                nso = addNamespace(c.namespace_name);
 
244
        nso->stubPrototype(c.name);
 
245
        nso->getClass(c.name)->setDeclared();
 
246
        nso->getClass(c.name)->setSystem();
 
247
 
 
248
        boost::intrusive_ptr<as_function> getter =
 
249
                new declare_native_function(c, mGlobal, mExtension);
 
250
 
 
251
        return mGlobal->init_destructive_property(c.name,
 
252
                *getter);
 
253
}
 
254
 
 
255
static const ClassHierarchy::nativeClass knownClasses[] =
 
256
{
 
257
// This makes clear the difference between "We don't know where the
 
258
// class belongs" and "it belongs in the global namespace", even though
 
259
// the result is the same.
 
260
    #define NS_GLOBAL 0
 
261
    #define NS_UNKNOWN 0
 
262
 
 
263
//  { function_name, name key, super name key, lowest version },
 
264
        { system_class_init, NSV::CLASS_SYSTEM, 0, NSV::NS_FLASH_SYSTEM, 1 },
 
265
        { stage_class_init, NSV::CLASS_STAGE, 0, NSV::NS_FLASH_DISPLAY, 1 },
 
266
        { movieclip_class_init, NSV::CLASS_MOVIE_CLIP, 0, NSV::NS_FLASH_DISPLAY, 3 },
 
267
        { textfield_class_init, NSV::CLASS_TEXT_FIELD, 0, NSV::NS_FLASH_TEXT, 3 },
 
268
        { math_class_init, NSV::CLASS_MATH, 0, NS_GLOBAL, 4 },
 
269
        { boolean_class_init, NSV::CLASS_BOOLEAN, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
 
270
        { button_class_init, NSV::CLASS_BUTTON, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
 
271
        { color_class_init, NSV::CLASS_COLOR, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
 
272
        { selection_class_init, NSV::CLASS_SELECTION, NSV::CLASS_OBJECT, NS_UNKNOWN, 5 },
 
273
        { sound_class_init, NSV::CLASS_SOUND, NSV::CLASS_OBJECT, NSV::NS_FLASH_MEDIA, 5 },
 
274
        { xmlsocket_class_init, NSV::CLASS_X_M_L_SOCKET, NSV::CLASS_OBJECT, NSV::NS_FLASH_NET, 5 },
 
275
        { date_class_init, NSV::CLASS_DATE, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
 
276
        { xml_class_init, NSV::CLASS_X_M_L, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
 
277
        { xmlnode_class_init, NSV::CLASS_X_M_L_NODE, NSV::CLASS_OBJECT, NSV::NS_FLASH_XML, 5 },
 
278
        { mouse_class_init, NSV::CLASS_MOUSE, NSV::CLASS_OBJECT, NSV::NS_FLASH_UI, 5 },
 
279
        { number_class_init, NSV::CLASS_NUMBER, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
 
280
        { textformat_class_init, NSV::CLASS_TEXT_FORMAT, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
 
281
        { key_class_init, NSV::CLASS_KEY, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
 
282
        { AsBroadcaster_init, NSV::CLASS_AS_BROADCASTER, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
 
283
        { textsnapshot_class_init, NSV::CLASS_TEXT_SNAPSHOT, NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 6 },
 
284
        { video_class_init, NSV::CLASS_VIDEO, NSV::CLASS_OBJECT, NSV::NS_FLASH_MEDIA, 6 },
 
285
        { camera_class_init, NSV::CLASS_CAMERA, NSV::CLASS_OBJECT, NSV::NS_FLASH_UI, 6 },
 
286
        { microphone_class_init, NSV::CLASS_MICROPHONE, NSV::CLASS_OBJECT, NSV::NS_FLASH_UI, 6 },
 
287
        { sharedobject_class_init, NSV::CLASS_SHARED_OBJECT, NSV::CLASS_OBJECT, NSV::NS_FLASH_NET, 6 },
 
288
        { loadvars_class_init, NSV::CLASS_LOAD_VARS, NSV::CLASS_OBJECT, NS_GLOBAL, 6 },
 
289
        { customactions_class_init, NSV::CLASS_CUSTOM_ACTIONS, NSV::CLASS_OBJECT, NSV::NS_ADOBE_UTILS, 6 },
 
290
        { netconnection_class_init, NSV::CLASS_NET_CONNECTION, NSV::CLASS_OBJECT, NSV::NS_FLASH_NET, 6 },
 
291
        { netstream_class_init, NSV::CLASS_NET_STREAM, NSV::CLASS_OBJECT, NSV::NS_FLASH_NET, 6 },
 
292
        { contextmenu_class_init, NSV::CLASS_CONTEXT_MENU, NSV::CLASS_OBJECT, NSV::NS_FLASH_UI, 7 },
 
293
        { moviecliploader_class_init, NSV::CLASS_MOVIE_CLIP_LOADER, NSV::CLASS_OBJECT, NS_GLOBAL, 7 },
 
294
        { Error_class_init, NSV::CLASS_ERROR, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
 
295
        { Accessibility_class_init, NSV::CLASS_ACCESSIBILITY, NSV::CLASS_OBJECT, NS_GLOBAL, 5 }
 
296
// These classes are all implicitly constructed; that is, it is not necessary for
 
297
// the class name to be used to construct the class, so they must always be available.
 
298
//      { object_class_init, NSV::CLASS_OBJECT, 0, NS_GLOBAL, 5 }
 
299
//      { function_class_init, NSV::CLASS_FUNCTION, NSV::CLASS_OBJECT, NS_GLOBAL, 6 }
 
300
//      { array_class_init, NSV::CLASS_ARRAY, NSV::CLASS_OBJECT, NS_GLOBAL, 5 }
 
301
//      { string_class_init, NSV::CLASS_STRING, NSV::CLASS_OBJECT, NS_GLOBAL, 5 }
 
302
 
 
303
};
 
304
 
 
305
void
 
306
ClassHierarchy::massDeclare(int version)
 
307
{
 
308
        // Natives get declared first. It doesn't make any sense for a native
 
309
        // to depend on an extension, but it does make sense the other way
 
310
        // around.
 
311
        const size_t size = sizeof (knownClasses) / sizeof (nativeClass);
 
312
        for (size_t i = 0; i < size; ++i)
 
313
        {
 
314
                const nativeClass& c = knownClasses[i];
 
315
                if (c.version > version) continue;
 
316
 
 
317
                if ( ! declareClass(c) )
 
318
                {
 
319
                        log_error("Could not declare class %s", c);
 
320
                }
 
321
        }
 
322
 
 
323
        if (mExtension != NULL)
 
324
        {
 
325
                /* Load extensions here */
 
326
        }
 
327
}
 
328
 
 
329
void
 
330
ClassHierarchy::markReachableResources() const
 
331
{
 
332
        // TODO
 
333
}
 
334
 
 
335
std::ostream& operator << (std::ostream& os, const ClassHierarchy::nativeClass& c)
 
336
{
 
337
        string_table& st = VM::get().getStringTable();
 
338
 
 
339
        os << "("
 
340
                << " name:" << st.value(c.name)
 
341
                << " super:" << st.value(c.super_name)
 
342
                << " namespace:" << st.value(c.namespace_name)
 
343
                << " version:" << c.version
 
344
                << ")";
 
345
 
 
346
        return os;
 
347
}
 
348
 
 
349
std::ostream& operator << (std::ostream& os, const ClassHierarchy::extensionClass& c)
 
350
{
 
351
        string_table& st = VM::get().getStringTable();
 
352
 
 
353
        os << "(file:" << c.file_name
 
354
                << " init:" << c.init_name
 
355
                << " name:" << st.value(c.name)
 
356
                << " super:" << st.value(c.super_name)
 
357
                << " namespace:" << st.value(c.namespace_name)
 
358
                << " version:" << c.version
 
359
                << ")";
 
360
 
 
361
        return os;
 
362
}
 
363
 
 
364
} /* namespace gnash */