Projects
Essentials
lightspark
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 99
View file
lightspark.spec
Changed
@@ -20,7 +20,7 @@ %bcond_without librtmp Name: lightspark -Version: 0.7.2.99+git20160228.0950 +Version: 0.7.2.99+git20160306.1920 Release: 0 Summary: Modern, free, open-source flash player implementation License: LGPL-3.0+ @@ -64,9 +64,9 @@ BuildRequires: pkgconfig(libssl) %endif %if %{with ffmpeg} -BuildRequires: pkgconfig(libavcodec) = 56.60.100 -BuildRequires: pkgconfig(libavformat) = 56.40.101 -BuildRequires: pkgconfig(libavutil) = 54.31.100 +BuildRequires: pkgconfig(libavcodec) +BuildRequires: pkgconfig(libavformat) +BuildRequires: pkgconfig(libavutil) %endif %description
View file
lightspark.tar.xz/src/asobject.cpp
Changed
@@ -180,7 +180,7 @@ { assert_and_throw(implEnable); - return _MR(Class<ASString>::getInstanceS(getNameAt(index-1))); + return _MR(abstract_s(getNameAt(index-1))); } _R<ASObject> ASObject::nextValue(uint32_t index) @@ -324,8 +324,8 @@ multiname valueOfName(NULL); valueOfName.name_type=multiname::NAME_STRING; valueOfName.name_s_id=getSys()->getUniqueStringId("valueOf"); - valueOfName.ns.push_back(nsNameAndKind("",NAMESPACE)); - valueOfName.ns.push_back(nsNameAndKind(AS3,NAMESPACE)); + valueOfName.ns.emplace_back("",NAMESPACE); + valueOfName.ns.emplace_back(AS3,NAMESPACE); valueOfName.isAttribute = false; return hasPropertyByMultiname(valueOfName, true, true); } @@ -338,8 +338,8 @@ multiname valueOfName(NULL); valueOfName.name_type=multiname::NAME_STRING; valueOfName.name_s_id=getSys()->getUniqueStringId("valueOf"); - valueOfName.ns.push_back(nsNameAndKind("",NAMESPACE)); - valueOfName.ns.push_back(nsNameAndKind(AS3,NAMESPACE)); + valueOfName.ns.emplace_back("",NAMESPACE); + valueOfName.ns.emplace_back(AS3,NAMESPACE); valueOfName.isAttribute = false; assert_and_throw(hasPropertyByMultiname(valueOfName, true, true)); @@ -358,8 +358,8 @@ multiname toStringName(NULL); toStringName.name_type=multiname::NAME_STRING; toStringName.name_s_id=getSys()->getUniqueStringId("toString"); - toStringName.ns.push_back(nsNameAndKind("",NAMESPACE)); - toStringName.ns.push_back(nsNameAndKind(AS3,NAMESPACE)); + toStringName.ns.emplace_back("",NAMESPACE); + toStringName.ns.emplace_back(AS3,NAMESPACE); toStringName.isAttribute = false; return ASObject::hasPropertyByMultiname(toStringName, true, true); } @@ -372,8 +372,8 @@ multiname toStringName(NULL); toStringName.name_type=multiname::NAME_STRING; toStringName.name_s_id=getSys()->getUniqueStringId("toString"); - toStringName.ns.push_back(nsNameAndKind("",NAMESPACE)); - toStringName.ns.push_back(nsNameAndKind(AS3,NAMESPACE)); + toStringName.ns.emplace_back("",NAMESPACE); + toStringName.ns.emplace_back(AS3,NAMESPACE); toStringName.isAttribute = false; assert(ASObject::hasPropertyByMultiname(toStringName, true, true)); @@ -393,8 +393,8 @@ multiname toJSONName(NULL); toJSONName.name_type=multiname::NAME_STRING; toJSONName.name_s_id=getSys()->getUniqueStringId("toJSON"); - toJSONName.ns.push_back(nsNameAndKind("",NAMESPACE)); - toJSONName.ns.push_back(nsNameAndKind(AS3,NAMESPACE)); + toJSONName.ns.emplace_back("",NAMESPACE); + toJSONName.ns.emplace_back(AS3,NAMESPACE); toJSONName.isAttribute = false; if (!ASObject::hasPropertyByMultiname(toJSONName, true, true)) return res; @@ -1000,7 +1000,7 @@ else ret="[object Object]"; - return Class<ASString>::getInstanceS(ret); + return abstract_s(ret); } ASFUNCTIONBODY(ASObject,_toLocaleString) @@ -1008,7 +1008,7 @@ multiname toStringName(NULL); toStringName.name_type=multiname::NAME_STRING; toStringName.name_s_id=getSys()->getUniqueStringId("toString"); - toStringName.ns.push_back(nsNameAndKind("",NAMESPACE)); + toStringName.ns.emplace_back("",NAMESPACE); toStringName.isAttribute = false; if (obj->hasPropertyByMultiname(toStringName, true, false)) { @@ -1029,7 +1029,7 @@ multiname name(NULL); name.name_type=multiname::NAME_STRING; name.name_s_id=getSys()->getUniqueStringId(args[0]->toString()); - name.ns.push_back(nsNameAndKind("",NAMESPACE)); + name.ns.emplace_back("",NAMESPACE); name.isAttribute=false; bool ret=obj->hasPropertyByMultiname(name, true, false); return abstract_b(ret); @@ -1069,7 +1069,7 @@ multiname name(NULL); name.name_type=multiname::NAME_STRING; name.name_s_id=getSys()->getUniqueStringId(args[0]->toString()); - name.ns.push_back(nsNameAndKind("",NAMESPACE)); + name.ns.emplace_back("",NAMESPACE); name.isAttribute=false; if (obj->is<Array>()) // propertyIsEnumerable(index) isn't mentioned in the ECMA specs but is tested for { @@ -1095,7 +1095,7 @@ multiname name(NULL); name.name_type=multiname::NAME_STRING; name.name_s_id=getSys()->getUniqueStringId(args[0]->toString()); - name.ns.push_back(nsNameAndKind("",NAMESPACE)); + name.ns.emplace_back("",NAMESPACE); name.isAttribute=false; obj->setIsEnumerable(name, isEnum); return NULL; @@ -1158,7 +1158,7 @@ return findGettableImpl(Variables,name,nskind); } -const variable* ASObject::findVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt, Class_base* cls, NS_KIND &nskind) +const variable* ASObject::findVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt, Class_base* cls, NS_KIND &nskind) const { //Get from the current object without considering borrowed properties const variable* var=findGettable(name,nskind); @@ -1247,7 +1247,7 @@ varName.name_type=multiname::NAME_STRING; varName.name_s_id=getSys()->getUniqueStringId(name); for (auto ns=namespaces.begin(); ns!=namespaces.end(); ns++) - varName.ns.push_back(nsNameAndKind(*ns,NAMESPACE)); + varName.ns.emplace_back(*ns,NAMESPACE); varName.isAttribute = false; return getVariableByMultiname(varName,SKIP_IMPL); @@ -1397,6 +1397,8 @@ void ASObject::setClass(Class_base* c) { + if (classdef == c) + return; if(classdef) { classdef->abandonObject(this); @@ -1410,23 +1412,47 @@ } } -void ASObject::finalize() +void ASObject::destroy() { - Variables.destroyContents(); if(classdef) { classdef->abandonObject(this); classdef->decRef(); classdef=NULL; } - if (proxyMultiName) - delete proxyMultiName; - proxyMultiName = NULL; +} + +void ASObject::finalize() +{ } ASObject::~ASObject() { + destroy(); +} +void ASObject::destruct() +{ finalize(); + Variables.destroyContents(); + if (proxyMultiName) + delete proxyMultiName; + proxyMultiName = NULL; + traitsInitialized =false; + constructIndicator = false; + constructorCallComplete =false; + implEnable = true; +#ifndef NDEBUG + //Stuff only used in debugging + initialized=false; +#endif + if (classdef && classdef->isReusable) + { + classdef->pushObjectToFreeList(this); + } + else + { + RefCountable::destruct(); + } } void variables_map::initSlot(unsigned int n, uint32_t nameId, const nsNameAndKind& ns) @@ -1625,7 +1651,7 @@ multiname writeExternalName(NULL); writeExternalName.name_type=multiname::NAME_STRING; writeExternalName.name_s_id=getSys()->getUniqueStringId("writeExternal"); - writeExternalName.ns.push_back(nsNameAndKind("",NAMESPACE)); + writeExternalName.ns.emplace_back("",NAMESPACE); writeExternalName.isAttribute = false; _NR<ASObject> o=getVariableByMultiname(writeExternalName,SKIP_IMPL); @@ -1759,6 +1785,7 @@ prot->describeInstance(root);
View file
lightspark.tar.xz/src/asobject.h
Changed
@@ -321,6 +321,10 @@ void setClass(Class_base* c); static variable* findSettableImpl(variables_map& map, const multiname& name, bool* has_getter); static const variable* findGettableImpl(const variables_map& map, const multiname& name, NS_KIND &nskind); + //overridden from RefCountable + void destruct(); + // called when object is really destroyed + virtual void destroy(); public: ASObject(Class_base* c); #ifndef NDEBUG @@ -356,12 +360,13 @@ o->decRef(); } /* - The finalize function should be implemented in all derived class that stores pointers. - It should decRef all referenced objects. It's guaranteed that the only operations + The finalize function is called when the reference count reaches 0 and the objects is added to the free list of the class. + It should be implemented in all derived class. + It should decRef all referenced objects. + It has to reset all data to their default state. that will happen on the object after finalization are decRef and delete. - Each class must call BaseClass::finalize in their finalize function. The finalize method must be callable multiple time with the same effects (no double frees). - Each class must also call his own ::finalize in the destructor!*/ + */ virtual void finalize(); enum GET_VARIABLE_OPTION {NONE=0x00, SKIP_IMPL=0x01, XML_STRICT=0x02}; @@ -374,7 +379,7 @@ * Helper method using the get the raw variable struct instead of calling the getter. * It is used by getVariableByMultiname and by early binding code */ - const variable* findVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt, Class_base* cls, NS_KIND &nskind); + const variable* findVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt, Class_base* cls, NS_KIND &nskind) const; /* * Gets a variable of this object. It looks through all classes (beginning at cls), * then the prototype chain, and then instance variables.
View file
lightspark.tar.xz/src/scripting/abc.cpp
Changed
@@ -612,7 +612,7 @@ ret->ns.reserve(s->count); for(unsigned int i=0;i<s->count;i++) { - ret->ns.push_back(nsNameAndKind(th->context, s->ns[i])); + ret->ns.emplace_back(th->context, s->ns[i]); } sort(ret->ns.begin(),ret->ns.end()); ret->name_d=rtd; @@ -664,7 +664,7 @@ ret->ns.reserve(s->count); for(unsigned int i=0;i<s->count;i++) { - ret->ns.push_back(nsNameAndKind(th->context, s->ns[i])); + ret->ns.emplace_back(th->context, s->ns[i]); } sort(ret->ns.begin(),ret->ns.end()); ret->name_i=rti; @@ -751,7 +751,7 @@ { ret->name_s_id=getSys()->getUniqueStringId("any"); ret->name_type=multiname::NAME_STRING; - ret->ns.emplace_back(nsNameAndKind("",NAMESPACE)); + ret->ns.emplace_back("",NAMESPACE); ret->isAttribute=false; return ret; } @@ -761,7 +761,7 @@ case 0x07: //QName case 0x0D: //QNameA { - ret->ns.push_back(nsNameAndKind(this, m->ns)); + ret->ns.emplace_back(this, m->ns); if (m->name) { ret->name_s_id=getSys()->getUniqueStringId(getString(m->name)); @@ -776,7 +776,7 @@ ret->ns.reserve(s->count); for(unsigned int i=0;i<s->count;i++) { - ret->ns.push_back(nsNameAndKind(this, s->ns[i])); + ret->ns.emplace_back(this, s->ns[i]); } sort(ret->ns.begin(),ret->ns.end()); @@ -794,7 +794,7 @@ ret->ns.reserve(s->count); for(unsigned int i=0;i<s->count;i++) { - ret->ns.push_back(nsNameAndKind(this, s->ns[i])); + ret->ns.emplace_back(this, s->ns[i]); } sort(ret->ns.begin(),ret->ns.end()); break; @@ -834,7 +834,7 @@ } name += getString(p->name); } - ret->ns.push_back(nsNameAndKind(this, td->ns)); + ret->ns.emplace_back(this, td->ns); ret->name_s_id=getSys()->getUniqueStringId(name); ret->name_type=multiname::NAME_STRING; break; @@ -877,7 +877,7 @@ ret=m->dynamic; ret->isAttribute=m->cached->isAttribute; ret->ns.clear(); - ret->ns.push_back(nsNameAndKind(qname->getURI(),NAMESPACE)); + ret->ns.emplace_back(qname->getURI(),NAMESPACE); } else n->applyProxyProperty(*ret); @@ -892,7 +892,7 @@ assert_and_throw(n->classdef==Class<Namespace>::getClass()); Namespace* tmpns=static_cast<Namespace*>(n); ret->ns.clear(); - ret->ns.push_back(nsNameAndKind(tmpns->uri,tmpns->nskind)); + ret->ns.emplace_back(tmpns->uri,tmpns->nskind); n->decRef(); break; } @@ -903,7 +903,7 @@ assert_and_throw(n2->classdef==Class<Namespace>::getClass()); Namespace* tmpns=static_cast<Namespace*>(n2); ret->ns.clear(); - ret->ns.push_back(nsNameAndKind(tmpns->uri,tmpns->nskind)); + ret->ns.emplace_back(tmpns->uri,tmpns->nskind); ret->setName(n); n->decRef(); n2->decRef(); @@ -1814,7 +1814,7 @@ //invoked on the client object multiname headerName(NULL); headerName.name_type=multiname::NAME_STRING; - headerName.ns.push_back(nsNameAndKind("",NAMESPACE)); + headerName.ns.emplace_back("",NAMESPACE); tiny_string headerNameString; if(!message->readUTF(headerNameString)) return; @@ -1881,7 +1881,7 @@ multiname onResultName(NULL); onResultName.name_type=multiname::NAME_STRING; onResultName.name_s_id=getSys()->getUniqueStringId("onResult"); - onResultName.ns.push_back(nsNameAndKind("",NAMESPACE)); + onResultName.ns.emplace_back("",NAMESPACE); _NR<ASObject> callback = responder->getVariableByMultiname(onResultName); if(!callback.isNull() && callback->getObjectType() == T_FUNCTION) { @@ -1910,7 +1910,7 @@ tiny_string ABCVm::getDefaultXMLNamespace() { - return currentCallContext->defaultNamespaceUri; + return currentCallContext->defaultNamespaceUri == NULL ? tiny_string() : currentCallContext->defaultNamespaceUri->data; } const tiny_string& ABCContext::getString(unsigned int s) const @@ -2036,7 +2036,7 @@ case 0x00: //Undefined return getSys()->getUndefinedRef(); case 0x01: //String - return Class<ASString>::getInstanceS(constant_pool.strings[index]); + return abstract_s(constant_pool.strings[index]); case 0x03: //Int return abstract_i(constant_pool.integer[index]); case 0x06: //Double
View file
lightspark.tar.xz/src/scripting/abc_fast_interpreter.cpp
Changed
@@ -1036,28 +1036,40 @@ { //convert_i ASObject* val=context->runtime_stack_pop(); - context->runtime_stack_push(abstract_i(convert_i(val))); + if (val->is<Integer>()) + context->runtime_stack_push(val); + else + context->runtime_stack_push(abstract_i(convert_i(val))); break; } case 0x74: { //convert_u ASObject* val=context->runtime_stack_pop(); - context->runtime_stack_push(abstract_ui(convert_u(val))); + if (val->is<UInteger>()) + context->runtime_stack_push(val); + else + context->runtime_stack_push(abstract_ui(convert_u(val))); break; } case 0x75: { //convert_d ASObject* val=context->runtime_stack_pop(); - context->runtime_stack_push(abstract_d(convert_d(val))); + if (val->is<Number>()) + context->runtime_stack_push(val); + else + context->runtime_stack_push(abstract_d(convert_d(val))); break; } case 0x76: { //convert_b ASObject* val=context->runtime_stack_pop(); - context->runtime_stack_push(abstract_b(convert_b(val))); + if (val->is<Boolean>()) + context->runtime_stack_push(val); + else + context->runtime_stack_push(abstract_b(convert_b(val))); break; } case 0x77: @@ -1114,7 +1126,11 @@ case 0x85: { //coerce_s - context->runtime_stack_push(coerce_s(context->runtime_stack_pop())); + ASObject* val=context->runtime_stack_pop(); + if (val->is<ASString>()) + context->runtime_stack_push(val); + else + context->runtime_stack_push(coerce_s(val)); break; } case 0x86:
View file
lightspark.tar.xz/src/scripting/abc_interpreter.cpp
Changed
@@ -40,11 +40,11 @@ { method_info* mi=function->mi; - memorystream code(mi->body->code.data(), mi->body->code.size()); + const int code_len=mi->body->code.size(); + memorystream code(mi->body->code.data(), code_len); //This may be non-zero and point to the position of an exception handler code.seekg(context->exec_pos); - const int code_len=mi->body->code.size(); u8 opcode; @@ -1143,28 +1143,40 @@ { //convert_i ASObject* val=context->runtime_stack_pop(); - context->runtime_stack_push(abstract_i(convert_i(val))); + if (val->is<Integer>()) + context->runtime_stack_push(val); + else + context->runtime_stack_push(abstract_i(convert_i(val))); break; } case 0x74: { //convert_u ASObject* val=context->runtime_stack_pop(); - context->runtime_stack_push(abstract_ui(convert_u(val))); + if (val->is<UInteger>()) + context->runtime_stack_push(val); + else + context->runtime_stack_push(abstract_ui(convert_u(val))); break; } case 0x75: { //convert_d ASObject* val=context->runtime_stack_pop(); - context->runtime_stack_push(abstract_d(convert_d(val))); + if (val->is<Number>()) + context->runtime_stack_push(val); + else + context->runtime_stack_push(abstract_d(convert_d(val))); break; } case 0x76: { //convert_b ASObject* val=context->runtime_stack_pop(); - context->runtime_stack_push(abstract_b(convert_b(val))); + if (val->is<Boolean>()) + context->runtime_stack_push(val); + else + context->runtime_stack_push(abstract_b(convert_b(val))); break; } case 0x77: @@ -1209,7 +1221,11 @@ case 0x85: { //coerce_s - context->runtime_stack_push(coerce_s(context->runtime_stack_pop())); + ASObject* val=context->runtime_stack_pop(); + if (val->is<ASString>()) + context->runtime_stack_push(val); + else + context->runtime_stack_push(coerce_s(val)); break; } case 0x86:
View file
lightspark.tar.xz/src/scripting/abc_opcodes.cpp
Changed
@@ -125,7 +125,7 @@ ASObject* ret=o; if(o->getObjectType()!=T_STRING) { - ret=Class<ASString>::getInstanceS(o->toString()); + ret=abstract_s(o->toString()); o->decRef(); } return ret; @@ -334,7 +334,7 @@ tmpcls = tmpcls->super; } } - if(!o.isNull() && !(obj->classdef && obj->classdef->isSubClass(Class<Proxy>::getClass()))) + if(!o.isNull() && !(obj->classdef && obj->classdef->isProxy)) { o->incRef(); callImpl(th, o.getPtr(), obj, args, m, called_mi, keepReturn); @@ -342,13 +342,13 @@ else { //If the object is a Proxy subclass, try to invoke callProperty - if(obj->classdef && obj->classdef->isSubClass(Class<Proxy>::getClass())) + if(obj->classdef && obj->classdef->isProxy) { //Check if there is a custom caller defined, skipping implementation to avoid recursive calls multiname callPropertyName(NULL); callPropertyName.name_type=multiname::NAME_STRING; callPropertyName.name_s_id=getSys()->getUniqueStringId("callProperty"); - callPropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE)); + callPropertyName.ns.emplace_back(flash_proxy,NAMESPACE); _NR<ASObject> oproxy=obj->getVariableByMultiname(callPropertyName,ASObject::SKIP_IMPL); if(!oproxy.isNull()) @@ -364,7 +364,7 @@ IFunction* f=static_cast<IFunction*>(oproxy.getPtr()); //Create a new array ASObject** proxyArgs=g_newa(ASObject*, m+1); - ASObject* namearg = Class<ASString>::getInstanceS(name->normalizedName()); + ASObject* namearg = abstract_s(name->normalizedName()); namearg->setProxyProperty(*name); proxyArgs[0]=namearg; for(int i=0;i<m;i++) @@ -868,7 +868,7 @@ assert_and_throw(false); } obj->decRef(); - return Class<ASString>::getInstanceS(ret); + return abstract_s(ret); } void ABCVm::jump(int offset) @@ -1001,7 +1001,7 @@ LOG(LOG_CALLS,"add " << a << '+' << b); val1->decRef(); val2->decRef(); - return Class<ASString>::getInstanceS(a + b); + return abstract_s(a + b); } else if( (val1->is<XML>() || val1->is<XMLList>()) && (val2->is<XML>() || val2->is<XMLList>()) ) { @@ -1034,7 +1034,7 @@ string a(val1p->toString().raw_buf()); string b(val2p->toString().raw_buf()); LOG(LOG_CALLS,"add " << a << '+' << b); - return Class<ASString>::getInstanceS(a+b); + return abstract_s(a+b); } else {//Convert both to numbers and add @@ -1093,7 +1093,7 @@ const tiny_string& b=val2->toString(); val2->decRef(); LOG(LOG_CALLS,_("add ") << a << '+' << b); - return Class<ASString>::getInstanceS(a+b); + return abstract_s(a+b); } else { @@ -1127,7 +1127,7 @@ const tiny_string& b=val2->toString(); val2->decRef(); LOG(LOG_CALLS,_("add ") << a << '+' << b); - return Class<ASString>::getInstanceS(a+b); + return abstract_s(a+b); } else { @@ -1874,7 +1874,7 @@ name.name_type=multiname::NAME_OBJECT; //Acquire the reference name.name_o=val1; - name.ns.push_back(nsNameAndKind("",NAMESPACE)); + name.ns.emplace_back("",NAMESPACE); bool ret=val2->hasPropertyByMultiname(name, true, true); name.name_o=NULL; val1->decRef(); @@ -1982,7 +1982,7 @@ //Duplicated keys overwrite the previous value multiname propertyName(NULL); propertyName.name_type=multiname::NAME_STRING; - propertyName.ns.push_back(nsNameAndKind("",NAMESPACE)); + propertyName.ns.emplace_back("",NAMESPACE); for(int i=0;i<n;i++) { ASObject* value=th->runtime_stack_pop(); @@ -2028,12 +2028,12 @@ targetobject = xmlObj; xmlObj->getDescendantsByQName(name->normalizedName(), ns_uri,name->isAttribute, ret); } - else if(obj->getClass()->isSubClass(Class<Proxy>::getClass())) + else if(obj->getClass()->isProxy) { multiname callPropertyName(NULL); callPropertyName.name_type=multiname::NAME_STRING; callPropertyName.name_s_id=getSys()->getUniqueStringId("getDescendants"); - callPropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE)); + callPropertyName.ns.emplace_back(flash_proxy,NAMESPACE); _NR<ASObject> o=obj->getVariableByMultiname(callPropertyName,ASObject::SKIP_IMPL); if(!o.isNull()) @@ -2043,7 +2043,7 @@ IFunction* f=static_cast<IFunction*>(o.getPtr()); //Create a new array ASObject** proxyArgs=g_newa(ASObject*, 1); - ASObject* namearg = Class<ASString>::getInstanceS(name->normalizedName()); + ASObject* namearg = abstract_s(name->normalizedName()); namearg->setProxyProperty(*name); proxyArgs[0]=namearg; @@ -2518,9 +2518,9 @@ ASObject* ABCVm::pushString(call_context* th, int n) { - tiny_string s=th->context->getString(n); + const tiny_string s=th->context->getString(n); LOG(LOG_CALLS, _("pushString ") << s ); - return Class<ASString>::getInstanceS(s); + return abstract_s(s); } ASObject* ABCVm::newCatch(call_context* th, int n) @@ -2554,7 +2554,7 @@ else t = XML::encodeToXML(o->toString(),true); o->decRef(); - return Class<ASString>::getInstanceS(t); + return abstract_s(t); } ASObject* ABCVm::esc_xelem(ASObject* o) @@ -2567,7 +2567,7 @@ else t = XML::encodeToXML(o->toString(),false); o->decRef(); - return Class<ASString>::getInstanceS(t); + return abstract_s(t); } /* This should walk prototype chain of value, trying to find type. See ECMA. @@ -2621,7 +2621,9 @@ if(!th->mi->hasDXNS()) throw Class<VerifyError>::getInstanceS("dxns without SET_DXNS"); - th->defaultNamespaceUri = th->context->getString(n); + if (!th->defaultNamespaceUri.isNull()) + th->defaultNamespaceUri->decRef(); + th->defaultNamespaceUri = _NR<ASString>(abstract_s(th->context->getString(n))); } /* @spec-checked avm2overview */ @@ -2630,6 +2632,8 @@ if(!th->mi->hasDXNS()) throw Class<VerifyError>::getInstanceS("dxnslate without SET_DXNS"); - th->defaultNamespaceUri = o->toString(); + if (!th->defaultNamespaceUri.isNull()) + th->defaultNamespaceUri->decRef(); + th->defaultNamespaceUri = _NR<ASString>(abstract_s(o->toString())); o->decRef(); }
View file
lightspark.tar.xz/src/scripting/abcutils.h
Changed
@@ -63,7 +63,7 @@ /* Current namespace set by 'default xml namespace = ...'. * Defaults to empty string according to ECMA-357 13.1.1.1 */ - tiny_string defaultNamespaceUri; + _NR<ASString> defaultNamespaceUri; int initialScopeStack; ~call_context(); void runtime_stack_clear();
View file
lightspark.tar.xz/src/scripting/class.cpp
Changed
@@ -165,7 +165,7 @@ case T_UINTEGER: return abstract_ui(args[0]->toUInt()); case T_STRING: - return Class<ASString>::getInstanceS(args[0]->toString()); + return abstract_s(args[0]->toString()); case T_FUNCTION: case T_OBJECT: args[0]->incRef();
View file
lightspark.tar.xz/src/scripting/class.h
Changed
@@ -121,12 +121,15 @@ { if(realClass==NULL) realClass=this; - T* ret=new (realClass->memoryAccount) T(realClass); + T* ret = realClass->getObjectFromFreeList()->as<T>(); + if (!ret) + ret=new (realClass->memoryAccount) T(realClass); if(construct) handleConstruction(ret,args,argslen,true); return ret; } public: + /* template<typename... Args> static T* getInstanceS(Args&&... args) { @@ -135,6 +138,31 @@ c->handleConstruction(ret,NULL,0,true); return ret; } + */ + template<typename... Args> + static T* getInstanceS(Args&&... args) + { + Class<T>* c=Class<T>::getClass(); + T* ret=newWithOptionalClass<T, sizeof...(Args)>::doNew(c, std::forward<Args>(args)...); + c->setupDeclaredTraits(ret); + ret->constructionComplete(); + ret->setConstructIndicator(); + return ret; + } + // constructor without arguments + static T* getInstanceSNoArgs() + { + Class<T>* c=Class<T>::getClass(); + T* ret = c->getObjectFromFreeList()->as<T>(); + if (!ret) + { + ret=new (c->memoryAccount) T(c); + } + c->setupDeclaredTraits(ret); + ret->constructionComplete(); + ret->setConstructIndicator(); + return ret; + } static Class<T>* getClass() { uint32_t classId=ClassName<T>::id; @@ -235,8 +263,16 @@ static ASObject* getInstanceS() { Class<ASObject>* c=Class<ASObject>::getClass(); - return c->getInstance(true,NULL,0); + ASObject* ret = c->getObjectFromFreeList(); + if (!ret) + ret=new (c->memoryAccount) ASObject(c); + c->setupDeclaredTraits(ret); + ret->constructionComplete(); + ret->setConstructIndicator(); + return ret; + //return c->getInstance(true,NULL,0); } + static Class<ASObject>* getClass(); static _R<Class<ASObject>> getRef() {
View file
lightspark.tar.xz/src/scripting/flash/utils/Proxy.cpp
Changed
@@ -38,6 +38,7 @@ void Proxy::sinit(Class_base* c) { CLASS_SETUP_NO_CONSTRUCTOR(c, ASObject,CLASS_DYNAMIC_NOT_FINAL); + c->isProxy = true; c->setDeclaredMethodByQName("isAttribute","",Class<IFunction>::getFunction(_isAttribute),NORMAL_METHOD,true); } @@ -66,7 +67,7 @@ multiname setPropertyName(NULL); setPropertyName.name_type=multiname::NAME_STRING; setPropertyName.name_s_id=getSys()->getUniqueStringId("setProperty"); - setPropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE)); + setPropertyName.ns.emplace_back(flash_proxy,NAMESPACE); _NR<ASObject> proxySetter=getVariableByMultiname(setPropertyName,ASObject::SKIP_IMPL); if(proxySetter.isNull()) @@ -79,7 +80,7 @@ IFunction* f=static_cast<IFunction*>(proxySetter.getPtr()); - ASObject* namearg = Class<ASString>::getInstanceS(name.normalizedName()); + ASObject* namearg = abstract_s(name.normalizedName()); namearg->setProxyProperty(name); ASObject* args[2]; args[0]=namearg; @@ -108,7 +109,7 @@ multiname getPropertyName(NULL); getPropertyName.name_type=multiname::NAME_STRING; getPropertyName.name_s_id=getSys()->getUniqueStringId("getProperty"); - getPropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE)); + getPropertyName.ns.emplace_back(flash_proxy,NAMESPACE); o=getVariableByMultiname(getPropertyName,ASObject::SKIP_IMPL); if(o.isNull()) @@ -118,7 +119,7 @@ IFunction* f=static_cast<IFunction*>(o.getPtr()); - ASObject* namearg = Class<ASString>::getInstanceS(name.normalizedName()); + ASObject* namearg = abstract_s(name.normalizedName()); namearg->setProxyProperty(name); ASObject* arg = namearg; //We now suppress special handling @@ -144,7 +145,7 @@ multiname hasPropertyName(NULL); hasPropertyName.name_type=multiname::NAME_STRING; hasPropertyName.name_s_id=getSys()->getUniqueStringId("hasProperty"); - hasPropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE)); + hasPropertyName.ns.emplace_back(flash_proxy,NAMESPACE); _NR<ASObject> proxyHasProperty=getVariableByMultiname(hasPropertyName,ASObject::SKIP_IMPL); if(proxyHasProperty.isNull()) @@ -156,7 +157,7 @@ IFunction* f=static_cast<IFunction*>(proxyHasProperty.getPtr()); - ASObject* namearg = Class<ASString>::getInstanceS(name.normalizedName()); + ASObject* namearg = abstract_s(name.normalizedName()); namearg->setProxyProperty(name); ASObject* arg = namearg; //We now suppress special handling @@ -180,7 +181,7 @@ multiname deletePropertyName(NULL); deletePropertyName.name_type=multiname::NAME_STRING; deletePropertyName.name_s_id=getSys()->getUniqueStringId("deleteProperty"); - deletePropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE)); + deletePropertyName.ns.emplace_back(flash_proxy,NAMESPACE); _NR<ASObject> proxyDeleter=getVariableByMultiname(deletePropertyName,ASObject::SKIP_IMPL); if(proxyDeleter.isNull()) @@ -192,7 +193,7 @@ IFunction* f=static_cast<IFunction*>(proxyDeleter.getPtr()); - ASObject* namearg = Class<ASString>::getInstanceS(name.normalizedName()); + ASObject* namearg = abstract_s(name.normalizedName()); namearg->setProxyProperty(name); ASObject* arg = namearg; //We now suppress special handling @@ -213,7 +214,7 @@ multiname nextNameIndexName(NULL); nextNameIndexName.name_type=multiname::NAME_STRING; nextNameIndexName.name_s_id=getSys()->getUniqueStringId("nextNameIndex"); - nextNameIndexName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE)); + nextNameIndexName.ns.emplace_back(flash_proxy,NAMESPACE); _NR<ASObject> o=getVariableByMultiname(nextNameIndexName,ASObject::SKIP_IMPL); assert_and_throw(!o.isNull() && o->getObjectType()==T_FUNCTION); IFunction* f=static_cast<IFunction*>(o.getPtr()); @@ -233,7 +234,7 @@ multiname nextNameName(NULL); nextNameName.name_type=multiname::NAME_STRING; nextNameName.name_s_id=getSys()->getUniqueStringId("nextName"); - nextNameName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE)); + nextNameName.ns.emplace_back(flash_proxy,NAMESPACE); _NR<ASObject> o=getVariableByMultiname(nextNameName,ASObject::SKIP_IMPL); assert_and_throw(!o.isNull() && o->getObjectType()==T_FUNCTION); IFunction* f=static_cast<IFunction*>(o.getPtr()); @@ -250,7 +251,7 @@ multiname nextValueName(NULL); nextValueName.name_type=multiname::NAME_STRING; nextValueName.name_s_id=getSys()->getUniqueStringId("nextValue"); - nextValueName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE)); + nextValueName.ns.emplace_back(flash_proxy,NAMESPACE); _NR<ASObject> o=getVariableByMultiname(nextValueName,ASObject::SKIP_IMPL); assert_and_throw(!o.isNull() && o->getObjectType()==T_FUNCTION); IFunction* f=static_cast<IFunction*>(o.getPtr());
View file
lightspark.tar.xz/src/scripting/toplevel/ASString.cpp
Changed
@@ -70,12 +70,16 @@ ASFUNCTIONBODY(ASString,_getLength) { + // fast path if obj is ASString + if (obj->is<ASString>()) + return abstract_i(obj->as<ASString>()->data.numChars()); return abstract_i(obj->toString().numChars()); } void ASString::sinit(Class_base* c) { CLASS_SETUP(c, ASObject, _constructor, CLASS_FINAL | CLASS_SEALED); + c->isReusable = true; c->setDeclaredMethodByQName("split",AS3,Class<IFunction>::getFunction(split,2),NORMAL_METHOD,true); c->setDeclaredMethodByQName("substr",AS3,Class<IFunction>::getFunction(substr,2),NORMAL_METHOD,true); c->setDeclaredMethodByQName("substring",AS3,Class<IFunction>::getFunction(substring,2),NORMAL_METHOD,true); @@ -250,7 +254,7 @@ ASFUNCTIONBODY(ASString,_toString) { if(Class<ASString>::getClass()->prototype->getObj() == obj) - return Class<ASString>::getInstanceS(""); + return abstract_s(); if(!obj->is<ASString>()) { LOG(LOG_ERROR,"String.toString is not generic:"<<obj->toDebugString()); @@ -270,7 +274,7 @@ uint32_t limit = 0x7fffffff; if(argslen == 0 ) { - ret->push(_MR(Class<ASString>::getInstanceS(data))); + ret->push(_MR(abstract_s(data))); return ret; } if (argslen > 1 && !args[1]->is<Undefined>()) @@ -288,7 +292,7 @@ { if (ret->size() >= limit) break; - ret->push(_MR(Class<ASString>::getInstanceS( tiny_string::fromChar(*i) ) )); + ret->push(_MR(abstract_s( tiny_string::fromChar(*i) ) )); } return ret; } @@ -323,7 +327,7 @@ continue; } //Extract string from last match until the beginning of the current match - ASString* s=Class<ASString>::getInstanceS(data.substr_bytes(lastMatch,end-lastMatch)); + ASString* s=abstract_s(data.substr_bytes(lastMatch,end-lastMatch)); if (ret->size() >= limit) break; ret->push(_MR(s)); @@ -335,14 +339,14 @@ if (ret->size() >= limit) break; //use string interface through raw(), because we index on bytes, not on UTF-8 characters - ASString* s=Class<ASString>::getInstanceS(data.substr_bytes(ovector[i*2],ovector[i*2+1]-ovector[i*2])); + ASString* s=abstract_s(data.substr_bytes(ovector[i*2],ovector[i*2+1]-ovector[i*2])); ret->push(_MR(s)); } } while(end<data.numBytes() && ret->size() < limit); if(ret->size() < limit && lastMatch != data.numBytes()+1) { - ASString* s=Class<ASString>::getInstanceS(data.substr_bytes(lastMatch,data.numBytes()-lastMatch)); + ASString* s=abstract_s(data.substr_bytes(lastMatch,data.numBytes()-lastMatch)); ret->push(_MR(s)); } pcre_free(pcreRE); @@ -356,7 +360,7 @@ if (data.numChars() == 0) { - ret->push(_MR(Class<ASString>::getInstanceS(""))); + ret->push(_MR(abstract_s())); } uint32_t j = 0; for(auto i=data.begin();i!=data.end();++i) @@ -364,7 +368,7 @@ if (j >= limit) break; j++; - ret->push(_MR(Class<ASString>::getInstanceS( tiny_string::fromChar(*i) ) )); + ret->push(_MR(abstract_s( tiny_string::fromChar(*i) ) )); } return ret; } @@ -377,13 +381,13 @@ match++; if(match==-1) match= len; - ASString* s=Class<ASString>::getInstanceS(data.substr(start,(match-start))); + ASString* s=abstract_s(data.substr(start,(match-start))); if (ret->size() >= limit) break; ret->push(_MR(s)); start=match+del.numChars(); if (start == len) - ret->push(_MR(Class<ASString>::getInstanceS(""))); + ret->push(_MR(abstract_s())); } while(start<len && ret->size() < limit); } @@ -400,7 +404,7 @@ if (!std::isnan(args[0]->toNumber())) start=args[0]->toInt(); if (start >= 0 && std::isinf(args[0]->toNumber())) - return Class<ASString>::getInstanceS(""); + return abstract_s(); } if(start<0) { start=data.numChars()+start; @@ -421,7 +425,7 @@ else len=args[1]->toInt(); } - return Class<ASString>::getInstanceS(data.substr(start,len)); + return abstract_s(data.substr(start,len)); } ASFUNCTIONBODY(ASString,substring) @@ -446,7 +450,7 @@ end=tmp; } - return Class<ASString>::getInstanceS(data.substr(start,end-start)); + return abstract_s(data.substr(start,end-start)); } tiny_string ASString::toString_priv() const @@ -621,30 +625,46 @@ } if(endIndex>(int)data.numChars()) endIndex=data.numChars(); - if(endIndex<=startIndex) - return Class<ASString>::getInstanceS(""); + return abstract_s(); else - return Class<ASString>::getInstanceS(data.substr(startIndex,endIndex-startIndex)); + return abstract_s(data.substr(startIndex,endIndex-startIndex)); } ASFUNCTIONBODY(ASString,charAt) { - tiny_string data = obj->toString(); number_t index; ARG_UNPACK (index, 0); + // fast path if obj is ASString + if (obj->is<ASString>()) + { + int maxIndex=obj->as<ASString>()->data.numChars(); + + if(index<0 || index>=maxIndex || std::isinf(index)) + return abstract_s(); + return abstract_s( tiny_string::fromChar(obj->as<ASString>()->data.charAt(index)) ); + } + tiny_string data = obj->toString(); int maxIndex=data.numChars(); if(index<0 || index>=maxIndex || std::isinf(index)) - return Class<ASString>::getInstanceS(""); - return Class<ASString>::getInstanceS( tiny_string::fromChar(data.charAt(index)) ); + return abstract_s(); + return abstract_s( tiny_string::fromChar(data.charAt(index)) ); } ASFUNCTIONBODY(ASString,charCodeAt) { - tiny_string data = obj->toString(); number_t index; ARG_UNPACK (index, 0); + + // fast path if obj is ASString + if (obj->is<ASString>()) + { + if(index<0 || index>=obj->as<ASString>()->data.numChars() || std::isinf(index) || std::isnan(index)) + return abstract_d(Number::NaN); + return abstract_i(obj->as<ASString>()->data.charAt(index)); + } + tiny_string data = obj->toString(); if(index<0 || index>=data.numChars() || std::isinf(index) || std::isnan(index)) return abstract_d(Number::NaN); else @@ -698,13 +718,13 @@ ASFUNCTIONBODY(ASString,toLowerCase) { tiny_string data = obj->toString(); - return Class<ASString>::getInstanceS(data.lowercase()); + return abstract_s(data.lowercase()); } ASFUNCTIONBODY(ASString,toUpperCase) { tiny_string data = obj->toString(); - return Class<ASString>::getInstanceS(data.uppercase()); + return abstract_s(data.uppercase()); } ASFUNCTIONBODY(ASString,localeCompare)
View file
lightspark.tar.xz/src/scripting/toplevel/ASString.h
Changed
@@ -32,6 +32,9 @@ */ class ASString: public ASObject { + friend ASString* abstract_s(); + friend ASString* abstract_s(const char* s, uint32_t len); + friend ASString* abstract_s(const tiny_string& s); private: tiny_string toString_priv() const; number_t parseStringInfinite(const char *s, char **end) const; @@ -78,11 +81,15 @@ std::string toDebugString() { return std::string("\"") + std::string(data) + "\""; } static bool isEcmaSpace(uint32_t c); static bool isEcmaLineTerminator(uint32_t c); + void finalize() { data.clear(); } }; template<> inline ASObject* Class<ASString>::coerce(ASObject* o) const -{ //Special handling for Null and Undefined follows avm2overview's description of 'coerce_s' opcode +{ + if (o->is<ASString>()) + return o; + //Special handling for Null and Undefined follows avm2overview's description of 'coerce_s' opcode if(o->is<Null>()) return o; if(o->is<Undefined>()) @@ -94,7 +101,7 @@ return o; tiny_string n = o->toString(); o->decRef(); - return Class<ASString>::getInstanceS(n); + return lightspark::abstract_s(n); } }
View file
lightspark.tar.xz/src/scripting/toplevel/Boolean.cpp
Changed
@@ -80,6 +80,7 @@ void Boolean::sinit(Class_base* c) { CLASS_SETUP(c, ASObject, _constructor, CLASS_SEALED | CLASS_FINAL); + c->isReusable = true; c->setDeclaredMethodByQName("toString",AS3,Class<IFunction>::getFunction(_toString),NORMAL_METHOD,true); c->prototype->setVariableByQName("toString","",Class<IFunction>::getFunction(_toString),DYNAMIC_TRAIT); c->prototype->setVariableByQName("valueOf","",Class<IFunction>::getFunction(_valueOf),DYNAMIC_TRAIT); @@ -100,13 +101,13 @@ ASFUNCTIONBODY(Boolean,_toString) { if(Class<Boolean>::getClass()->prototype->getObj() == obj) //See ECMA 15.6.4 - return Class<ASString>::getInstanceS("false"); + return abstract_s("false"); if(!obj->is<Boolean>()) throw Class<TypeError>::getInstanceS(""); Boolean* th=static_cast<Boolean*>(obj); - return Class<ASString>::getInstanceS(th->toString()); + return abstract_s(th->toString()); } ASFUNCTIONBODY(Boolean,_valueOf)
View file
lightspark.tar.xz/src/scripting/toplevel/Boolean.h
Changed
@@ -39,6 +39,7 @@ static void sinit(Class_base*); static void buildTraits(ASObject* o){}; bool val; + void finalize() { val=false;} int32_t toInt() { return val ? 1 : 0;
View file
lightspark.tar.xz/src/scripting/toplevel/Date.cpp
Changed
@@ -33,16 +33,24 @@ Date::~Date() { - if(datetime) - g_date_time_unref(datetime); - if(datetimeUTC) +} + +void Date::finalize() +{ + if (datetimeUTC) g_date_time_unref(datetimeUTC); + if (datetime) + g_date_time_unref(datetime); + datetime = NULL; + datetimeUTC = NULL; + extrayears = 0; + nan = false; } void Date::sinit(Class_base* c) { CLASS_SETUP_CONSTRUCTOR_LENGTH(c, ASObject, _constructor, 7, CLASS_FINAL); - c->prototype->isSealed=true; + c->isReusable = true; c->setDeclaredMethodByQName("getTimezoneOffset",AS3,Class<IFunction>::getFunction(getTimezoneOffset),NORMAL_METHOD,true); c->setDeclaredMethodByQName("valueOf",AS3,Class<IFunction>::getFunction(valueOf),NORMAL_METHOD,true); c->setDeclaredMethodByQName("getTime",AS3,Class<IFunction>::getFunction(getTime),NORMAL_METHOD,true); @@ -278,7 +286,7 @@ th->MakeDateFromMilliseconds(g_date_time_to_unix(tmp)*1000 + g_date_time_get_microsecond (tmp)/1000); g_date_time_unref(tmp); - return Class<ASString>::getInstanceS(th->toString()); + return abstract_s(th->toString()); } ASFUNCTIONBODY(Date,UTC) @@ -783,8 +791,8 @@ multiname name(NULL); name.name_type=multiname::NAME_STRING; name.name_s_id=getSys()->getUniqueStringId("value"); - name.ns.push_back(nsNameAndKind("",NAMESPACE)); - name.ns.push_back(nsNameAndKind(AS3,NAMESPACE)); + name.ns.emplace_back("",NAMESPACE); + name.ns.emplace_back(AS3,NAMESPACE); name.isAttribute = true; obj->setVariableByMultiname(name,abstract_d(ms),CONST_NOT_ALLOWED); return abstract_d(ms); @@ -854,27 +862,27 @@ ASFUNCTIONBODY(Date,_toString) { if (!obj->is<Date>()) - return Class<ASString>::getInstanceS("Invalid Date"); + return abstract_s("Invalid Date"); Date* th=static_cast<Date*>(obj); - return Class<ASString>::getInstanceS(th->toString()); + return abstract_s(th->toString()); } ASFUNCTIONBODY(Date,toUTCString) { Date* th=static_cast<Date*>(obj); - return Class<ASString>::getInstanceS(th->toString_priv(true,"%a %b %e %H:%M:%S UTC")); + return abstract_s(th->toString_priv(true,"%a %b %e %H:%M:%S UTC")); } ASFUNCTIONBODY(Date,toDateString) { Date* th=static_cast<Date*>(obj); - return Class<ASString>::getInstanceS(th->toString_priv(false,"%a %b %e")); + return abstract_s(th->toString_priv(false,"%a %b %e")); } ASFUNCTIONBODY(Date,toTimeString) { Date* th=static_cast<Date*>(obj); - return Class<ASString>::getInstanceS(g_date_time_format(th->datetime, "%H:%M:%S GMT%z")); + return abstract_s(g_date_time_format(th->datetime, "%H:%M:%S GMT%z")); } @@ -882,7 +890,7 @@ { Date* th=static_cast<Date*>(obj); if (!th->datetime) - return Class<ASString>::getInstanceS(""); + return abstract_s(); tiny_string res = th->toString_priv(false,"%a %b %e"); gchar* fs = g_date_time_format(th->datetime, " %I:%M:%S"); res += fs; @@ -891,17 +899,17 @@ else res += " AM"; g_free(fs); - return Class<ASString>::getInstanceS(res); + return abstract_s(res); } ASFUNCTIONBODY(Date,toLocaleDateString) { Date* th=static_cast<Date*>(obj); - return Class<ASString>::getInstanceS(th->toString_priv(false,"%a %b %e")); + return abstract_s(th->toString_priv(false,"%a %b %e")); } ASFUNCTIONBODY(Date,toLocaleTimeString) { Date* th=static_cast<Date*>(obj); - return Class<ASString>::getInstanceS(g_date_time_format(th->datetime, "%H:%M:%S %Z%z")); + return abstract_s(g_date_time_format(th->datetime, "%H:%M:%S %Z%z")); } ASFUNCTIONBODY(Date,_parse)
View file
lightspark.tar.xz/src/scripting/toplevel/Date.h
Changed
@@ -41,6 +41,7 @@ static number_t parse(tiny_string str); public: Date(Class_base* c); + void finalize(); static void sinit(Class_base*); static void buildTraits(ASObject* o); ASFUNCTION(_constructor);
View file
lightspark.tar.xz/src/scripting/toplevel/Integer.cpp
Changed
@@ -29,7 +29,7 @@ ASFUNCTIONBODY(Integer,_toString) { if(Class<Integer>::getClass()->prototype->getObj() == obj) - return Class<ASString>::getInstanceS("0"); + return abstract_s("0"); Integer* th=static_cast<Integer*>(obj); int radix=10; @@ -40,12 +40,12 @@ { char buf[20]; snprintf(buf,20,"%i",th->val); - return Class<ASString>::getInstanceS(buf); + return abstract_s(buf); } else { tiny_string s=Number::toStringRadix((number_t)th->val, radix); - return Class<ASString>::getInstanceS(s); + return abstract_s(s); } } @@ -195,6 +195,7 @@ void Integer::sinit(Class_base* c) { CLASS_SETUP(c, ASObject, _constructor, CLASS_SEALED | CLASS_FINAL); + c->isReusable = true; c->setVariableByQName("MAX_VALUE","",abstract_i(numeric_limits<int32_t>::max()),CONSTANT_TRAIT); c->setVariableByQName("MIN_VALUE","",abstract_i(numeric_limits<int32_t>::min()),CONSTANT_TRAIT); c->setDeclaredMethodByQName("toString",AS3,Class<IFunction>::getFunction(_toString),NORMAL_METHOD,true); @@ -304,7 +305,7 @@ else fractionDigits = imin(imax((int32_t)ceil(::log10(::fabs(v))), 1), 20); } - return Class<ASString>::getInstanceS(Number::toExponentialString(v, fractionDigits)); + return abstract_s(Number::toExponentialString(v, fractionDigits)); } ASFUNCTIONBODY(Integer,_toFixed) @@ -312,15 +313,15 @@ Integer *th=obj->as<Integer>(); int fractiondigits; ARG_UNPACK (fractiondigits, 0); - return Class<ASString>::getInstanceS(Number::toFixedString(th->val, fractiondigits)); + return abstract_s(Number::toFixedString(th->val, fractiondigits)); } ASFUNCTIONBODY(Integer,_toPrecision) { Integer *th=obj->as<Integer>(); if (argslen == 0 || args[0]->is<Undefined>()) - return Class<ASString>::getInstanceS(th->toString()); + return abstract_s(th->toString()); int precision; ARG_UNPACK (precision); - return Class<ASString>::getInstanceS(Number::toPrecisionString(th->val, precision)); + return abstract_s(Number::toPrecisionString(th->val, precision)); }
View file
lightspark.tar.xz/src/scripting/toplevel/Integer.h
Changed
@@ -37,6 +37,7 @@ int32_t val; static void buildTraits(ASObject* o){}; static void sinit(Class_base* c); + void finalize() { val=0;} ASFUNCTION(_toString); tiny_string toString(); static tiny_string toString(int32_t val); @@ -66,6 +67,7 @@ * whitespace, zeroes). Returns 0 if conversion fails. */ static int32_t stringToASInteger(const char* cur, int radix); + }; }
View file
lightspark.tar.xz/src/scripting/toplevel/Number.cpp
Changed
@@ -74,46 +74,37 @@ { if(std::isnan(val)) return TUNDEFINED; - if(o->getObjectType()==T_INTEGER) - { - const Integer* i=static_cast<const Integer*>(o); - return (val<i->val)?TTRUE:TFALSE; - } - if(o->getObjectType()==T_UINTEGER) - { - const UInteger* i=static_cast<const UInteger*>(o); - return (val<i->val)?TTRUE:TFALSE; - } - else if(o->getObjectType()==T_NUMBER) - { - const Number* i=static_cast<const Number*>(o); - if(std::isnan(i->val)) return TUNDEFINED; - return (val<i->val)?TTRUE:TFALSE; - } - else if(o->getObjectType()==T_BOOLEAN) - { - return (val<o->toNumber())?TTRUE:TFALSE; - } - else if(o->getObjectType()==T_UNDEFINED) - { - //Undefined is NaN, so the result is undefined - return TUNDEFINED; - } - else if(o->getObjectType()==T_STRING) - { - double val2=o->toNumber(); - if(std::isnan(val2)) return TUNDEFINED; - return (val<val2)?TTRUE:TFALSE; - } - else if(o->getObjectType()==T_NULL) - { - return (val<0)?TTRUE:TFALSE; - } - else + switch(o->getObjectType()) { - double val2=o->toPrimitive()->toNumber(); - if(std::isnan(val2)) return TUNDEFINED; - return (val<val2)?TTRUE:TFALSE; + case T_INTEGER: + return (val<o->as<Integer>()->val)?TTRUE:TFALSE; + case T_UINTEGER: + return (val<o->as<UInteger>()->val)?TTRUE:TFALSE; + case T_NUMBER: + { + const Number* i=static_cast<const Number*>(o); + if(std::isnan(i->val)) return TUNDEFINED; + return (val<i->val)?TTRUE:TFALSE; + } + case T_BOOLEAN: + return (val<o->toNumber())?TTRUE:TFALSE; + case T_UNDEFINED: + //Undefined is NaN, so the result is undefined + return TUNDEFINED; + case T_STRING: + { + double val2=o->toNumber(); + if(std::isnan(val2)) return TUNDEFINED; + return (val<val2)?TTRUE:TFALSE; + } + case T_NULL: + return (val<0)?TTRUE:TFALSE; + default: + { + double val2=o->toPrimitive()->toNumber(); + if(std::isnan(val2)) return TUNDEFINED; + return (val<val2)?TTRUE:TFALSE; + } } } @@ -176,7 +167,7 @@ ASFUNCTIONBODY(Number,_toString) { if(Class<Number>::getClass()->prototype->getObj() == obj) - return Class<ASString>::getInstanceS("0"); + return abstract_s("0"); if(!obj->is<Number>()) throwError<TypeError>(kInvokeOnIncompatibleObjectError, "Number.toString"); Number* th=static_cast<Number*>(obj); @@ -186,11 +177,11 @@ if(radix==10 || std::isnan(th->val) || std::isinf(th->val)) { //see e 15.7.4.2 - return Class<ASString>::getInstanceS(th->toString()); + return abstract_s(th->toString()); } else { - return Class<ASString>::getInstanceS(Number::toStringRadix(th->val, radix)); + return abstract_s(Number::toStringRadix(th->val, radix)); } } @@ -261,6 +252,7 @@ void Number::sinit(Class_base* c) { CLASS_SETUP(c, ASObject, _constructor, CLASS_SEALED | CLASS_FINAL); + c->isReusable = true; c->setVariableByQName("NEGATIVE_INFINITY","",abstract_d(-numeric_limits<double>::infinity()),CONSTANT_TRAIT); c->setVariableByQName("POSITIVE_INFINITY","",abstract_d(numeric_limits<double>::infinity()),CONSTANT_TRAIT); c->setVariableByQName("MAX_VALUE","",abstract_d(numeric_limits<double>::max()),CONSTANT_TRAIT); @@ -330,7 +322,7 @@ number_t val = obj->toNumber(); int fractiondigits; ARG_UNPACK (fractiondigits,0); - return Class<ASString>::getInstanceS(toFixedString(val, fractiondigits)); + return abstract_s(toFixedString(val, fractiondigits)); } tiny_string Number::toFixedString(double v, int32_t fractiondigits) @@ -375,7 +367,7 @@ ARG_UNPACK(fractionDigits, 0); if (argslen == 0 || args[0]->is<Undefined>()) fractionDigits = imin(imax(Number::countSignificantDigits(v)-1, 1), 20); - return Class<ASString>::getInstanceS(toExponentialString(v, fractionDigits)); + return abstract_s(toExponentialString(v, fractionDigits)); } tiny_string Number::toExponentialString(double v, int32_t fractionDigits) @@ -479,11 +471,11 @@ Number* th=obj->as<Number>(); double v = th->val; if (argslen == 0 || args[0]->is<Undefined>()) - return Class<ASString>::getInstanceS(toString(v)); + return abstract_s(toString(v)); int32_t precision; ARG_UNPACK(precision); - return Class<ASString>::getInstanceS(toPrecisionString(v, precision)); + return abstract_s(toPrecisionString(v, precision)); } tiny_string Number::toPrecisionString(double v, int32_t precision)
View file
lightspark.tar.xz/src/scripting/toplevel/Number.h
Changed
@@ -40,6 +40,7 @@ Number(Class_base* c, double v=(std::numeric_limits<double>::quiet_NaN())):ASObject(c),val(v){type=T_NUMBER;} static const number_t NaN; double val; + void finalize() { val=std::numeric_limits<double>::quiet_NaN();} ASFUNCTION(_constructor); ASFUNCTION(_toString); ASFUNCTION(toExponential);
View file
lightspark.tar.xz/src/scripting/toplevel/UInteger.cpp
Changed
@@ -119,6 +119,7 @@ void UInteger::sinit(Class_base* c) { CLASS_SETUP(c, ASObject, _constructor, CLASS_SEALED | CLASS_FINAL); + c->isReusable = true; c->setVariableByQName("MAX_VALUE","",abstract_ui(0xFFFFFFFF),CONSTANT_TRAIT); c->setVariableByQName("MIN_VALUE","",abstract_ui(0),CONSTANT_TRAIT); c->setDeclaredMethodByQName("toString",AS3,Class<IFunction>::getFunction(_toString),NORMAL_METHOD,true); @@ -136,7 +137,7 @@ ASFUNCTIONBODY(UInteger,_toString) { if(Class<UInteger>::getClass()->prototype->getObj() == obj) - return Class<ASString>::getInstanceS("0"); + return abstract_s("0"); UInteger* th=static_cast<UInteger*>(obj); uint32_t radix; @@ -146,12 +147,12 @@ { char buf[20]; snprintf(buf,20,"%u",th->val); - return Class<ASString>::getInstanceS(buf); + return abstract_s(buf); } else { tiny_string s=Number::toStringRadix((number_t)th->val, radix); - return Class<ASString>::getInstanceS(s); + return abstract_s(s); } } @@ -186,7 +187,7 @@ else fractionDigits = imin(imax((int32_t)ceil(::log10(v)), 1), 20); } - return Class<ASString>::getInstanceS(Number::toExponentialString(v, fractionDigits)); + return abstract_s(Number::toExponentialString(v, fractionDigits)); } ASFUNCTIONBODY(UInteger,_toFixed) @@ -194,17 +195,17 @@ UInteger *th=obj->as<UInteger>(); int fractiondigits; ARG_UNPACK (fractiondigits, 0); - return Class<ASString>::getInstanceS(Number::toFixedString(th->val, fractiondigits)); + return abstract_s(Number::toFixedString(th->val, fractiondigits)); } ASFUNCTIONBODY(UInteger,_toPrecision) { UInteger *th=obj->as<UInteger>(); if (argslen == 0 || args[0]->is<Undefined>()) - return Class<ASString>::getInstanceS(th->toString()); + return abstract_s(th->toString()); int precision; ARG_UNPACK (precision); - return Class<ASString>::getInstanceS(Number::toPrecisionString(th->val, precision)); + return abstract_s(Number::toPrecisionString(th->val, precision)); } void UInteger::serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap,
View file
lightspark.tar.xz/src/scripting/toplevel/UInteger.h
Changed
@@ -35,6 +35,7 @@ static void sinit(Class_base* c); tiny_string toString(); static tiny_string toString(uint32_t val); + void finalize() { val=0;} int32_t toInt() { return val;
View file
lightspark.tar.xz/src/scripting/toplevel/toplevel.cpp
Changed
@@ -227,7 +227,7 @@ ASFUNCTIONBODY(IFunction,_toString) { - return Class<ASString>::getInstanceS("function Function() {}"); + return abstract_s("function Function() {}"); } ASObject* Class<IFunction>::generator(ASObject* const* args, const unsigned int argslen) @@ -266,7 +266,6 @@ SyntheticFunction::~SyntheticFunction() { - finalize(); } void SyntheticFunction::finalize() @@ -384,11 +383,15 @@ cc.scope_stack=func_scope; cc.initialScopeStack=func_scope.size(); cc.exec_pos=0; - if (getVm()->currentCallContext) - cc.defaultNamespaceUri = getVm()->currentCallContext->defaultNamespaceUri; + call_context* saved_cc = getVm()->currentCallContext; + if (saved_cc) + { + if (!saved_cc->defaultNamespaceUri.isNull()) + saved_cc->defaultNamespaceUri->incRef(); + cc.defaultNamespaceUri = saved_cc->defaultNamespaceUri; + } /* Set the current global object, each script in each DoABCTag has its own */ - call_context* saved_cc = getVm()->currentCallContext; getVm()->currentCallContext = &cc; if(isBound()) @@ -455,11 +458,7 @@ cur_recursion++; //increment current recursion depth Log::calls_indent++; - std::pair<uint32_t,ASObject*> s; - s.first = this->functionname; - s.second = obj; - - getVm()->stacktrace.push_back(s); + getVm()->stacktrace.push_back(std::pair<uint32_t,ASObject*>(this->functionname,obj)); while (true) { try @@ -767,14 +766,14 @@ Class_base::Class_base(const QName& name, MemoryAccount* m):ASObject(Class_object::getClass()),protected_ns("",NAMESPACE),constructor(NULL), borrowedVariables(m), - context(NULL),class_name(name),memoryAccount(m),length(1),class_index(-1),isFinal(false),isSealed(false),isInterface(false),use_protected(false) + context(NULL),class_name(name),memoryAccount(m),length(1),class_index(-1),isFinal(false),isSealed(false),isInterface(false),isReusable(false),isProxy(false),use_protected(false) { type=T_CLASS; } Class_base::Class_base(const Class_object*):ASObject((MemoryAccount*)NULL),protected_ns("",NAMESPACE),constructor(NULL), borrowedVariables(NULL), - context(NULL),class_name("Class",""),memoryAccount(NULL),length(1),class_index(-1),isFinal(false),isSealed(false),isInterface(false),use_protected(false) + context(NULL),class_name("Class",""),memoryAccount(NULL),length(1),class_index(-1),isFinal(false),isSealed(false),isInterface(false),isReusable(false),isProxy(false),use_protected(false) { type=T_CLASS; //We have tested that (Class is Class == true) so the classdef is 'this' @@ -860,6 +859,7 @@ void Class_base::setSuper(Ref<Class_base> super_) { assert(!super); + isProxy = super_->isProxy; super = super_; copyBorrowedTraitsFromSuper(); } @@ -871,7 +871,7 @@ ret = "[class "; ret += th->class_name.name; ret += "]"; - return Class<ASString>::getInstanceS(ret); + return abstract_s(ret); } void Class_base::addConstructorGetter() @@ -1048,14 +1048,10 @@ } } -void Class_base::finalize() +void Class_base::destroy() { finalizeObjects(); - ASObject::finalize(); - borrowedVariables.destroyContents(); - super.reset(); - prototype.reset(); if(constructor) { constructor->decRef(); @@ -1063,6 +1059,45 @@ } } +ASObject *Class_base::getObjectFromFreeList() +{ + Locker l(referencedObjectsMutex); + ASObject* ret = NULL; + if (!freelist.empty()) + { + ret=freelist.front(); + freelist.pop_front(); + ret->incRef(); + } +// else +// LOG(LOG_INFO,"cache miss:"<<this->class_name); + + return ret; +} + +void Class_base::pushObjectToFreeList(ASObject *obj) +{ + Locker l(referencedObjectsMutex); + freelist.push_front(obj); +} + +void Class_base::finalize() +{ + borrowedVariables.destroyContents(); + super.reset(); + prototype.reset(); + protected_ns = nsNameAndKind("",NAMESPACE); + constructor = NULL; + context = NULL; + length = 1; + class_index = -1; + isFinal = false; + isSealed = false; + isInterface = false; + isProxy = false; + use_protected = false; +} + Template_base::Template_base(QName name) : ASObject((Class_base*)(NULL)),template_name(name) { type = T_TEMPLATE; @@ -1673,13 +1708,13 @@ if(th->uri_is_null) return getSys()->getNullRef(); else - return Class<ASString>::getInstanceS(th->uri); + return abstract_s(th->uri); } ASFUNCTIONBODY(ASQName,_getLocalName) { ASQName* th=static_cast<ASQName*>(obj); - return Class<ASString>::getInstanceS(th->local_name); + return abstract_s(th->local_name); } ASFUNCTIONBODY(ASQName,_toString) @@ -1687,7 +1722,7 @@ if(!obj->is<ASQName>()) throw Class<TypeError>::getInstanceS("QName.toString is not generic"); ASQName* th=static_cast<ASQName*>(obj); - return Class<ASString>::getInstanceS(th->toString()); + return abstract_s(th->toString()); } bool ASQName::isEqual(ASObject* o) @@ -1735,9 +1770,9 @@ switch(index) { case 1: - return _MR(Class<ASString>::getInstanceS("uri")); + return _MR(abstract_s("uri")); case 2: - return _MR(Class<ASString>::getInstanceS("localName")); + return _MR(abstract_s("localName")); default: return ASObject::nextName(index-2); } @@ -1752,9 +1787,9 @@ if (uri_is_null) return _MR(getSys()->getNullRef()); else - return _MR(Class<ASString>::getInstanceS(this->uri)); + return _MR(abstract_s(this->uri)); case 2: - return _MR(Class<ASString>::getInstanceS(this->local_name)); + return _MR(abstract_s(this->local_name)); default: return ASObject::nextName(index-2); } @@ -1973,7 +2008,7 @@ ASFUNCTIONBODY(Namespace,_getURI) { Namespace* th=static_cast<Namespace*>(obj); - return Class<ASString>::getInstanceS(th->uri); + return abstract_s(th->uri);
View file
lightspark.tar.xz/src/scripting/toplevel/toplevel.h
Changed
@@ -32,6 +32,7 @@ #include "scripting/toplevel/XML.h" #include "memory_support.h" #include <boost/intrusive/list.hpp> +#include <forward_list> namespace lightspark { @@ -157,11 +158,15 @@ Mutex referencedObjectsMutex; boost::intrusive::list<ASObject, boost::intrusive::constant_time_size<false> > referencedObjects; void finalizeObjects(); + std::forward_list<ASObject*> freelist; protected: void copyBorrowedTraitsFromSuper(); ASFUNCTION(_toString); void initStandardProps(); + void destroy(); public: + ASObject* getObjectFromFreeList(); + void pushObjectToFreeList(ASObject* obj); variables_map borrowedVariables; ASPROPERTY_GETTER(_NR<Prototype>,prototype); ASPROPERTY_GETTER(_NR<ObjectConstructor>,constructorprop); @@ -176,6 +181,11 @@ bool isFinal:1; bool isSealed:1; bool isInterface:1; + + // indicates if objects can be reused after they have lost their last reference + bool isReusable:1; + // this is only set to true for Proxy and Proxy-derived classes + bool isProxy:1; private: //TODO: move in Class_inherit bool use_protected:1;
View file
lightspark.tar.xz/src/smartrefs.h
Changed
@@ -29,7 +29,6 @@ class RefCountable { private: ATOMIC_INT32(ref_count); - protected: RefCountable() : ref_count(1) {} @@ -50,15 +49,19 @@ uint32_t t=ATOMIC_DECREMENT(ref_count); if(t==0) { - //Let's make refcount very invalid - ref_count=-1024; - delete this; + destruct(); } } void fake_decRef() { ATOMIC_DECREMENT(ref_count); } + virtual void destruct() + { + //Let's make refcount very invalid + ref_count=-1024; + delete this; + } }; /* @@ -143,8 +146,14 @@ { m->decRef(); } - T* operator->() const {return m;} - T* getPtr() const { return m; } + T* operator->() const + { + return m; + } + T* getPtr() const + { + return m; + } }; #define _R Ref
View file
lightspark.tar.xz/src/swftypes.cpp
Changed
@@ -1343,24 +1343,46 @@ } return s; } +ASString* lightspark::abstract_s() +{ + return Class<ASString>::getInstanceSNoArgs(); +} +ASString* lightspark::abstract_s(const char* s, uint32_t len) +{ + ASString* ret= Class<ASString>::getInstanceSNoArgs(); + ret->data = std::string(s,len); + return ret; +} +ASString* lightspark::abstract_s(const char* s) +{ + ASString* ret= Class<ASString>::getInstanceSNoArgs(); + ret->data = s; + return ret; +} +ASString* lightspark::abstract_s(const tiny_string& s) +{ + ASString* ret= Class<ASString>::getInstanceSNoArgs(); + ret->data = s; + return ret; +} ASObject* lightspark::abstract_d(number_t i) { - Number* ret=Class<Number>::getInstanceS(); - // we have to set the value seperately, because for i = NaN, getInstanceS will overwrite the value + Number* ret=Class<Number>::getInstanceSNoArgs(); ret->val = i; return ret; } - ASObject* lightspark::abstract_i(int32_t i) { - Integer* ret=Class<Integer>::getInstanceS(i); + Integer* ret=Class<Integer>::getInstanceSNoArgs(); + ret->val = i; return ret; } ASObject* lightspark::abstract_ui(uint32_t i) { - UInteger* ret=Class<UInteger>::getInstanceS(i); + UInteger* ret=Class<UInteger>::getInstanceSNoArgs(); + ret->val = i; return ret; } @@ -1418,7 +1440,7 @@ multiname ret(NULL); ret.name_type = multiname::NAME_STRING; ret.name_s_id = getSys()->getUniqueStringId(name); - ret.ns.push_back( nsNameAndKind(ns, NAMESPACE) ); + ret.ns.emplace_back(ns, NAMESPACE); ret.isAttribute = false; return ret; }
View file
lightspark.tar.xz/src/swftypes.h
Changed
@@ -82,6 +82,7 @@ typedef double number_t; class ASObject; +class ASString; class ABCContext; struct namespace_info; @@ -1332,6 +1333,10 @@ ASObject* abstract_i(int32_t i); ASObject* abstract_ui(uint32_t i); ASObject* abstract_d(number_t i); +ASString* abstract_s(); +ASString* abstract_s(const char* s, uint32_t len); +ASString* abstract_s(const char* s); +ASString* abstract_s(const tiny_string& s); void stringToQName(const tiny_string& tmp, tiny_string& name, tiny_string& ns);
View file
lightspark.tar.xz/src/tiny_string.cpp
Changed
@@ -316,6 +316,14 @@ return stringSize == 1; } +void tiny_string::clear() +{ + resetToStatic(); + numchars = 0; + isASCII = true; + hasNull = false; +} + /* returns the length in bytes, not counting the trailing \0 */ uint32_t tiny_string::numBytes() const { @@ -483,9 +491,17 @@ tiny_string ret; ret.buf = ret._buf_static; ret.type = STATIC; - ret.stringSize = c&0x80 ? 2 : g_unichar_to_utf8(c,ret.buf) + 1; - ret.buf[ret.stringSize-1] = '\0'; ret.isASCII = c<0x80; + if (ret.isASCII) + { + ret.buf[0] = c&0xff; + ret.stringSize = 2; + } + else + { + ret.stringSize = g_unichar_to_utf8(c,ret.buf) + 1; + } + ret.buf[ret.stringSize-1] = '\0'; ret.hasNull = c == 0; ret.numchars = 1; return ret;
View file
lightspark.tar.xz/src/tiny_string.h
Changed
@@ -151,6 +151,7 @@ bool operator!=(const Glib::ustring&) const; const char* raw_buf() const; bool empty() const; + void clear(); /* returns the length in bytes, not counting the trailing \0 */ uint32_t numBytes() const; /* returns the length in utf-8 characters, not counting the trailing \0 */
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.