示例#1
0
ASFUNCTIONBODY(Array,forEach)
{
	Array* th=static_cast<Array*>(obj);
	_NR<IFunction> f;
	ARG_UNPACK(f);
	if (f.isNull())
		return NULL;
	ASObject* params[3];

	std::map<uint32_t, data_slot>::iterator it=th->data.begin();
	for(;it != th->data.end();++it)
	{
		assert_and_throw(it->second.type==DATA_OBJECT);
		params[0] = it->second.data;
		it->second.data->incRef();
		params[1] = abstract_i(it->first);
		params[2] = th;
		th->incRef();

		ASObject *funcret;
		if( argslen == 1 )
		{
			funcret=f->call(getSys()->getNullRef(), params, 3);
		}
		else
		{
			args[1]->incRef();
			funcret=f->call(args[1], params, 3);
		}
		if(funcret)
			funcret->decRef();
	}

	return NULL;
}
示例#2
0
bool ASObject::hasPropertyByMultiname(const multiname& name, bool considerDynamic)
{
	//We look in all the object's levels
	uint32_t validTraits=DECLARED_TRAIT;
	if(considerDynamic)
		validTraits|=DYNAMIC_TRAIT;

	if(Variables.findObjVar(name, NO_CREATE_TRAIT, validTraits)!=NULL)
		return true;

	if(classdef && classdef->Variables.findObjVar(name, NO_CREATE_TRAIT, BORROWED_TRAIT)!=NULL)
		return true;

	//Check prototype inheritance chain
	if(getClass())
	{
		ASObject* proto = getClass()->prototype.getPtr();
		while(proto)
		{
			if(proto->findGettable(name, false) != NULL)
				return true;
			proto = proto->getprop_prototype();
		}
	}

	//Must not ask for non borrowed traits as static class member are not valid
	return false;
}
示例#3
0
ASFUNCTIONBODY(ASObject,propertyIsEnumerable)
{
	assert_and_throw(argslen==1);
	multiname name;
	name.name_type=multiname::NAME_STRING;
	name.name_s=args[0]->toString();
	name.ns.push_back(nsNameAndKind("",NAMESPACE));
	name.isAttribute=false;
	unsigned int index = 0;
	if (obj->is<Array>()) // propertyIsEnumerable(index) isn't mentioned in the ECMA specs but is tested for
	{
		Array* a = static_cast<Array*>(obj);
		if (a->isValidMultiname(name,index))
		{
			return abstract_b(index < (unsigned int)a->size());
		}
	}
	if(obj->getClass())
	{
		ASObject* proto = obj->getClass()->prototype.getPtr();
		if  (proto->hasPropertyByMultiname(name, true))
			return abstract_b(false);
	}
	if (obj->hasPropertyByMultiname(name,true))
		return abstract_b(true);
	return abstract_b(false);
}
示例#4
0
ASFUNCTIONBODY(JSON,_stringify)
{
	_NR<ASObject> value;
	ARG_UNPACK(value);
	std::vector<ASObject *> path;
	tiny_string filter;
	IFunction* replacer = NULL;
	if (argslen > 1 && !args[1]->is<Null>() && !args[1]->is<Undefined>())
	{
		if (args[1]->is<IFunction>())
		{
			replacer = args[1]->as<IFunction>();
		}
		else if (args[1]->is<Array>())
		{
			filter = " ";
			Array* ar = args[1]->as<Array>();
			for (uint64_t i = 0; i < ar->size(); i++)
			{
				filter += ar->at(i)->toString();
				filter += " ";
			}
		}
		else
			throwError<TypeError>(kJSONInvalidReplacer);
	}

	tiny_string spaces = "";
	if (argslen > 2)
	{
		ASObject* space = args[2];
		spaces = "          ";
		if (space->is<Number>() || space->is<Integer>() || space->is<UInteger>())
		{
			int32_t v = space->toInt();
			if (v < 0) v = 0;
			if (v > 10) v = 10;
			spaces = spaces.substr_bytes(0,v);
		}
		else if (space->is<Boolean>() || space->is<Null>())
		{
			spaces = "";
		}
		else
		{
			if(space->has_toString())
			{
				_R<ASObject> ret = space->call_toString();
				spaces = ret->toString();
			}
			else
				spaces = space->toString();
			if (spaces.numBytes() > 10)
				spaces = spaces.substr_bytes(0,10);
		}
	}
	tiny_string res = value->toJSON(path,replacer,spaces,filter);

	return Class<ASString>::getInstanceS(res);
}
示例#5
0
ASFUNCTIONBODY(Array,forEach)
{
	assert_and_throw(argslen == 1 || argslen == 2);
	Array* th=static_cast<Array*>(obj);
	IFunction* f = static_cast<IFunction*>(args[0]);
	ASObject* params[3];

	for(unsigned int i=0; i < th->data.size(); i++)
	{
		assert_and_throw(th->data[i].type==DATA_OBJECT);
		params[0] = th->data[i].data;
		th->data[i].data->incRef();
		params[1] = abstract_i(i);
		params[2] = th;
		th->incRef();

		ASObject *funcret;
		if( argslen == 1 )
		{
			funcret=f->call(new Null, params, 3);
		}
		else
		{
			args[1]->incRef();
			funcret=f->call(args[1], params, 3);
		}
		if(funcret)
			funcret->decRef();
	}

	return NULL;
}
示例#6
0
tiny_string Vector::toJSON(std::vector<ASObject *> &path, IFunction *replacer, const tiny_string &spaces, const tiny_string &filter)
{
	bool ok;
	tiny_string res = call_toJSON(ok,path,replacer,spaces,filter);
	if (ok)
		return res;
	// check for cylic reference
	if (std::find(path.begin(),path.end(), this) != path.end())
		throwError<TypeError>(kJSONCyclicStructure);

	path.push_back(this);
	res += "[";
	bool bfirst = true;
	tiny_string newline = (spaces.empty() ? "" : "\n");
	for (unsigned int i =0;  i < vec.size(); i++)
	{
		tiny_string subres;
		ASObject* o = vec[i];
		if (!o)
			o = getSystemState()->getNullRef();
		if (replacer != NULL)
		{
			ASObject* params[2];
			
			params[0] = abstract_di(getSystemState(),i);
			params[0]->incRef();
			params[1] = o;
			params[1]->incRef();
			ASObject *funcret=replacer->call(getSystemState()->getNullRef(), params, 2);
			if (funcret)
				subres = funcret->toJSON(path,NULL,spaces,filter);
		}
		else
		{
			subres = o->toJSON(path,replacer,spaces,filter);
		}
		if (!subres.empty())
		{
			if (!bfirst)
				res += ",";
			res += newline+spaces;
			
			bfirst = false;
			res += subres;
		}
	}
	if (!bfirst)
		res += newline+spaces.substr_bytes(0,spaces.numBytes()/2);
	res += "]";
	path.pop_back();
	return res;
}
示例#7
0
ASFUNCTIONBODY(ASObject,hasOwnProperty)
{
	assert_and_throw(argslen==1);
	multiname name;
	name.name_type=multiname::NAME_STRING;
	name.name_s=args[0]->toString();
	name.ns.push_back(nsNameAndKind("",NAMESPACE));
	name.isAttribute=false;
	if(obj->getClass())
	{
		ASObject* proto = obj->getClass()->prototype.getPtr();
		if  (proto != obj && proto->hasPropertyByMultiname(name, true))
			return abstract_b(false);
	}
	bool ret=obj->hasPropertyByMultiname(name, true);
	return abstract_b(ret);
}
示例#8
0
ASFUNCTIONBODY(Vector, every)
{
	Vector* th=static_cast<Vector*>(obj);
	if (argslen < 1)
		throwError<ArgumentError>(kWrongArgumentCountError, "Vector.some", "1", Integer::toString(argslen));
	if (!args[0]->is<IFunction>())
		throwError<TypeError>(kCheckTypeFailedError, args[0]->getClassName(), "Function");
	IFunction* f = static_cast<IFunction*>(args[0]);
	ASObject* params[3];
	ASObject *funcRet;

	for(unsigned int i=0; i < th->size(); i++)
	{
		if (th->vec[i])
		{
			params[0] = th->vec[i];
			th->vec[i]->incRef();
		}
		else
			params[0] = obj->getSystemState()->getNullRef();
		params[1] = abstract_i(obj->getSystemState(),i);
		params[2] = th;
		th->incRef();

		if(argslen==1)
		{
			funcRet=f->call(obj->getSystemState()->getNullRef(), params, 3);
		}
		else
		{
			args[1]->incRef();
			funcRet=f->call(args[1], params, 3);
		}
		if(funcRet)
		{
			if (funcRet->is<Undefined>() || funcRet->is<Null>())
				throwError<TypeError>(kCallOfNonFunctionError, funcRet->toString());
			if(!Boolean_concrete(funcRet))
			{
				return funcRet;
			}
			funcRet->decRef();
		}
	}
	return abstract_b(obj->getSystemState(),true);
}
示例#9
0
ASFUNCTIONBODY(Vector,_map)
{
	Vector* th=static_cast<Vector*>(obj);
	_NR<IFunction> func;
	_NR<ASObject> thisObject;
	
	if (argslen >= 1 && !args[0]->is<IFunction>())
		throwError<TypeError>(kCheckTypeFailedError, args[0]->getClassName(), "Function");

	ARG_UNPACK(func)(thisObject,NullRef);
	
	Vector* ret= (Vector*)obj->getClass()->getInstance(true,NULL,0);

	ASObject* thisObj;
	for(uint32_t i=0;i<th->size();i++)
	{
		ASObject* funcArgs[3];
		if (!th->vec[i])
			funcArgs[0]=obj->getSystemState()->getNullRef();
		else
		{
			if(th->vec[i])
			{
				funcArgs[0]=th->vec[i];
				funcArgs[0]->incRef();
			}
			else
				funcArgs[0]=obj->getSystemState()->getUndefinedRef();
		}
		funcArgs[1]=abstract_i(obj->getSystemState(),i);
		funcArgs[2]=th;
		funcArgs[2]->incRef();
		if (thisObject.isNull())
			thisObj = obj->getSystemState()->getNullRef();
		else
		{
			thisObj = thisObject.getPtr();
			thisObj->incRef();
		}
		ASObject* funcRet=func->call(thisObj, funcArgs, 3);
		assert_and_throw(funcRet);
		ret->vec.push_back(funcRet);
	}

	return ret;
}
示例#10
0
文件: Vector.cpp 项目: gg0/lightspark
ASFUNCTIONBODY(Vector, every)
{
	Vector* th=static_cast<Vector*>(obj);
	if (argslen < 1)
		throw Class<ArgumentError>::getInstanceS("Error #1063");
	if (!args[0]->is<IFunction>())
		throw Class<TypeError>::getInstanceS("Error #1034"); 
	IFunction* f = static_cast<IFunction*>(args[0]);
	ASObject* params[3];
	ASObject *funcRet;

	for(unsigned int i=0; i < th->size(); i++)
	{
		if (th->vec[i])
		{
			params[0] = th->vec[i];
			th->vec[i]->incRef();
		}
		else
			params[0] = getSys()->getNullRef();
		params[1] = abstract_i(i);
		params[2] = th;
		th->incRef();

		if(argslen==1)
		{
			funcRet=f->call(getSys()->getNullRef(), params, 3);
		}
		else
		{
			args[1]->incRef();
			funcRet=f->call(args[1], params, 3);
		}
		if(funcRet)
		{
			if (funcRet->is<Undefined>() || funcRet->is<Null>())
				throw Class<TypeError>::getInstanceS("Error #1006");
			if(!Boolean_concrete(funcRet))
			{
				return funcRet;
			}
			funcRet->decRef();
		}
	}
	return abstract_b(true);
}
示例#11
0
ASFUNCTIONBODY(Array,filter)
{
	Array* th=static_cast<Array*>(obj);
	Array* ret=Class<Array>::getInstanceS();
	_NR<IFunction> f;
	ARG_UNPACK(f);
	if (f.isNull())
		return ret;

	ASObject* params[3];
	ASObject *funcRet;

	std::map<uint32_t, data_slot>::iterator it=th->data.begin();
	for(;it != th->data.end();++it)
	{
		assert_and_throw(it->second.type==DATA_OBJECT);
		params[0] = it->second.data;
		it->second.data->incRef();
		params[1] = abstract_i(it->first);
		params[2] = th;
		th->incRef();

		// ensure that return values are the original values
		ASObject *origval = it->second.data;
		it->second.data->incRef();
		if(argslen==1)
		{
			funcRet=f->call(getSys()->getNullRef(), params, 3);
		}
		else
		{
			args[1]->incRef();
			funcRet=f->call(args[1], params, 3);
		}
		if(funcRet)
		{
			if(Boolean_concrete(funcRet))
				ret->push(_MR(origval));
			else
				origval->decRef();
			funcRet->decRef();
		}
	}
	return ret;
}
示例#12
0
ASFUNCTIONBODY(Vector,filter)
{
	if (argslen < 1 || argslen > 2)
		throwError<ArgumentError>(kWrongArgumentCountError, "Vector.filter", "1", Integer::toString(argslen));
	if (!args[0]->is<IFunction>())
		throwError<TypeError>(kCheckTypeFailedError, args[0]->getClassName(), "Function");
	Vector* th=static_cast<Vector*>(obj);
	  
	IFunction* f = static_cast<IFunction*>(args[0]);
	ASObject* params[3];
	Vector* ret= (Vector*)obj->getClass()->getInstance(true,NULL,0);
	ASObject *funcRet;

	for(unsigned int i=0;i<th->size();i++)
	{
		if (!th->vec[i])
			continue;
		params[0] = th->vec[i];
		th->vec[i]->incRef();
		params[1] = abstract_i(obj->getSystemState(),i);
		params[2] = th;
		th->incRef();

		if(argslen==1)
		{
			funcRet=f->call(obj->getSystemState()->getNullRef(), params, 3);
		}
		else
		{
			args[1]->incRef();
			funcRet=f->call(args[1], params, 3);
		}
		if(funcRet)
		{
			if(Boolean_concrete(funcRet))
			{
				th->vec[i]->incRef();
				ret->vec.push_back(th->vec[i]);
			}
			funcRet->decRef();
		}
	}
	return ret;
}
示例#13
0
文件: Vector.cpp 项目: gg0/lightspark
ASFUNCTIONBODY(Vector,filter)
{
	if (argslen < 1 || argslen > 2)
		throw Class<ArgumentError>::getInstanceS("Error #1063"); 
	if (!args[0]->is<IFunction>())
		throw Class<TypeError>::getInstanceS("Error #1034"); 
	Vector* th=static_cast<Vector*>(obj);
	  
	IFunction* f = static_cast<IFunction*>(args[0]);
	ASObject* params[3];
	Vector* ret= (Vector*)obj->getClass()->getInstance(true,NULL,0);
	ASObject *funcRet;

	for(unsigned int i=0;i<th->size();i++)
	{
		if (!th->vec[i])
			continue;
		params[0] = th->vec[i];
		th->vec[i]->incRef();
		params[1] = abstract_i(i);
		params[2] = th;
		th->incRef();

		if(argslen==1)
		{
			funcRet=f->call(getSys()->getNullRef(), params, 3);
		}
		else
		{
			args[1]->incRef();
			funcRet=f->call(args[1], params, 3);
		}
		if(funcRet)
		{
			if(Boolean_concrete(funcRet))
			{
				th->vec[i]->incRef();
				ret->vec.push_back(th->vec[i]);
			}
			funcRet->decRef();
		}
	}
	return ret;
}
示例#14
0
ASObject* ASObject::getValueAt(int index)
{
	obj_var* obj=Variables.getValueAt(index);
	assert_and_throw(obj);
	ASObject* ret;
	if(obj->getter)
	{
		//Call the getter
		LOG(LOG_CALLS,_("Calling the getter"));
		IFunction* getter=obj->getter->getOverride();
		incRef();
		ret=getter->call(this,NULL,0);
		ret->fake_decRef();
		LOG(LOG_CALLS,_("End of getter"));
	}
	else
		ret=obj->var;

	return ret;
}
示例#15
0
ASFUNCTIONBODY(Vector, some)
{
	if (argslen < 1)
		throw Class<ArgumentError>::getInstanceS("Error #1063");
	if (!args[0]->is<IFunction>())
		throw Class<TypeError>::getInstanceS("Error #1034"); 
	Vector* th=static_cast<Vector*>(obj);
	IFunction* f = static_cast<IFunction*>(args[0]);
	ASObject* params[3];
	ASObject *funcRet;

	for(unsigned int i=0; i < th->size(); i++)
	{
		if (!th->vec[i])
			continue;
		params[0] = th->vec[i];
		th->vec[i]->incRef();
		params[1] = abstract_i(i);
		params[2] = th;
		th->incRef();

		if(argslen==1)
		{
			funcRet=f->call(new Null, params, 3);
		}
		else
		{
			args[1]->incRef();
			funcRet=f->call(args[1], params, 3);
		}
		if(funcRet)
		{
			if(Boolean_concrete(funcRet))
			{
				return funcRet;
			}
			funcRet->decRef();
		}
	}
	return abstract_b(false);
}
示例#16
0
文件: Vector.cpp 项目: gg0/lightspark
ASObject* Vector::generator(TemplatedClass<Vector>* o_class, ASObject* const* args, const unsigned int argslen)
{
	assert_and_throw(argslen == 1);
	assert_and_throw(args[0]->getClass());
	assert_and_throw(o_class->getTypes().size() == 1);

	Type* type = o_class->getTypes()[0];

	if(args[0]->getClass() == Class<Array>::getClass())
	{
		//create object without calling _constructor
		Vector* ret = o_class->getInstance(false,NULL,0);

		Array* a = static_cast<Array*>(args[0]);
		for(unsigned int i=0;i<a->size();++i)
		{
			ASObject* obj = a->at(i).getPtr();
			obj->incRef();
			//Convert the elements of the array to the type of this vector
			ret->vec.push_back( type->coerce(obj) );
		}
		return ret;
	}
	else if(args[0]->getClass()->getTemplate() == Template<Vector>::getTemplate())
	{
		Vector* arg = static_cast<Vector*>(args[0]);

		//create object without calling _constructor
		Vector* ret = o_class->getInstance(false,NULL,0);
		for(auto i = arg->vec.begin(); i != arg->vec.end(); ++i)
		{
			(*i)->incRef();
			ret->vec.push_back( type->coerce(*i) );
		}
		return ret;
	}
	else
	{
		throw Class<ArgumentError>::getInstanceS("global Vector() function takes Array or Vector");
	}
}
示例#17
0
ASFUNCTIONBODY(Array,filter)
{
	Array* th=static_cast<Array*>(obj);
	assert_and_throw(argslen==1 || argslen==2);
	IFunction* f = static_cast<IFunction*>(args[0]);
	ASObject* params[3];
	Array* ret=Class<Array>::getInstanceS();
	ASObject *funcRet;

	std::map<uint32_t, data_slot>::iterator it=th->data.begin();
	for(;it != th->data.end();++it)
	{
		assert_and_throw(it->second.type==DATA_OBJECT);
		params[0] = it->second.data;
		it->second.data->incRef();
		params[1] = abstract_i(it->first);
		params[2] = th;
		th->incRef();

		if(argslen==1)
		{
			funcRet=f->call(getSys()->getNullRef(), params, 3);
		}
		else
		{
			args[1]->incRef();
			funcRet=f->call(args[1], params, 3);
		}
		if(funcRet)
		{
			if(Boolean_concrete(funcRet))
			{
				it->second.data->incRef();
				ret->push(_MR(it->second.data));
			}
			funcRet->decRef();
		}
	}
	return ret;
}
示例#18
0
ASFUNCTIONBODY(Array,filter)
{
	Array* th=static_cast<Array*>(obj);
	assert_and_throw(argslen==1 || argslen==2);
	IFunction* f = static_cast<IFunction*>(args[0]);
	ASObject* params[3];
	Array* ret=Class<Array>::getInstanceS();
	ASObject *funcRet;

	for(unsigned int i=0;i<th->data.size();i++)
	{
		assert_and_throw(th->data[i].type==DATA_OBJECT);
		params[0] = th->data[i].data;
		th->data[i].data->incRef();
		params[1] = abstract_i(i);
		params[2] = th;
		th->incRef();

		if(argslen==1)
		{
			funcRet=f->call(new Null, params, 3);
		}
		else
		{
			args[1]->incRef();
			funcRet=f->call(args[1], params, 3);
		}
		if(funcRet)
		{
			if(Boolean_concrete(funcRet))
			{
				th->data[i].data->incRef();
				ret->push(th->data[i].data);
			}
			funcRet->decRef();
		}
	}
	return ret;
}
示例#19
0
void Proxy::setVariableByMultiname(const multiname& name, ASObject* o, CONST_ALLOWED_FLAG allowConst)
{
	//If a variable named like this already exist, use that
	if(ASObject::hasPropertyByMultiname(name, true, false) || !implEnable)
	{
		ASObject::setVariableByMultiname(name,o,allowConst);
		return;
	}

	//Check if there is a custom setter defined, skipping implementation to avoid recursive calls
	multiname setPropertyName(NULL);
	setPropertyName.name_type=multiname::NAME_STRING;
	setPropertyName.name_s_id=getSys()->getUniqueStringId("setProperty");
	setPropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE));
	_NR<ASObject> proxySetter=getVariableByMultiname(setPropertyName,ASObject::SKIP_IMPL);

	if(proxySetter.isNull())
	{
		ASObject::setVariableByMultiname(name,o,allowConst);
		return;
	}

	assert_and_throw(proxySetter->getObjectType()==T_FUNCTION);

	IFunction* f=static_cast<IFunction*>(proxySetter.getPtr());

	ASObject* namearg = Class<ASString>::getInstanceS(name.normalizedName());
	namearg->setProxyProperty(name);
	ASObject* args[2];
	args[0]=namearg;
	args[1]=o;
	//We now suppress special handling
	implEnable=false;
	LOG(LOG_CALLS,_("Proxy::setProperty"));
	incRef();
	_R<ASObject> ret=_MR( f->call(this,args,2) );
	assert_and_throw(ret->is<Undefined>());
	implEnable=true;
}
示例#20
0
/*
 * (creates and) sets the property 'prototype' to o
 * 'prototype' is usually DYNAMIC_TRAIT, but on Class_base
 * it is a DECLARED_TRAIT, which is gettable only
 */
void ASObject::setprop_prototype(_NR<ASObject>& o)
{
	ASObject* obj = o.getPtr();
	obj->incRef();

	multiname prototypeName;
	prototypeName.name_type=multiname::NAME_STRING;
	prototypeName.name_s="prototype";
	prototypeName.ns.push_back(nsNameAndKind("",NAMESPACE));
	bool has_getter = false;
	variable* ret=findSettable(prototypeName,false, &has_getter);
	if(!ret && has_getter)
		throw Class<ReferenceError>::getInstanceS("Error #1074: Illegal write to read-only property prototype");
	if(!ret)
		ret = Variables.findObjVar(prototypeName,DYNAMIC_TRAIT,DECLARED_TRAIT|DYNAMIC_TRAIT);
	if(ret->setter)
	{
		this->incRef();
		_MR( ret->setter->call(this,&obj,1) );
	}
	else
		ret->setVar(obj);
}
示例#21
0
bool Proxy::hasPropertyByMultiname(const multiname& name, bool considerDynamic, bool considerPrototype)
{
	if (name.normalizedName() == "isAttribute")
		return true;
	//If a variable named like this already exist, use that
	bool asobject_has_property=ASObject::hasPropertyByMultiname(name, considerDynamic, considerPrototype);
	if(asobject_has_property || !implEnable)
		return asobject_has_property;

	//Check if there is a custom hasProperty defined, skipping implementation to avoid recursive calls
	multiname hasPropertyName(NULL);
	hasPropertyName.name_type=multiname::NAME_STRING;
	hasPropertyName.name_s_id=getSys()->getUniqueStringId("hasProperty");
	hasPropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE));
	_NR<ASObject> proxyHasProperty=getVariableByMultiname(hasPropertyName,ASObject::SKIP_IMPL);

	if(proxyHasProperty.isNull())
	{
		return false;
	}

	assert_and_throw(proxyHasProperty->getObjectType()==T_FUNCTION);

	IFunction* f=static_cast<IFunction*>(proxyHasProperty.getPtr());

	ASObject* namearg = Class<ASString>::getInstanceS(name.normalizedName());
	namearg->setProxyProperty(name);
	ASObject* arg = namearg;
	//We now suppress special handling
	implEnable=false;
	LOG(LOG_CALLS,_("Proxy::hasProperty"));
	incRef();
	_NR<ASObject> ret=_MNR(f->call(this,&arg,1));
	implEnable=true;
	Boolean* b = static_cast<Boolean*>(ret.getPtr());
	return b->val;
}
示例#22
0
_NR<ASObject> Proxy::getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt)
{
	//It seems that various kind of implementation works only with the empty namespace
	assert_and_throw(name.ns.size()>0);
	_NR<ASObject> o;
	LOG(LOG_CALLS,"Proxy::getVar "<< name << " " << this->toDebugString());
	if(ASObject::hasPropertyByMultiname(name, true, true) || !implEnable || (opt & ASObject::SKIP_IMPL)!=0)
		o = ASObject::getVariableByMultiname(name,opt);
	if (!o.isNull() || !implEnable || (opt & ASObject::SKIP_IMPL)!=0)
		return o;

	//Check if there is a custom getter defined, skipping implementation to avoid recursive calls
	multiname getPropertyName(NULL);
	getPropertyName.name_type=multiname::NAME_STRING;
	getPropertyName.name_s_id=getSys()->getUniqueStringId("getProperty");
	getPropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE));
	o=getVariableByMultiname(getPropertyName,ASObject::SKIP_IMPL);

	if(o.isNull())
		return ASObject::getVariableByMultiname(name,opt);

	assert_and_throw(o->getObjectType()==T_FUNCTION);

	IFunction* f=static_cast<IFunction*>(o.getPtr());

	ASObject* namearg = Class<ASString>::getInstanceS(name.normalizedName());
	namearg->setProxyProperty(name);
	ASObject* arg = namearg;
	//We now suppress special handling
	implEnable=false;
	LOG(LOG_CALLS,"Proxy::getProperty "<< name.normalizedName() << " " << this->toDebugString());
	incRef();
	_NR<ASObject> ret=_MNR(f->call(this,&arg,1));
	implEnable=true;
	return ret;
}
示例#23
0
bool Proxy::deleteVariableByMultiname(const multiname& name)
{
	//If a variable named like this already exist, use that
	if(ASObject::hasPropertyByMultiname(name, true, false) || !implEnable)
	{
		return ASObject::deleteVariableByMultiname(name);
	}

	//Check if there is a custom deleter defined, skipping implementation to avoid recursive calls
	multiname deletePropertyName(NULL);
	deletePropertyName.name_type=multiname::NAME_STRING;
	deletePropertyName.name_s_id=getSys()->getUniqueStringId("deleteProperty");
	deletePropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE));
	_NR<ASObject> proxyDeleter=getVariableByMultiname(deletePropertyName,ASObject::SKIP_IMPL);

	if(proxyDeleter.isNull())
	{
		return ASObject::deleteVariableByMultiname(name);
	}

	assert_and_throw(proxyDeleter->getObjectType()==T_FUNCTION);

	IFunction* f=static_cast<IFunction*>(proxyDeleter.getPtr());

	ASObject* namearg = Class<ASString>::getInstanceS(name.normalizedName());
	namearg->setProxyProperty(name);
	ASObject* arg = namearg;
	//We now suppress special handling
	implEnable=false;
	LOG(LOG_CALLS,_("Proxy::deleteProperty"));
	incRef();
	_NR<ASObject> ret=_MNR(f->call(this,&arg,1));
	implEnable=true;
	Boolean* b = static_cast<Boolean*>(ret.getPtr());
	return b->val;
}
示例#24
0
ASFUNCTIONBODY(Vector,forEach)
{
	if (argslen < 1)
		throwError<ArgumentError>(kWrongArgumentCountError, "Vector.forEach", "1", Integer::toString(argslen));
	if (!args[0]->is<IFunction>())
		throwError<TypeError>(kCheckTypeFailedError, args[0]->getClassName(), "Function");
	Vector* th=static_cast<Vector*>(obj);
	IFunction* f = static_cast<IFunction*>(args[0]);
	ASObject* params[3];

	for(unsigned int i=0; i < th->size(); i++)
	{
		if (!th->vec[i])
			continue;
		params[0] = th->vec[i];
		th->vec[i]->incRef();
		params[1] = abstract_i(obj->getSystemState(),i);
		params[2] = th;
		th->incRef();

		ASObject *funcret;
		if( argslen == 1 )
		{
			funcret=f->call(obj->getSystemState()->getNullRef(), params, 3);
		}
		else
		{
			args[1]->incRef();
			funcret=f->call(args[1], params, 3);
		}
		if(funcret)
			funcret->decRef();
	}

	return NULL;
}
示例#25
0
文件: Vector.cpp 项目: gg0/lightspark
ASFUNCTIONBODY(Vector,forEach)
{
	if (argslen < 1)
		throw Class<ArgumentError>::getInstanceS("Error #1063");
	if (!args[0]->is<IFunction>())
		throw Class<TypeError>::getInstanceS("Error #1034"); 
	Vector* th=static_cast<Vector*>(obj);
	IFunction* f = static_cast<IFunction*>(args[0]);
	ASObject* params[3];

	for(unsigned int i=0; i < th->size(); i++)
	{
		if (!th->vec[i])
			continue;
		params[0] = th->vec[i];
		th->vec[i]->incRef();
		params[1] = abstract_i(i);
		params[2] = th;
		th->incRef();

		ASObject *funcret;
		if( argslen == 1 )
		{
			funcret=f->call(getSys()->getNullRef(), params, 3);
		}
		else
		{
			args[1]->incRef();
			funcret=f->call(args[1], params, 3);
		}
		if(funcret)
			funcret->decRef();
	}

	return NULL;
}
示例#26
0
void NetStream::execute()
{
	if(downloader->hasFailed())
	{
		sys->currentVm->addEvent(this,Class<Event>::getInstanceS("ioError"));
		sys->downloadManager->destroy(downloader);
		return;
	}

	//The downloader hasn't failed yet at this point

	//mutex access to downloader
	istream s(downloader);
	s.exceptions ( istream::eofbit | istream::failbit | istream::badbit );

	ThreadProfile* profile=sys->allocateProfiler(RGB(0,0,200));
	profile->setTag("NetStream");
	//We need to catch possible EOF and other error condition in the non reliable stream
	uint32_t decodedAudioBytes=0;
	uint32_t decodedVideoFrames=0;
	//The decoded time is computed from the decodedAudioBytes to avoid drifts
	uint32_t decodedTime=0;
	bool waitForFlush=true;
	try
	{
		ScriptDataTag tag;
		Chronometer chronometer;
		STREAM_TYPE t=classifyStream(s);
		if(t==FLV_STREAM)
		{
			FLV_HEADER h(s);
			if(!h.isValid())
				throw ParseException("FLV is not valid");

			unsigned int prevSize=0;
			bool done=false;
			do
			{
				//Check if threadAbort has been called, if so, stop this loop
				if(closed)
					done = true;
				UI32 PreviousTagSize;
				s >> PreviousTagSize;
				PreviousTagSize.bswap();
				assert_and_throw(PreviousTagSize==prevSize);

				//Check tag type and read it
				UI8 TagType;
				s >> TagType;
				switch(TagType)
				{
					case 8:
					{
						AudioDataTag tag(s);
						prevSize=tag.getTotalLen();

						if(audioDecoder==NULL)
						{
							audioCodec=tag.SoundFormat;
							switch(tag.SoundFormat)
							{
								case AAC:
									assert_and_throw(tag.isHeader())
#ifdef ENABLE_LIBAVCODEC
									audioDecoder=new FFMpegAudioDecoder(tag.SoundFormat,
											tag.packetData, tag.packetLen);
#else
									audioDecoder=new NullAudioDecoder();
#endif
									tag.releaseBuffer();
									break;
								case MP3:
#ifdef ENABLE_LIBAVCODEC
									audioDecoder=new FFMpegAudioDecoder(tag.SoundFormat,NULL,0);
#else
									audioDecoder=new NullAudioDecoder();
#endif
									decodedAudioBytes+=
										audioDecoder->decodeData(tag.packetData,tag.packetLen,decodedTime);
									//Adjust timing
									decodedTime=decodedAudioBytes/audioDecoder->getBytesPerMSec();
									break;
								default:
									throw RunTimeException("Unsupported SoundFormat");
							}
							if(audioDecoder->isValid() && sys->audioManager->pluginLoaded())
								audioStream=sys->audioManager->createStreamPlugin(audioDecoder);
						}
						else
						{
							assert_and_throw(audioCodec==tag.SoundFormat);
							decodedAudioBytes+=
								audioDecoder->decodeData(tag.packetData,tag.packetLen,decodedTime);
							if(audioStream==0 && audioDecoder->isValid() && sys->audioManager->pluginLoaded())
								audioStream=sys->audioManager->createStreamPlugin(audioDecoder);
							//Adjust timing
							decodedTime=decodedAudioBytes/audioDecoder->getBytesPerMSec();
						}
						break;
					}
					case 9:
					{
						VideoDataTag tag(s);
						prevSize=tag.getTotalLen();
						//If the framerate is known give the right timing, otherwise use decodedTime from audio
						uint32_t frameTime=(frameRate!=0.0)?(decodedVideoFrames*1000/frameRate):decodedTime;

						if(videoDecoder==NULL)
						{
							//If the isHeader flag is on then the decoder becomes the owner of the data
							if(tag.isHeader())
							{
								//The tag is the header, initialize decoding
#ifdef ENABLE_LIBAVCODEC
								videoDecoder=
									new FFMpegVideoDecoder(tag.codec,tag.packetData,tag.packetLen, frameRate);
#else
								videoDecoder=new NullVideoDecoder();
#endif
								tag.releaseBuffer();
							}
							else if(videoDecoder==NULL)
							{
								//First packet but no special handling
#ifdef ENABLE_LIBAVCODEC
								videoDecoder=new FFMpegVideoDecoder(tag.codec,NULL,0,frameRate);
#else
								videoDecoder=new NullVideoDecoder();
#endif
								videoDecoder->decodeData(tag.packetData,tag.packetLen, frameTime);
								decodedVideoFrames++;
							}
							Event* status=Class<NetStatusEvent>::getInstanceS("status", "NetStream.Play.Start");
							getVm()->addEvent(this, status);
							status->decRef();
							status=Class<NetStatusEvent>::getInstanceS("status", "NetStream.Buffer.Full");
							getVm()->addEvent(this, status);
							status->decRef();
						}
						else
						{
							videoDecoder->decodeData(tag.packetData,tag.packetLen, frameTime);
							decodedVideoFrames++;
						}
						break;
					}
					case 18:
					{
						tag = ScriptDataTag(s);
						prevSize=tag.getTotalLen();

						//The frameRate of the container overrides the stream
						
						if(tag.metadataDouble.find("framerate") != tag.metadataDouble.end())
							frameRate=tag.metadataDouble["framerate"];
						break;
					}
					default:
						LOG(LOG_ERROR,_("Unexpected tag type ") << (int)TagType << _(" in FLV"));
						threadAbort();
				}
				if(!tickStarted && isReady())
				{
					{
						multiname onMetaDataName;
						onMetaDataName.name_type=multiname::NAME_STRING;
						onMetaDataName.name_s="onMetaData";
						onMetaDataName.ns.push_back(nsNameAndKind("",NAMESPACE));
						ASObject* callback = client->getVariableByMultiname(onMetaDataName);
						if(callback && callback->getObjectType() == T_FUNCTION)
						{
							ASObject* callbackArgs[1];
							ASObject* metadata = Class<ASObject>::getInstanceS();
							if(tag.metadataDouble.find("width") != tag.metadataDouble.end())
								metadata->setVariableByQName("width", "", 
										abstract_d(tag.metadataDouble["width"]));
							else
								metadata->setVariableByQName("width", "", abstract_d(getVideoWidth()));
							if(tag.metadataDouble.find("height") != tag.metadataDouble.end())
								metadata->setVariableByQName("height", "", 
										abstract_d(tag.metadataDouble["height"]));
							else
								metadata->setVariableByQName("height", "", abstract_d(getVideoHeight()));

							if(tag.metadataDouble.find("framerate") != tag.metadataDouble.end())
								metadata->setVariableByQName("framerate", "", 
										abstract_d(tag.metadataDouble["framerate"]));
							if(tag.metadataDouble.find("duration") != tag.metadataDouble.end())
								metadata->setVariableByQName("duration", "", 
										abstract_d(tag.metadataDouble["duration"]));
							if(tag.metadataInteger.find("canseekontime") != tag.metadataInteger.end())
								metadata->setVariableByQName("canSeekToEnd", "", 
										abstract_b(tag.metadataInteger["canseekontime"] == 1));

							if(tag.metadataDouble.find("audiodatarate") != tag.metadataDouble.end())
								metadata->setVariableByQName("audiodatarate", "", 
										abstract_d(tag.metadataDouble["audiodatarate"]));
							if(tag.metadataDouble.find("videodatarate") != tag.metadataDouble.end())
								metadata->setVariableByQName("videodatarate", "", 
										abstract_d(tag.metadataDouble["videodatarate"]));

							//TODO: missing: audiocodecid (Number), cuePoints (Object[]), 
							//videocodecid (Number), custommetadata's
							callbackArgs[0] = metadata;
							client->incRef();
							metadata->incRef();
							FunctionEvent* event = 
								new FunctionEvent(static_cast<IFunction*>(callback), client, callbackArgs, 1);
							getVm()->addEvent(NULL,event);
							event->decRef();
						}
					}

					tickStarted=true;
					if(frameRate==0)
					{
						assert(videoDecoder->frameRate);
						frameRate=videoDecoder->frameRate;
					}
					sys->addTick(1000/frameRate,this);
					//Also ask for a render rate equal to the video one (capped at 24)
					float localRenderRate=dmin(frameRate,24);
					sys->setRenderRate(localRenderRate);
				}
				profile->accountTime(chronometer.checkpoint());
				if(aborting)
				{
					throw JobTerminationException();
				}
			}
			while(!done);
		}
		else
			threadAbort();

	}
示例#27
0
_NR<ASObject> ASObject::getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt, Class_base* cls)
{
	check();
	assert(!cls || classdef->isSubClass(cls));
	//Get from the current object without considering borrowed properties
	variable* obj=findGettable(name, false);

	if(!obj && cls)
	{
		//Look for borrowed traits before
		obj=cls->findGettable(name,true);
	}

	if(!obj && cls)
	{
		//Check prototype chain
		ASObject* proto = cls->prototype.getPtr();
		while(proto)
		{
			obj = proto->findGettable(name, false);
			if(obj)
			{
				obj->var->incRef();
				return _MNR(obj->var);
			}
			proto = proto->getprop_prototype();
		}
	}

	if(!obj)
		return NullRef;

	if(obj->getter)
	{
		//Call the getter
		ASObject* target=this;
		if(target->classdef)
		{
			LOG(LOG_CALLS,_("Calling the getter on type ") << target->classdef->class_name);
		}
		else
		{
			LOG(LOG_CALLS,_("Calling the getter"));
		}
		IFunction* getter=obj->getter;
		target->incRef();
		ASObject* ret=getter->call(target,NULL,0);
		LOG(LOG_CALLS,_("End of getter"));
		// No incRef because ret is a new instance
		return _MNR(ret);
	}
	else
	{
		assert_and_throw(!obj->setter);
		assert_and_throw(obj->var);
		if(obj->var->getObjectType()==T_FUNCTION && obj->var->as<IFunction>()->isMethod())
		{
			LOG(LOG_CALLS,"Attaching this " << this << " to function " << name);
			//the obj reference is acquired by the smart reference
			this->incRef();
			IFunction* f=obj->var->as<IFunction>()->bind(_MR(this),-1);
			//No incref is needed, as the function is a new instance
			return _MNR(f);
		}
		obj->var->incRef();
		return _MNR(obj->var);
	}
}
示例#28
0
void NetStream::execute()
{
	//checkPolicyFile only applies to per-pixel access, loading and playing is always allowed.
	//So there is no need to disallow playing if policy files disallow it.
	//We do need to check if per-pixel access is allowed.
	SecurityManager::EVALUATIONRESULT evaluationResult = sys->securityManager->evaluatePoliciesURL(url, true);
	if(evaluationResult == SecurityManager::NA_CROSSDOMAIN_POLICY)
		rawAccessAllowed = true;

	if(downloader->hasFailed())
	{
		this->incRef();
		sys->currentVm->addEvent(_MR(this),_MR(Class<Event>::getInstanceS("ioError")));
		sys->downloadManager->destroy(downloader);
		return;
	}

	//The downloader hasn't failed yet at this point

	istream s(downloader);
	s.exceptions ( istream::eofbit | istream::failbit | istream::badbit );

	ThreadProfile* profile=sys->allocateProfiler(RGB(0,0,200));
	profile->setTag("NetStream");
	bool waitForFlush=true;
	StreamDecoder* streamDecoder=NULL;
	//We need to catch possible EOF and other error condition in the non reliable stream
	try
	{
		Chronometer chronometer;
		streamDecoder=new FFMpegStreamDecoder(s);
		if(!streamDecoder->isValid())
			threadAbort();

		bool done=false;
		while(!done)
		{
			//Check if threadAbort has been called, if so, stop this loop
			if(closed)
				done = true;
			bool decodingSuccess=streamDecoder->decodeNextFrame();
			if(decodingSuccess==false)
				done = true;

			if(videoDecoder==NULL && streamDecoder->videoDecoder)
			{
				videoDecoder=streamDecoder->videoDecoder;
				this->incRef();
				getVm()->addEvent(_MR(this),
						_MR(Class<NetStatusEvent>::getInstanceS("status", "NetStream.Play.Start")));
				this->incRef();
				getVm()->addEvent(_MR(this),
						_MR(Class<NetStatusEvent>::getInstanceS("status", "NetStream.Buffer.Full")));
			}

			if(audioDecoder==NULL && streamDecoder->audioDecoder)
				audioDecoder=streamDecoder->audioDecoder;

			if(audioStream==NULL && audioDecoder && audioDecoder->isValid() && sys->audioManager->pluginLoaded())
				audioStream=sys->audioManager->createStreamPlugin(audioDecoder);

			if(audioStream && audioStream->paused() && !paused)
			{
				//The audio stream is paused but should not!
				//As we have new data fill the stream
				audioStream->fill();
			}

			if(!tickStarted && isReady())
			{
				multiname onMetaDataName;
				onMetaDataName.name_type=multiname::NAME_STRING;
				onMetaDataName.name_s="onMetaData";
				onMetaDataName.ns.push_back(nsNameAndKind("",NAMESPACE));
				ASObject* callback = client->getVariableByMultiname(onMetaDataName);
				if(callback && callback->getObjectType() == T_FUNCTION)
				{
					ASObject* callbackArgs[1];
					ASObject* metadata = Class<ASObject>::getInstanceS();
					double d;
					uint32_t i;
					if(streamDecoder->getMetadataDouble("width",d))
						metadata->setVariableByQName("width", "",abstract_d(d),DYNAMIC_TRAIT);
					else
						metadata->setVariableByQName("width", "", abstract_d(getVideoWidth()),DYNAMIC_TRAIT);
					if(streamDecoder->getMetadataDouble("height",d))
						metadata->setVariableByQName("height", "",abstract_d(d),DYNAMIC_TRAIT);
					else
						metadata->setVariableByQName("height", "", abstract_d(getVideoHeight()),DYNAMIC_TRAIT);
					if(streamDecoder->getMetadataDouble("framerate",d))
						metadata->setVariableByQName("framerate", "",abstract_d(d),DYNAMIC_TRAIT);
					if(streamDecoder->getMetadataDouble("duration",d))
						metadata->setVariableByQName("duration", "",abstract_d(d),DYNAMIC_TRAIT);
					if(streamDecoder->getMetadataInteger("canseekontime",i))
						metadata->setVariableByQName("canSeekToEnd", "",abstract_b(i == 1),DYNAMIC_TRAIT);
					if(streamDecoder->getMetadataDouble("audiodatarate",d))
						metadata->setVariableByQName("audiodatarate", "",abstract_d(d),DYNAMIC_TRAIT);
					if(streamDecoder->getMetadataDouble("videodatarate",d))
						metadata->setVariableByQName("videodatarate", "",abstract_d(d),DYNAMIC_TRAIT);

					//TODO: missing: audiocodecid (Number), cuePoints (Object[]),
					//videocodecid (Number), custommetadata's
					client->incRef();
					metadata->incRef();
					callbackArgs[0] = metadata;
					callback->incRef();
					_R<FunctionEvent> event(new FunctionEvent(_MR(static_cast<IFunction*>(callback)),
							_MR(client), callbackArgs, 1));
					getVm()->addEvent(NullRef,event);
				}

				tickStarted=true;
				if(frameRate==0)
				{
					assert(videoDecoder->frameRate);
					frameRate=videoDecoder->frameRate;
				}
				sys->addTick(1000/frameRate,this);
				//Also ask for a render rate equal to the video one (capped at 24)
				float localRenderRate=dmin(frameRate,24);
				sys->setRenderRate(localRenderRate);
			}
			profile->accountTime(chronometer.checkpoint());
			if(aborting)
				throw JobTerminationException();
		}

	}
	catch(LightsparkException& e)
	{
		LOG(LOG_ERROR, "Exception in NetStream " << e.cause);
		threadAbort();
		waitForFlush=false;
	}
	catch(JobTerminationException& e)
	{
		waitForFlush=false;
	}
	catch(exception& e)
	{
		LOG(LOG_ERROR, _("Exception in reading: ")<<e.what());
	}
	if(waitForFlush)
	{
		//Put the decoders in the flushing state and wait for the complete consumption of contents
		if(audioDecoder)
			audioDecoder->setFlushing();
		if(videoDecoder)
			videoDecoder->setFlushing();
		
		if(audioDecoder)
			audioDecoder->waitFlushed();
		if(videoDecoder)
			videoDecoder->waitFlushed();

		this->incRef();
		getVm()->addEvent(_MR(this), _MR(Class<NetStatusEvent>::getInstanceS("status", "NetStream.Play.Stop")));
		this->incRef();
		getVm()->addEvent(_MR(this), _MR(Class<NetStatusEvent>::getInstanceS("status", "NetStream.Buffer.Flush")));
	}
	//Before deleting stops ticking, removeJobs also spin waits for termination
	sys->removeJob(this);
	tickStarted=false;
	sem_wait(&mutex);
	//Change the state to invalid to avoid locking
	videoDecoder=NULL;
	audioDecoder=NULL;
	//Clean up everything for a possible re-run
	sys->downloadManager->destroy(downloader);
	//This transition is critical, so the mutex is needed
	downloader=NULL;
	if(audioStream)
		sys->audioManager->freeStreamPlugin(audioStream);
	audioStream=NULL;
	sem_post(&mutex);
	delete streamDecoder;
}
示例#29
0
void ASObject::setVariableByMultiname(const multiname& name, ASObject* o, Class_base* cls)
{
	check();
	assert(!cls || classdef->isSubClass(cls));
	//NOTE: we assume that [gs]etSuper and [sg]etProperty correctly manipulate the cur_level (for getActualClass)
	bool has_getter=false;
	variable* obj=findSettable(name, false, &has_getter);

	if(!obj && cls)
	{
		//Look for borrowed traits before
		//It's valid to override only a getter, so keep
		//looking for a settable even if a super class sets
		//has_getter to true.
		obj=cls->findSettable(name,true,&has_getter);
	}

	if(!obj && cls)
	{
		//Look in prototype chain
		ASObject* proto = cls->prototype.getPtr();
		while(proto)
		{
			variable* tmp = proto->findSettable(name, false, NULL /*prototypes never have getters/setters*/);
			
			if(tmp)
			{
				if (tmp->kind != DYNAMIC_TRAIT) // dynamic prototype properties can be overridden 
					obj = tmp;
				break;
			}
			proto = proto->getprop_prototype();
		}
	}

	if(!obj)
	{
		if(has_getter)
		{
			tiny_string err=tiny_string("Error #1074: Illegal write to read-only property ")+name.normalizedName();
			if(cls)
				err+=tiny_string(" on type ")+cls->getQualifiedClassName();
			throw Class<ReferenceError>::getInstanceS(err);
		}
		//Create a new dynamic variable
		obj=Variables.findObjVar(name,DYNAMIC_TRAIT,DYNAMIC_TRAIT);
	}

	if(obj->setter)
	{
		//Call the setter
		LOG(LOG_CALLS,_("Calling the setter"));
		//Overriding function is automatically done by using cur_level
		IFunction* setter=obj->setter;
		//One argument can be passed without creating an array
		ASObject* target=this;
		target->incRef();
		_R<ASObject> ret= _MR( setter->call(target,&o,1) );
		assert_and_throw(ret->is<Undefined>());
		LOG(LOG_CALLS,_("End of setter"));
	}
	else
	{
		assert_and_throw(!obj->getter);
		obj->setVar(o);
	}
}
示例#30
0
// Conversion to ASObject
ASObject* ExtVariant::getASObject() const
{
	ASObject* asobj;
	switch(getType())
	{
	case EV_STRING:
		asobj = Class<ASString>::getInstanceS(getString().c_str());
		break;
	case EV_INT32:
		asobj = abstract_i(getInt());
		break;
	case EV_DOUBLE:
		asobj = abstract_d(getDouble());
		break;
	case EV_BOOLEAN:
		asobj = abstract_b(getBoolean());
		break;
	case EV_OBJECT:
		{
			ExtObject* objValue = getObject();

			ExtVariant* property;
			uint32_t count;

			// We are converting an array, so lets set indexes
			if(objValue->getType() == ExtObject::EO_ARRAY)
			{
				asobj = Class<Array>::getInstanceS();
				count = objValue->getLength();
				static_cast<Array*>(asobj)->resize(count);
				for(uint32_t i = 0; i < count; i++)
				{
					property = objValue->getProperty(i);
					static_cast<Array*>(asobj)->set(i, property->getASObject());
					delete property;
				}
			}
			// We are converting an object, so lets set variables
			else
			{
				asobj = Class<ASObject>::getInstanceS();
			
				ExtIdentifier** ids;
				uint32_t count;
				std::stringstream conv;
				if(objValue != NULL && objValue->enumerate(&ids, &count))
				{
					for(uint32_t i = 0; i < count; i++)
					{
						property = objValue->getProperty(*ids[i]);

						if(ids[i]->getType() == ExtIdentifier::EI_STRING)
						{
							asobj->setVariableByQName(ids[i]->getString(), "",
									property->getASObject(), DYNAMIC_TRAIT);
						}
						else
						{
							conv << ids[i]->getInt();
							asobj->setVariableByQName(conv.str().c_str(), "",
									property->getASObject(), DYNAMIC_TRAIT);
						}
						delete property;
						delete ids[i];
					}
				}
				delete ids;
			}
			if(objValue != NULL)
				delete objValue;
		}
		break;
	case EV_NULL:
		asobj = new Null;
		break;
	case EV_VOID:
	default:
		asobj = new Undefined;
		break;
	}
	return asobj;
}