void variables_map::initializeVar(const multiname& mname, ASObject* obj, multiname* typemname, ABCContext* context, TRAIT_KIND traitKind) { const Type* type = NULL; /* If typename is a builtin type, we coerce obj. * It it's not it must be a user defined class, * so we only allow Null and Undefined (which are both coerced to Null) */ type = Type::getBuiltinType(typemname); if(type==NULL) { assert_and_throw(obj->is<Null>() || obj->is<Undefined>()); if(obj->is<Undefined>()) { //Casting undefined to an object (of unknown class) //results in Null obj->decRef(); obj = getSys()->getNullRef(); } } else obj = type->coerce(obj); assert(traitKind==DECLARED_TRAIT || traitKind==CONSTANT_TRAIT); uint32_t name=mname.normalizedNameId(); Variables.insert(make_pair(varName(name, mname.ns[0]), variable(traitKind, obj, typemname, type))); }
void variables_map::killObjVar(const multiname& mname) { uint32_t name=mname.normalizedNameId(); //The namespaces in the multiname are ordered. So it's possible to use lower_bound //to find the first candidate one and move from it assert(!mname.ns.empty()); var_iterator ret=Variables.lower_bound(varName(name,mname.ns.front())); auto nsIt=mname.ns.begin(); //Find the namespace while(ret!=Variables.end() && ret->first.nameId==name) { //breaks when the namespace is not found const nsNameAndKind& ns=ret->first.ns; if(ns==*nsIt) { Variables.erase(ret); return; } else if(*nsIt<ns) { ++nsIt; if(nsIt==mname.ns.end()) break; } else if(ns<*nsIt) ++ret; } throw RunTimeException("Variable to kill not found"); }