Projects
Essentials
lightspark
Sign Up
Log In
Username
Password
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); // TODO: undocumented constructor node + //LOG(LOG_INFO,"describeType:"<< Class<XML>::getInstanceS(root)->toXMLString_internal()); return Class<XML>::getInstanceS(root); } @@ -1867,7 +1894,7 @@ res += " "; ASObject* params[2]; - params[0] = Class<ASString>::getInstanceS(getSys()->getStringFromUniqueId(varIt->first.nameId)); + params[0] = abstract_s(getSys()->getStringFromUniqueId(varIt->first.nameId)); params[1] = varIt->second.var; params[1]->incRef(); ASObject *funcret=replacer->call(getSys()->getNullRef(), params, 2); @@ -1928,7 +1955,7 @@ multiname prototypeName(NULL); prototypeName.name_type=multiname::NAME_STRING; prototypeName.name_s_id=getSys()->getUniqueStringId("prototype"); - prototypeName.ns.push_back(nsNameAndKind("",NAMESPACE)); + prototypeName.ns.emplace_back("",NAMESPACE); bool has_getter = false; variable* ret=findSettable(prototypeName,&has_getter); if(!ret && has_getter)
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) { @@ -730,7 +750,7 @@ ASFUNCTIONBODY(ASString,fromCharCode) { - ASString* ret=Class<ASString>::getInstanceS(); + ASString* ret=abstract_s(); for(uint32_t i=0;i<argslen;i++) { ret->data += tiny_string::fromChar(args[i]->toUInt16()); @@ -743,7 +763,7 @@ tiny_string data = obj->toString(); enum REPLACE_TYPE { STRING=0, FUNC }; REPLACE_TYPE type; - ASString* ret=Class<ASString>::getInstanceS(data); + ASString* ret=abstract_s(data); tiny_string replaceWith; if(argslen < 2) @@ -800,12 +820,12 @@ IFunction* f=static_cast<IFunction*>(args[1]); ASObject** subargs = g_newa(ASObject*, 3+capturingGroups); //we index on bytes, not on UTF-8 characters - subargs[0]=Class<ASString>::getInstanceS(ret->data.substr_bytes(ovector[0],ovector[1]-ovector[0])); + subargs[0]=abstract_s(ret->data.substr_bytes(ovector[0],ovector[1]-ovector[0])); for(int i=0;i<capturingGroups;i++) - subargs[i+1]=Class<ASString>::getInstanceS(ret->data.substr_bytes(ovector[i*2+2],ovector[i*2+3]-ovector[i*2+2])); + subargs[i+1]=abstract_s(ret->data.substr_bytes(ovector[i*2+2],ovector[i*2+3]-ovector[i*2+2])); subargs[capturingGroups+1]=abstract_i(ovector[0]-retDiff); - subargs[capturingGroups+2]=Class<ASString>::getInstanceS(data); + subargs[capturingGroups+2]=abstract_s(data); ASObject* ret=f->call(getSys()->getNullRef(), subargs, 3+capturingGroups); replaceWithTmp=ret->toString().raw_buf(); ret->decRef(); @@ -877,7 +897,7 @@ ASFUNCTIONBODY(ASString,concat) { tiny_string data = obj->toString(); - ASString* ret=Class<ASString>::getInstanceS(data); + ASString* ret=abstract_s(data); for(unsigned int i=0;i<argslen;i++) ret->data+=args[i]->toString().raw_buf(); @@ -888,9 +908,9 @@ { assert(argslen<=1); if (argslen == 0) - return Class<ASString>::getInstanceS(""); + return abstract_s(); else - return Class<ASString>::getInstanceS(args[0]->toString()); + return abstract_s(args[0]->toString()); } bool ASString::isEcmaSpace(uint32_t c)
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); } /* ASFUNCTIONBODY(Namespace,_setPrefix) @@ -1998,7 +2033,7 @@ if(th->prefix_is_undefined) return getSys()->getUndefinedRef(); else - return Class<ASString>::getInstanceS(th->prefix); + return abstract_s(th->prefix); } ASFUNCTIONBODY(Namespace,_toString) @@ -2006,12 +2041,12 @@ if(!obj->is<Namespace>()) throw Class<TypeError>::getInstanceS("Namespace.toString is not generic"); Namespace* th=static_cast<Namespace*>(obj); - return Class<ASString>::getInstanceS(th->uri); + return abstract_s(th->uri); } ASFUNCTIONBODY(Namespace,_valueOf) { - return Class<ASString>::getInstanceS(obj->as<Namespace>()->uri); + return abstract_s(obj->as<Namespace>()->uri); } ASFUNCTIONBODY(Namespace,_ECMA_valueOf) @@ -2019,7 +2054,7 @@ if(!obj->is<Namespace>()) throw Class<TypeError>::getInstanceS("Namespace.valueOf is not generic"); Namespace* th=static_cast<Namespace*>(obj); - return Class<ASString>::getInstanceS(th->uri); + return abstract_s(th->uri); } bool Namespace::isEqual(ASObject* o) @@ -2056,9 +2091,9 @@ switch(index) { case 1: - return _MR(Class<ASString>::getInstanceS("uri")); + return _MR(abstract_s("uri")); case 2: - return _MR(Class<ASString>::getInstanceS("prefix")); + return _MR(abstract_s("prefix")); default: return ASObject::nextName(index-2); } @@ -2070,12 +2105,12 @@ switch(index) { case 1: - return _MR(Class<ASString>::getInstanceS(this->uri)); + return _MR(abstract_s(this->uri)); case 2: if(prefix_is_undefined) return _MR(getSys()->getUndefinedRef()); else - return _MR(Class<ASString>::getInstanceS(this->prefix)); + return _MR(abstract_s(this->prefix)); default: return ASObject::nextName(index-2); } @@ -2262,28 +2297,28 @@ { tiny_string str; ARG_UNPACK (str, "undefined"); - return Class<ASString>::getInstanceS(URLInfo::encode(str, URLInfo::ENCODE_URI)); + return abstract_s(URLInfo::encode(str, URLInfo::ENCODE_URI)); } ASFUNCTIONBODY(lightspark,decodeURI) { tiny_string str; ARG_UNPACK (str, "undefined"); - return Class<ASString>::getInstanceS(URLInfo::decode(str, URLInfo::ENCODE_URI)); + return abstract_s(URLInfo::decode(str, URLInfo::ENCODE_URI)); } ASFUNCTIONBODY(lightspark,encodeURIComponent) { tiny_string str; ARG_UNPACK (str, "undefined"); - return Class<ASString>::getInstanceS(URLInfo::encode(str, URLInfo::ENCODE_URICOMPONENT)); + return abstract_s(URLInfo::encode(str, URLInfo::ENCODE_URICOMPONENT)); } ASFUNCTIONBODY(lightspark,decodeURIComponent) { tiny_string str; ARG_UNPACK (str, "undefined"); - return Class<ASString>::getInstanceS(URLInfo::decode(str, URLInfo::ENCODE_URICOMPONENT)); + return abstract_s(URLInfo::decode(str, URLInfo::ENCODE_URICOMPONENT)); } ASFUNCTIONBODY(lightspark,escape) @@ -2291,8 +2326,8 @@ tiny_string str; ARG_UNPACK (str, "undefined"); if (argslen > 0 && args[0]->is<Undefined>()) - return Class<ASString>::getInstanceS("null"); - return Class<ASString>::getInstanceS(URLInfo::encode(str, URLInfo::ENCODE_ESCAPE)); + return abstract_s("null"); + return abstract_s(URLInfo::encode(str, URLInfo::ENCODE_ESCAPE)); } ASFUNCTIONBODY(lightspark,unescape) @@ -2300,8 +2335,8 @@ tiny_string str; ARG_UNPACK (str, "undefined"); if (argslen > 0 && args[0]->is<Undefined>()) - return Class<ASString>::getInstanceS("null"); - return Class<ASString>::getInstanceS(URLInfo::decode(str, URLInfo::ENCODE_ESCAPE)); + return abstract_s("null"); + return abstract_s(URLInfo::decode(str, URLInfo::ENCODE_ESCAPE)); } ASFUNCTIONBODY(lightspark,print)
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
.