Beispiel #1
0
    /**
     * traverse the delegate chain looking for a value.
     * [ed] it's okay to look only at the HT's in the delegate chain because
     * delegate values may only be instances of Object.  They cannot be objects
     * with slots.  We don't need to look at traits at each step.
     * todo - enforce this rule
     * @param name
     * @return
     */
    Atom ScriptObject::getAtomProperty(Atom name) const
    {
        if (!traits()->needsHashtable())
        {
            return getAtomPropertyFromProtoChain(name, delegate, traits());
        }
        else
        {
            Stringp s = core()->atomToString(name);
            AvmAssert(s->isInterned());
            Atom ival = s->getIntAtom();
            if (ival)
            {
                name = ival;
            }

            // dynamic lookup on this object
            const ScriptObject *o = this;
            do
            {
                // ensure prototype is dynamic
                if (!o->vtable->traits->getHashtableOffset())
                    continue;
                Atom const value = o->getTable()->getNonEmpty(name);
                if (!InlineHashtable::isEmpty(value))
                    return value;
            }
            while ((o = o->delegate) != NULL);
            return undefinedAtom;
        }
    }
Beispiel #2
0
    Atom ScriptObject::getUintProperty(uint32_t i) const
    {
        // N.B.: a key present in ScriptObject must be interned string;
        // thus uninterned implies absent (cf. bugzilla 556023).

        AvmCore* core = this->core();

        if (!(i&MAX_INTEGER_MASK))
        {
            if (!traits()->needsHashtable())
            {
                Stringp interned;
                bool present = core->isInternedUint(i, &interned);
                if (present)
                {
                    Atom name = interned->atom();
                    return getAtomPropertyFromProtoChain(name, delegate,
                                                         traits());
                }
                else
                {
                    return undefinedAtom;
                }
            }
            else
            {
                // dynamic lookup on this object
                Atom name = core->uintToAtom (i);
                const ScriptObject *o = this;
                do
                {
                    // ensure prototype is dynamic
                    if (!o->vtable->traits->getHashtableOffset())
                        continue;
                    Atom const value = o->getTable()->getNonEmpty(name);
                    if (!InlineHashtable::isEmpty(value))
                        return value;
                }
                while ((o = o->delegate) != NULL);
                return undefinedAtom;
            }
        }
        else
        {
            Stringp interned;
            bool present;
            present = core->isInternedUint(i, &interned);
            if (present)
            {
                return getAtomProperty(interned->atom());
            }
            else
            {
                return undefinedAtom;
            }
        }
    }
STRATEGY* JlsCodecFactory<STRATEGY>::GetCodecImpl(const JlsParamaters& _info)
{
  if (_info.ilv == ILV_SAMPLE && _info.components != 3)
    return NULL;

#ifndef DISABLE_SPECIALIZATIONS

  // optimized lossless versions common formats
  if (_info.allowedlossyerror == 0)
  {
    if (_info.ilv == ILV_SAMPLE)
    {
      if (_info.bitspersample == 8)
        return new JlsCodec<LosslessTraitsT<Triplet<BYTE>,8>, STRATEGY>(LosslessTraitsT<Triplet<BYTE>,8>(), _info);
    }
    else
    {
      switch (_info.bitspersample)
      {
        case  8: return new JlsCodec<LosslessTraitsT<BYTE,   8>, STRATEGY>(LosslessTraitsT<BYTE,   8>(), _info);
        case 12: return new JlsCodec<LosslessTraitsT<USHORT,12>, STRATEGY>(LosslessTraitsT<USHORT,  12>(), _info);
        case 16: return new JlsCodec<LosslessTraitsT<USHORT,16>, STRATEGY>(LosslessTraitsT<USHORT,  16>(), _info);
      }
    }
  }

#endif

  int maxval = (1 << _info.bitspersample) - 1;

  if (_info.bitspersample <= 8)
  {
    if (_info.ilv == ILV_SAMPLE)
    {
      DefaultTraitsT<BYTE,Triplet<BYTE> > traits(maxval, _info.allowedlossyerror);
      return new JlsCodec<DefaultTraitsT<BYTE,Triplet<BYTE> >, STRATEGY>(traits, _info);
    }
    DefaultTraitsT<BYTE, BYTE> traits((1 << _info.bitspersample) - 1, _info.allowedlossyerror);
    return new JlsCodec<DefaultTraitsT<BYTE, BYTE>, STRATEGY>(traits, _info);
  }
  else if (_info.bitspersample <= 16)
  {
    if (_info.ilv == ILV_SAMPLE)
    {
      DefaultTraitsT<USHORT,Triplet<USHORT> > traits(maxval, _info.allowedlossyerror);
      return new JlsCodec<DefaultTraitsT<USHORT,Triplet<USHORT> >, STRATEGY>(traits, _info);
    }

    DefaultTraitsT<USHORT, USHORT> traits(maxval, _info.allowedlossyerror);
    return new JlsCodec<DefaultTraitsT<USHORT, USHORT>, STRATEGY>(traits, _info);
  }
  return NULL;
}
	bool ArrayObject::delUintProperty(uint32 index)
	{
		// if we get here, we have a valid integer index.
		if (traits()->needsHashtable())
		{
			if ((index < getDenseLength()))
			{
				if (index == (getDenseLength() - 1))
				{
					m_denseArr.pop();
				}
				// We're deleting an element in the middle of our array.  The lower
				// part can be left in the dense array but the upper part needs to
				// get moved to the HT.
				else
				{
					for (uint32 i = index + 1; i < getDenseLength(); i++)
					{
						ScriptObject::setUintProperty (i, m_denseArr.getAtFast(i));
					}
					m_denseArr.splice (index, 0, (getDenseLength() - index), 0);
				}

				return true;
			}
		}
		return ScriptObject::delUintProperty(index);
	}
Beispiel #5
0
 NamespaceClass::NamespaceClass(VTable* cvtable)
     : ClassClosure(cvtable)
 {
     toplevel()->_namespaceClass = this;
     AvmAssert(traits()->getSizeOfInstance() == sizeof(NamespaceClass));
     createVanillaPrototype();
 }
Beispiel #6
0
	// this = argv[0] (ignored)
	// arg1 = argv[1]
	// argN = argv[argc]
	Atom RegExpClass::construct(int argc, Atom* argv)
	{
		AvmCore* core = this->core();
		Stringp pattern;

		Atom patternAtom = (argc>0) ? argv[1] : undefinedAtom;
		Atom optionsAtom = (argc>1) ? argv[2] : undefinedAtom;

		if (AvmCore::istype(patternAtom, traits()->itraits)) {
			// Pattern is a RegExp object
			if (optionsAtom != undefinedAtom) {
				// ECMA 15.10.4.1 says to throw an error if flags specified
				toplevel()->throwTypeError(kRegExpFlagsArgumentError);
			}
			// Return a clone of the RegExp object
			RegExpObject* regExpObject = (RegExpObject*)AvmCore::atomToScriptObject(patternAtom);
			return (new (core->GetGC(), ivtable()->getExtraSize()) RegExpObject(regExpObject))->atom();
		} else {
			if (patternAtom != undefinedAtom) {
				pattern = core->string(argv[1]);
			} else {
				// cn:  disable this, breaking ecma3 tests.   was: todo look into this. it's what SpiderMonkey does.
				pattern = core->kEmptyString; //core->newConstantStringLatin1("(?:)");
			}
		}

		Stringp options = NULL;
		if (optionsAtom != undefinedAtom) {
			options = core->string(optionsAtom);
		}

		RegExpObject* inst = new (core->GetGC(), ivtable()->getExtraSize()) RegExpObject(this, pattern, options);
		return inst->atom();
	}
Beispiel #7
0
TEST(ObjectSerializationTest, DynamicSealedAnonymousObject) {
	AmfObjectTraits traits("", true, false);

	AmfObject obj(traits);

	obj.addSealedProperty("sealedProp", AmfString("value"));
	obj.addDynamicProperty("dynamicProp", AmfString("dynamicValue"));

	isEqual(v8 {
		0x0a, // AMF_OBJECT
		0x1b, // 0b11011, U29O-traits, dynamic, 1 sealed property
		0x01, // class-name "" (anonymous object)
		// sealed property names
		// UTF-8-vr "sealedProp"
		0x15, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70,
		// sealed property values
		// AmfString "value"
		0x06, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65,
		// dynamic members
		// UTF-8-vr "dynamicProp"
		0x17, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x72, 0x6f, 0x70,
		// AmfString "dynamicValue"
		0x06, 0x19, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65,
		// end of dynamic members
		0x01
	}, obj);
}
Beispiel #8
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
    }
Beispiel #9
0
TEST(ObjectSerializationTest, DynamicSealedNamedObject) {
	AmfObjectTraits traits("de.ventero.AmfTest", true, false);
	AmfObject obj(traits);

	obj.addSealedProperty("sealedProp", AmfDouble(3.14159));
	obj.addDynamicProperty("dynamicProp", AmfInteger(17));

	isEqual(v8 {
		0x0a, // AMF_OBJECT
		0x1b, // 0b11011, U29O-traits, dynamic, 1 sealed property
		// class-name UTF-8-vr "de.ventero.AmfTest"
		0x25, 0x64, 0x65, 0x2e, 0x76, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x6f, 0x2e,
		0x41, 0x6d, 0x66, 0x54, 0x65, 0x73, 0x74,
		// sealed property names
		// UTF-8-vr "sealedProp"
		0x15, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70,
		// sealed property values
		// AmfDouble 3.14159
		0x05, 0x40, 0x09, 0x21, 0xf9, 0xf0, 0x1b, 0x86, 0x6e,
		// dynamic members
		// UTF-8-vr dynamicProp
		0x17, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x72, 0x6f, 0x70,
		// AmfInteger 17
		0x04, 0x11,
		// end of dynamic members
		0x01
	}, obj);
}
Beispiel #10
0
	ClassClosure* FunctionClass::createEmptyFunction()
	{
		// invoke AS3 private static function emptyCtor, which returns an empty function.
		TraitsBindingsp t = traits()->getTraitsBindings();
		Binding b = t->findBinding(core()->internConstantStringLatin1("emptyCtor"));
		MethodEnv *f = vtable->methods[AvmCore::bindingToMethodId(b)];
		return (ClassClosure*)AvmCore::atomToScriptObject(f->coerceEnter(this->atom()));
	}
Beispiel #11
0
    Atom ScriptObject::getMultinameProperty(const Multiname* multiname) const
    {
        if (multiname->isValidDynamicName())
        {
            return getStringProperty(multiname->getName());
        }
        else
        {
            Toplevel* toplevel = this->toplevel();

            if (multiname->isNsset())
                toplevel->throwReferenceError(kReadSealedErrorNs, multiname, traits());
            else
                toplevel->throwReferenceError(kReadSealedError, multiname, traits());
            return undefinedAtom;
        }
    }
Beispiel #12
0
TEST(ObjectSerializationTest, SealedAnonymousObject) {
	{
		AmfObjectTraits traits("", false, false);
		AmfObject obj(traits);
		obj.addSealedProperty("sealedProp", AmfString("value"));

		isEqual(v8 {
			0x0a, // AMF_OBJECT
			0x13, // 0b10011, U29O-traits, not dynamic, 1 sealed property
			0x01, // class-name "" (anonymous object)
			// sealed property names
			// UTF-8-vr "sealedProp"
			0x15, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70,
			// sealed property values
			// AmfString "value"
			0x06, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65
			// no dynamic members, so no empty string
		}, obj);
	}

	{
		AmfObjectTraits traits("", false, false);
		AmfObject obj(traits);

		obj.addSealedProperty("sealedProp", AmfString("value"));
		obj.addSealedProperty("otherSealedProp", AmfString("otherValue"));

		isEqual(v8 {
			0x0a, // AMF_OBJECT
			0x23, // 0b100011, U29O-traits, not dynamic, 2 sealed properties
			0x01, // class-name "" (anonymous object)
			// sealed property names
			// UTF-8-vr "sealedProp"
			0x15, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70,
			// UTF-8-vr "otherSealedProp"
			0x1f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, 0x65, 0x61, 0x6c, 0x65, 0x64,
			0x50, 0x72, 0x6f, 0x70,
			// sealed propety values
			// AmfString "value"
			0x06, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65,
			// AmfString "otherValue"
			0x06, 0x15, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65
			// no dynamic members
		}, obj);
	}
}
Beispiel #13
0
	MathClass::MathClass(VTable* cvtable)
		: ClassClosure(cvtable)
	{
		AvmAssert(traits()->getSizeOfInstance() == sizeof(MathClass));
		MathUtils::initRandom(&seed);

        // todo does ES4 Math have a prototype object?
	}
Beispiel #14
0
    /* The storage for a ScriptObject or a subclass SO of ScriptObject is
     * laid out as follows.
     *
     *   - first the bits of the C++ class; if there are pointers here
     *     then they must be traced explicitly by the appropriate class's
     *     gcTrace method
     *   - then the bits for the ActionScript slots
     *   - optionally an InlineHashtable for dynamic properties
     *
     * The in-line slots are native and their representation is described
     * by the Traits object (vtable->traits).  They are not named, but named
     * lookup is possible by going to the Traits object, which contains
     * a name->slot map.
     *
     * The InlineHashtable always stores Atoms.
     */
    bool ScriptObject::gcTrace(MMgc::GC* gc, size_t cursor)
    {
        (void)cursor;
        gc->TraceLocation(&vtable);
        gc->TraceLocation(&delegate);
        traits()->traceSlots(gc, this);
        if (traits()->needsHashtable())
        {
            // Avoid initializing the hash table here
            InlineHashtable* iht = getTableNoInit();
            // The iht pointer can be NULL for Dictionary objects that
            // haven't had init called yet.
            if(iht)
                iht->gcTrace(gc);
        }

        return false;
    }
Beispiel #15
0
    int ScriptObject::nextNameIndex(int index)
    {
        AvmAssert(index >= 0);

        if (!traits()->needsHashtable())
            return 0;

        return getTable()->next(index);
    }
	ArrayObject::ArrayObject(VTable *vtable, ScriptObject* proto, uint32 capacity)
		: ScriptObject(vtable, proto, 0),
		m_denseArr(capacity)
	{
		SAMPLE_FRAME("Array", core());
		AvmAssert(traits()->getSizeOfInstance() >= sizeof(ArrayObject));
		m_length = 0;
		m_lowHTentry = NO_LOW_HTENTRY;
	}
void CommentHandler::handleComment(Annotator &A, Generator& generator, clang::Sema &Sema,
                                   const char *bufferStart, int commentStart, int len,
                                   clang::SourceLocation searchLocBegin, clang::SourceLocation searchLocEnd,
                                   clang::SourceLocation commentLoc)
{
    llvm::StringRef rawString(bufferStart+commentStart, len);
    std::string attributes;
    std::string DeclRef;


    if ((rawString.ltrim().startswith("/**") && !rawString.ltrim().startswith("/***"))
            || rawString.ltrim().startswith("/*!") || rawString.ltrim().startswith("//!")
            || (rawString.ltrim().startswith("///") && !rawString.ltrim().startswith("////")))
#if CLANG_VERSION_MAJOR==3 && CLANG_VERSION_MINOR<=4
        if (rawString.find("deprecated") == rawString.npos) // workaround crash in comments::Sema::checkDeprecatedCommand
#endif
    {
        attributes = "class=\"doc\"";

        clang::Preprocessor &PP = Sema.getPreprocessor();
        clang::comments::CommandTraits traits(PP.getPreprocessorAllocator(), clang::CommentOptions());
#if CLANG_VERSION_MAJOR==3 && CLANG_VERSION_MINOR<=4
        traits.registerBlockCommand("deprecated"); // avoid typo correction leading to crash.
#endif
        clang::comments::Lexer lexer(PP.getPreprocessorAllocator(), PP.getDiagnostics(), traits,
                                     clang::SourceLocation::getFromRawEncoding(commentStart), bufferStart + commentStart, bufferStart + commentStart + len);
        clang::comments::Sema sema(PP.getPreprocessorAllocator(), PP.getSourceManager(), PP.getDiagnostics(), traits, &PP);
        clang::comments::Parser parser(lexer, sema, PP.getPreprocessorAllocator(), PP.getSourceManager(),
                                       PP.getDiagnostics(), traits);
        auto fullComment = parser.parseFullComment();
        CommentVisitor visitor{A, generator, traits, Sema};
        visitor.visit(fullComment);
        DeclRef = visitor.DeclRef;
    }

    if (!DeclRef.empty()) {
        docs.insert({std::move(DeclRef), { rawString.str() , commentLoc }});
        generator.addTag("i", attributes, commentStart, len);
        return;
    }

    // Try to find a matching declaration
    const auto &dof = decl_offsets;
    //is there one and one single decl in that range.
    auto it_before = dof.lower_bound(searchLocBegin);
    auto it_after = dof.upper_bound(searchLocEnd);
    if (it_before != dof.end() && it_after != dof.begin() && it_before == (--it_after)) {
        if (it_before->second.second) {
            docs.insert({it_before->second.first, { rawString.str() , commentLoc }});
        } else {
            attributes %= " data-doc=\"" % it_before->second.first % "\"";
        }
    }

    generator.addTag("i", attributes, commentStart, len);
}
Beispiel #18
0
TEST(ObjectSerializationTest, EmptySealedAnonymousObject) {
	AmfObjectTraits traits("", false, false);
	AmfObject obj(traits);

	isEqual(v8 {
		0x0a, // AMF_OBJECT
		0x03, // 0b0011, U29O-traits, not dynamic, 0 sealed properties
		0x01 // class-name "" (anonymous object)
	}, obj);
}
MethodClosureClass::MethodClosureClass(VTable* cvtable)
    : ClassClosure(cvtable)
{
    Toplevel* toplevel = this->toplevel();

    toplevel->methodClosureClass = this;
    AvmAssert(traits()->getSizeOfInstance() == sizeof(MethodClosureClass));

    prototype = toplevel->functionClass->createEmptyFunction();
}
Beispiel #20
0
    Atom ScriptObject::nextName(int index)
    {
        if (!traits()->needsHashtable())
            return nullStringAtom;
        
        AvmAssert(index > 0);

        InlineHashtable* ht = getTable();
        Atom m = ht->keyAt(index);
        return AvmCore::isNullOrUndefined(m) ? nullStringAtom : m;
    }
	void ArrayObject::_setUintProperty(uint32 index, Atom value)
	{
		if (traits()->needsHashtable())
		{
			if (hasDense())
			{
				if (index == getDenseLength())
				{
					this->m_denseArr.push (value);
					if (m_length < getDenseLength())
						m_length = getDenseLength();

					checkForSparseToDenseConversion ();
					return;
				}
				else if (index < getDenseLength())
				{
					this->m_denseArr.setAt (index, value);
					return;
				}
				else 
				{
					// fall through and put the new property into our HT
				}
			}
			// If we're NOT dense yet and setting first element, we can create a dense array
			else if (index == 0)
			{			
				m_denseArr.push (value);
				if (!m_length)
					m_length = 1;
				else
					checkForSparseToDenseConversion ();
				return;
			}

			if (m_length <= index) {
				m_length = index+1;
			}

			if ((m_lowHTentry == NO_LOW_HTENTRY) || (index < m_lowHTentry))
				m_lowHTentry = index;
		}
		// end if (dynamic)

		// If our index value is going to overflow our int atom storage and be
		// converted to a string, do that here instead of calling the
		// SciptObject::setUintProperty which will call ArrayObject::setAtomProperty
		// which will call back into this routine in an infinite loop.
		if (index & ScriptObject::MAX_INTEGER_MASK)
			ScriptObject::setAtomProperty(core()->internUint32(index)->atom(), value);
		else
			ScriptObject::setUintProperty(index, value);
	}
Beispiel #22
0
	QNameClass::QNameClass(VTable* cvtable)
		: ClassClosure(cvtable)
	{
		AvmAssert(traits()->getSizeOfInstance() == sizeof(QNameClass));

		createVanillaPrototype();

		AvmCore* core = this->core();
		kUri = core->internConstantStringLatin1("uri")->atom();
		kLocalName = core->internConstantStringLatin1("localName")->atom();
	}
Beispiel #23
0
 bool ScriptObject::deleteMultinameProperty(const Multiname* name)
 {
     if (traits()->needsHashtable() && name->isValidDynamicName())
     {
         return deleteStringProperty(name->getName());
     }
     else
     {
         return false;
     }
 }
Beispiel #24
0
 void ScriptObject::setMultinameProperty(const Multiname* name, Atom value)
 {
     if (traits()->needsHashtable() && name->isValidDynamicName())
     {
         setStringProperty(name->getName(), value);
     }
     else
     {
         throwWriteSealedError(*name);
     }
 }
Beispiel #25
0
TEST(ObjectSerializationTest, EmptyDynamicAnonymousObject) {
	AmfObjectTraits traits("", true, false);
	AmfObject obj(traits);

	isEqual(v8 {
		0x0a, // AMF_OBJECT
		0x0b, // U29O-traits | dynamic, 0 sealed properties
		0x01, // class-name "" (anonymous object)
		0x01  // end of object (UTF-8-empty)
	}, obj);
}
Beispiel #26
0
 bool ScriptObject::hasMultinameProperty(const Multiname* multiname) const
 {
     if (traits()->needsHashtable() && multiname->isValidDynamicName())
         {
             return hasAtomProperty(multiname->getName()->atom());
         }
         else
         {
         // ISSUE should this walk the proto chain?
         return false;
     }
 }
Beispiel #27
0
 uint64_t ScriptObject::bytesUsed() const
 {
     uint64_t bytesUsed = traits()->getTotalSize();
     if(traits()->needsHashtable())
     {
         if (traits()->isDictionary())
         {
             union {
                 uint8_t* p;
                 HeapHashtable** hht;
             };
             p = (uint8_t*)this + traits()->getHashtableOffset();
             bytesUsed += (*hht)->bytesUsed();
         }
         else
         {
             bytesUsed += getTable()->bytesUsed();
         }
     }
     return bytesUsed;
 }
	bool ArrayObject::hasUintProperty(uint32 index) const
	{
		if (traits()->needsHashtable())
		{
			if (hasDense())
			{
				if (index < getDenseLength())
					return true;
			}
		}

		return ScriptObject::hasUintProperty (index);
	}
	ObjectClass::ObjectClass(VTable* cvtable)
		: ClassClosure(cvtable)
	{
		toplevel()->objectClass = this;

		// patch Object's instance vtable scope, since we created it earlier for
		// bootstrapping
		//ivtable()->scope = cvtable->scope;

		AvmAssert(traits()->getSizeOfInstance() == sizeof(ObjectClass));
        // it is correct call construct() when this.prototype == null
        prototype = construct();
	}
Beispiel #30
0
    Atom ScriptObject::nextValue(int index)
    {
        if (!traits()->needsHashtable())
            return undefinedAtom;

        AvmAssert(index > 0);

        InlineHashtable* ht = getTable();
        Atom m = ht->keyAt(index);
        if (AvmCore::isNullOrUndefined(m))
            return nullStringAtom;
        return ht->valueAt(index);
    }