Ejemplo n.º 1
0
    // Execute the ToString algorithm as described in ECMA-262 Section 9.8.
    // This is ToString(ToPrimitive(input argument, hint String))
    // ToPrimitive(input argument, hint String) calls [[DefaultValue]]
    // described in ECMA-262 8.6.2.6.  The [[DefaultValue]] algorithm
    // with hint String is inlined here.
    Stringp ScriptObject::toString()
    {
        AvmCore *core = this->core();
        Toplevel* toplevel = this->toplevel();

        Atom atomv_out[1];

        // call this.toString()
        // NOTE use callers versioned public to get correct toString
        Multiname tempname(core->findPublicNamespace(), core->ktoString);
        atomv_out[0] = atom();
        Atom result = toplevel->callproperty(atom(), &tempname, 0, atomv_out, vtable);

        // if result is primitive, return its ToString
        if (atomKind(result) != kObjectType)
            return core->string(result);

        // otherwise call this.valueOf()
        tempname.setName(core->kvalueOf);
        atomv_out[0] = atom();
        result = toplevel->callproperty(atom(), &tempname, 0, atomv_out, vtable);

        // if result is primitive, return it
        if (atomKind(result) != kObjectType)
            return core->string(result);

        // could not convert to primitive.
        toplevel->throwTypeError(kConvertToPrimitiveError, core->toErrorString(traits()));
        return NULL; // unreachable
    }
Ejemplo n.º 2
0
    ScriptObject* ScriptObject::getSlotObject(uint32_t slot)
    {
        Traits* traits = this->traits();
        const TraitsBindingsp td = traits->getTraitsBindings();
        void* p;
        const SlotStorageType sst = td->calcSlotAddrAndSST(slot, (void*)this, p);

        // based on profiling of Flex apps, it's *much* more common for the slot in this case
        // to have a type (vs "atom"), so check for that first...
        if (sst == SST_scriptobject)
        {
            return *((ScriptObject**)p);
        }
        else if (sst == SST_atom)
        {
            Atom const a = *((const Atom*)p);

            // don't call AvmCore::isObject(); it checks for null, which we don't care about here
            if (atomKind(a) == kObjectType)
                return (ScriptObject*)atomPtr(a);

            // else fall thru and return null
        }

        return NULL;
    }
Ejemplo n.º 3
0
	/**
		15.2.4.5 Object.prototype.hasOwnProperty (V)
		When the hasOwnProperty method is called with argument V, the following steps are taken:
		1. Let O be this object.
		2. Call ToString(V).
		3. If O doesn’t have a property with the name given by Result(2), return false.
		4. Return true.
		NOTE Unlike [[HasProperty]] (section 8.6.2.4), this method does not consider objects in the prototype chain.
     */
	bool ObjectClass::_hasOwnProperty(Atom thisAtom, Stringp name)
	{
		AvmCore* core = this->core();
		name = name ? core->internString(name) : (Stringp)core->knull;

		Traitsp t = NULL;
		switch (atomKind(thisAtom))
		{
			case kObjectType:
			{
				// ISSUE should this look in traits and dynamic vars, or just dynamic vars.
				ScriptObject* obj = AvmCore::atomToScriptObject(thisAtom);
				if (obj->hasStringProperty(name))
					return true;
				t = obj->traits();
				break;
			}
			case kNamespaceType:
			case kStringType:
			case kBooleanType:
			case kDoubleType:
			case kIntegerType:
				t = toplevel()->toTraits(thisAtom);
				break;
			default:
				return false;
		}
		return t->getTraitsBindings()->findBinding(name, core->publicNamespace) != BIND_NONE;
	}
Ejemplo n.º 4
0
    /**
        15.2.4.5 Object.prototype.hasOwnProperty (V)
        When the hasOwnProperty method is called with argument V, the following steps are taken:
        1. Let O be this object.
        2. Call ToString(V).
        3. If O doesn't have a property with the name given by Result(2), return false.
        4. Return true.
        NOTE Unlike [[HasProperty]] (section 8.6.2.4), this method does not consider objects in the prototype chain.
     */
    bool ObjectClass::_hasOwnProperty(Atom thisAtom, Stringp name)
    {
        AvmCore* core = this->core();
        name = name ? core->internString(name) : (Stringp)core->knull;

        Traitsp t = NULL;
        switch (atomKind(thisAtom))
        {
            case kObjectType:
            {
                // ISSUE should this look in traits and dynamic vars, or just dynamic vars.
                ScriptObject* obj = AvmCore::atomToScriptObject(thisAtom);
                // TODO
                // The change below is important as otherwise we will throw error in a call to hasAtomProperty for ByteArrayObject.
                // This gets us back to the behaviour which we had in Marlin.
                // A bugzilla bug [ 562224 ] has been created to address this issue more cleanly in near future
                return obj->traits()->getTraitsBindings()->findBinding(name, core->findPublicNamespace()) != BIND_NONE ||
                    obj->hasStringProperty(name);
            }
            case kNamespaceType:
            case kStringType:
            case kBooleanType:
            case kDoubleType:
            case kIntptrType:
                t = toplevel()->toTraits(thisAtom);
                break;
            default:
                return false;
        }
        // NOTE use caller's public namespace
        return t->getTraitsBindings()->findBinding(name, core->findPublicNamespace()) != BIND_NONE;
    }
Ejemplo n.º 5
0
    bool ObjectClass::_propertyIsEnumerable(Atom thisAtom, Stringp name)
    {
        AvmCore* core = this->core();
        name = name ? core->internString(name) : (Stringp)core->knull;

        if (atomKind(thisAtom) == kObjectType)
        {
            ScriptObject* obj = AvmCore::atomToScriptObject(thisAtom);
            return obj->getStringPropertyIsEnumerable(name);
        }
        else if (atomKind(thisAtom) == kNamespaceType)
        {
            // Special case:
            // E4X 13.2.5.1, 13.2.5.2 specifies that prefix and uri
            // are not DontEnum.
            return name == core->kuri || name == core->kprefix;
        }
        else
        {
            return false;
        }
    }
Ejemplo n.º 6
0
    void ObjectClass::_setPropertyIsEnumerable(Atom thisAtom, Stringp name, bool enumerable)
    {
        AvmCore* core = this->core();
        name = name ? core->internString(name) : (Stringp)core->knull;

        if (atomKind(thisAtom) == kObjectType)
        {
            ScriptObject* obj = AvmCore::atomToScriptObject(thisAtom);
            obj->setStringPropertyIsEnumerable(name, enumerable);
        }
        else
        {
            // cannot create properties on a sealed object.
            // NOTE just use the unmarked version
            Multiname multiname(core->getAnyPublicNamespace(), name);
            // NOTE use default public
            toplevel()->throwReferenceError(kWriteSealedError, &multiname, traits());
        }
    }
Ejemplo n.º 7
0
    /**
     * @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;
    }
Ejemplo n.º 8
0
bool LocalConnectionObject::SendMethod(const char*name,const char*strDomain,const char*method,ArrayObject*args)
{
	AvmCore*c=core();
	ScriptObject*pClient=m_pClient;
	if(pClient==NULL) pClient=this;
	//pClient->callProperty(
	//callProperty
	Stringp s=c->internStringLatin1(method);
	if(!pClient->hasAtomProperty(s->atom())) return false;
	Atom atom=pClient->getAtomProperty(s->atom());
	args->setIntProperty(0,atom);
	if(atomKind(atom)==kObjectType)
	{
		ScriptObject*pCall=c->atomToScriptObject(atom);
		if(pCall)
		{
			//pCall->call(args->get_length()-1,args->GetAtoms());
			pCall->call(args->getDenseLength()-1,args->GetAtoms());
			return true;
		}
	}
	return true;
}
Ejemplo n.º 9
0
	void CallStackNode::enumerateScopeChainAtoms(IScopeChainEnumerator& scb)
	{
		// First, get the "dynamic" portion of the scope chain, that is, the
		// part that is modified on-the-fly within the function.  This includes
		// activation objects for try/catch blocks and "with" clauses.

		if (m_info)
		{
            MethodSignaturep const ms = m_info->getMethodSignature();
            for (int i = (ms->max_scope() + ms->local_count() - 1), n = ms->local_count(); i >= n; --i)
            {
                Atom const scope = m_info->boxOneLocal(m_framep, i, m_traits);
                AvmAssert(atomKind(scope) != kUnusedAtomTag);
                // go ahead and call addScope, even if null or undefined.
                scb.addScope(scope);
            }
		}

		// Next, get the "static" portion of the scope chain, that is, the
		// part that is defined as part of the definition of the function.  This
		// includes the locals of any functions that enclose this one, and the "this"
		// object, if any.

		ScopeChain* scopeChain = m_env ? m_env->scope() : NULL;
		if (scopeChain) 
		{
			int scopeChainLength = scopeChain->getSize();
			for (int i = scopeChainLength - 1; i >= 0; --i)
			{
				Atom scope = scopeChain->getScope(i);
				if (AvmCore::isObject(scope))
				{
                    scb.addScope(scope);
				}
			}
		}
	}
Ejemplo n.º 10
0
RecordedType ProfiledState::getRecordedType(Atom value) {
  Atom atom_kind = atomKind(value);
  switch (atom_kind) {
  case kDoubleType: return kDOUBLE;
  case kIntptrType: return kINTEGER;
  case kStringType: return kSTRING;
  case kBooleanType: return kBOOLEAN;
  case kObjectType: {
    ScriptObject* object = AvmCore::atomToScriptObject(value);
    if (object == NULL) return kOBJECT; // undefined object
    if (object->toArrayObject() != NULL) return kARRAY;
    return kOBJECT;
  }
  case kUnusedAtomTag: return kUNINITIALIZED;
  case kNamespaceType: return kUNSUPPORTED;
  case kSpecialBibopType: return kUNSUPPORTED;
  default:
    printf("Unknown atom type %d\n", (int) atom_kind);
    AvmAssert (false);
  }

  AvmAssert (false);
  return kUNINITIALIZED;
}
Ejemplo n.º 11
0
 bool Exception::isValid()
 {
     return atomKind(atom) == kObjectType;
 }
Ejemplo n.º 12
0
 // interactive
 Atom Debugger::autoAtomKindAt(DebugFrame* frame, int autoIndex, AutoVarKind kind) {
     if (!frame) return unreachableAtom;
     else return atomKind(autoAtomAt(frame, autoIndex, kind));
 }
Ejemplo n.º 13
0
    // note: coerceAndSetSlotAtom now includes a simplified and streamlined version
    // of Toplevel::coerce. If you modify that code, you might need to modify this code.
    void ScriptObject::coerceAndSetSlotAtom(uint32_t slot, Atom value)
    {
        Traits* traits = this->traits();
        const TraitsBindingsp td = traits->getTraitsBindings();
        void* p;
        const SlotStorageType sst = td->calcSlotAddrAndSST(slot, (void*)this, p);
        // repeated if-else is actually more performant than a switch statement in this case.
        // SST_atom is most common case, put it first
        if (sst == SST_atom)
        {
            // no call to coerce() needed, since anything will fit here... with one exception:
            // BUILTIN_object needs to convert undefined->null (though BUILTIN_any does not).
            // it's cheaper to do that here than call out to coerce().
            AvmAssert(td->getSlotTraits(slot) == NULL || td->getSlotTraits(slot)->builtinType == BUILTIN_object);
            if (value == undefinedAtom && td->getSlotTraits(slot) != NULL)
                value = nullObjectAtom;
            WBATOM(traits->core->GetGC(), this, (Atom*)p, value);
        }
        else if (sst == SST_double)
        {
            *((double*)p) = AvmCore::number(value);
        }
        else if (sst == SST_int32)
        {
            *((int32_t*)p) = AvmCore::integer(value);
        }
        else if (sst == SST_uint32)
        {
            *((uint32_t*)p) = AvmCore::toUInt32(value);
        }
        else if (sst == SST_bool32)
        {
            *((int32_t*)p) = AvmCore::boolean(value);
        }
        else
        {
            // null/undefined -> NULL for all of these
            if (AvmCore::isNullOrUndefined(value))
            {
                value = (Atom)0; // don't bother setting tag bits
            }
            else if (sst == SST_string)
            {
                value = (Atom)traits->core->string(value); // don't bother setting tag bits
            }
            else if (sst == SST_namespace)
            {
                // Namespace is final, so we don't have to do the hard work
                if (atomKind(value) != kNamespaceType)
                    goto failure;
            }
            else // if (sst == SST_scriptobject)
            {
                AvmAssert(sst == SST_scriptobject);
                if (atomKind(value) != kObjectType || !AvmCore::atomToScriptObject(value)->traits()->subtypeof(td->getSlotTraits(slot)))
                    goto failure;
            }
            WBRC(traits->core->GetGC(), this, p, atomPtr(value));
        }
        return;

    failure:
        toplevel()->throwTypeError(kCheckTypeFailedError, traits->core->atomToErrorString(value), traits->core->toErrorString(td->getSlotTraits(slot)));
        return;
    }