Atom nextValue(int i) { if (count == 0) { return undefinedAtom; } Sampler * const sampler = script->core()->get_sampler(); if (sampler == NULL || sampleBufferId != sampler->getSampleBufferId()) { count = 0; return undefinedAtom; } (void) i; Sample s; sampler->readSample(cursor, s); count--; ScriptObject* sam = SamplerScript::makeSample(script, cf, s); if(!sam) { count = 0; return undefinedAtom; } return sam->atom(); }
// this = argv[0] (ignored) // arg1 = argv[1] // argN = argv[argc] Atom FunctionObject::construct(int argc, Atom* argv) { AvmAssert(argv != NULL); // need at least one arg spot passed in ScriptObject* obj = newInstance(); // this is a function argv[0] = obj->atom(); // new object is receiver Atom result = _call->coerceEnter(argc, argv); // for E3 13.2.2 compliance, check result and return it if (Type(result) is Object) /* ISSUE does this apply to class constructors too? answer: no. from E4: A constructor may invoke a return statement as long as that statement does not supply a value; a constructor cannot return a value. The newly created object is returned automatically. A constructors return type must be omitted. A constructor always returns a new instance. */ return AvmCore::isNull(result) || AvmCore::isObject(result) ? result : obj->atom(); }
Atom nextValue(int i) { (void) i; Sample s; sampler->readSample(cursor, s); count--; ScriptObject* sam = SamplerScript::makeSample(script, s); if(!sam) { count = 0; return undefinedAtom; } return sam->atom(); }
/** 15.2.4.6 Object.prototype.isPrototypeOf (V) When the isPrototypeOf method is called with argument V, the following steps are taken: 1. Let O be this object. 2. If V is not an object, return false. 3. Let V be the value of the [[Prototype]] property of V. 4. if V is null, return false 5. If O and V refer to the same object or if they refer to objects joined to each other (section 13.1.2), return true. 6. Go to step 3. */ bool ObjectClass::_isPrototypeOf(Atom thisAtom, Atom V) { // ECMA-262 Section 15.2.4.6 if (AvmCore::isNullOrUndefined(V)) return false; ScriptObject* o = toplevel()->toPrototype(V); for (; o != NULL; o = o->getDelegate()) { if (o->atom() == thisAtom) return true; } return false; }
// this = argv[0] (ignored) // arg1 = argv[1] // argN = argv[argc] Atom ClassClosure::construct(int argc, Atom* argv) { VTable* ivtable = this->ivtable(); AvmAssert(ivtable != NULL); AvmAssert(argv != NULL); // need at least one arg spot passed in ScriptObject* obj = newInstance(); AvmAssert(obj != NULL); //should never be null Atom a = obj->atom(); argv[0] = a; // new object is receiver ivtable->init->coerceEnter(argc, argv); // this is a class. always return new instance. return a; }
Stringp StringClass::_replace(Stringp subject, Atom pattern, Atom replacementAtom) { AvmCore* core = this->core(); ScriptObject *replaceFunction = NULL; Stringp replacement = NULL; if (AvmCore::istype(replacementAtom, core->traits.function_itraits)) { replaceFunction = AvmCore::atomToScriptObject(replacementAtom); } else { replacement = core->string(replacementAtom); } if (AvmCore::istype(pattern, core->traits.regexp_itraits)) { // RegExp mode RegExpObject *reObj = (RegExpObject*) core->atomToScriptObject(pattern); if (replaceFunction) { return core->string(reObj->replace(subject, replaceFunction)); } else { return core->string(reObj->replace(subject, replacement)); } } else { // String replace mode Stringp searchString = core->string(pattern); int index = subject->indexOf(searchString); if (index == -1) { // Search string not found; return input unchanged. return subject; } if (replaceFunction) { // Invoke the replacement function to figure out the // replacement string Atom argv[4] = { undefinedAtom, searchString->atom(), core->uintToAtom(index), subject->atom() }; replacement = core->string(toplevel()->op_call(replaceFunction->atom(), 3, argv)); } Stringp out = subject->substring(0, index); out = String::concatStrings(out, replacement); out = String::concatStrings(out, subject->substring(index + searchString->length(), subject->length())); return out; } }
Atom DictionaryObject::nextName(int index) { Atom k = ScriptObject::nextName(index); if(weakKeys && AvmCore::isGCObject(k)) { GCWeakRef *ref = (GCWeakRef*) (k&~7); if(ref->get()) { ScriptObject *key = ((ScriptObject*)ref->get()); AvmAssert(key->traits() != NULL); return key->atom(); } else return undefinedAtom; } return k; }
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); // OOO: In the distribution, we search core->codeContext()->domainEnv rather than // our own domainEnv, which is surely a bug? ScriptObject *container = finddef(multiname, 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); }
/** * @return a pointer to an object Atom whose members are * the active locals for this frame. */ bool DebugStackFrame::locals(Atom*& ar, int& count) { bool worked = true; if (trace->framep() && trace->info()) { int firstLocal, pastLastLocal; localBounds(&firstLocal, &pastLastLocal); count = pastLastLocal - firstLocal; AvmAssert(count >= 0); if ((count > 0) && debugger) { // frame looks like [this][param0...paramN][local0...localN] ar = (Atom*) debugger->core->GetGC()->Calloc(count, sizeof(Atom), GC::kContainsPointers|GC::kZero); MethodInfo* info = trace->info(); info->boxLocals(trace->framep(), firstLocal, trace->types(), ar, 0, count); // If NEED_REST or NEED_ARGUMENTS is set, and the jit is being used, then the first // local is actually not an atom at all -- it is an ArrayObject*. So, we need to // convert it to an atom. (If the interpreter is being used instead of the jit, then // it is stored as an atom.) if (info->needRestOrArguments()) { int atomType = atomKind(ar[0]); if (atomType == 0) // 0 is not a legal atom type, so ar[0] is not an atom { ScriptObject* obj = (ScriptObject*)ar[0]; ar[0] = obj->atom(); } } } } else { worked = false; count = 0; } return worked; }
/*static*/ Atom DescribeTypeClass::describeTypeJSON(ScriptObject* self, Atom v, uint32_t flags) { TypeDescriber td(self->toplevel()); ScriptObject* o = td.describeType(v, flags); return o ? o->atom() : nullObjectAtom; }
ClassClosure *SamplerScript::getType(Toplevel* ss_toplevel, SamplerObjectType sot, const void *ptr) { Toplevel* tl; switch (sotGetKind(sot)) { case kSOT_String: { // toplevel can be null here if there was no CodeContext active // when the sample was taken (ie, string was allocated from C++ code). // in that case, use the TL from the SamplerScript itself... it isn't // technically the right one to use, but is adequate for our purposes here // (it will return a stringClass or namespaceClass that will be valid // for the sampler) tl = sotGetToplevel(sot); if (!tl) tl = ss_toplevel; return tl->stringClass(); } case kSOT_Namespace: { tl = sotGetToplevel(sot); if (!tl) tl = ss_toplevel; return tl->namespaceClass(); } default: AvmAssert(0); case kSOT_Object: break; } VTable* vt = sotGetVTable(sot); tl = vt->toplevel(); AvmCore* core = tl->core(); ClassClosure *type; ScriptObject* obj = (ScriptObject*)ptr; if (obj && AvmCore::istype(obj->atom(), core->traits.class_itraits)) { type = tl->classClass(); } else if (obj && AvmCore::istype(obj->atom(), core->traits.function_itraits)) { type = tl->functionClass(); } else if (obj && obj->traits()->isActivationTraits()) { type = tl->objectClass; } else { // fallback answer type = tl->objectClass; // note that note all types will have an init method, // so those types may get reported as "objectClass" rather // than something more specific. However, it's not clear // that the Sampler ever really cared about reporting those // objects well in the first place (eg activation or catch objects), // so it doesn't seem we're a lot worse off than before. ScopeChain* sc = NULL; if (vt->init) sc = vt->init->scope(); if (sc && sc->getSize() <= 1) { if(sc->getSize() == 1) type = tl->classClass(); } else if (sc) { Atom ccAtom = sc->getScope(sc->getSize()-1); if(AvmCore::isObject(ccAtom)) { type = (ClassClosure*) AvmCore::atomToScriptObject(ccAtom); if(!AvmCore::istype(type->atom(), core->traits.class_itraits)) { // obj is a ClassClosure type = tl->classClass(); } } } } AvmAssert(AvmCore::istype(type->atom(), core->traits.class_itraits)); return type; }