Projects
Essentials
lightspark
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 75
View file
lightspark.spec
Changed
@@ -24,7 +24,7 @@ %endif Name: lightspark -Version: 0.7.2.99+git20150809.1236 +Version: 0.7.2.99+git20150823.1908 Release: 0 Summary: Modern, free, open-source flash player implementation License: LGPL-3.0+
View file
lightspark.tar.xz/src/parsing/tags.cpp
Changed
@@ -261,6 +261,7 @@ LOG(LOG_ERROR,_("Error while reading tag ") << h.getTagType() << _(". Size=") << actualLen << _(" expected: ") << expectedLen); throw ParseException("Malformed SWF file"); } + root->loaderInfo->setBytesLoaded(f.tellg()); return ret; } @@ -1203,6 +1204,8 @@ if(placedTag==NULL) throw RunTimeException("No tag to place"); + placedTag->loadedFrom->checkBinding(placedTag); + //We can create the object right away ASObject *instance = placedTag->instance(); DisplayObject* toAdd=dynamic_cast<DisplayObject*>(instance); @@ -1463,10 +1466,11 @@ } } } + Class_base* realClass=(c)?c:bindedTo; - if(c==NULL) - c=Class<SimpleButton>::getClass(); - SimpleButton* ret=new (c->memoryAccount) SimpleButton(c, states[0], states[1], states[2], states[3]); + if(realClass==NULL) + realClass=Class<SimpleButton>::getClass(); + SimpleButton* ret=new (realClass->memoryAccount) SimpleButton(realClass, states[0], states[1], states[2], states[3]); return ret; }
View file
lightspark.tar.xz/src/parsing/tags.h
Changed
@@ -75,11 +75,12 @@ the first one is reported here. This behaviour is tested. */ Class_base* bindedTo; + tiny_string bindingclassname; RootMovieClip* loadedFrom; DictionaryTag(RECORDHEADER h, RootMovieClip* root):Tag(h),bindedTo(NULL),loadedFrom(root){ } virtual TAGTYPE getType()const{ return DICT_TAG; } virtual int getId() const=0; - virtual ASObject* instance(Class_base* c=NULL) const { return NULL; }; + virtual ASObject* instance(Class_base* c=NULL) const { return NULL; } }; /* @@ -312,7 +313,7 @@ CLIPACTIONS ClipActions; PlaceObject2Tag(RECORDHEADER h):DisplayListTag(h){} void setProperties(DisplayObject* obj, DisplayObjectContainer* parent) const; - const DictionaryTag* placedTag; + DictionaryTag* placedTag; public: STRING Name; PlaceObject2Tag(RECORDHEADER h, std::istream& in, RootMovieClip* root);
View file
lightspark.tar.xz/src/scripting/abc.cpp
Changed
@@ -26,9 +26,9 @@ #include <llvm/ExecutionEngine/ExecutionEngine.h> #ifndef LLVM_36 #include <llvm/ExecutionEngine/JIT.h> -#include "llvm/IR/LegacyPassManager.h" -#else #include <llvm/PassManager.h> +#else +#include "llvm/IR/LegacyPassManager.h" #endif #ifdef HAVE_IR_DATALAYOUT_H # include <llvm/IR/Module.h> @@ -1387,7 +1387,7 @@ Class_inherit* derived_class_tmp=static_cast<Class_inherit*>(derived_class); if(derived_class_tmp->isBinded()) { - LOG(LOG_ERROR, "Class already binded to a tag. Not binding:"<<s<< " class:"<<derived_class_tmp->getQualifiedClassName()); + //LOG(LOG_ERROR, "Class already binded to a tag. Not binding:"<<s<< " class:"<<derived_class_tmp->getQualifiedClassName()); return NULL; } return derived_class_tmp; @@ -1663,10 +1663,11 @@ th->ex=eb.create(); assert_and_throw(th->ex); - th->FPM=new llvm::FunctionPassManager(th->module); #ifdef LLVM_36 + th->FPM=new llvm::legacy::FunctionPassManager(th->module); th->FPM->add(new llvm::DataLayoutPass()); #else + th->FPM=new llvm::FunctionPassManager(th->module); #ifdef LLVM_35 th->FPM->add(new llvm::DataLayoutPass(*th->ex->getDataLayout())); #elif defined HAVE_DATALAYOUT_H || defined HAVE_IR_DATALAYOUT_H
View file
lightspark.tar.xz/src/scripting/abc_opcodes.cpp
Changed
@@ -2264,6 +2264,7 @@ ret->constructor=constructorFunc; } ret->class_index=n; + th->context->root->bindClass(className,ret); //Add prototype variable ret->prototype = _MNR(new_objectPrototype());
View file
lightspark.tar.xz/src/scripting/flash/display/flashdisplay.cpp
Changed
@@ -1026,16 +1026,6 @@ (*it)->execute(displayList.getPtr()); } -void Frame::bindClasses(RootMovieClip *root) -{ - ABCVm *vm = getVm(); - auto it=classesToBeBound.begin(); - for(;it!=classesToBeBound.end();++it) - vm->buildClassAndBindTag(it->first.raw_buf(), it->second); - - classesToBeBound.clear(); -} - FrameContainer::FrameContainer():framesLoaded(0) { frames.emplace_back(Frame()); @@ -1239,7 +1229,10 @@ { uint32_t dest=getFrameIdByLabel(args[0]->toString(), sceneName); if(dest==FRAME_NOT_FOUND) - throwError<ArgumentError>(kInvalidArgumentError,stop ? "gotoAndStop: label not found" : "gotoAndPlay: label not found"); + { + LOG(LOG_ERROR, (stop ? "gotoAndStop: label not found:" : "gotoAndPlay: label not found:") <<args[0]->toString()); + throwError<ArgumentError>(kInvalidArgumentError,args[0]->toString()); + } next_FP = dest; } @@ -1250,7 +1243,7 @@ return NULL; /*this behavior was observed by testing */ next_FP = getFrameIdByNumber(inFrameNo-1, sceneName); - if(next_FP >= getFramesLoaded()) + if(next_FP > getFramesLoaded()) { LOG(LOG_ERROR, next_FP << "= next_FP >= state.max_FP = " << getFramesLoaded()); /* spec says we should throw an error, but then YT breaks */
View file
lightspark.tar.xz/src/scripting/flash/display/flashdisplay.h
Changed
@@ -49,6 +49,7 @@ class Vector; class Graphics; class Rectangle; +class Class_inherit; class InteractiveObject: public DisplayObject { @@ -278,6 +279,8 @@ bytesTotal=b; } void setBytesLoaded(uint32_t b); + uint32_t getBytesLoaded() { return bytesLoaded; } + uint32_t getBytesTotal() { return bytesTotal; } void setURL(const tiny_string& _url, bool setParameters=true); void setLoaderURL(const tiny_string& _url) { loaderURL=_url; } void setParameters(_NR<ASObject> p) { parameters = p; } @@ -418,14 +421,12 @@ { public: std::list<const DisplayListTag*> blueprint; - std::list< std::pair<tiny_string, DictionaryTag*> > classesToBeBound; void execute(_R<DisplayObjectContainer> displayList); /** * destroyTags must be called only by the tag destructor, not by * the objects that are instance of tags */ void destroyTags(); - void bindClasses(RootMovieClip *root); }; class FrameContainer
View file
lightspark.tar.xz/src/scripting/flash/events/flashevents.cpp
Changed
@@ -498,17 +498,26 @@ } } -IOErrorEvent::IOErrorEvent(Class_base* c) : ErrorEvent(c, "ioError") +IOErrorEvent::IOErrorEvent(Class_base* c,const tiny_string& t, const std::string& e, int id) : ErrorEvent(c, t,e,id) { } +Event *IOErrorEvent::cloneImpl() const +{ + return Class<IOErrorEvent>::getInstanceS(text, errorMsg,errorID); +} + + void IOErrorEvent::sinit(Class_base* c) { CLASS_SETUP(c, ErrorEvent, _constructor, CLASS_SEALED); - c->setVariableByQName("DISK_ERROR","",Class<ASString>::getInstanceS("diskError"),DECLARED_TRAIT); - c->setVariableByQName("IO_ERROR","",Class<ASString>::getInstanceS("ioError"),DECLARED_TRAIT); - c->setVariableByQName("NETWORK_ERROR","",Class<ASString>::getInstanceS("networkError"),DECLARED_TRAIT); - c->setVariableByQName("VERIFY_ERROR","",Class<ASString>::getInstanceS("verifyError"),DECLARED_TRAIT); + c->setVariableByQName("IO_ERROR","",Class<ASString>::getInstanceS("ioError"),CONSTANT_TRAIT); + c->setVariableByQName("DISK_ERROR","",Class<ASString>::getInstanceS("diskError"),CONSTANT_TRAIT); + c->setVariableByQName("NETWORK_ERROR","",Class<ASString>::getInstanceS("networkError"),CONSTANT_TRAIT); + c->setVariableByQName("VERIFY_ERROR","",Class<ASString>::getInstanceS("verifyError"),CONSTANT_TRAIT); + c->setVariableByQName("STANDARD_ERROR_IO_ERROR","",Class<ASString>::getInstanceS("standardErrorIoError"),CONSTANT_TRAIT); + c->setVariableByQName("STANDARD_INPUT_IO_ERROR","",Class<ASString>::getInstanceS("standardInputIoError"),CONSTANT_TRAIT); + c->setVariableByQName("STANDARD_OUTPUT_IO_ERROR","",Class<ASString>::getInstanceS("standardOutputIoError"),CONSTANT_TRAIT); } EventDispatcher::EventDispatcher(Class_base* c):ASObject(c) @@ -980,7 +989,7 @@ return NULL; } -ErrorEvent::ErrorEvent(Class_base* c, const tiny_string& t, const std::string& e): TextEvent(c,t), errorMsg(e) +ErrorEvent::ErrorEvent(Class_base* c, const tiny_string& t, const std::string& e, int id): TextEvent(c,t), errorMsg(e),errorID(id) { } @@ -988,16 +997,22 @@ { CLASS_SETUP(c, TextEvent, _constructor, CLASS_SEALED); c->setVariableByQName("ERROR","",Class<ASString>::getInstanceS("error"),DECLARED_TRAIT); + REGISTER_GETTER(c,errorID); } +ASFUNCTIONBODY_GETTER(ErrorEvent,errorID); Event* ErrorEvent::cloneImpl() const { - return Class<ErrorEvent>::getInstanceS(text, errorMsg); + return Class<ErrorEvent>::getInstanceS(text, errorMsg,errorID); } ASFUNCTIONBODY(ErrorEvent,_constructor) { - TextEvent::_constructor(obj,args,argslen); + ErrorEvent* th=static_cast<ErrorEvent*>(obj); + uint32_t baseClassArgs=imin(argslen,4); + TextEvent::_constructor(obj,args,baseClassArgs); + if(argslen>=5) + th->errorID=args[4]->toInt(); return NULL; }
View file
lightspark.tar.xz/src/scripting/flash/events/flashevents.h
Changed
@@ -181,11 +181,12 @@ class ErrorEvent: public TextEvent { -private: +protected: std::string errorMsg; Event* cloneImpl() const; + ASPROPERTY_GETTER(int32_t,errorID); public: - ErrorEvent(Class_base* c, const tiny_string& t = "error", const std::string& e = ""); + ErrorEvent(Class_base* c, const tiny_string& t = "error", const std::string& e = "", int id = 0); static void sinit(Class_base*); static void buildTraits(ASObject* o) { @@ -195,8 +196,10 @@ class IOErrorEvent: public ErrorEvent { +private: + Event* cloneImpl() const; public: - IOErrorEvent(Class_base* c); + IOErrorEvent(Class_base* c, const tiny_string& t = "ioError", const std::string& e = "", int id = 0); static void sinit(Class_base*); static void buildTraits(ASObject* o) {
View file
lightspark.tar.xz/src/scripting/flash/system/flashsystem.cpp
Changed
@@ -23,6 +23,8 @@ #include "scripting/argconv.h" #include "compat.h" #include "backends/security.h" +#include "scripting/toplevel/XML.h" +#include "scripting/toplevel/XMLList.h" #include <istream> #include <gdk/gdk.h> @@ -576,7 +578,7 @@ { CLASS_SETUP(c, ASObject, _constructorNotInstantiatable, CLASS_SEALED | CLASS_FINAL); c->setDeclaredMethodByQName("totalMemory","",Class<IFunction>::getFunction(totalMemory),GETTER_METHOD,false); - c->setDeclaredMethodByQName("disposeXML","",Class<IFunction>::getFunction(totalMemory),GETTER_METHOD,false); + c->setDeclaredMethodByQName("disposeXML","",Class<IFunction>::getFunction(disposeXML),NORMAL_METHOD,false); } @@ -587,7 +589,17 @@ } ASFUNCTIONBODY(System,disposeXML) { - LOG(LOG_NOT_IMPLEMENTED, "System.disposeXML not implemented"); + _NR<XML> xmlobj; + ARG_UNPACK (xmlobj); + LOG(LOG_NOT_IMPLEMENTED,"disposeXML only removes the node from its parent"); + if (!xmlobj.isNull() && xmlobj->getParentNode()->is<XML>()) + { + XML* parent = xmlobj->getParentNode()->as<XML>(); + XMLList* l = parent->getChildrenlist(); + if (l) + l->removeNode(xmlobj.getPtr()); + parent->decRef(); + } return NULL; }
View file
lightspark.tar.xz/src/scripting/toplevel/Array.cpp
Changed
@@ -405,8 +405,9 @@ ASFUNCTIONBODY(Array,lastIndexOf) { Array* th=static_cast<Array*>(obj); + number_t index; _NR<ASObject> arg0; - ARG_UNPACK(arg0); + ARG_UNPACK(arg0) (index, 0x7fffffff); int ret=-1; if(argslen == 1 && th->data.empty()) @@ -414,26 +415,23 @@ size_t i = th->size()-1; - if(argslen == 2 && std::isnan(args[1]->toNumber())) - return abstract_i(-1); + if(std::isnan(index)) + return abstract_i(0); - if(argslen == 2 && args[1]->getObjectType() != T_UNDEFINED && !std::isnan(args[1]->toNumber())) + int j = index; //Preserve sign + if(j < 0) //Negative offset, use it as offset from the end of the array { - int j = args[1]->toInt(); //Preserve sign - if(j < 0) //Negative offset, use it as offset from the end of the array - { - if((size_t)-j > th->size()) - i = 0; - else - i = th->size()+j; - } - else //Positive offset, use it directly - { - if((size_t)j > th->size()) //If the passed offset is bigger than the array, cap the offset - i = th->size()-1; - else - i = j; - } + if((size_t)-j > th->size()) + return abstract_i(-1); + else + i = th->size()+j; + } + else //Positive offset, use it directly + { + if((size_t)j > th->size()) //If the passed offset is bigger than the array, cap the offset + i = th->size()-1; + else + i = j; } do { @@ -637,7 +635,8 @@ int32_t index; _NR<ASObject> arg0; ARG_UNPACK(arg0) (index, 0); - if (index < 0) index = abs(index); + if (index < 0) index = th->size()+ index; + if (index < 0) index = 0; DATA_TYPE dtype; std::map<uint32_t,data_slot>::iterator it;
View file
lightspark.tar.xz/src/scripting/toplevel/XMLList.cpp
Changed
@@ -606,6 +606,22 @@ { nodes.clear(); } + +void XMLList::removeNode(XML *node) +{ + XMLList::XMLListVector::iterator it = nodes.end(); + while (it != nodes.begin()) + { + it--; + _R<XML> n = *it; + if (n.getPtr() == node) + { + node->parentNode = NullRef; + nodes.erase(it); + break; + } + } +} void XMLList::getTargetVariables(const multiname& name,XML::XMLVector& retnodes) { unsigned int index=0;
View file
lightspark.tar.xz/src/scripting/toplevel/XMLList.h
Changed
@@ -116,6 +116,7 @@ void prependNodesTo(XML *dest) const; void normalize(); void clear(); + void removeNode(XML* node); XMLList* getTargetObject() { return targetobject; } }; }
View file
lightspark.tar.xz/src/swf.cpp
Changed
@@ -146,6 +146,7 @@ Class_base* movieClipClass = Class<MovieClip>::getClass(); RootMovieClip* ret=new (movieClipClass->memoryAccount) RootMovieClip(li, appDomain, secDomain, movieClipClass); ret->constructIndicator = true; + ret->constructorCallComplete = true; return ret; } @@ -246,9 +247,8 @@ _NR<LoaderInfo> loaderInfo=_MR(Class<LoaderInfo>::getInstanceS()); loaderInfo->applicationDomain = applicationDomain; - //If the size is not known those will stay at zero - loaderInfo->setBytesLoaded(fileSize); - loaderInfo->setBytesTotal(fileSize); + loaderInfo->setBytesLoaded(0); + loaderInfo->setBytesTotal(0); mainClip=RootMovieClip::getInstance(loaderInfo, applicationDomain, securityDomain); stage=Class<Stage>::getInstanceS(); mainClip->incRef(); @@ -347,7 +347,7 @@ if(ok) { - //cout << varName << ' ' << varValue << endl; + cout << varName << endl << varValue << endl; if(pfile) f << varName << endl << varValue << endl; @@ -379,7 +379,7 @@ getline(i,value); ret->setVariableByQName(name,"",Class<ASString>::getInstanceS(value),DYNAMIC_TRAIT); - //cout << name << ' ' << value << endl; + cout << name << ' ' << value << endl; } setParameters(ret); i.close(); @@ -1242,7 +1242,10 @@ f >> FileLength; //Enable decompression if needed if(fileType==FT_SWF) + { LOG(LOG_INFO, _("Uncompressed SWF file: Version ") << (int)version); + root->loaderInfo->setBytesTotal(FileLength); + } else { //The file is compressed, create a filtering streambuf @@ -1263,11 +1266,14 @@ assert(false); } f.rdbuf(uncompressingFilter); + // the first 8 bytes from the header are always uncompressed (magic bytes + FileLength) + root->loaderInfo->setBytesTotal(FileLength-8); } f >> FrameSize >> FrameRate >> FrameCount; root->fileLength=FileLength; + root->loaderInfo->setBytesLoaded(0); float frameRate=FrameRate; if (frameRate == 0) //The Adobe player ignores frameRate == 0 and substitutes @@ -1508,6 +1514,11 @@ root->parsingFailed(); throw; } + if (root->loaderInfo->getBytesLoaded() != root->loaderInfo->getBytesTotal()) + { + LOG(LOG_NOT_IMPLEMENTED,"End of parsing, bytesLoaded != bytesTotal:"<< root->loaderInfo->getBytesLoaded()<<"/"<<root->loaderInfo->getBytesTotal()); + root->loaderInfo->setBytesLoaded(root->loaderInfo->getBytesTotal()); + } LOG(LOG_TRACE,_("End of parsing")); } @@ -1981,16 +1992,10 @@ if(getFramesLoaded() == 0) return; - /* Bind classes between the previous and new frame. */ - std::list<Frame>::iterator frame=frames.begin(); - for(unsigned int i=0;i<=state.FP;i++) - { - if((int)i > state.last_FP) - { - frame->bindClasses(this); - } - ++frame; - } + ABCVm *vm = getVm(); + auto it=classesToBeBound.begin(); + for(;it!=classesToBeBound.end();++it) + vm->buildClassAndBindTag(it->first.raw_buf(), it->second); MovieClip::initFrame(); } @@ -2016,5 +2021,82 @@ { // This function will be called only be the parsing thread, // and will only access the last frame, so no locking needed. - frames.back().classesToBeBound.push_back(make_pair(name, tag)); + tag->bindingclassname = name; + classesToBeBound.push_back(make_pair(name, tag)); +} + +void RootMovieClip::bindClass(const QName& classname, Class_inherit* cls) +{ + if (cls->isBinded()) + return; + + tiny_string clsname; + if (!classname.ns.empty()) + clsname = classname.ns + "."; + clsname += classname.name; + + auto it=classesToBeBound.begin(); + for(;it!=classesToBeBound.end();++it) + { + if (it->first == clsname) + { + if(it->second->bindedTo==NULL) + it->second->bindedTo=cls; + + cls->bindToTag(it->second); + break; + } + } +} + +void RootMovieClip::checkBinding(DictionaryTag *tag) +{ + if (tag->bindingclassname.empty()) + return; + multiname clsname(NULL); + clsname.name_type=multiname::NAME_STRING; + clsname.isAttribute = false; + + uint32_t pos = tag->bindingclassname.rfind("."); + tiny_string ns; + tiny_string nm; + if (pos != tiny_string::npos) + { + nm = tag->bindingclassname.substr(pos+1,tag->bindingclassname.numBytes()); + ns = tag->bindingclassname.substr(0,pos); + } + else + { + nm = tag->bindingclassname; + ns = ""; + } + clsname.name_s_id=getSys()->getUniqueStringId(nm); + clsname.ns.push_back(nsNameAndKind(ns,NAMESPACE)); + + ASObject* typeObject = NULL; + auto i = applicationDomain->classesBeingDefined.cbegin(); + while (i != applicationDomain->classesBeingDefined.cend()) + { + if(i->first->qualifiedString() == clsname.qualifiedString()) + { + typeObject = i->second; + break; + } + i++; + } + if (typeObject == NULL) + { + ASObject* target; + typeObject=applicationDomain->getVariableAndTargetByMultiname(clsname,target); + } + if (typeObject != NULL) + { + Class_inherit* cls = typeObject->as<Class_inherit>(); + if (cls) + { + tag->bindedTo=cls; + tag->bindingclassname = ""; + cls->bindToTag(tag); + } + } }
View file
lightspark.tar.xz/src/swf.h
Changed
@@ -56,6 +56,7 @@ class Tag; class ApplicationDomain; class SecurityDomain; +class Class_inherit; class RootMovieClip: public MovieClip { @@ -67,6 +68,8 @@ RGB Background; Spinlock dictSpinlock; std::list < DictionaryTag* > dictionary; + std::list< std::pair<tiny_string, DictionaryTag*> > classesToBeBound; + //frameSize and frameRate are valid only after the header has been parsed RECT frameSize; float frameRate; @@ -117,6 +120,8 @@ //DisplayObject interface _NR<RootMovieClip> getRoot(); void addBinding(const tiny_string& name, DictionaryTag *tag); + void bindClass(const QName &classname, Class_inherit* cls); + void checkBinding(DictionaryTag* tag); }; class ThreadProfile
View file
lightspark.tar.xz/tools/pygil
Changed
@@ -29,6 +29,9 @@ rset2 = re.compile('.*REGISTER_SETTER\([^,]*, *(.*)\)') rgetset2 = re.compile('.*REGISTER_GETTER_SETTER\([^,]*, *(.*)\)') rconst = re.compile('[^/]*->setVariableByQName\("([A-Za-z_0-9]*)",.*[A-Z]*\_TRAIT'); +#looks like Event *IOErrorEvent::cloneImpl() const +rclone = re.compile('[^/]* *\* *([^\:]*)\:\:cloneImpl\(\)') + rcomment = re.compile('[ \t]*/') def getFullname(cls,name): @@ -150,6 +153,15 @@ if m: const.add((curClass,m.group(1))) continue + m = rclone.match(line) + if m: + curClassClone = m.group(1) + if curClassClone not in internalToExternal: + warnNotRegistered.add(curClassClone) + else: + curClassClone = internalToExternal[curClassClone] + methods.add((curClassClone, 'clone')) + continue #print getters #print setters
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
.