ClassClosure* DomainObject::getClass(Stringp name) { AvmCore *core = this->core(); if (name == NULL) { toplevel()->throwArgumentError(kNullArgumentError, core->toErrorString("name")); } // Search for a dot from the end. int dot = name->lastIndexOf(core->cachedChars[(int)'.']); // If there is a '.', this is a fully-qualified // class name in a package. Must turn it into // a namespace-qualified multiname. Namespace* ns; Stringp className; if (dot >= 0) { Stringp uri = core->internString(name->substring(0, dot)); ns = core->internNamespace(core->newNamespace(uri)); className = core->internString(name->substring(dot+1, name->length())); } else { ns = core->publicNamespace; className = core->internString(name); } Multiname multiname(ns, className); ShellCodeContext* codeContext = (ShellCodeContext*)core->codeContext(); ScriptObject *container = finddef(multiname, codeContext->domainEnv()); if (!container) { toplevel()->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname)); } Atom atom = toplevel()->getproperty(container->atom(), &multiname, container->vtable); if (!AvmCore::istype(atom, core->traits.class_itraits)) { toplevel()->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname)); } return (ClassClosure*)AvmCore::atomToScriptObject(atom); }
double SamplerScript::_getInvocationCount(ScriptObject* self, Atom a, QNameObject* qname, uint32_t type) { #ifdef DEBUGGER AvmCore* core = self->core(); Sampler* s = core->get_sampler(); if (!s || !trusted(self)) return -1; Multiname multiname; if(qname) qname->getMultiname(multiname); ScriptObject* object = self->toplevel()->global(); if(!AvmCore::isObject(a)) { // not sure if this will be true for standalone avmplus AvmAssert(core->codeContext() != NULL); DomainEnv *domainEnv = core->codeContext()->domainEnv(); ScriptEnv* script = (ScriptEnv*) core->domainMgr()->findScriptEnvInDomainEnvByMultiname(domainEnv, multiname); if (script != (ScriptEnv*)BIND_NONE) { if (script == (ScriptEnv*)BIND_AMBIGUOUS) self->toplevel()->throwReferenceError(kAmbiguousBindingError, &multiname); object = script->global; if (object == NULL) { object = script->initGlobal(); script->coerceEnter(script->global->atom()); } } } else { object = AvmCore::atomToScriptObject(a); if(AvmCore::istype(a, CLASS_TYPE) && !qname) { // return constructor count ClassClosure *cc = (ClassClosure*)object; if (cc->vtable->init) // Vector related crash here, Tommy says: I didn't think a type could ever not have a constructor but I guess there's no reason it has to. return (double)cc->vtable->init->invocationCount(); } } if(!object || !qname) return -1; VTable *v = object->vtable; again: MethodEnv *env = NULL; Binding b = self->toplevel()->getBinding(v->traits, &multiname); switch (AvmCore::bindingKind(b)) { case BKIND_VAR: case BKIND_CONST: { // only look at slots for first pass, otherwise we're applying instance traits to the Class if(v == object->vtable) { Atom method = object->getSlotAtom(AvmCore::bindingToSlotId(b)); if(AvmCore::isObject(method)) { env = AvmCore::atomToScriptObject(method)->getCallMethodEnv(); } } break; } case BKIND_METHOD: { int m = AvmCore::bindingToMethodId(b); env = v->methods[m]; break; } case BKIND_GET: case BKIND_GETSET: case BKIND_SET: { if(type == GET && AvmCore::hasGetterBinding(b)) env = v->methods[AvmCore::bindingToGetterId(b)]; else if(type == SET && AvmCore::hasSetterBinding(b)) env = v->methods[AvmCore::bindingToSetterId(b)]; break; } case BKIND_NONE: { Atom method = object->getStringProperty(multiname.getName()); if(AvmCore::isObject(method)) { env = AvmCore::atomToScriptObject(method)->getCallMethodEnv(); } else if(v->ivtable) { v = v->ivtable; goto again; } } default: break; } if(env) return (double)env->invocationCount(); #else (void)self; (void)type; (void)qname; (void)a; #endif return -1; }