void registerBitmapClass(as_object& where, Global_as::ASFunction ctor, Global_as::Properties p, const ObjectURI& uri) { Global_as& gl = getGlobal(where); VM& vm = getVM(where); // We should be looking for flash.filters.BitmapFilter, but as this // triggers a lookup of the flash.filters package while we are creating // it, so entering infinite recursion, we'll cheat and assume that // the object 'where' is the filters package. as_function* constructor = getMember(where, getURI(vm, "BitmapFilter")).to_function(); as_object* proto; if (constructor) { fn_call::Args args; VM& vm = getVM(where); proto = constructInstance(*constructor, as_environment(vm), args); } else proto = 0; as_object* cl = gl.createClass(ctor, createObject(gl)); if (proto) p(*proto); // The startup script overwrites the prototype assigned by ASconstructor, // so the new prototype doesn't have a constructor property. We do the // same here. cl->set_member(NSV::PROP_PROTOTYPE, proto); where.init_member(uri , cl, as_object::DefaultFlags); }
/// Order of property lookup: // /// 1. Visible own properties. /// 2. If DisplayObject, magic properties /// 3. Visible own properties of all __proto__ objects (a DisplayObject /// ends the chain). /// 4. __resolve property of this object and all __proto__ objects (a Display /// Object ends the chain). This should ignore visibility but doesn't. bool as_object::get_member(const ObjectURI& uri, as_value* val) { assert(val); const int version = getSWFVersion(*this); PrototypeRecursor<IsVisible> pr(this, uri, IsVisible(version)); Property* prop = pr.getProperty(); if (!prop) { if (displayObject()) { DisplayObject* d = displayObject(); if (getDisplayObjectProperty(*d, uri, *val)) return true; } while (pr()) { if ((prop = pr.getProperty())) break; } } // If the property isn't found or doesn't apply to any objects in the // inheritance chain, try the __resolve property. if (!prop) { PrototypeRecursor<Exists> pr(this, NSV::PROP_uuRESOLVE); as_value resolve; for (;;) { Property* res = pr.getProperty(); if (res) { resolve = res->isGetterSetter() ? res->getCache() : res->getValue(*this); if (version < 7) break; if (resolve.is_object()) break; } // Finished searching. if (!pr()) return false; } // If __resolve exists, call it with the name of the undefined // property. string_table& st = getStringTable(*this); const std::string& undefinedName = st.value(getName(uri)); fn_call::Args args; args += undefinedName; // Invoke the __resolve property. *val = invoke(resolve, as_environment(getVM(*this)), this, args); return true; } try { *val = prop->getValue(*this); return true; } catch (const ActionTypeError& exc) { IF_VERBOSE_ASCODING_ERRORS( log_aserror(_("Caught exception: %s"), exc.what()); ); return false; }