Fix test for bug #32625
[gnash.git] / libcore / ClassHierarchy.cpp
blob8ea107b07fc5a425306c03985756c96ff6071578
1 //
2 // Copyright (C) 2007, 2008, 2009, 2010 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.
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
19 #include "ClassHierarchy.h"
21 #include <boost/bind.hpp>
23 #include "as_object.h"
24 #include "PropFlags.h"
25 #include "as_value.h"
26 #include "namedStrings.h"
27 #include "as_function.h"
28 #include "Global_as.h"
29 #include "extension.h"
31 namespace gnash {
33 // anonymous namespace
34 namespace {
36 void
37 addVisibilityFlag(int& flags, int version)
39 // TODO: more visibility for swf10+?
40 switch (version)
42 default:
43 return;
44 case 9:
45 flags |= PropFlags::onlySWF9Up;
46 break;
47 case 8:
48 flags |= PropFlags::onlySWF8Up;
49 break;
50 case 7:
51 flags |= PropFlags::onlySWF7Up;
52 break;
53 case 6:
54 flags |= PropFlags::onlySWF6Up;
55 break;
59 class declare_extension_function : public as_function
61 private:
62 ClassHierarchy::ExtensionClass _decl;
63 as_object *mTarget;
64 Extension *mExtension;
66 public:
67 bool isBuiltin() { return true; }
69 declare_extension_function(ClassHierarchy::ExtensionClass &c, as_object *g,
70 Extension* e)
72 as_function(getGlobal(*g)),
73 _decl(c),
74 mTarget(g),
75 mExtension(e)
79 virtual as_value call(const fn_call& fn)
81 string_table& st = getStringTable(fn);
82 log_debug("Loading extension class %s", st.value(getName(_decl.uri)));
84 if (mExtension->initModuleWithFunc(_decl.file_name,
85 _decl.init_name, *mTarget))
87 // Successfully loaded it, now find it, set its proto, and return.
88 as_value us;
89 mTarget->get_member(_decl.uri, &us);
90 return us;
92 // Error here -- not successful in loading.
93 log_error("Could not load class %s", st.value(getName(_decl.uri)));
94 return as_value();
98 class declare_native_function : public as_function
101 public:
103 bool isBuiltin() { return true; }
105 declare_native_function(const ClassHierarchy::NativeClass &c, as_object *g)
107 as_function(getGlobal(*g)),
108 _decl(c),
109 mTarget(g)
113 virtual as_value call(const fn_call& fn)
115 string_table& st = getStringTable(fn);
116 log_debug("Loading native class %s", st.value(getName(_decl.uri)));
118 _decl.initializer(*mTarget, _decl.uri);
119 // Successfully loaded it, now find it, set its proto, and return.
120 as_value us;
121 if (mTarget->get_member(_decl.uri, &us)) {
122 if (!toObject(us, getVM(fn))) {
123 log_error("Native class %s is not an object after "
124 "initialization (%s)",
125 st.value(getName(_decl.uri)), us);
128 else
130 log_error("Native class %s is not found after initialization",
131 st.value(getName(_decl.uri)));
133 return us;
136 private:
138 ClassHierarchy::NativeClass _decl;
139 as_object *mTarget;
143 } // end anonymous namespace
145 ClassHierarchy::~ClassHierarchy()
149 bool
150 ClassHierarchy::declareClass(ExtensionClass& c)
152 if (!mExtension) return false;
154 as_function* getter(new declare_extension_function(c, mGlobal, mExtension));
156 int flags = PropFlags::dontEnum;
157 addVisibilityFlag(flags, c.version);
158 return mGlobal->init_destructive_property(c.uri, *getter, flags);
161 bool
162 ClassHierarchy::declareClass(const NativeClass& c)
164 as_function* getter = new declare_native_function(c, mGlobal);
166 int flags = PropFlags::dontEnum;
167 addVisibilityFlag(flags, c.version);
168 return mGlobal->init_destructive_property(c.uri, *getter, flags);
172 void
173 ClassHierarchy::declareAll(const NativeClasses& classes)
175 // This is necessary to resolve the overload...
176 bool(ClassHierarchy::*nf)(const NativeClass& f) =
177 &ClassHierarchy::declareClass;
179 std::for_each(classes.begin(), classes.end(), boost::bind(nf, this, _1));
182 } // end of namespace gnash
184 // local Variables:
185 // mode: C++
186 // indent-tabs-mode: t
187 // End: