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 73
View file
lightspark.spec
Changed
@@ -24,7 +24,7 @@ %endif Name: lightspark -Version: 0.7.2.99+git20150629.1759 +Version: 0.7.2.99+git20150712.0853 Release: 0 Summary: Modern, free, open-source flash player implementation License: LGPL-3.0+
View file
lightspark.tar.xz/ChangeLog
Changed
@@ -2,6 +2,10 @@ Version NEXT: + * implement several missing opcodes + * fix serialization + * implement data generation mode + * support for avmplus classes (mostly stubs) * Support LLVM up to version 3.6 * fix event dispatcher handling * several fixes for object initialization
View file
lightspark.tar.xz/docs/man/lightspark.1
Changed
@@ -19,7 +19,7 @@ lightspark \- a free Flash player .SH SYNOPSIS .B lightspark -[\-\-url|\-u http://loader.url/file.swf] [\-\-air] [\-\-disable-interpreter|\-ni] [\-\-enable-fast-interpreter|\-fi] [\-\-enable\-jit|\-j] [\-\-log\-level|\-l 0-4] [\-\-parameters\-file|\-p params-file] [\-\-profiling-output|\-o] [\-\-security-sandbox|\-s <sandbox type>] [\-\-exit-on-error] [\-\-HTTP-cookies <cookie>] [\-\-version|\-v] file.swf +[\-\-url|\-u http://loader.url/file.swf] [\-\-air] [\-\-avmplus] [\-\-disable-interpreter|\-ni] [\-\-enable-fast-interpreter|\-fi] [\-\-enable\-jit|\-j] [\-\-log\-level|\-l 0-4] [\-\-parameters\-file|\-p params-file] [\-\-profiling-output|\-o] [\-\-security-sandbox|\-s <sandbox type>] [\-\-exit-on-error] [\-\-HTTP-cookies <cookie>] [\-\-version|\-v] file.swf .SH DESCRIPTION .B Lightspark is a free, modern Flash Player implementation, this documents the options accepted by the standalone version of the program. @@ -77,6 +77,10 @@ .IP Run as an AIR application: grant permission to access both local files and network, and enable AIR APIs. .HP +\fB\-\-avmplus\fP +.IP +Run as an application with avmplus package: grant permission to access both local files and network, and enable avmplus APIs. +.HP \fB\-\-version\fP, \fB\-v\fP .IP Shows lightspark version and exits.
View file
lightspark.tar.xz/src/CMakeLists.txt
Changed
@@ -105,6 +105,7 @@ scripting/flash/text/flashtextengine.cpp scripting/flash/utils/flashutils.cpp scripting/flash/utils/ByteArray.cpp + scripting/flash/utils/CompressionAlgorithm.cpp scripting/flash/utils/Dictionary.cpp scripting/flash/utils/Proxy.cpp scripting/flash/utils/Timer.cpp @@ -132,6 +133,7 @@ scripting/toplevel/XMLList.cpp scripting/class.cpp scripting/toplevel/toplevel.cpp + scripting/avmplus/avmplus.cpp platforms/engineutils.cpp) IF(MINGW) SET(LIBSPARK_SOURCES ${LIBSPARK_SOURCES} platforms/slowpaths_generic.cpp)
View file
lightspark.tar.xz/src/allclasses.cpp
Changed
@@ -59,6 +59,7 @@ #include "scripting/flash/sensors/flashsensors.h" #include "scripting/flash/utils/flashutils.h" #include "scripting/flash/utils/ByteArray.h" +#include "scripting/flash/utils/CompressionAlgorithm.h" #include "scripting/flash/utils/Dictionary.h" #include "scripting/flash/utils/Proxy.h" #include "scripting/flash/utils/Timer.h" @@ -76,6 +77,7 @@ #include "scripting/flash/ui/ContextMenu.h" #include "scripting/flash/ui/ContextMenuItem.h" #include "scripting/flash/ui/ContextMenuBuiltInItems.h" +#include "scripting/avmplus/avmplus.h" using namespace lightspark;
View file
lightspark.tar.xz/src/allclasses.h
Changed
@@ -273,6 +273,7 @@ //Utils REGISTER_CLASS_NAME(ByteArray,"flash.utils") +REGISTER_CLASS_NAME(CompressionAlgorithm,"flash.utils") REGISTER_CLASS_NAME(Dictionary,"flash.utils") REGISTER_CLASS_NAME(Endian,"flash.utils") REGISTER_CLASS_NAME(IDataInput,"flash.utils") @@ -294,3 +295,9 @@ REGISTER_CLASS_NAME(XMLDocument,"flash.xml") REGISTER_CLASS_NAME(XMLNode,"flash.xml") +//avmplus +REGISTER_CLASS_NAME(avmplusFile,"avmplus") +REGISTER_CLASS_NAME(avmplusSystem,"avmplus") +REGISTER_CLASS_NAME(avmplusDomain,"avmplus") + +
View file
lightspark.tar.xz/src/asobject.cpp
Changed
@@ -384,34 +384,27 @@ return _MR(ret); } -bool ASObject::has_toJSON() -{ - 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.isAttribute = false; - return ASObject::hasPropertyByMultiname(toJSONName, true, true); -} - -tiny_string ASObject::call_toJSON() +tiny_string ASObject::call_toJSON(bool& ok,std::vector<ASObject *> &path, IFunction *replacer, const tiny_string &spaces,const tiny_string& filter) { + tiny_string res; + ok = false; 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.isAttribute = false; - assert(ASObject::hasPropertyByMultiname(toJSONName, true, true)); + if (!ASObject::hasPropertyByMultiname(toJSONName, true, true)) + return res; _NR<ASObject> o=getVariableByMultiname(toJSONName,SKIP_IMPL); - assert_and_throw(o->is<IFunction>()); + if (!o->is<IFunction>()) + return res; + IFunction* f=o->as<IFunction>(); incRef(); ASObject *ret=f->call(this,NULL,0); - tiny_string res; if (ret->is<ASString>()) { res += "\""; @@ -419,8 +412,8 @@ res += "\""; } else - res = ret->toString(); - + res = ret->toJSON(path,replacer,spaces,filter); + ok = true; return res; } @@ -1701,13 +1694,12 @@ tiny_string ASObject::toJSON(std::vector<ASObject *> &path, IFunction *replacer, const tiny_string &spaces,const tiny_string& filter) { - if (has_toJSON()) - { - return call_toJSON(); - } + bool ok; + tiny_string res = call_toJSON(ok,path,replacer,spaces,filter); + if (ok) + return res; tiny_string newline = (spaces.empty() ? "" : "\n"); - tiny_string res; if (this->isPrimitive()) { switch(this->type) @@ -1759,6 +1751,17 @@ case T_UNDEFINED: res += "null"; break; + case T_NUMBER: + case T_INTEGER: + case T_UINTEGER: + { + tiny_string s = this->toString(); + if (s == "Infinity" || s == "-Infinity" || s == "NaN") + res += "null"; + else + res += s; + break; + } default: res += this->toString(); break;
View file
lightspark.tar.xz/src/asobject.h
Changed
@@ -451,8 +451,7 @@ _R<ASObject> call_valueOf(); bool has_toString(); _R<ASObject> call_toString(); - bool has_toJSON(); - tiny_string call_toJSON(); + tiny_string call_toJSON(bool &ok, std::vector<ASObject *> &path, IFunction *replacer, const tiny_string &spaces, const tiny_string &filter); /* Helper function for calling getClass()->getQualifiedClassName() */ virtual tiny_string getClassName() const;
View file
lightspark.tar.xz/src/backends/urlutils.cpp
Changed
@@ -68,6 +68,8 @@ std::string str = std::string(url.raw_buf()); valid = false; + if (u.empty()) + return; //Check for :// marking that there is a protocol in this url size_t colonPos = str.find("://"); @@ -513,14 +515,27 @@ isxdigit(u[i+2]) && isxdigit(u[i+3]) && isxdigit(u[i+4]) && isxdigit(u[i+5])) { - tiny_string s=tiny_string::fromChar((uint32_t)strtoul(u.substr(i+2, 4).c_str(), NULL, 16)); - str.append(s.raw_buf()); + uint32_t c = (uint32_t)strtoul(u.substr(i+2, 4).c_str(), NULL, 16); + if (c == 0) + str.push_back(c); + else + { + tiny_string s=tiny_string::fromChar(c); + str.append(s.raw_buf()); + } i += 5; + } else if(isxdigit(u[i+1]) && isxdigit(u[i+2])) { - tiny_string s=tiny_string::fromChar((uint32_t)strtoul(u.substr(i+1, 2).c_str(), NULL, 16)); - str.append(s.raw_buf()); + uint32_t c = (uint32_t)strtoul(u.substr(i+1, 2).c_str(), NULL, 16); + if (c == 0) + str.push_back(c); + else + { + tiny_string s=tiny_string::fromChar(c); + str.append(s.raw_buf()); + } i += 2; } else
View file
lightspark.tar.xz/src/backends/xml_support.cpp
Changed
@@ -61,7 +61,7 @@ if(!context_->wellFormed) LOG(LOG_ERROR, "XML data not well formed!"); - if (context_->myDoc) + if (context_->wellFormed && context_->myDoc) doc_ = new RecoveryDocument(context_->myDoc); // This is to indicate to release_underlying that we took the // ownership on the doc. @@ -86,13 +86,17 @@ } catch(const exception& e) { + LOG(LOG_ERROR,"xml error: "<<e.what()); } xmlpp::Document* doc=parser.get_document(); if(doc) { + xmlpp::Node *root = NULL; if (!doc->get_root_node()) { - buf = removeWhitespace(str)+"<parent></parent>"; + buf="<parent>"; + buf += str; + buf += "</parent>"; try { parser.parse_memory_raw((const unsigned char*)buf.c_str(), buf.size()); @@ -101,11 +105,33 @@ { } doc=parser.get_document(); + if (doc && doc->get_root_node()) + { + root = doc->get_root_node()->get_first_child(); + } + } + if (!doc || !doc->get_root_node()) + { + try + { + buf="<parent>"; + buf += XMLBase::encodeToXML(str,false); + buf += "</parent>"; + parser.parse_memory_raw((const unsigned char*)buf.c_str(), buf.size()); + } + catch(const exception& e) + { + } + doc=parser.get_document(); + if (doc && doc->get_root_node()) + { + root = doc->get_root_node()->get_first_child(); + } } if (doc && doc->get_root_node()) { *hasParent = true; - xmlpp::Element *root = doc->get_root_node(); + if (root==NULL) root = doc->get_root_node(); // It would be better to remove empty nodes during // parsing, but xmlpp doesn't offer an interface. if (ignoreEmptyTextNodes) @@ -116,6 +142,7 @@ } //If everything fails, create a fake document and add a single text string child // see 10.3.1 in ECMA 357 + if (default_ns.empty()) buf="<parent></parent>"; else @@ -125,8 +152,46 @@ *hasParent = false; return parser.get_document()->get_root_node()->add_child_text(str); } +const tiny_string XMLBase::encodeToXML(const tiny_string value, bool bIsAttribute) +{ + + tiny_string res; + auto it = value.begin(); + while (it != value.end()) + { + switch (*it) + { + case '<': + res += "<"; + break; + case '>': + res += bIsAttribute ? ">" : ">"; + break; + case '&': + res += "&"; + break; + case '\"': + res += bIsAttribute ? """ : "\""; + break; + case '\r': + res += bIsAttribute ? "
" : "\r"; + break; + case '\n': + res += bIsAttribute ? "
" : "\n"; + break; + case '\t': + res += bIsAttribute ? "	" : "\t"; + break; + default: + res += *it; + break; + } + it++; + } + return res; +} -void XMLBase::addDefaultNamespace(xmlpp::Element *root, const string& default_ns) +void XMLBase::addDefaultNamespace(xmlpp::Node *root, const string& default_ns) { if(default_ns.empty() || !root->get_namespace_uri().empty()) return; @@ -190,10 +255,10 @@ string XMLBase::quirkCData(const string& str) { //if this is a CDATA node replace CDATA tags to make it look like a text-node //for compatibility with the Adobe player - if (str.compare(0, 9, "<![CDATA[") == 0) { - return "<a>"+str.substr(9, str.size()-12)+"</a>"; - } - else + //if (str.compare(0, 9, "<![CDATA[") == 0) { + // return "<a>"+str.substr(9, str.size()-12)+"</a>"; + //} + //else return str; } @@ -219,7 +284,7 @@ return buf; } -void XMLBase::removeWhitespaceNodes(xmlpp::Element *node) +void XMLBase::removeWhitespaceNodes(xmlpp::Node *node) { xmlpp::Node::NodeList children = node->get_children(); xmlpp::Node::NodeList::iterator it;
View file
lightspark.tar.xz/src/backends/xml_support.h
Changed
@@ -60,16 +60,17 @@ bool ignoreEmptyTextnodes, bool *hasParent, const std::string& default_ns=std::string()); - void addDefaultNamespace(xmlpp::Element *root, const std::string& default_ns); + void addDefaultNamespace(xmlpp::Node *root, const std::string& default_ns); void addDefaultNamespaceRecursive(xmlNodePtr node, xmlNsPtr ns); // Set the root to be a copy of src. If src is a text node, // create a new element node with the same content. xmlpp::Node* buildCopy(const xmlpp::Node* node, bool *hasParent); static std::string quirkCData(const std::string& str); static std::string quirkXMLDeclarationInMiddle(const std::string& str); - void removeWhitespaceNodes(xmlpp::Element *node); + void removeWhitespaceNodes(xmlpp::Node *node); tiny_string removeWhitespace(tiny_string val); public: + static const tiny_string encodeToXML(const tiny_string value, bool bIsAttribute); static std::string parserQuirks(const std::string& str); };
View file
lightspark.tar.xz/src/main.cpp
Changed
@@ -147,6 +147,8 @@ } else if(strcmp(argv[i],"--air")==0) flashMode=SystemState::AIR; + else if(strcmp(argv[i],"--avmplus")==0) + flashMode=SystemState::AVMPLUS; else if(strcmp(argv[i],"-ni")==0 || strcmp(argv[i],"--disable-interpreter")==0) useInterpreter=false; else if(strcmp(argv[i],"-fi")==0 || strcmp(argv[i],"--enable-fast-interpreter")==0) @@ -242,7 +244,7 @@ LOG(LOG_ERROR, "Usage: " << argv[0] << " [--url|-u http://loader.url/file.swf]" << " [--disable-interpreter|-ni] [--enable-fast-interpreter|-fi] [--enable-jit|-j]" << " [--log-level|-l 0-4] [--parameters-file|-p params-file] [--security-sandbox|-s sandbox]" << - " [--exit-on-error] [--HTTP-cookies cookie] [--air]" << + " [--exit-on-error] [--HTTP-cookies cookie] [--air] [--avmplus]" << #ifdef PROFILING_SUPPORT " [--profiling-output|-o profiling-file]" << #endif
View file
lightspark.tar.xz/src/parsing/amf3_generator.cpp
Changed
@@ -17,16 +17,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. **************************************************************************/ +#include "scripting/abc.h" #include "parsing/amf3_generator.h" #include "scripting/toplevel/toplevel.h" #include "scripting/toplevel/Array.h" #include "scripting/toplevel/ASString.h" +#include "scripting/toplevel/Date.h" #include "scripting/class.h" #include "scripting/flash/xml/flashxml.h" #include "toplevel/XML.h" #include <iostream> #include <fstream> #include "scripting/flash/utils/ByteArray.h" +#include "scripting/flash/utils/Dictionary.h" using namespace std; using namespace lightspark; @@ -65,6 +68,26 @@ return _MR(abstract_d(tmp.val)); } +_R<ASObject> Amf3Deserializer::parseDate() const +{ + union + { + uint64_t dummy; + double val; + } tmp; + uint8_t* tmpPtr=reinterpret_cast<uint8_t*>(&tmp.dummy); + + for(uint32_t i=0;i<8;i++) + { + if(!input->readByte(tmpPtr[i])) + throw ParseException("Not enough data to parse date"); + } + tmp.dummy=GINT64_FROM_BE(tmp.dummy); + Date* dt = Class<Date>::getInstanceS(); + dt->MakeDateFromMilliseconds((int64_t)tmp.val); + return _MR(dt); +} + tiny_string Amf3Deserializer::parseStringVR(std::vector<tiny_string>& stringMap) const { uint32_t strRef; @@ -138,6 +161,190 @@ return ret; } +_R<ASObject> Amf3Deserializer::parseVector(uint8_t marker, std::vector<tiny_string>& stringMap, + std::vector<ASObject*>& objMap, + std::vector<TraitsRef>& traitsMap) const +{ + uint32_t vectorRef; + if(!input->readU29(vectorRef)) + throw ParseException("Not enough data to parse AMF3 vector"); + + if((vectorRef&0x01)==0) + { + //Just a reference + if(objMap.size() <= (vectorRef >> 1)) + throw ParseException("Invalid object reference in AMF3 data"); + ASObject* ret=objMap[vectorRef >> 1]; + ret->incRef(); + return _MR(ret); + } + + uint8_t b; + if (!input->readByte(b)) + throw ParseException("Not enough data to parse AMF3 vector"); + const Type* type =NULL; + switch (marker) + { + case vector_int_marker: + type = Class<Integer>::getClass(); + break; + case vector_uint_marker: + type = Class<UInteger>::getClass(); + break; + case vector_double_marker: + type = Class<Number>::getClass(); + break; + case vector_object_marker: + { + tiny_string vectypename; + vectypename = parseStringVR(stringMap); + multiname m(NULL); + m.name_type=multiname::NAME_STRING; + m.name_s_id=getSys()->getUniqueStringId(vectypename); + m.ns.push_back(nsNameAndKind("",NAMESPACE)); + m.isAttribute = false; + type = Type::getTypeFromMultiname(&m,getVm()->currentCallContext->context); + if (type == NULL) + { + LOG(LOG_ERROR,"unknown vector type during deserialization:"<<m); + type = Class<ASObject>::getClass(); + } + break; + } + default: + LOG(LOG_ERROR,"invalid marker during deserialization of vector:"<<marker); + throw ParseException("invalid marker in AMF3 vector"); + + } + _R<lightspark::Vector> ret=_MR(Template<Vector>::getInstanceS(type)); + //Add object to the map + objMap.push_back(ret.getPtr()); + + + int32_t count = vectorRef >> 1; + + for(int32_t i=0;i<count;i++) + { + switch (marker) + { + case vector_int_marker: + { + uint32_t value = 0; + if (!input->readUnsignedInt(value)) + throw ParseException("Not enough data to parse AMF3 vector"); + ret->append(abstract_i(value)); + break; + } + case vector_uint_marker: + { + uint32_t value = 0; + if (!input->readUnsignedInt(value)) + throw ParseException("Not enough data to parse AMF3 vector"); + ret->append(abstract_ui(value)); + break; + } + case vector_double_marker: + { + _R<ASObject> v = parseDouble(); + v->incRef(); + ret->append(v.getPtr()); + break; + } + case vector_object_marker: + { + _R<ASObject> value=parseValue(stringMap, objMap, traitsMap); + value->incRef(); + ret->append(value.getPtr()); + break; + } + } + } + // set fixed at last to avoid rangeError + ret->setFixed(b == 0x01); + return ret; +} + + +_R<ASObject> Amf3Deserializer::parseDictionary(std::vector<tiny_string>& stringMap, + std::vector<ASObject*>& objMap, + std::vector<TraitsRef>& traitsMap) const +{ + uint32_t dictRef; + if(!input->readU29(dictRef)) + throw ParseException("Not enough data to parse AMF3 dictionary"); + + if((dictRef&0x01)==0) + { + //Just a reference + if(objMap.size() <= (dictRef >> 1)) + throw ParseException("Invalid object reference in AMF3 data"); + ASObject* ret=objMap[dictRef >> 1]; + ret->incRef(); + return _MR(ret); + } + + uint8_t weakkeys; + if (!input->readByte(weakkeys)) + throw ParseException("Not enough data to parse AMF3 vector"); + if (weakkeys) + LOG(LOG_NOT_IMPLEMENTED,"handling of weak keys in Dictionary"); + _R<Dictionary> ret=_MR(Class<Dictionary>::getInstanceS()); + //Add object to the map + objMap.push_back(ret.getPtr()); + + + int32_t count = dictRef >> 1; + + for(int32_t i=0;i<count;i++) + { + _R<ASObject> key=parseValue(stringMap, objMap, traitsMap); + _R<ASObject> value=parseValue(stringMap, objMap, traitsMap); + multiname name(NULL); + name.name_type=multiname::NAME_OBJECT; + name.name_o = key.getPtr(); + name.ns.push_back(nsNameAndKind("",NAMESPACE)); + key->incRef(); + value->incRef(); + ret->setVariableByMultiname(name,value.getPtr(),ASObject::CONST_ALLOWED); + } + return ret; +} +
View file
lightspark.tar.xz/src/parsing/amf3_generator.h
Changed
@@ -46,8 +46,14 @@ xml_doc_marker = 0x7, date_marker = 0x8, array_marker = 0x9, - object_marker = 0xa, - xml_marker = 0xb + object_marker = 0xA, + xml_marker = 0xB, + byte_array_marker = 0x0C, + vector_int_marker = 0x0D, + vector_uint_marker = 0x0E, + vector_double_marker = 0x0F, + vector_object_marker = 0x10, + dictionary_marker = 0x11 }; enum amf0_markers_type @@ -93,11 +99,21 @@ _R<ASObject> parseArray(std::vector<tiny_string>& stringMap, std::vector<ASObject*>& objMap, std::vector<TraitsRef>& traitsMap) const; + _R<ASObject> parseVector(uint8_t marker, std::vector<tiny_string>& stringMap, + std::vector<ASObject*>& objMap, + std::vector<TraitsRef>& traitsMap) const; + _R<ASObject> parseDictionary(std::vector<tiny_string>& stringMap, + std::vector<ASObject*>& objMap, + std::vector<TraitsRef>& traitsMap) const; + _R<ASObject> parseByteArray(std::vector<tiny_string>& stringMap, + std::vector<ASObject*>& objMap, + std::vector<TraitsRef>& traitsMap) const; _R<ASObject> parseValue(std::vector<tiny_string>& stringMap, std::vector<ASObject*>& objMap, std::vector<TraitsRef>& traitsMap) const; _R<ASObject> parseInteger() const; _R<ASObject> parseDouble() const; + _R<ASObject> parseDate() const; _R<ASObject> parseXML(std::vector<ASObject*>& objMap, bool legacyXML) const;
View file
lightspark.tar.xz/src/scripting/abc.cpp
Changed
@@ -101,6 +101,7 @@ #include "scripting/flash/system/flashsystem.h" #include "scripting/flash/sensors/flashsensors.h" #include "scripting/flash/utils/flashutils.h" +#include "scripting/flash/utils/CompressionAlgorithm.h" #include "scripting/flash/utils/Dictionary.h" #include "scripting/flash/utils/Proxy.h" #include "scripting/flash/utils/Timer.h" @@ -116,6 +117,7 @@ #include "scripting/flash/ui/ContextMenu.h" #include "scripting/flash/ui/ContextMenuItem.h" #include "scripting/flash/ui/ContextMenuBuiltInItems.h" +#include "scripting/avmplus/avmplus.h" #include "scripting/class.h" #include "exceptions.h" #include "scripting/abc.h" @@ -376,6 +378,7 @@ builtin->registerBuiltin("Endian","flash.utils",Class<Endian>::getRef()); builtin->registerBuiltin("ByteArray","flash.utils",Class<ByteArray>::getRef()); + builtin->registerBuiltin("CompressionAlgorithm","flash.utils",Class<CompressionAlgorithm>::getRef()); builtin->registerBuiltin("Dictionary","flash.utils",Class<Dictionary>::getRef()); builtin->registerBuiltin("Proxy","flash.utils",Class<Proxy>::getRef()); builtin->registerBuiltin("Timer","flash.utils",Class<Timer>::getRef()); @@ -508,7 +511,6 @@ builtin->registerBuiltin("isFinite","",_MR(Class<IFunction>::getFunction(isFinite,1))); builtin->registerBuiltin("isXMLName","",_MR(Class<IFunction>::getFunction(_isXMLName))); - //If needed add AIR definitions if(getSys()->flashMode==SystemState::AIR) { @@ -519,6 +521,32 @@ builtin->registerBuiltin("FileStream","flash.filesystem",Class<FileStream>::getRef()); } + // if needed add AVMPLUS definitions + if(getSys()->flashMode==SystemState::AVMPLUS) + { + builtin->registerBuiltin("getQualifiedClassName","avmplus",_MR(Class<IFunction>::getFunction(getQualifiedClassName))); + builtin->registerBuiltin("getQualifiedSuperclassName","avmplus",_MR(Class<IFunction>::getFunction(getQualifiedSuperclassName))); + builtin->registerBuiltin("getTimer","",_MR(Class<IFunction>::getFunction(getTimer))); + builtin->registerBuiltin("FLASH10_FLAGS","avmplus",_MR(abstract_ui(0x7FF))); + builtin->registerBuiltin("describeType","avmplus",_MR(Class<IFunction>::getFunction(describeType))); + + builtin->registerBuiltin("System","avmplus",Class<avmplusSystem>::getRef()); + builtin->registerBuiltin("Domain","avmplus",Class<avmplusDomain>::getRef()); + builtin->registerBuiltin("File","avmplus",Class<avmplusFile>::getRef()); + + builtin->registerBuiltin("AbstractBase","avmshell",Class<ASObject>::getRef()); + builtin->registerBuiltin("AbstractRestrictedBase","avmshell",Class<ASObject>::getRef()); + builtin->registerBuiltin("NativeBase","avmshell",Class<ASObject>::getRef()); + builtin->registerBuiltin("NativeBaseAS3","avmshell",Class<ASObject>::getRef()); + builtin->registerBuiltin("NativeSubclassOfAbstractBase","avmshell",Class<ASObject>::getRef()); + builtin->registerBuiltin("NativeSubclassOfAbstractRestrictedBase","avmshell",Class<ASObject>::getRef()); + builtin->registerBuiltin("NativeSubclassOfRestrictedBase","avmshell",Class<ASObject>::getRef()); + builtin->registerBuiltin("RestrictedBase","avmshell",Class<ASObject>::getRef()); + builtin->registerBuiltin("SubclassOfAbstractBase","avmshell",Class<ASObject>::getRef()); + builtin->registerBuiltin("SubclassOfAbstractRestrictedBase","avmshell",Class<ASObject>::getRef()); + builtin->registerBuiltin("SubclassOfRestrictedBase","avmshell",Class<ASObject>::getRef()); + } + Class_object::getRef()->getClass()->prototype = _MNR(new_objectPrototype()); Class_object::getRef()->getClass()->initStandardProps(); @@ -1387,7 +1415,7 @@ derived_class_tmp->bindToTag(t); } -inline method_info* ABCContext::get_method(unsigned int m) +method_info* ABCContext::get_method(unsigned int m) { if(m<method_count) return &methods[m]; @@ -2038,7 +2066,7 @@ { multiname* mname=getMultiname(t->name,NULL); //Should be a Qname - assert_and_throw(mname->ns.size()==1 && mname->name_type==multiname::NAME_STRING); + assert_and_throw(mname->name_type==multiname::NAME_STRING); if(t->kind>>4) LOG(LOG_CALLS,_("Next slot has flags ") << (t->kind>>4));
View file
lightspark.tar.xz/src/scripting/abc.h
Changed
@@ -256,28 +256,49 @@ _R<ApplicationDomain> appDomain = getCurrentApplicationDomain(th); appDomain->writeToDomainMemory<T>(addr, val); } + static void loadFloat(call_context* th) + { + ASObject* arg1=th->runtime_stack_pop(); + float addr=arg1->toNumber(); + arg1->decRef(); + _R<ApplicationDomain> appDomain = getCurrentApplicationDomain(th); + number_t ret=appDomain->readFromDomainMemory<float>(addr); + th->runtime_stack_push(abstract_d(ret)); + } - static void loadNumber(call_context* th) + static void loadDouble(call_context* th) { ASObject* arg1=th->runtime_stack_pop(); - number_t addr=arg1->toNumber(); + double addr=arg1->toNumber(); arg1->decRef(); _R<ApplicationDomain> appDomain = getCurrentApplicationDomain(th); - number_t ret=appDomain->readFromDomainMemory<number_t>(addr); + number_t ret=appDomain->readFromDomainMemory<double>(addr); th->runtime_stack_push(abstract_d(ret)); } - static void storeNumber(call_context* th) + static void storeFloat(call_context* th) + { + ASObject* arg1=th->runtime_stack_pop(); + ASObject* arg2=th->runtime_stack_pop(); + number_t addr=arg1->toNumber(); + arg1->decRef(); + float val=(float)arg2->toNumber(); + arg2->decRef(); + _R<ApplicationDomain> appDomain = getCurrentApplicationDomain(th); + appDomain->writeToDomainMemory<float>(addr, val); + } + static void storeDouble(call_context* th) { ASObject* arg1=th->runtime_stack_pop(); ASObject* arg2=th->runtime_stack_pop(); number_t addr=arg1->toNumber(); arg1->decRef(); - number_t val=arg2->toNumber(); + double val=arg2->toNumber(); arg2->decRef(); _R<ApplicationDomain> appDomain = getCurrentApplicationDomain(th); - appDomain->writeToDomainMemory<number_t>(addr, val); + appDomain->writeToDomainMemory<double>(addr, val); } + static void callStatic(call_context* th, int n, int m, method_info** called_mi, bool keepReturn); static void callSuper(call_context* th, int n, int m, method_info** called_mi, bool keepReturn); static void callProperty(call_context* th, int n, int m, method_info** called_mi, bool keepReturn); static void callImpl(call_context* th, ASObject* f, ASObject* obj, ASObject** args, int m, method_info** called_mi, bool keepReturn);
View file
lightspark.tar.xz/src/scripting/abc_fast_interpreter.cpp
Changed
@@ -575,14 +575,14 @@ { //lf32 LOG(LOG_CALLS, "lf32"); - loadNumber(context); + loadFloat(context); break; } case 0x39: { //lf32 LOG(LOG_CALLS, "lf64"); - loadNumber(context); + loadDouble(context); break; } case 0x3a: @@ -606,6 +606,20 @@ storeIntN<uint32_t>(context); break; } + case 0x3d: + { + //sf32 + LOG(LOG_CALLS, "sf32"); + storeFloat(context); + break; + } + case 0x3e: + { + //sf32 + LOG(LOG_CALLS, "sf64"); + storeDouble(context); + break; + } case 0x40: { //newfunction @@ -634,6 +648,20 @@ instructionPointer+=4; break; } + case 0x44: + { + //callstatic + uint32_t t=data->uints[0]; + uint32_t t2=data->uints[1]; + method_info* called_mi=NULL; + PROF_ACCOUNT_TIME(mi->profTime[instructionPointer],profilingCheckpoint(startTime)); + callStatic(context,t,t2,&called_mi,true); + if(called_mi) + PROF_ACCOUNT_TIME(mi->profCalls[called_mi],profilingCheckpoint(startTime)); + else + PROF_IGNORE_TIME(profilingCheckpoint(startTime)); + break; + } case 0x45: { //callsuper @@ -726,6 +754,36 @@ instructionPointer+=8; break; } + case 0x50: + { + //sxi1 + LOG(LOG_CALLS, "sxi1"); + ASObject* arg1=context->runtime_stack_pop(); + int32_t ret=arg1->toUInt() & 0x1; + arg1->decRef(); + context->runtime_stack_push(abstract_i(ret)); + break; + } + case 0x51: + { + //sxi8 + LOG(LOG_CALLS, "sxi8"); + ASObject* arg1=context->runtime_stack_pop(); + int32_t ret=(int8_t)arg1->toUInt(); + arg1->decRef(); + context->runtime_stack_push(abstract_i(ret)); + break; + } + case 0x52: + { + //sxi16 + LOG(LOG_CALLS, "sxi16"); + ASObject* arg1=context->runtime_stack_pop(); + int32_t ret=(int16_t)arg1->toUInt(); + arg1->decRef(); + context->runtime_stack_push(abstract_i(ret)); + break; + } case 0x53: { //constructgenerictype @@ -841,7 +899,7 @@ LOG(LOG_CALLS, _("setLocal ") << i ); ASObject* obj=context->runtime_stack_pop(); assert_and_throw(obj); - if ((int)i != context->argarrayposition) + if ((int)i != context->argarrayposition || obj->is<Array>()) { if(context->locals[i]) context->locals[i]->decRef(); @@ -1445,7 +1503,7 @@ int i=opcode&3; LOG(LOG_CALLS, "setLocal " << i ); ASObject* obj=context->runtime_stack_pop(); - if ((int)i != context->argarrayposition) + if ((int)i != context->argarrayposition || obj->is<Array>()) { if(context->locals[i]) context->locals[i]->decRef();
View file
lightspark.tar.xz/src/scripting/abc_interpreter.cpp
Changed
@@ -673,14 +673,14 @@ { //lf32 LOG(LOG_CALLS, "lf32"); - loadNumber(context); + loadFloat(context); break; } case 0x39: { //lf32 LOG(LOG_CALLS, "lf64"); - loadNumber(context); + loadDouble(context); break; } case 0x3a: @@ -708,14 +708,14 @@ { //sf32 LOG(LOG_CALLS, "sf32"); - storeNumber(context); + storeFloat(context); break; } case 0x3e: { //sf32 LOG(LOG_CALLS, "sf64"); - storeNumber(context); + storeDouble(context); break; } case 0x40: @@ -748,6 +748,21 @@ construct(context,t); break; } + case 0x44: + { + //callstatic + u30 t,t2; + code >> t; + code >> t2; + method_info* called_mi=NULL; + PROF_ACCOUNT_TIME(mi->profTime[instructionPointer],profilingCheckpoint(startTime)); + callStatic(context,t,t2,&called_mi,true); + if(called_mi) + PROF_ACCOUNT_TIME(mi->profCalls[called_mi],profilingCheckpoint(startTime)); + else + PROF_IGNORE_TIME(profilingCheckpoint(startTime)); + break; + } case 0x45: { //callsuper @@ -841,6 +856,36 @@ PROF_IGNORE_TIME(profilingCheckpoint(startTime)); break; } + case 0x50: + { + //sxi1 + LOG(LOG_CALLS, "sxi1"); + ASObject* arg1=context->runtime_stack_pop(); + int32_t ret=arg1->toUInt() >>31; + arg1->decRef(); + context->runtime_stack_push(abstract_i(ret)); + break; + } + case 0x51: + { + //sxi8 + LOG(LOG_CALLS, "sxi8"); + ASObject* arg1=context->runtime_stack_pop(); + int32_t ret=(int8_t)arg1->toUInt(); + arg1->decRef(); + context->runtime_stack_push(abstract_i(ret)); + break; + } + case 0x52: + { + //sxi16 + LOG(LOG_CALLS, "sxi16"); + ASObject* arg1=context->runtime_stack_pop(); + int32_t ret=(int16_t)arg1->toUInt(); + arg1->decRef(); + context->runtime_stack_push(abstract_i(ret)); + break; + } case 0x53: { //constructgenerictype @@ -962,7 +1007,7 @@ LOG(LOG_CALLS, _("setLocal ") << i ); ASObject* obj=context->runtime_stack_pop(); assert_and_throw(obj); - if ((int)i != context->argarrayposition) + if ((int)i != context->argarrayposition || obj->is<Array>()) { if(context->locals[i]) context->locals[i]->decRef(); @@ -1005,8 +1050,8 @@ u30 t; code >> t; ASObject* value=context->runtime_stack_pop(); - multiname* name=context->context->getMultiname(t,context); - ASObject* obj=context->runtime_stack_pop(); + multiname* name=context->context->getMultiname(t,context); + ASObject* obj=context->runtime_stack_pop(); initProperty(obj,value,name); name->resetNameIfObject(); break; @@ -1554,7 +1599,7 @@ int i=opcode&3; LOG(LOG_CALLS, _("setLocal ") << i); ASObject* obj=context->runtime_stack_pop(); - if ((int)i != context->argarrayposition) + if ((int)i != context->argarrayposition || obj->is<Array>()) { if(context->locals[i]) context->locals[i]->decRef();
View file
lightspark.tar.xz/src/scripting/abc_opcodes.cpp
Changed
@@ -398,7 +398,10 @@ throwError<ReferenceError>(kWriteOnlyError, name->normalizedName(), obj->getClass()->getQualifiedClassName()); if (obj->getClass() && obj->getClass()->isSealed) throwError<ReferenceError>(kReadSealedError, name->normalizedName(), obj->getClass()->getQualifiedClassName()); - throwError<TypeError>(kCallNotFoundError, name->qualifiedString(), obj->getClassName()); + if (obj->is<Class_base>()) + throwError<TypeError>(kCallNotFoundError, name->qualifiedString(), obj->as<Class_base>()->class_name.getQualifiedName()); + else + throwError<TypeError>(kCallNotFoundError, name->qualifiedString(), obj->getClassName()); if(keepReturn) th->runtime_stack_push(getSys()->getUndefinedRef()); @@ -433,7 +436,7 @@ ASObject* ABCVm::getProperty(ASObject* obj, multiname* name) { - LOG(LOG_CALLS, _("getProperty ") << *name << ' ' << obj << ' '<<obj->isInitialized()); + LOG(LOG_CALLS, _("getProperty ") << *name << ' ' << obj->toDebugString() << ' '<<obj->isInitialized()); checkDeclaredTraits(obj); _NR<ASObject> prop=obj->getVariableByMultiname(*name); @@ -447,8 +450,8 @@ throwError<ReferenceError>(kReadSealedErrorNs, name->normalizedNameUnresolved(), obj->getClassName()); if (obj->is<Undefined>()) throwError<TypeError>(kConvertUndefinedToObjectError); - if (Log::getLevel() >= LOG_NOT_IMPLEMENTED && obj->getClassName() != "Object") - LOG(LOG_NOT_IMPLEMENTED,"getProperty: " << name->normalizedNameUnresolved() << " not found on " << obj->toDebugString()); + if (Log::getLevel() >= LOG_NOT_IMPLEMENTED && (!obj->getClass() || obj->getClass()->isSealed)) + LOG(LOG_NOT_IMPLEMENTED,"getProperty: " << name->normalizedNameUnresolved() << " not found on " << obj->toDebugString() << " "<<obj->getClassName()); ret = getSys()->getUndefinedRef(); } else @@ -1558,6 +1561,44 @@ obj->decRef(); } +void ABCVm::callStatic(call_context* th, int n, int m, method_info** called_mi, bool keepReturn) +{ + ASObject** args=g_newa(ASObject*, m); + for(int i=0;i<m;i++) + args[m-i-1]=th->runtime_stack_pop(); + + ASObject* obj=th->runtime_stack_pop(); + if(obj->is<Null>()) + { + LOG(LOG_ERROR,"trying to callStatic on null"); + throwError<TypeError>(kConvertNullToObjectError); + } + if (obj->is<Undefined>()) + { + LOG(LOG_ERROR,"trying to callStatic on undefined"); + throwError<TypeError>(kConvertUndefinedToObjectError); + } + method_info* mi = th->context->get_method(n); + assert_and_throw(mi); + SyntheticFunction* f=Class<IFunction>::getSyntheticFunction(mi); + + if(f) + { + f->incRef(); + callImpl(th, f, obj, args, m, called_mi, keepReturn); + } + else + { + obj->decRef(); + for(int i=0;i<m;i++) + args[i]->decRef(); + throwError<ReferenceError>(kCallNotFoundError, "?", obj->getClassName()); + if(keepReturn) + th->runtime_stack_push(getSys()->getUndefinedRef()); + } + LOG(LOG_CALLS,"End of callStatic "); +} + void ABCVm::callSuper(call_context* th, int n, int m, method_info** called_mi, bool keepReturn) { ASObject** args=g_newa(ASObject*, m); @@ -1785,6 +1826,9 @@ bool ABCVm::in(ASObject* val2, ASObject* val1) { LOG(LOG_CALLS, _("in") ); + if(val2->is<Null>()) + throwError<TypeError>(kConvertNullToObjectError); + multiname name(NULL); name.name_type=multiname::NAME_OBJECT; //Acquire the reference @@ -1826,6 +1870,11 @@ for(int i=0;i<m;++i) args[i]->decRef(); obj->decRef(); + if (obj->is<Undefined>()) + throwError<TypeError>(kConvertUndefinedToObjectError); + if (obj->isPrimitive()) + throwError<TypeError>(kConstructOfNonFunctionError); + throwError<ReferenceError>(kUndefinedVarError, name->normalizedNameUnresolved()); } @@ -1940,7 +1989,7 @@ { multiname callPropertyName(NULL); callPropertyName.name_type=multiname::NAME_STRING; - callPropertyName.name_s_id=getSys()->getUniqueStringId("callProperty"); + callPropertyName.name_s_id=getSys()->getUniqueStringId("getDescendants"); callPropertyName.ns.push_back(nsNameAndKind(flash_proxy,NAMESPACE)); _NR<ASObject> o=obj->getVariableByMultiname(callPropertyName,ASObject::SKIP_IMPL); @@ -1950,17 +1999,16 @@ IFunction* f=static_cast<IFunction*>(o.getPtr()); //Create a new array - ASObject** proxyArgs=g_newa(ASObject*, 2); - proxyArgs[0]=Class<ASString>::getInstanceS("descendants"); + ASObject** proxyArgs=g_newa(ASObject*, 1); ASObject* namearg = Class<ASString>::getInstanceS(name->normalizedName()); namearg->setProxyProperty(*name); - proxyArgs[1]=namearg; + proxyArgs[0]=namearg; //We now suppress special handling - LOG(LOG_CALLS,_("Proxy::callProperty")); + LOG(LOG_CALLS,_("Proxy::getDescendants")); f->incRef(); obj->incRef(); - ASObject* ret=f->call(obj,proxyArgs,2); + ASObject* ret=f->call(obj,proxyArgs,1); f->decRef(); th->runtime_stack_push(ret); @@ -2177,7 +2225,7 @@ #ifdef PROFILING_SUPPORT if(!constructor->validProfName) { - constructor->profName=mname->name_s+"::__CONSTRUCTOR__"; + constructor->profName=mname->normalizedName()+"::__CONSTRUCTOR__"; constructor->validProfName=true; } #endif @@ -2482,9 +2530,6 @@ */ bool ABCVm::instanceOf(ASObject* value, ASObject* type) { - if(value->is<Null>()) - return false; - if(type->is<IFunction>()) { IFunction* t=static_cast<IFunction*>(type); @@ -2504,6 +2549,10 @@ if(!type->is<Class_base>()) throwError<TypeError>(kCantUseInstanceofOnNonObjectError); + if(value->is<Null>()) + return false; + + if(value->is<Class_base>()) // Classes are instance of Class and Object but not // itself or super classes
View file
lightspark.tar.xz/src/scripting/avmplus
Added
+(directory)
View file
lightspark.tar.xz/src/scripting/avmplus/avmplus.cpp
Added
@@ -0,0 +1,223 @@ +/************************************************************************** + Lightspark, a free flash player implementation + + Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +**************************************************************************/ + +#include "scripting/avmplus/avmplus.h" +#include "scripting/flash/utils/ByteArray.h" +#include "scripting/class.h" +#include "scripting/argconv.h" + +using namespace lightspark; + +avmplusFile::avmplusFile(Class_base* c): + ASObject(c) +{ +} + +void avmplusFile::sinit(Class_base* c) +{ + CLASS_SETUP_NO_CONSTRUCTOR(c, ASObject, CLASS_SEALED); + c->setDeclaredMethodByQName("exists","",Class<IFunction>::getFunction(exists),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("read","",Class<IFunction>::getFunction(read),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("write","",Class<IFunction>::getFunction(write),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("readByteArray","",Class<IFunction>::getFunction(readByteArray),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("writeByteArray","",Class<IFunction>::getFunction(writeByteArray),NORMAL_METHOD,false); +} + +ASFUNCTIONBODY(avmplusFile,exists) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.File.exists is unimplemented.")); + return NULL; +} +ASFUNCTIONBODY(avmplusFile,read) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.File.read is unimplemented.")); + return NULL; +} +ASFUNCTIONBODY(avmplusFile,write) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.File.write is unimplemented.")); + return NULL; +} +ASFUNCTIONBODY(avmplusFile,readByteArray) +{ + avmplusFile* th=static_cast<avmplusFile*>(obj); + tiny_string filename; + ARG_UNPACK(filename); + + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.File.readByteArray is unimplemented.")); + return Class<ByteArray>::getInstanceS(); +} +ASFUNCTIONBODY(avmplusFile,writeByteArray) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.File.writeByteArray is unimplemented.")); + return NULL; +} + +avmplusSystem::avmplusSystem(Class_base* c): + ASObject(c) +{ +} + +void avmplusSystem::sinit(Class_base* c) +{ + CLASS_SETUP_NO_CONSTRUCTOR(c, ASObject, CLASS_SEALED); + c->setDeclaredMethodByQName("getFeatures","",Class<IFunction>::getFunction(getFeatures),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("queueCollection","",Class<IFunction>::getFunction(queueCollection),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("forceFullCollection","",Class<IFunction>::getFunction(forceFullCollection),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("getAvmplusVersion","",Class<IFunction>::getFunction(getAvmplusVersion),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("pauseForGCIfCollectionImminent","",Class<IFunction>::getFunction(pauseForGCIfCollectionImminent),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("getRunmode","",Class<IFunction>::getFunction(getRunmode),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("isDebugger","",Class<IFunction>::getFunction(isDebugger),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("isGlobal","",Class<IFunction>::getFunction(isGlobal),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("freeMemory","",Class<IFunction>::getFunction(_freeMemory),GETTER_METHOD,false); + c->setDeclaredMethodByQName("totalMemory","",Class<IFunction>::getFunction(_totalMemory),GETTER_METHOD,false); + c->setDeclaredMethodByQName("privateMemory","",Class<IFunction>::getFunction(_privateMemory),GETTER_METHOD,false); + c->setDeclaredMethodByQName("argv","",Class<IFunction>::getFunction(argv),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("exec","",Class<IFunction>::getFunction(exec),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("write","",Class<IFunction>::getFunction(write),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("exit","",Class<IFunction>::getFunction(exit),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("trace","",Class<IFunction>::getFunction(lightspark::trace),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("canonicalizeNumber","",Class<IFunction>::getFunction(canonicalizeNumber),NORMAL_METHOD,false); +} + +ASFUNCTIONBODY(avmplusSystem,getFeatures) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.getFeatures is unimplemented.")); + return Class<ASString>::getInstanceS(""); +} +ASFUNCTIONBODY(avmplusSystem,getRunmode) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.getRunmode is unimplemented.")); + return Class<ASString>::getInstanceS("jit"); +} + +ASFUNCTIONBODY(avmplusSystem,queueCollection) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.queueCollection is unimplemented.")); + return NULL; +} + +ASFUNCTIONBODY(avmplusSystem,forceFullCollection) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.forceFullCollection is unimplemented.")); + return NULL; +} + +ASFUNCTIONBODY(avmplusSystem,getAvmplusVersion) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.getAvmplusVersion is unimplemented.")); + return Class<ASString>::getInstanceS("0"); +} +ASFUNCTIONBODY(avmplusSystem,pauseForGCIfCollectionImminent) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.pauseForGCIfCollectionImminent is unimplemented.")); + return NULL; +} + +ASFUNCTIONBODY(avmplusSystem,isDebugger) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.isDebugger is unimplemented.")); + return abstract_b(false); +} +ASFUNCTIONBODY(avmplusSystem,isGlobal) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.isDebugger is unimplemented.")); + return abstract_b(false); +} +ASFUNCTIONBODY(avmplusSystem,_freeMemory) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.freeMemory is unimplemented.")); + return abstract_d(1024); +} +ASFUNCTIONBODY(avmplusSystem,_totalMemory) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.totalMemory is unimplemented.")); + return abstract_d(1024); +} +ASFUNCTIONBODY(avmplusSystem,_privateMemory) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.privateMemory is unimplemented.")); + return abstract_d(1024); +} +ASFUNCTIONBODY(avmplusSystem,argv) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.argv is unimplemented.")); + return Class<Array>::getInstanceS(); +} +ASFUNCTIONBODY(avmplusSystem,exec) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.exec is unimplemented.")); + return NULL; +} +ASFUNCTIONBODY(avmplusSystem,write) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.write is unimplemented.")); + return NULL; +} +ASFUNCTIONBODY(avmplusSystem,exit) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.exit is unimplemented.")); + return NULL; +} +ASFUNCTIONBODY(avmplusSystem,canonicalizeNumber) +{ + LOG(LOG_NOT_IMPLEMENTED, _("avmplus.System.canonicalizeNumber is unimplemented.")); + _NR<ASObject> o; + ARG_UNPACK(o); + o->incRef(); + return o.getPtr(); +} + +avmplusDomain::avmplusDomain(Class_base* c): + ApplicationDomain(c) +{ + domainMemory->setLength(0); +} + +void avmplusDomain::sinit(Class_base* c) +{ + CLASS_SETUP(c, ApplicationDomain,_constructor, CLASS_SEALED); + c->setDeclaredMethodByQName("currentDomain","",Class<IFunction>::getFunction(_getCurrentDomain),GETTER_METHOD,false); + c->setDeclaredMethodByQName("MIN_DOMAIN_MEMORY_LENGTH","",Class<IFunction>::getFunction(_getMinDomainMemoryLength),GETTER_METHOD,false); + c->setDeclaredMethodByQName("load","",Class<IFunction>::getFunction(load),NORMAL_METHOD,true); + c->setDeclaredMethodByQName("loadBytes","",Class<IFunction>::getFunction(load),NORMAL_METHOD,true);
View file
lightspark.tar.xz/src/scripting/avmplus/avmplus.h
Added
@@ -0,0 +1,76 @@ +/************************************************************************** + Lightspark, a free flash player implementation + + Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +**************************************************************************/ + +#ifndef SCRIPTING_AVMPLUS_AVMPLUS_H +#define SCRIPTING_AVMPLUS_AVMPLUS_H 1 + +#include "asobject.h" +#include "scripting/flash/system/flashsystem.h" + +namespace lightspark +{ + +class avmplusFile : public ASObject +{ +public: + avmplusFile(Class_base* c); + static void sinit(Class_base*); + ASFUNCTION(exists); + ASFUNCTION(read); + ASFUNCTION(write); + ASFUNCTION(readByteArray); + ASFUNCTION(writeByteArray); +}; + +class avmplusSystem : public ASObject +{ +public: + avmplusSystem(Class_base* c); + static void sinit(Class_base*); + ASFUNCTION(getFeatures); + ASFUNCTION(queueCollection); + ASFUNCTION(forceFullCollection); + ASFUNCTION(getAvmplusVersion); + ASFUNCTION(pauseForGCIfCollectionImminent); + ASFUNCTION(getRunmode); + ASFUNCTION(isDebugger); + ASFUNCTION(isGlobal); + ASFUNCTION(_freeMemory); + ASFUNCTION(_totalMemory); + ASFUNCTION(_privateMemory); + ASFUNCTION(argv); + ASFUNCTION(exec); + ASFUNCTION(write); + ASFUNCTION(exit); + ASFUNCTION(canonicalizeNumber); +}; + +class avmplusDomain : public ApplicationDomain +{ +public: + avmplusDomain(Class_base* c); + static void sinit(Class_base*); + ASFUNCTION(_constructor); + ASFUNCTION(load); + ASFUNCTION(loadBytes); + ASFUNCTION(getClass); +}; + +} +#endif /* SCRIPTING_AVMPLUS_AVMPLUS_H */
View file
lightspark.tar.xz/src/scripting/class.h
Changed
@@ -381,7 +381,7 @@ o->decRef(); return getSys()->getNullRef(); } - else if ((o->is<Vector>() && o->as<Vector>()->sameType(this->class_name)) || + else if ((o->is<Vector>() && o->as<Vector>()->sameType(this)) || o->is<Null>()) { // Vector.<x> can be coerced to Vector.<y>
View file
lightspark.tar.xz/src/scripting/flash/net/flashnet.cpp
Changed
@@ -398,11 +398,13 @@ { //Send a complete event for this object loader->setData(data); + loader->incRef(); getVm()->addEvent(loader,_MR(Class<Event>::getInstanceS("complete"))); } else if(!success && !threadAborting) { //Notify an error during loading + loader->incRef(); getVm()->addEvent(loader,_MR(Class<IOErrorEvent>::getInstanceS())); } @@ -1538,8 +1540,11 @@ } if (frameRate) { - this->bufferLength = (framesdecoded / frameRate) - (streamTime-prevstreamtime)/1000.0; this->playbackBytesPerSecond = s.tellg() / (framesdecoded / frameRate); + // TODO this overrides the real number of decoded frames + // otherwise on slow computers we never get the buffer filled + framesdecoded = (this->getReceivedLength() / this->playbackBytesPerSecond) * frameRate; + this->bufferLength = (framesdecoded / frameRate) - (streamTime-prevstreamtime)/1000.0; } countermutex.unlock(); }
View file
lightspark.tar.xz/src/scripting/flash/system/flashsystem.cpp
Changed
@@ -63,7 +63,15 @@ ASFUNCTIONBODY(Capabilities,_getPlayerType) { - return Class<ASString>::getInstanceS("PlugIn"); + switch (getSys()->flashMode) + { + case SystemState::AVMPLUS: + return Class<ASString>::getInstanceS("AVMPlus"); + case SystemState::AIR: + return Class<ASString>::getInstanceS("Desktop"); + default: + return Class<ASString>::getInstanceS("PlugIn"); + } } ASFUNCTIONBODY(Capabilities,_getLanguage) @@ -110,7 +118,7 @@ ASFUNCTIONBODY(Capabilities,_getServerString) { LOG(LOG_NOT_IMPLEMENTED,"Capabilities: not all capabilities are reported in ServerString"); - tiny_string res = "A=t&SA=t&SV=t&MP3=t&OS=Linux&PT=PlugIn&L=en&TLS=t"; + tiny_string res = "A=t&SA=t&SV=t&MP3=t&OS=Linux&PT=PlugIn&L=en&TLS=t&DD=t"; res +="&V="; res += EMULATED_VERSION; res +="&M="; @@ -596,11 +604,17 @@ { CLASS_SETUP(c, EventDispatcher, _constructorNotInstantiatable, CLASS_SEALED | CLASS_FINAL); c->setDeclaredMethodByQName("current","",Class<IFunction>::getFunction(_getCurrent),GETTER_METHOD,false); + c->setDeclaredMethodByQName("getSharedProperty","",Class<IFunction>::getFunction(getSharedProperty),NORMAL_METHOD,true); } ASFUNCTIONBODY(ASWorker,_getCurrent) { LOG(LOG_NOT_IMPLEMENTED, "Worker not implemented"); return Class<ASObject>::getInstanceS(); } +ASFUNCTIONBODY(ASWorker,getSharedProperty) +{ + LOG(LOG_NOT_IMPLEMENTED, "Worker.getSharedProperty not implemented"); + return Class<ASObject>::getInstanceS(); +}
View file
lightspark.tar.xz/src/scripting/flash/system/flashsystem.h
Changed
@@ -88,10 +88,10 @@ T readFromDomainMemory(uint32_t addr) const { if(domainMemory.isNull()) - throw RunTimeException("No memory domain is set"); + return 0; uint32_t bufLen=domainMemory->getLength(); if(bufLen < (addr+sizeof(T))) - throw RunTimeException("Memory domain access is out of bounds"); + throwError<RangeError>(kInvalidRangeError); uint8_t* buf=domainMemory->getBuffer(bufLen, false); return *reinterpret_cast<T*>(buf+addr); } @@ -99,10 +99,10 @@ void writeToDomainMemory(uint32_t addr, T val) { if(domainMemory.isNull()) - throw RunTimeException("No memory domain is set"); + return; uint32_t bufLen=domainMemory->getLength(); if(bufLen < (addr+sizeof(T))) - throw RunTimeException("Memory domain access is out of bounds"); + throwError<RangeError>(kInvalidRangeError); uint8_t* buf=domainMemory->getBuffer(bufLen, false); *reinterpret_cast<T*>(buf+addr)=val; } @@ -165,6 +165,7 @@ ASWorker(Class_base* c); static void sinit(Class_base*); ASFUNCTION(_getCurrent); + ASFUNCTION(getSharedProperty); }; }
View file
lightspark.tar.xz/src/scripting/flash/utils/ByteArray.cpp
Changed
@@ -105,7 +105,7 @@ REGISTER_GETTER_SETTER(c,shareable); c->setDeclaredMethodByQName("atomicCompareAndSwapIntAt","",Class<IFunction>::getFunction(atomicCompareAndSwapIntAt),NORMAL_METHOD,true); c->setDeclaredMethodByQName("atomicCompareAndSwapLength","",Class<IFunction>::getFunction(atomicCompareAndSwapLength),NORMAL_METHOD,true); - c->setDeclaredMethodByQName("toJSON",AS3,Class<IFunction>::getFunction(_toJSON),NORMAL_METHOD,true); + c->prototype->setVariableByQName("toJSON",AS3,Class<IFunction>::getFunction(_toJSON),DYNAMIC_TRAIT); c->addImplementedInterface(InterfaceClass<IDataInput>::getClass()); IDataInput::linkTraits(c); @@ -131,7 +131,7 @@ // the flash documentation doesn't tell how large ByteArrays are allowed to be // so we simply don't allow bytearrays larger than 1GiB // maybe we should set this smaller - if (size > 0x4000000) + if (size > 0x40000000) throwError<ASError>(kOutOfMemoryError); // The first allocation is exactly the size we need, // the subsequent reallocations happen in increments of BA_CHUNK_SIZE bytes @@ -420,9 +420,21 @@ return false; if(len < (position+stringLen)) return false; - //Very inefficient copy - //TODO: optmize - ret=string((char*)bytes+position, (size_t)stringLen); + // check for BOM + if (len > position+3) + { + if (bytes[position] == 0xef && + bytes[position+1] == 0xbb && + bytes[position+2] == 0xbf) + { + position += 3; + stringLen -= stringLen > 3 ? 3 : 0; + } + } + char buf[stringLen+1]; + buf[stringLen]=0; + strncpy(buf,(char*)bytes+position,(size_t)stringLen); + ret=buf; position+=stringLen; return true; } @@ -454,11 +466,25 @@ th->unlock(); throwError<EOFError>(kEOFError); } + // check for BOM + if (th->len > th->position+3) + { + if (th->bytes[th->position] == 0xef && + th->bytes[th->position+1] == 0xbb && + th->bytes[th->position+2] == 0xbf) + { + th->position += 3; + length -= length > 3 ? 3 : 0; + } + } uint8_t *bufStart=th->bytes+th->position; + char buf[length+1]; + buf[length]=0; + strncpy(buf,(char*)bufStart,(size_t)length); th->position+=length; th->unlock(); - return Class<ASString>::getInstanceS((char *)bufStart,length); + return Class<ASString>::getInstanceS((char *)buf,strlen(buf)); } void ByteArray::writeUTF(const tiny_string& str) @@ -987,8 +1013,16 @@ ASFUNCTIONBODY(ByteArray,_toString) { ByteArray* th=static_cast<ByteArray*>(obj); - //TODO: check for Byte Order Mark - return Class<ASString>::getInstanceS((char*)th->bytes,th->len); + //check for Byte Order Mark + int start = 0; + if (th->len > 3) + { + if (th->bytes[0] == 0xef && + th->bytes[1] == 0xbb && + th->bytes[2] == 0xbf) + start = 3; + } + return Class<ASString>::getInstanceS((char*)th->bytes+start,th->len-start); } bool ByteArray::hasPropertyByMultiname(const multiname& name, bool considerDynamic, bool considerPrototype) @@ -1101,6 +1135,18 @@ } } +void ByteArray::serializeDouble(number_t val) +{ + //We have to write the double in network byte order (big endian) + const uint64_t* tmpPtr=reinterpret_cast<const uint64_t*>(&val); + uint64_t bigEndianVal=GINT64_FROM_BE(*tmpPtr); + uint8_t* bigEndianPtr=reinterpret_cast<uint8_t*>(&bigEndianVal); + + for(uint32_t i=0;i<8;i++) + writeByte(bigEndianPtr[i]); + +} + void ByteArray::writeStringVR(map<tiny_string, uint32_t>& stringMap, const tiny_string& s) { const uint32_t len=s.numBytes(); @@ -1412,3 +1458,30 @@ { return Class<ASString>::getInstanceS("ByteArray"); } + +void ByteArray::serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, + std::map<const ASObject*, uint32_t>& objMap, + std::map<const Class_base*, uint32_t>& traitsMap) +{ + assert_and_throw(objMap.find(this)==objMap.end()); + out->writeByte(byte_array_marker); + //Check if the bytearray has been already serialized + auto it=objMap.find(this); + if(it!=objMap.end()) + { + //The least significant bit is 0 to signal a reference + out->writeU29(it->second << 1); + } + else + { + //Add the dictionary to the map + objMap.insert(make_pair(this, objMap.size())); + + assert_and_throw(len<0x20000000); + uint32_t value = (len << 1) | 1; + out->writeU29(value); + // TODO faster implementation + for (uint i = 0; i < len; i++) + out->writeByte(this->bytes[i]); + } +}
View file
lightspark.tar.xz/src/scripting/flash/utils/ByteArray.h
Changed
@@ -46,7 +46,6 @@ Mutex mutex; void lock(); void unlock(); - void setLength(uint32_t newLen); public: ByteArray(Class_base* c, uint8_t* b = NULL, uint32_t l = 0); ~ByteArray(); @@ -65,6 +64,10 @@ void writeStringVR(std::map<tiny_string, uint32_t>& stringMap, const tiny_string& s); void writeXMLString(std::map<const ASObject*, uint32_t>& objMap, ASObject *xml, const tiny_string& s); void writeU29(uint32_t val); + + void serializeDouble(number_t val); + + void setLength(uint32_t newLen); uint32_t getPosition() const; void setPosition(uint32_t p); @@ -152,6 +155,10 @@ void setVariableByMultiname(const multiname& name, ASObject* o, CONST_ALLOWED_FLAG allowConst); void setVariableByMultiname_i(const multiname& name, int32_t value); bool hasPropertyByMultiname(const multiname& name, bool considerDynamic, bool considerPrototype); + + void serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, + std::map<const ASObject*, uint32_t>& objMap, + std::map<const Class_base*, uint32_t>& traitsMap); }; }
View file
lightspark.tar.xz/src/scripting/flash/utils/CompressionAlgorithm.cpp
Added
@@ -0,0 +1,39 @@ +/************************************************************************** + Lightspark, a free flash player implementation + + Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +**************************************************************************/ + +#include "scripting/flash/utils/CompressionAlgorithm.h" +#include "asobject.h" +#include "scripting/class.h" +#include "scripting/argconv.h" + +using namespace std; +using namespace lightspark; + +CompressionAlgorithm::CompressionAlgorithm(Class_base* c): + ASObject(c) +{ +} + +void CompressionAlgorithm::sinit(Class_base* c) +{ + CLASS_SETUP_NO_CONSTRUCTOR(c, ASObject, CLASS_SEALED|CLASS_FINAL); + c->setVariableByQName("DEFLATE","",Class<ASString>::getInstanceS("deflate"),CONSTANT_TRAIT); + c->setVariableByQName("LZMA","",Class<ASString>::getInstanceS("lzma"),CONSTANT_TRAIT); + c->setVariableByQName("ZLIB","",Class<ASString>::getInstanceS("zlib"),CONSTANT_TRAIT); +}
View file
lightspark.tar.xz/src/scripting/flash/utils/CompressionAlgorithm.h
Added
@@ -0,0 +1,39 @@ +/************************************************************************** + Lightspark, a free flash player implementation + + Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +**************************************************************************/ + +#ifndef SCRIPTING_FLASH_UTILS_COMPRESSIONALGORITHM_H +#define SCRIPTING_FLASH_UTILS_COMPRESSIONALGORITHM_H 1 + +#include "compat.h" +#include "swftypes.h" +#include "scripting/flash/utils/flashutils.h" + +namespace lightspark +{ + +class CompressionAlgorithm : public ASObject +{ +public: + CompressionAlgorithm(Class_base* c); + static void sinit(Class_base*); +}; + +} + +#endif /* SCRIPTING_FLASH_UTILS_COMPRESSIONALGORITHM_H */
View file
lightspark.tar.xz/src/scripting/flash/utils/Dictionary.cpp
Changed
@@ -43,7 +43,7 @@ void Dictionary::sinit(Class_base* c) { CLASS_SETUP(c, ASObject, _constructor, CLASS_DYNAMIC_NOT_FINAL); - c->setDeclaredMethodByQName("toJSON",AS3,Class<IFunction>::getFunction(_toJSON),NORMAL_METHOD,true); + c->prototype->setVariableByQName("toJSON",AS3,Class<IFunction>::getFunction(_toJSON),DYNAMIC_TRAIT); } void Dictionary::buildTraits(ASObject* o) @@ -52,6 +52,10 @@ ASFUNCTIONBODY(Dictionary,_constructor) { + bool weak = false; + ARG_UNPACK(weak, false); + if (weak) + LOG(LOG_NOT_IMPLEMENTED,"Dictionary:weak keys not implemented"); return NULL; } @@ -348,3 +352,42 @@ return retstr.str(); } + +void Dictionary::serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, + std::map<const ASObject*, uint32_t>& objMap, + std::map<const Class_base*, uint32_t>& traitsMap) +{ + assert_and_throw(objMap.find(this)==objMap.end()); + out->writeByte(dictionary_marker); + //Check if the dictionary has been already serialized + auto it=objMap.find(this); + if(it!=objMap.end()) + { + //The least significant bit is 0 to signal a reference + out->writeU29(it->second << 1); + } + else + { + //Add the dictionary to the map + objMap.insert(make_pair(this, objMap.size())); + + uint32_t count = 0; + uint32_t tmp; + while ((tmp = nextNameIndex(count)) != 0) + { + count = tmp; + } + assert_and_throw(count<0x20000000); + uint32_t value = (count << 1) | 1; + out->writeU29(value); + out->writeByte(0x00); // TODO handle weak keys + + tmp = 0; + while ((tmp = nextNameIndex(tmp)) != 0) + { + nextName(tmp)->serialize(out, stringMap, objMap, traitsMap); + nextValue(tmp)->serialize(out, stringMap, objMap, traitsMap); + } + } +} +
View file
lightspark.tar.xz/src/scripting/flash/utils/Dictionary.h
Changed
@@ -57,6 +57,10 @@ uint32_t nextNameIndex(uint32_t cur_index); _R<ASObject> nextName(uint32_t index); _R<ASObject> nextValue(uint32_t index); + + void serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, + std::map<const ASObject*, uint32_t>& objMap, + std::map<const Class_base*, uint32_t>& traitsMap); }; }
View file
lightspark.tar.xz/src/scripting/flash/utils/Proxy.cpp
Changed
@@ -38,11 +38,21 @@ void Proxy::sinit(Class_base* c) { CLASS_SETUP_NO_CONSTRUCTOR(c, ASObject,CLASS_DYNAMIC_NOT_FINAL); + c->setDeclaredMethodByQName("isAttribute","",Class<IFunction>::getFunction(_isAttribute),NORMAL_METHOD,true); } void Proxy::buildTraits(ASObject* o) { } +ASFUNCTIONBODY(Proxy,_isAttribute) +{ + _NR<ASObject> name; + ARG_UNPACK(name); + multiname mname(NULL); + name->applyProxyProperty(mname); + LOG(LOG_ERROR,"isAttr:"<<mname.isAttribute); + return abstract_b(mname.isAttribute); +} void Proxy::setVariableByMultiname(const multiname& name, ASObject* o, CONST_ALLOWED_FLAG allowConst) {
View file
lightspark.tar.xz/src/scripting/flash/utils/Proxy.h
Changed
@@ -34,6 +34,7 @@ static void sinit(Class_base*); static void buildTraits(ASObject* o); // ASFUNCTION(_constructor); + ASFUNCTION(_isAttribute); _NR<ASObject> getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt=NONE); int32_t getVariableByMultiname_i(const multiname& name) {
View file
lightspark.tar.xz/src/scripting/flash/utils/flashutils.cpp
Changed
@@ -126,7 +126,8 @@ else c=static_cast<Class_base*>(target)->super.getPtr(); - assert_and_throw(c); + if (!c) + return getSys()->getNullRef(); return Class<ASString>::getInstanceS(c->getQualifiedClassName()); } @@ -162,7 +163,7 @@ ASFUNCTIONBODY(lightspark,describeType) { - assert_and_throw(argslen==1); + assert_and_throw(argslen>=1); return args[0]->describeType(); }
View file
lightspark.tar.xz/src/scripting/toplevel/Array.cpp
Changed
@@ -329,6 +329,8 @@ uint32_t newLen; ARG_UNPACK(newLen); Array* th=static_cast<Array*>(obj); + if (th->getClass() && th->getClass()->isSealed) + return NULL; //If newLen is equal to size do nothing if(newLen==th->size()) return NULL; @@ -408,12 +410,12 @@ int ret=-1; if(argslen == 1 && th->data.empty()) - return abstract_d(0); + return abstract_d(-1); size_t i = th->size()-1; if(argslen == 2 && std::isnan(args[1]->toNumber())) - return abstract_i(0); + return abstract_i(-1); if(argslen == 2 && args[1]->getObjectType() != T_UNDEFINED && !std::isnan(args[1]->toNumber())) { @@ -1007,6 +1009,9 @@ return getSys()->getUndefinedRef(); } Array* th=static_cast<Array*>(obj); + // Derived classes may be sealed! + if (th->getClass() && th->getClass()->isSealed) + throwError<ReferenceError>(kWriteSealedError,"unshift",th->getClass()->getQualifiedClassName()); if (argslen > 0) { th->resize(th->size()+argslen); @@ -1220,34 +1225,41 @@ uint32_t index=0; if(!isValidMultiname(name,index)) return ASObject::getVariableByMultiname(name,opt); - if(index<size()) + if(index<size() && data.count(index)) { ASObject* ret=NULL; - if (!data.count(index)) - ret = getSys()->getUndefinedRef(); - else + data_slot sl = data[index]; + switch(sl.type) { - data_slot sl = data[index]; - switch(sl.type) - { - case DATA_OBJECT: - ret=sl.data; - if(ret==NULL) - { - ret=getSys()->getUndefinedRef(); - sl.data=ret; - } - ret->incRef(); - break; - case DATA_INT: - ret=abstract_d(sl.data_i); - break; - } + case DATA_OBJECT: + ret=sl.data; + if(ret==NULL) + { + ret=getSys()->getUndefinedRef(); + sl.data=ret; + } + ret->incRef(); + break; + case DATA_INT: + ret=abstract_d(sl.data_i); + break; } return _MNR(ret); } - else - return NullRef; + _NR<ASObject> ret; + //Check prototype chain + Prototype* proto = this->getClass()->prototype.getPtr(); + while(proto) + { + ret = proto->getObj()->getVariableByMultiname(name, opt); + if(!ret.isNull()) + return ret; + proto = proto->prevPrototype.getPtr(); + } + if(index<size()) + return _MNR(getSys()->getUndefinedRef()); + + return NullRef; } void Array::setVariableByMultiname_i(const multiname& name, int32_t value) @@ -1367,6 +1379,8 @@ unsigned int index=0; if(!isValidMultiname(name,index)) return ASObject::deleteVariableByMultiname(name); + if (getClass() && getClass()->isSealed) + return false; if(index>=size()) return true; @@ -1587,13 +1601,21 @@ for(uint32_t i=0;i<denseCount;i++) { if (!data.count(i)) - throw UnsupportedException("undefined not supported in Array::serialize"); - switch(data.at(i).type) { - case DATA_INT: - throw UnsupportedException("int not supported in Array::serialize"); - case DATA_OBJECT: - data.at(i).data->serialize(out, stringMap, objMap, traitsMap); + out->writeByte(null_marker); + } + else + { + switch(data.at(i).type) + { + case DATA_INT: + out->writeByte(double_marker); + out->serializeDouble(data.at(i).data_i); + break; + case DATA_OBJECT: + data.at(i).data->serialize(out, stringMap, objMap, traitsMap); + break; + } } } } @@ -1601,12 +1623,12 @@ tiny_string Array::toJSON(std::vector<ASObject *> &path, IFunction *replacer, const tiny_string& spaces,const tiny_string& filter) { - if (has_toJSON()) - { - return call_toJSON(); - } + bool ok; + tiny_string res = call_toJSON(ok,path,replacer,spaces,filter); + if (ok) + return res; - tiny_string res = "["; + res += "["; std::map<uint32_t,data_slot>::iterator it; // check for cylic reference if (std::find(path.begin(),path.end(), this) != path.end()) @@ -1616,34 +1638,42 @@ tiny_string newline = (spaces.empty() ? "" : "\n"); for (it=data.begin() ; it != data.end(); ++it) { - if(it->second.type==DATA_OBJECT && it->second.data) + tiny_string subres; + ASObject* o = it->second.type==DATA_OBJECT ? it->second.data : abstract_i(it->second.data_i); + if (replacer != NULL) { - tiny_string subres; - if (replacer != NULL) + ASObject* params[2]; + + params[0] = Class<Number>::getInstanceS(it->first); + params[0]->incRef(); + params[1] = o; + params[1]->incRef(); + ASObject *funcret=replacer->call(getSys()->getNullRef(), params, 2); + if (funcret) + subres = funcret->toJSON(path,NULL,spaces,filter); + } + else + { + if(it->second.type==DATA_OBJECT) { - ASObject* params[2]; - - params[0] = Class<Number>::getInstanceS(it->first); - params[0]->incRef(); - params[1] = it->second.data; - params[1]->incRef(); - ASObject *funcret=replacer->call(getSys()->getNullRef(), params, 2); - if (funcret) - subres = funcret->toJSON(path,NULL,spaces,filter); + if (it->second.data) + subres = it->second.data->toJSON(path,replacer,spaces,filter); + else + continue; } else - subres = it->second.data->toJSON(path,replacer,spaces,filter); - if (!subres.empty()) - { - if (!bfirst) - res += ","; - res += newline+spaces; -
View file
lightspark.tar.xz/src/scripting/toplevel/Array.h
Changed
@@ -132,11 +132,7 @@ { return currentsize; } - void push(_R<ASObject> o) - { - currentsize++; - set(currentsize-1,o); - } + void push(_R<ASObject> o); void resize(uint64_t n); _NR<ASObject> getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt); int32_t getVariableByMultiname_i(const multiname& name);
View file
lightspark.tar.xz/src/scripting/toplevel/Date.cpp
Changed
@@ -17,9 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. **************************************************************************/ +#include "parsing/amf3_generator.h" #include "scripting/toplevel/Date.h" #include "scripting/class.h" #include "scripting/argconv.h" +#include "scripting/flash/utils/ByteArray.h" #include "compat.h" using namespace std; @@ -40,6 +42,7 @@ void Date::sinit(Class_base* c) { CLASS_SETUP_CONSTRUCTOR_LENGTH(c, ASObject, _constructor, 7, CLASS_FINAL); + c->prototype->isSealed=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); @@ -76,7 +79,6 @@ c->setDeclaredMethodByQName("setTime",AS3,Class<IFunction>::getFunction(setTime,1),NORMAL_METHOD,true); c->setDeclaredMethodByQName("UTC","",Class<IFunction>::getFunction(UTC,7),NORMAL_METHOD,false); c->setDeclaredMethodByQName("toString",AS3,Class<IFunction>::getFunction(_toString),NORMAL_METHOD,true); - c->setDeclaredMethodByQName("toJSON",AS3,Class<IFunction>::getFunction(_toString),NORMAL_METHOD,true); c->setDeclaredMethodByQName("toUTCString",AS3,Class<IFunction>::getFunction(toUTCString),NORMAL_METHOD,true); c->setDeclaredMethodByQName("toDateString",AS3,Class<IFunction>::getFunction(toDateString),NORMAL_METHOD,true); c->setDeclaredMethodByQName("toTimeString",AS3,Class<IFunction>::getFunction(toTimeString),NORMAL_METHOD,true); @@ -159,6 +161,7 @@ c->prototype->setVariableByQName("toLocaleTimeString","",Class<IFunction>::getFunction(toLocaleTimeString),DYNAMIC_TRAIT); c->prototype->setVariableByQName("toLocaleDateString","",Class<IFunction>::getFunction(toLocaleDateString),DYNAMIC_TRAIT); c->prototype->setVariableByQName("toLocaleString","",Class<IFunction>::getFunction(toLocaleString),DYNAMIC_TRAIT); + c->prototype->setVariableByQName("toJSON",AS3,Class<IFunction>::getFunction(_toString),DYNAMIC_TRAIT); } void Date::buildTraits(ASObject* o) @@ -878,7 +881,17 @@ ASFUNCTIONBODY(Date,toLocaleString) { Date* th=static_cast<Date*>(obj); - return Class<ASString>::getInstanceS(th->toString()); + if (!th->datetime) + return Class<ASString>::getInstanceS(""); + tiny_string res = th->toString_priv(false,"%a %b %e"); + gchar* fs = g_date_time_format(th->datetime, " %I:%M:%S"); + res += fs; + if (g_date_time_get_hour(th->datetime) > 12) + res += " PM"; + else + res += " AM"; + g_free(fs); + return Class<ASString>::getInstanceS(res); } ASFUNCTIONBODY(Date,toLocaleDateString) { @@ -1120,6 +1133,20 @@ std::map<const ASObject*, uint32_t>& objMap, std::map<const Class_base*, uint32_t>& traitsMap) { - throw UnsupportedException("Date::serialize not implemented"); + number_t val = getMsSinceEpoch(); + out->writeByte(date_marker); + auto it=objMap.find(this); + if(it!=objMap.end()) + { + //The least significant bit is 0 to signal a reference + out->writeU29(it->second << 1); + } + else + { + //Add the Date to the map + objMap.insert(make_pair(this, objMap.size())); + // write milliseconds since 1970 as double + out->serializeDouble(val); + } }
View file
lightspark.tar.xz/src/scripting/toplevel/Date.h
Changed
@@ -38,7 +38,6 @@ number_t getMsSinceEpoch(); tiny_string toString_priv(bool utc, const char* formatstr) const; void MakeDate(int64_t year, int64_t month, int64_t day, int64_t hour, int64_t minute, int64_t second, int64_t millisecond, bool bIsLocalTime); - void MakeDateFromMilliseconds(int64_t ms); static number_t parse(tiny_string str); public: Date(Class_base* c); @@ -105,6 +104,7 @@ ASFUNCTION(toLocaleDateString); ASFUNCTION(toLocaleTimeString); + void MakeDateFromMilliseconds(int64_t ms); bool isEqual(ASObject* r); TRISTATE isLess(ASObject* r); tiny_string toString();
View file
lightspark.tar.xz/src/scripting/toplevel/Integer.cpp
Changed
@@ -214,11 +214,17 @@ std::map<const ASObject*, uint32_t>& objMap, std::map<const Class_base*, uint32_t>& traitsMap) { - out->writeByte(integer_marker); - //TODO: check behaviour for negative value if(val>=0x40000000 || val<=(int32_t)0xbfffffff) - throw AssertionException("Range exception in Integer::serialize"); - out->writeU29((uint32_t)val); + { + // write as double + out->writeByte(double_marker); + out->serializeDouble(val); + } + else + { + out->writeByte(integer_marker); + out->writeU29((uint32_t)val); + } } bool Integer::fromStringFlashCompatible(const char* cur, int64_t& ret, int radix)
View file
lightspark.tar.xz/src/scripting/toplevel/JSON.cpp
Changed
@@ -555,6 +555,7 @@ name.ns.push_back(nsNameAndKind("",NAMESPACE)); name.isAttribute = false; bool done = false; + bool needdata = false; while (!done && pos < len) { while (jsonstring.charAt(pos) == ' ' || @@ -572,14 +573,16 @@ break; case ',': name.name_i++; + needdata = true; pos++; break; default: pos = parse(jsonstring,pos,&subobj,name, reviver); + needdata = false; break; } } - if (!done) + if (!done || needdata) throwError<SyntaxError>(kJSONInvalidParseInput); return pos;
View file
lightspark.tar.xz/src/scripting/toplevel/Math.cpp
Changed
@@ -228,6 +228,9 @@ ASFUNCTIONBODY(Math,random) { + if(argslen > 0) + throwError<ArgumentError>(kWrongArgumentCountError, "object", "", ""); + number_t ret=rand(); ret/=(number_t(1.)+RAND_MAX); return abstract_d(ret);
View file
lightspark.tar.xz/src/scripting/toplevel/Number.cpp
Changed
@@ -20,6 +20,7 @@ #include "parsing/amf3_generator.h" #include "scripting/argconv.h" #include "scripting/toplevel/Number.h" +#include "scripting/toplevel/Math.h" #include "scripting/flash/utils/ByteArray.h" using namespace std; @@ -276,6 +277,38 @@ c->prototype->setVariableByQName("toExponential","",Class<IFunction>::getFunction(Number::toExponential, 1),DYNAMIC_TRAIT); c->prototype->setVariableByQName("toPrecision","",Class<IFunction>::getFunction(Number::toPrecision, 1),DYNAMIC_TRAIT); c->prototype->setVariableByQName("valueOf","",Class<IFunction>::getFunction(_valueOf),DYNAMIC_TRAIT); + + // if needed add AVMPLUS definitions + if(getSys()->flashMode==SystemState::AVMPLUS) + { + c->setVariableByQName("E","",abstract_d(2.71828182845905),CONSTANT_TRAIT); + c->setVariableByQName("LN10","",abstract_d(2.302585092994046),CONSTANT_TRAIT); + c->setVariableByQName("LN2","",abstract_d(0.6931471805599453),CONSTANT_TRAIT); + c->setVariableByQName("LOG10E","",abstract_d(0.4342944819032518),CONSTANT_TRAIT); + c->setVariableByQName("LOG2E","",abstract_d(1.442695040888963387),CONSTANT_TRAIT); + c->setVariableByQName("PI","",abstract_d(3.141592653589793),CONSTANT_TRAIT); + c->setVariableByQName("SQRT1_2","",abstract_d(0.7071067811865476),CONSTANT_TRAIT); + c->setVariableByQName("SQRT2","",abstract_d(1.4142135623730951),CONSTANT_TRAIT); + + c->setDeclaredMethodByQName("abs","",Class<IFunction>::getFunction(Math::abs,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("acos","",Class<IFunction>::getFunction(Math::acos,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("asin","",Class<IFunction>::getFunction(Math::asin,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("atan","",Class<IFunction>::getFunction(Math::atan,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("atan2","",Class<IFunction>::getFunction(Math::atan2,2),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("ceil","",Class<IFunction>::getFunction(Math::ceil,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("cos","",Class<IFunction>::getFunction(Math::cos,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("exp","",Class<IFunction>::getFunction(Math::exp,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("floor","",Class<IFunction>::getFunction(Math::floor,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("log","",Class<IFunction>::getFunction(Math::log,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("max","",Class<IFunction>::getFunction(Math::_max,2),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("min","",Class<IFunction>::getFunction(Math::_min,2),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("pow","",Class<IFunction>::getFunction(Math::pow,2),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("random","",Class<IFunction>::getFunction(Math::random),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("round","",Class<IFunction>::getFunction(Math::round,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("sin","",Class<IFunction>::getFunction(Math::sin,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("sqrt","",Class<IFunction>::getFunction(Math::sqrt,1),NORMAL_METHOD,false); + c->setDeclaredMethodByQName("tan","",Class<IFunction>::getFunction(Math::tan,1),NORMAL_METHOD,false); + } } ASFUNCTIONBODY(Number,_constructor) @@ -497,11 +530,5 @@ std::map<const Class_base*, uint32_t>& traitsMap) { out->writeByte(double_marker); - //We have to write the double in network byte order (big endian) - const uint64_t* tmpPtr=reinterpret_cast<const uint64_t*>(&val); - uint64_t bigEndianVal=GINT64_FROM_BE(*tmpPtr); - uint8_t* bigEndianPtr=reinterpret_cast<uint8_t*>(&bigEndianVal); - - for(uint32_t i=0;i<8;i++) - out->writeByte(bigEndianPtr[i]); + out->serializeDouble(val); }
View file
lightspark.tar.xz/src/scripting/toplevel/UInteger.cpp
Changed
@@ -18,8 +18,10 @@ **************************************************************************/ #include <cmath> +#include "parsing/amf3_generator.h" #include "scripting/argconv.h" #include "scripting/toplevel/UInteger.h" +#include "scripting/flash/utils/ByteArray.h" using namespace std; using namespace lightspark; @@ -204,3 +206,20 @@ ARG_UNPACK (precision); return Class<ASString>::getInstanceS(Number::toPrecisionString(th->val, precision)); } + +void UInteger::serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, + std::map<const ASObject*, uint32_t>& objMap, + std::map<const Class_base*, uint32_t>& traitsMap) +{ + if(val>=0x40000000) + { + // write as double + out->writeByte(double_marker); + out->serializeDouble(val); + } + else + { + out->writeByte(integer_marker); + out->writeU29((uint32_t)val); + } +}
View file
lightspark.tar.xz/src/scripting/toplevel/UInteger.h
Changed
@@ -53,7 +53,9 @@ ASFUNCTION(_toFixed); ASFUNCTION(_toPrecision); std::string toDebugString() { return toString()+"ui"; } - //CHECK: should this have a special serialization? + void serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, + std::map<const ASObject*, uint32_t>& objMap, + std::map<const Class_base*, uint32_t>& traitsMap); }; }
View file
lightspark.tar.xz/src/scripting/toplevel/Vector.cpp
Changed
@@ -120,10 +120,10 @@ if(types.size() == 1) vec_type = types[0]; } -bool Vector::sameType(const QName& classname) const +bool Vector::sameType(const Class_base *cls) const { tiny_string clsname = this->getClass()->getQualifiedClassName(); - return (clsname.startsWith(classname.getQualifiedName().raw_buf())); + return (clsname.startsWith(cls->class_name.getQualifiedName().raw_buf())); } ASObject* Vector::generator(TemplatedClass<Vector>* o_class, ASObject* const* args, const unsigned int argslen) @@ -963,9 +963,17 @@ return ASObject::getVariableByMultiname(name,opt); unsigned int index=0; - if(!Vector::isValidMultiname(name,index)) - return ASObject::getVariableByMultiname(name,opt); + if(!Vector::isValidMultiname(name,index) || index == UINT32_MAX) + { + if (name.name_type == multiname::NAME_INT || + (name.name_type == multiname::NAME_NUMBER && Number::isInteger(name.name_d))) + throwError<RangeError>(kOutOfRangeError,Integer::toString(name.name_i),Integer::toString(vec.size())); + _NR<ASObject> ret = ASObject::getVariableByMultiname(name,opt); + if (ret.isNull()) + throwError<ReferenceError>(kReadSealedError, name.normalizedName(), this->getClass()->getQualifiedClassName()); + return ret; + } if(index < vec.size()) { if (vec[index]) @@ -994,7 +1002,15 @@ unsigned int index=0; if(!Vector::isValidMultiname(name,index)) + { + if (name.name_type == multiname::NAME_INT || + (name.name_type == multiname::NAME_NUMBER && Number::isInteger(name.name_d))) + throwError<RangeError>(kOutOfRangeError,name.normalizedName(),Integer::toString(vec.size())); + + if (!ASObject::hasPropertyByMultiname(name,false,true)) + throwError<ReferenceError>(kWriteSealedError, name.normalizedName(), this->getClass()->getQualifiedClassName()); return ASObject::setVariableByMultiname(name, o, allowConst); + } ASObject* o2 = this->vec_type->coerce(o); if(index < vec.size()) @@ -1073,14 +1089,63 @@ return false; bool validIndex=name.toUInt(index, true); - // Don't throw for non-numeric NAME_STRING or NAME_OBJECT - // because they can still be valid built-in property names. - if(!validIndex && (name.name_type==multiname::NAME_INT || name.name_type==multiname::NAME_NUMBER)) - throwError<RangeError>(kOutOfRangeError, name.normalizedNameUnresolved(), "?"); return validIndex; } +tiny_string Vector::toJSON(std::vector<ASObject *> &path, IFunction *replacer, const tiny_string &spaces, const tiny_string &filter) +{ + bool ok; + tiny_string res = call_toJSON(ok,path,replacer,spaces,filter); + if (ok) + return res; + + res += "["; + // check for cylic reference + if (std::find(path.begin(),path.end(), this) != path.end()) + throwError<TypeError>(kJSONCyclicStructure); + path.push_back(this); + bool bfirst = true; + tiny_string newline = (spaces.empty() ? "" : "\n"); + for (uint i =0; i < vec.size(); i++) + { + tiny_string subres; + ASObject* o = vec[i]; + if (!o) + o = getSys()->getNullRef(); + if (replacer != NULL) + { + ASObject* params[2]; + + params[0] = Class<Number>::getInstanceS(i); + params[0]->incRef(); + params[1] = o; + params[1]->incRef(); + ASObject *funcret=replacer->call(getSys()->getNullRef(), params, 2); + if (funcret) + subres = funcret->toJSON(path,NULL,spaces,filter); + } + else + { + subres = o->toJSON(path,replacer,spaces,filter); + } + if (!subres.empty()) + { + if (!bfirst) + res += ","; + res += newline+spaces; + + bfirst = false; + res += subres; + } + path.push_back(o); + } + if (!bfirst) + res += newline+spaces.substr_bytes(0,spaces.numBytes()/2); + res += "]"; + return res; +} + ASObject* Vector::at(unsigned int index, ASObject *defaultValue) const { if (index < vec.size()) @@ -1088,3 +1153,61 @@ else return defaultValue; } + +void Vector::serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, + std::map<const ASObject*, uint32_t>& objMap, + std::map<const Class_base*, uint32_t>& traitsMap) +{ + uint8_t marker = 0; + if (vec_type == Class<Integer>::getClass()) + marker = vector_int_marker; + else if (vec_type == Class<UInteger>::getClass()) + marker = vector_uint_marker; + else if (vec_type == Class<Number>::getClass()) + marker = vector_double_marker; + else + marker = vector_object_marker; + out->writeByte(marker); + //Check if the vector has been already serialized + auto it=objMap.find(this); + if(it!=objMap.end()) + { + //The least significant bit is 0 to signal a reference + out->writeU29(it->second << 1); + } + else + { + //Add the Vector to the map + objMap.insert(make_pair(this, objMap.size())); + + uint32_t count = size(); + assert_and_throw(count<0x20000000); + uint32_t value = (count << 1) | 1; + out->writeU29(value); + out->writeByte(fixed ? 0x01 : 0x00); + if (marker == vector_object_marker) + { + out->writeStringVR(stringMap,vec_type->getName()); + } + for(uint32_t i=0;i<count;i++) + { + if (!vec[i]) + continue; + switch (marker) + { + case vector_int_marker: + out->writeUnsignedInt(out->endianIn((uint32_t)vec[i]->toInt())); + break; + case vector_uint_marker: + out->writeUnsignedInt(out->endianIn(vec[i]->toUInt())); + break; + case vector_double_marker: + out->serializeDouble(vec[i]->toNumber()); + break; + case vector_object_marker: + vec[i]->serialize(out, stringMap, objMap, traitsMap); + break; + } + } + } +}
View file
lightspark.tar.xz/src/scripting/toplevel/Vector.h
Changed
@@ -60,7 +60,7 @@ static ASObject* generator(TemplatedClass<Vector>* o_class, ASObject* const* args, const unsigned int argslen); void setTypes(const std::vector<const Type*>& types); - bool sameType(const QName& classname) const; + bool sameType(const Class_base* cls) const; //Overloads tiny_string toString(); @@ -69,6 +69,8 @@ _NR<ASObject> getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt); static bool isValidMultiname(const multiname& name, uint32_t& index); + tiny_string toJSON(std::vector<ASObject *> &path, IFunction *replacer, const tiny_string &spaces,const tiny_string& filter); + uint32_t nextNameIndex(uint32_t cur_index); _R<ASObject> nextName(uint32_t index); _R<ASObject> nextValue(uint32_t index); @@ -88,6 +90,7 @@ //Appends an object to the Vector. o is coerced to vec_type. //Takes ownership of o. void append(ASObject *o); + void setFixed(bool v) { fixed = v; } //TODO: do we need to implement generator? ASFUNCTION(_constructor); @@ -116,6 +119,11 @@ ASFUNCTION(slice); ASFUNCTION(every); ASFUNCTION(some); + + //Serialization interface + void serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, + std::map<const ASObject*, uint32_t>& objMap, + std::map<const Class_base*, uint32_t>& traitsMap); }; }
View file
lightspark.tar.xz/src/scripting/toplevel/XML.cpp
Changed
@@ -127,6 +127,7 @@ c->setDeclaredMethodByQName("propertyIsEnumerable",AS3,Class<IFunction>::getFunction(_propertyIsEnumerable),NORMAL_METHOD,true); c->prototype->setVariableByQName("hasOwnProperty",AS3,Class<IFunction>::getFunction(_hasOwnProperty),DYNAMIC_TRAIT); c->setDeclaredMethodByQName("prependChild",AS3,Class<IFunction>::getFunction(_prependChild),NORMAL_METHOD,true); + c->setDeclaredMethodByQName("replace",AS3,Class<IFunction>::getFunction(_replace),NORMAL_METHOD,true); } ASFUNCTIONBODY(XML,generator) @@ -288,7 +289,7 @@ XMLVector ret; multiname mname(NULL); name->applyProxyProperty(mname); - th->getDescendantsByQName(name->toString(),"",mname.isAttribute,ret); + th->getDescendantsByQName(name->toString(),mname.isQName() ? mname.ns[0].getImpl().name : "",mname.isAttribute,ret); return Class<XMLList>::getInstanceS(ret,th->getChildrenlist(),multiname(NULL)); } @@ -326,6 +327,15 @@ { if (newChild->constructed) { + if (this == newChild.getPtr()) + throwError<TypeError>(kXMLIllegalCyclicalLoop); + _NR<XML> node = this->parentNode; + while (!node.isNull()) + { + if (node == newChild) + throwError<TypeError>(kXMLIllegalCyclicalLoop); + node = node->parentNode; + } this->incRef(); newChild->parentNode = _NR<XML>(this); childrenlist->append(newChild); @@ -2194,6 +2204,11 @@ { ret=nodevalue; } + else if (getNodeKind() == XML_COMMENT_NODE || + getNodeKind() == XML_PI_NODE) + { + ret=""; + } else if (hasSimpleContent()) { auto it = childrenlist->nodes.begin(); @@ -2214,41 +2229,7 @@ const tiny_string XML::encodeToXML(const tiny_string value, bool bIsAttribute) { - - tiny_string res; - auto it = value.begin(); - while (it != value.end()) - { - switch (*it) - { - case '<': - res += "<"; - break; - case '>': - res += bIsAttribute ? ">" : ">"; - break; - case '&': - res += "&"; - break; - case '\"': - res += bIsAttribute ? """ : "\""; - break; - case '\r': - res += bIsAttribute ? "
" : "\r"; - break; - case '\n': - res += bIsAttribute ? "
" : "\n"; - break; - case '\t': - res += bIsAttribute ? "	" : "\t"; - break; - default: - res += *it; - break; - } - it++; - } - return res; + return XMLBase::encodeToXML(value,bIsAttribute); } bool XML::getPrettyPrinting() @@ -2479,7 +2460,7 @@ else if(args[0]->getClass()==Class<XMLList>::getClass()) { XMLList* list=Class<XMLList>::cast(args[0]); - list->appendNodesTo(th); + list->prependNodesTo(th); th->incRef(); return th; } @@ -2491,7 +2472,7 @@ arg=_MR(Class<XML>::getInstanceS(args[0]->toString())); } - th->appendChild(arg); + th->prependChild(arg); th->incRef(); return th; } @@ -2499,10 +2480,90 @@ { if (newChild->constructed) { + if (this == newChild.getPtr()) + throwError<TypeError>(kXMLIllegalCyclicalLoop); + _NR<XML> node = this->parentNode; + while (!node.isNull()) + { + if (node == newChild) + throwError<TypeError>(kXMLIllegalCyclicalLoop); + node = node->parentNode; + } this->incRef(); newChild->parentNode = _NR<XML>(this); - childrenlist->append(newChild); + childrenlist->prepend(newChild); } else newChild->decRef(); } + +ASFUNCTIONBODY(XML,_replace) +{ + XML* th=Class<XML>::cast(obj); + _NR<ASObject> propertyName; + _NR<ASObject> value; + ARG_UNPACK(propertyName) (value); + + multiname name(NULL); + name.name_type=multiname::NAME_STRING; + if (propertyName->is<ASQName>()) + { + name.name_s_id=getSys()->getUniqueStringId(propertyName->as<ASQName>()->getLocalName()); + name.ns.push_back(nsNameAndKind(propertyName->as<ASQName>()->getURI(),NAMESPACE)); + } + else if (propertyName->toString() == "*") + { + if (value->is<XMLList>()) + { + th->childrenlist->decRef(); + value->incRef(); + th->childrenlist = _NR<XMLList>(value->as<XMLList>()); + } + else if (value->is<XML>()) + { + th->childrenlist->clear(); + value->incRef(); + th->childrenlist->append(_R<XML>(value->as<XML>())); + } + else + { + XML* x = Class<XML>::getInstanceS(value->toString()); + x->incRef(); + th->childrenlist->clear(); + th->childrenlist->append(_R<XML>(x)); + } + th->incRef(); + return th; + } + else + { + name.name_s_id=getSys()->getUniqueStringId(propertyName->toString()); + name.ns.push_back(nsNameAndKind("",NAMESPACE)); + } + uint32_t index=0; + if(XML::isValidMultiname(name,index)) + { + th->childrenlist->setVariableByMultiname(name,value.getPtr(),CONST_NOT_ALLOWED); + } + else if (th->hasPropertyByMultiname(name,true,false)) + { + if (value->is<XMLList>()) + { + th->deleteVariableByMultiname(name); + th->setVariableByMultiname(name,value.getPtr(),CONST_NOT_ALLOWED); + } + else if (value->is<XML>()) + { + th->deleteVariableByMultiname(name); + th->setVariableByMultiname(name,value.getPtr(),CONST_NOT_ALLOWED); + } + else + { + XML* x = Class<XML>::getInstanceS(value->toString()); + th->deleteVariableByMultiname(name); + th->setVariableByMultiname(name,x,CONST_NOT_ALLOWED); + } + } + th->incRef(); + return th; +}
View file
lightspark.tar.xz/src/scripting/toplevel/XML.h
Changed
@@ -134,6 +134,7 @@ ASFUNCTION(_propertyIsEnumerable); ASFUNCTION(_hasOwnProperty); ASFUNCTION(_prependChild); + ASFUNCTION(_replace); static void buildTraits(ASObject* o){} static void sinit(Class_base* c);
View file
lightspark.tar.xz/src/scripting/toplevel/XMLList.cpp
Changed
@@ -127,9 +127,8 @@ REGISTER_XML_DELEGATE2(namespace,_namespace); REGISTER_XML_DELEGATE(namespaceDeclarations); REGISTER_XML_DELEGATE(nodeKind); - REGISTER_XML_DELEGATE2(prependChild,_appendChild); + REGISTER_XML_DELEGATE2(prependChild,_prependChild); REGISTER_XML_DELEGATE(removeNamespace); - //REGISTER_XML_DELEGATE(replace); REGISTER_XML_DELEGATE2(setChildren,_setChildren); REGISTER_XML_DELEGATE2(setLocalName,_setLocalName); REGISTER_XML_DELEGATE2(setName,_setName); @@ -149,7 +148,6 @@ ASFUNCTIONBODY_XML_DELEGATE(nodeKind); ASFUNCTIONBODY_XML_DELEGATE(_prependChild); ASFUNCTIONBODY_XML_DELEGATE(removeNamespace); -//ASFUNCTIONBODY_XML_DELEGATE(replace); ASFUNCTIONBODY_XML_DELEGATE(_setChildren); ASFUNCTIONBODY_XML_DELEGATE(_setLocalName); ASFUNCTIONBODY_XML_DELEGATE(_setName); @@ -1172,3 +1170,15 @@ ret->decRef(); } } + +void XMLList::prependNodesTo(XML *dest) const +{ + std::vector<_R<XML>, reporter_allocator<_R<XML>>>::const_reverse_iterator it; + for (it=nodes.rbegin(); it!=nodes.rend(); ++it) + { + ASObject *arg0=it->getPtr(); + ASObject *ret=XML::_prependChild(dest, &arg0, 1); + if(ret) + ret->decRef(); + } +}
View file
lightspark.tar.xz/src/scripting/toplevel/XMLList.h
Changed
@@ -115,6 +115,7 @@ _R<ASObject> nextValue(uint32_t index); _R<XML> reduceToXML() const; void appendNodesTo(XML *dest) const; + void prependNodesTo(XML *dest) const; void normalize(); void clear(); XMLList* getTargetObject() { return targetobject; }
View file
lightspark.tar.xz/src/scripting/toplevel/toplevel.cpp
Changed
@@ -108,7 +108,7 @@ ASObject *Undefined::describeType() const { - return getSys()->getUndefinedRef(); + return ASObject::describeType(); } void Undefined::serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, @@ -280,7 +280,9 @@ { const uint32_t opt_hit_threshold=1; const uint32_t jit_hit_threshold=20; - assert_and_throw(mi->body); + if (!mi->body) + return getSys()->getUndefinedRef(); + const uint16_t hit_count = mi->body->hit_count; const method_body_info::CODE_STATUS& codeStatus = mi->body->codeStatus; @@ -2166,6 +2168,7 @@ { o->incRef(); setVariableByQName(name,nsNameAndKind(ns,NAMESPACE),o.getPtr(),DECLARED_TRAIT); + //setVariableByQName(name,nsNameAndKind(ns,PACKAGE_NAMESPACE),o.getPtr(),DECLARED_TRAIT); } ASFUNCTIONBODY(lightspark,eval) @@ -2548,6 +2551,13 @@ return prevPrototype->getObj()->getVariableByMultiname(name, opt); } +void ObjectPrototype::setVariableByMultiname(const multiname &name, ASObject *o, ASObject::CONST_ALLOWED_FLAG allowConst) +{ + if (this->isSealed && this->hasPropertyByMultiname(name,false,true)) + throwError<ReferenceError>(kCannotAssignToMethodError, name.normalizedNameUnresolved(), ""); + ASObject::setVariableByMultiname(name, o, allowConst); +} + ObjectConstructor::ObjectConstructor(Class_base* c,uint32_t length) : ASObject(c),_length(length) {
View file
lightspark.tar.xz/src/scripting/toplevel/toplevel.h
Changed
@@ -260,11 +260,13 @@ class Prototype { public: - virtual ~Prototype() {}; + Prototype():isSealed(false) {} + virtual ~Prototype() {} _NR<Prototype> prevPrototype; virtual void incRef() = 0; virtual void decRef() = 0; virtual ASObject* getObj() = 0; + bool isSealed; /* * This method is actually forwarded to the object. It's here as a shorthand. */ @@ -286,6 +288,7 @@ void decRef() { ASObject::decRef(); } ASObject* getObj() { return this; } _NR<ASObject> getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt=NONE); + void setVariableByMultiname(const multiname& name, ASObject* o, CONST_ALLOWED_FLAG allowConst); bool isEqual(ASObject* r); };
View file
lightspark.tar.xz/src/swf.cpp
Changed
@@ -205,6 +205,8 @@ cookiesFileName = NULL; setTLSSys(this); + // it seems Adobe ignores any locale date settings + setlocale(LC_TIME, "en_US"); mainThread = Thread::self();
View file
lightspark.tar.xz/src/swf.h
Changed
@@ -263,7 +263,7 @@ bool showProfilingData; bool standalone; //Flash for execution mode - enum FLASH_MODE { FLASH=0, AIR }; + enum FLASH_MODE { FLASH=0, AIR, AVMPLUS }; const FLASH_MODE flashMode; // Error types used to decide when to exit, extend as a bitmap
View file
lightspark.tar.xz/src/tiny_string.cpp
Changed
@@ -508,7 +508,14 @@ uint32_t len = 0; for (CharIterator it=begin(); it!=end(); it++) { - gunichar c = g_unichar_tolower(*it); + gunichar c; + // Adobe player handles some Georgian chars not like glib does + if ( *it >= 0x10A0 && *it <= 0x10C5 ) + c = *it + 48; + else if (*it == 0x10C7 || *it == 0x10CD) + c = *it; + else + c = g_unichar_tolower(*it); gint n = g_unichar_to_utf8(c, p); p += n; len += n;
View file
lightspark.tar.xz/tests/make-tamarin
Changed
@@ -94,7 +94,7 @@ mkdir -p $CUR/tamarin-SWF/$(dirname $1) OUTPUT_SWF="$CUR/tamarin-SWF/${1/%ab[cs]/swf}" - COMMON="Assert.abc Utils.abc" + COMMON="Assert.abc Utils.abc $CUR/tamarin/test/acceptance/generated/intrinsics.abc" ABS_SUPPORT=$(if [[ -f ${1/%abc/abs} ]]; then echo abcasm/abs_helper.abc; fi) TEST_SUPPORT=$(if [[ -d ${1/%.abc/} ]]; then echo $(ls ${1/%.abc/}/*.abc 2> /dev/null); fi) sortSupportClasses @@ -109,13 +109,13 @@ # Exclude testcases that need imports from shell_toplevel (avmplus, # avmshell packages) until versioned identifiers are supported. function shouldExcludeTest() { - local asfile=${1/ab[cs]/as} - grep --quiet --no-messages "import avmplus\|import avmshell" "$asfile" - if [[ $? -eq 0 ]]; then - return 1 - else +# local asfile=${1/ab[cs]/as} +# grep --quiet --no-messages "import avmplus\|import avmshell" "$asfile" +# if [[ $? -eq 0 ]]; then +# return 1 +# else return 0 - fi +# fi } export -f linkTamarinTest sortSupportClasses shouldExcludeTest @@ -128,7 +128,7 @@ # incompatible with previous version of this script. Use Assert.as, a # file introduced in that commit, to detect the new test setup. if [[ -f $TAMARIN/test/acceptance/Assert.as ]]; then - makeTamarin2; + makeTamarin2 $1; else - makeTamarin1; + makeTamarin1 $1; fi
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
.