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 106
View file
lightspark.spec
Changed
@@ -20,7 +20,7 @@ %bcond_without librtmp Name: lightspark -Version: 0.7.2.99+git20160417.1917 +Version: 0.7.2.99+git20160424.1301 Release: 0 Summary: Modern, free, open-source flash player implementation License: LGPL-3.0+
View file
lightspark.tar.xz/src/asobject.cpp
Changed
@@ -276,6 +276,11 @@ return toPrimitive()->toInt(); } +int64_t ASObject::toInt64() +{ + return toPrimitive()->toInt64(); +} + /* Implements ECMA's ToPrimitive (9.1) and [[DefaultValue]] (8.6.2.6) */ _R<ASObject> ASObject::toPrimitive(TP_HINT hint) { @@ -1168,10 +1173,10 @@ if(!obj) return NullRef; - if (this->is<Class_base>() && + if ( (!obj->var || !obj->var->isConstructed() || obj->var->getObjectType() == T_UNDEFINED || - obj->var->getObjectType() == T_NULL)) + obj->var->getObjectType() == T_NULL) && this->is<Class_base>()) { if (obj->kind == INSTANCE_TRAIT && getSystemState()->getNamespaceFromUniqueId(nsRealId).kind != STATIC_PROTECTED_NAMESPACE) @@ -1323,8 +1328,9 @@ void variables_map::destroyContents() { - const_var_iterator it=Variables.begin(); - while(it!=Variables.end()) + const_var_iterator it=Variables.cbegin(); + const_var_iterator itend=Variables.cend(); + while(it!=itend) { if(it->second.var) it->second.var->decRef();
View file
lightspark.tar.xz/src/asobject.h
Changed
@@ -520,18 +520,18 @@ void initSlot(unsigned int n, const multiname& name); void appendSlot(const multiname& name); unsigned int numVariables() const; - tiny_string getNameAt(int i) const + inline tiny_string getNameAt(int i) const { return Variables.getNameAt(sys,i); } _R<ASObject> getValueAt(int i); - SWFOBJECT_TYPE getObjectType() const + inline SWFOBJECT_TYPE getObjectType() const { return type; } - SystemState* getSystemState() const + inline SystemState* getSystemState() const { - assert_and_throw(sys); + assert(sys); return sys; } void setSystemState(SystemState* s) @@ -544,6 +544,7 @@ tiny_string toLocaleString(); virtual int32_t toInt(); virtual uint32_t toUInt(); + virtual int64_t toInt64(); uint16_t toUInt16(); /* Implements ECMA's 9.3 ToNumber operation, but returns the concrete value */ virtual number_t toNumber();
View file
lightspark.tar.xz/src/scripting/abc.cpp
Changed
@@ -739,7 +739,7 @@ case 0x07: //QName case 0x0D: //QNameA { - ret->ns.emplace_back(this, m->ns); + ret->ns.emplace_back(constant_pool.namespaces[m->ns].getNS(this,m->ns)); if (m->name) { ret->name_s_id=getString(m->name); @@ -754,7 +754,7 @@ ret->ns.reserve(s->count); for(unsigned int i=0;i<s->count;i++) { - ret->ns.emplace_back(this, s->ns[i]); + ret->ns.emplace_back(constant_pool.namespaces[s->ns[i]].getNS(this,s->ns[i])); } sort(ret->ns.begin(),ret->ns.end()); @@ -772,7 +772,7 @@ ret->ns.reserve(s->count); for(unsigned int i=0;i<s->count;i++) { - ret->ns.emplace_back(this, s->ns[i]); + ret->ns.emplace_back(constant_pool.namespaces[s->ns[i]].getNS(this,s->ns[i])); } sort(ret->ns.begin(),ret->ns.end()); break; @@ -812,7 +812,7 @@ } name += root->getSystemState()->getStringFromUniqueId(getString(p->name)); } - ret->ns.emplace_back(this, td->ns); + ret->ns.emplace_back(constant_pool.namespaces[td->ns].getNS(this,td->ns)); ret->name_s_id=root->getSystemState()->getUniqueStringId(name); ret->name_type=multiname::NAME_STRING; break; @@ -1437,6 +1437,10 @@ if(locals[i]) locals[i]->decRef(); } + while (curr_scope_stack) + { + scope_stack[--curr_scope_stack]->decRef(); + } } void call_context::handleError(int errorcode)
View file
lightspark.tar.xz/src/scripting/abc.h
Changed
@@ -455,6 +455,7 @@ static void label(); static void lookupswitch(); static int32_t convert_i(ASObject*); + static int64_t convert_di(ASObject*); static uint32_t convert_u(ASObject*); static number_t convert_d(ASObject*); static ASObject* convert_s(ASObject*); @@ -466,9 +467,11 @@ static ASObject* nextName(ASObject* index, ASObject* obj); static ASObject* nextValue(ASObject* index, ASObject* obj); static uint32_t increment_i(ASObject*); + static uint64_t increment_di(ASObject*); static number_t increment(ASObject*); static number_t decrement(ASObject*); static uint32_t decrement_i(ASObject*); + static uint64_t decrement_di(ASObject*); static bool strictEquals(ASObject*,ASObject*); static ASObject* esc_xattr(ASObject* o); static ASObject* esc_xelem(ASObject* o);
View file
lightspark.tar.xz/src/scripting/abc_codesynt.cpp
Changed
@@ -1954,7 +1954,7 @@ /* yield t = locals[i+1] */ LOAD_LOCALPTR /*calc n+offsetof(Number,val) = &n->val*/ - t=Builder.CreateGEP(t, llvm::ConstantInt::get(int_type, offsetof(Number,val))); + t=Builder.CreateGEP(t, llvm::ConstantInt::get(int_type, offsetof(Number,dval))); t=Builder.CreateBitCast(t,numberptr_type); //cast t from int8* to number* blocks[0].locals_start[i+1] = STACK_NUMBER; //locals_start_obj should hold the pointer to the local's value
View file
lightspark.tar.xz/src/scripting/abc_fast_interpreter.cpp
Changed
@@ -1035,59 +1035,77 @@ }case 0x73: { //convert_i - ASObject* val=context->runtime_stack_pop(); - if (val->is<Integer>()) - context->runtime_stack_push(val); - else + ASObject* val=context->runtime_stack_peek(); + if (!val || !val->is<Integer>()) + { + context->runtime_stack_pop(); context->runtime_stack_push(abstract_i(function->getSystemState(),convert_i(val))); + } break; } case 0x74: { //convert_u - ASObject* val=context->runtime_stack_pop(); - if (val->is<UInteger>()) - context->runtime_stack_push(val); - else + ASObject* val=context->runtime_stack_peek(); + if (!val || !val->is<UInteger>()) + { + context->runtime_stack_pop(); // force exception context->runtime_stack_push(abstract_ui(function->getSystemState(),convert_u(val))); + } break; } case 0x75: { //convert_d - ASObject* val=context->runtime_stack_pop(); - if (val->is<Number>()) - context->runtime_stack_push(val); - else - context->runtime_stack_push(abstract_d(function->getSystemState(),convert_d(val))); + ASObject* val=context->runtime_stack_peek(); + if (!val) + context->runtime_stack_pop(); // force exception + switch (val->getObjectType()) + { + case T_INTEGER: + case T_BOOLEAN: + case T_UINTEGER: + val =context->runtime_stack_pop(); + context->runtime_stack_push(abstract_di(function->getSystemState(),convert_di(val))); + break; + case T_NUMBER: + break; + default: + val =context->runtime_stack_pop(); + context->runtime_stack_push(abstract_d(function->getSystemState(),convert_d(val))); + break; + } break; } case 0x76: { //convert_b - ASObject* val=context->runtime_stack_pop(); - if (val->is<Boolean>()) - context->runtime_stack_push(val); - else + ASObject* val=context->runtime_stack_peek(); + if (!val || !val->is<Boolean>()) + { + context->runtime_stack_pop(); context->runtime_stack_push(abstract_b(function->getSystemState(),convert_b(val))); + } break; } case 0x77: { //convert_o - ASObject* val=context->runtime_stack_pop(); + ASObject* val=context->runtime_stack_peek(); + if (!val) + context->runtime_stack_pop(); // force exception if (val->is<Null>()) { + context->runtime_stack_pop(); LOG(LOG_ERROR,"trying to call convert_o on null"); throwError<TypeError>(kConvertNullToObjectError); } if (val->is<Undefined>()) { + context->runtime_stack_pop(); LOG(LOG_ERROR,"trying to call convert_o on undefined"); throwError<TypeError>(kConvertUndefinedToObjectError); } - - context->runtime_stack_push(val); break; } case 0x78: @@ -1160,7 +1178,11 @@ { //negate ASObject* val=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),negate(val)); + ASObject* ret; + if ((val->is<Integer>() || val->is<UInteger>() || (val->is<Number>() && !val->as<Number>()->isfloat)) && val->toInt64() != 0 && val->toInt64() == val->toInt()) + ret=abstract_di(function->getSystemState(),negate_i(val)); + else + ret=abstract_d(function->getSystemState(),negate(val)); context->runtime_stack_push(ret); break; } @@ -1168,7 +1190,11 @@ { //increment ASObject* val=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),increment(val)); + ASObject* ret; + if (val->is<Integer>() || (val->is<Number>() && !val->as<Number>()->isfloat)) + ret=abstract_di(function->getSystemState(),increment_i(val)); + else + ret=abstract_d(function->getSystemState(),increment(val)); context->runtime_stack_push(ret); break; } @@ -1184,7 +1210,11 @@ { //decrement ASObject* val=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),decrement(val)); + ASObject* ret; + if (val->is<Integer>() || val->is<UInteger>() || (val->is<Number>() && !val->as<Number>()->isfloat)) + ret=abstract_di(function->getSystemState(),decrement_di(val)); + else + ret=abstract_d(function->getSystemState(),decrement(val)); context->runtime_stack_push(ret); break; } @@ -1237,7 +1267,20 @@ ASObject* v2=context->runtime_stack_pop(); ASObject* v1=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),subtract(v2, v1)); + ASObject* ret; + // if both values are Integers or int Numbers the result is also an int Number + if( (v1->is<Integer>() || v1->is<UInteger>() || (v1->is<Number>() && !v1->as<Number>()->isfloat)) && + (v2->is<Integer>() || v2->is<UInteger>() || (v2->is<Number>() && !v2->as<Number>()->isfloat))) + { + int64_t num1=v1->toInt64(); + int64_t num2=v2->toInt64(); + LOG(LOG_CALLS,_("subtractI ") << num1 << '-' << num2); + v1->decRef(); + v2->decRef(); + ret = abstract_di(function->getSystemState(), num1-num2); + } + else + ret=abstract_d(function->getSystemState(),subtract(v2, v1)); context->runtime_stack_push(ret); break; } @@ -1247,7 +1290,20 @@ ASObject* v2=context->runtime_stack_pop(); ASObject* v1=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),multiply(v2, v1)); + ASObject* ret; + // if both values are Integers or int Numbers the result is also an int Number + if( (v1->is<Integer>() || v1->is<UInteger>() || (v1->is<Number>() && !v1->as<Number>()->isfloat)) && + (v2->is<Integer>() || v2->is<UInteger>() || (v2->is<Number>() && !v2->as<Number>()->isfloat))) + { + int64_t num1=v1->toInt64(); + int64_t num2=v2->toInt64(); + LOG(LOG_CALLS,_("multiplyI ") << num1 << '*' << num2); + v1->decRef(); + v2->decRef(); + ret = abstract_di(function->getSystemState(), num1*num2); + } + else + ret=abstract_d(function->getSystemState(),multiply(v2, v1)); context->runtime_stack_push(ret); break; } @@ -1267,7 +1323,23 @@ ASObject* v2=context->runtime_stack_pop(); ASObject* v1=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),modulo(v1, v2)); + ASObject* ret; + // if both values are Integers or int Numbers the result is also an int Number + if( (v1->is<Integer>() || v1->is<UInteger>() || (v1->is<Number>() && !v1->as<Number>()->isfloat)) && + (v2->is<Integer>() || v2->is<UInteger>() || (v2->is<Number>() && !v2->as<Number>()->isfloat))) + { + int64_t num1=v1->toInt64(); + int64_t num2=v2->toInt64(); + LOG(LOG_CALLS,_("moduloI ") << num1 << '%' << num2); + v1->decRef(); + v2->decRef(); + if (num2 == 0) + ret=abstract_d(function->getSystemState(),Number::NaN); + else + ret = abstract_di(function->getSystemState(), num1%num2);
View file
lightspark.tar.xz/src/scripting/abc_interpreter.cpp
Changed
@@ -1082,59 +1082,78 @@ }case 0x73: { //convert_i - ASObject* val=context->runtime_stack_pop(); - if (val->is<Integer>()) - context->runtime_stack_push(val); - else + ASObject* val=context->runtime_stack_peek(); + if (!val || !val->is<Integer>()) + { + context->runtime_stack_pop(); context->runtime_stack_push(abstract_i(function->getSystemState(),convert_i(val))); + } break; } case 0x74: { //convert_u - ASObject* val=context->runtime_stack_pop(); - if (val->is<UInteger>()) - context->runtime_stack_push(val); - else + ASObject* val=context->runtime_stack_peek(); + if (!val || !val->is<UInteger>()) + { + context->runtime_stack_pop(); context->runtime_stack_push(abstract_ui(function->getSystemState(),convert_u(val))); + } break; } case 0x75: { //convert_d - ASObject* val=context->runtime_stack_pop(); - if (val->is<Number>()) - context->runtime_stack_push(val); - else - context->runtime_stack_push(abstract_d(function->getSystemState(),convert_d(val))); + ASObject* val=context->runtime_stack_peek(); + if (!val) + context->runtime_stack_pop(); // force exception + switch (val->getObjectType()) + { + case T_INTEGER: + case T_BOOLEAN: + case T_UINTEGER: + val =context->runtime_stack_pop(); + + context->runtime_stack_push(abstract_di(function->getSystemState(),convert_di(val))); + break; + case T_NUMBER: + break; + default: + val =context->runtime_stack_pop(); + context->runtime_stack_push(abstract_d(function->getSystemState(),convert_d(val))); + break; + } break; } case 0x76: { //convert_b - ASObject* val=context->runtime_stack_pop(); - if (val->is<Boolean>()) - context->runtime_stack_push(val); - else + ASObject* val=context->runtime_stack_peek(); + if (!val || !val->is<Boolean>()) + { + context->runtime_stack_pop(); context->runtime_stack_push(abstract_b(function->getSystemState(),convert_b(val))); + } break; } case 0x77: { //convert_o - ASObject* val=context->runtime_stack_pop(); + ASObject* val=context->runtime_stack_peek(); + if (!val) + context->runtime_stack_pop(); // force exception if (val->is<Null>()) { + context->runtime_stack_pop(); LOG(LOG_ERROR,"trying to call convert_o on null"); throwError<TypeError>(kConvertNullToObjectError); } if (val->is<Undefined>()) { + context->runtime_stack_pop(); LOG(LOG_ERROR,"trying to call convert_o on undefined"); throwError<TypeError>(kConvertUndefinedToObjectError); } - - context->runtime_stack_push(val); break; } case 0x78: @@ -1193,7 +1212,11 @@ { //negate ASObject* val=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),negate(val)); + ASObject* ret; + if ((val->is<Integer>() || val->is<UInteger>() || (val->is<Number>() && !val->as<Number>()->isfloat)) && val->toInt64() != 0 && val->toInt64() == val->toInt()) + ret=abstract_di(function->getSystemState(),negate_i(val)); + else + ret=abstract_d(function->getSystemState(),negate(val)); context->runtime_stack_push(ret); break; } @@ -1201,7 +1224,11 @@ { //increment ASObject* val=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),increment(val)); + ASObject* ret; + if (val->is<Integer>() || val->is<UInteger>() || (val->is<Number>() && !val->as<Number>()->isfloat )) + ret=abstract_di(function->getSystemState(),increment_di(val)); + else + ret=abstract_d(function->getSystemState(),increment(val)); context->runtime_stack_push(ret); break; } @@ -1216,7 +1243,11 @@ { //decrement ASObject* val=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),decrement(val)); + ASObject* ret; + if (val->is<Integer>() || val->is<UInteger>() || (val->is<Number>() && !val->as<Number>()->isfloat)) + ret=abstract_di(function->getSystemState(),decrement_di(val)); + else + ret=abstract_d(function->getSystemState(),decrement(val)); context->runtime_stack_push(ret); break; } @@ -1268,7 +1299,20 @@ ASObject* v2=context->runtime_stack_pop(); ASObject* v1=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),subtract(v2, v1)); + ASObject* ret; + // if both values are Integers or int Numbers the result is also an int Number + if( (v1->is<Integer>() || v1->is<UInteger>() || (v1->is<Number>() && !v1->as<Number>()->isfloat)) && + (v2->is<Integer>() || v2->is<UInteger>() || (v2->is<Number>() && !v2->as<Number>()->isfloat))) + { + int64_t num1=v1->toInt64(); + int64_t num2=v2->toInt64(); + LOG(LOG_CALLS,_("subtractI ") << num1 << '-' << num2); + v1->decRef(); + v2->decRef(); + ret = abstract_di(function->getSystemState(), num1-num2); + } + else + ret=abstract_d(function->getSystemState(),subtract(v2, v1)); context->runtime_stack_push(ret); break; } @@ -1278,7 +1322,20 @@ ASObject* v2=context->runtime_stack_pop(); ASObject* v1=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),multiply(v2, v1)); + ASObject* ret; + // if both values are Integers or int Numbers the result is also an int Number + if( (v1->is<Integer>() || v1->is<UInteger>() || (v1->is<Number>() && !v1->as<Number>()->isfloat)) && + (v2->is<Integer>() || v2->is<UInteger>() || (v2->is<Number>() && !v2->as<Number>()->isfloat))) + { + int64_t num1=v1->toInt64(); + int64_t num2=v2->toInt64(); + LOG(LOG_CALLS,_("multiplyI ") << num1 << '*' << num2); + v1->decRef(); + v2->decRef(); + ret = abstract_di(function->getSystemState(), num1*num2); + } + else + ret=abstract_d(function->getSystemState(),multiply(v2, v1)); context->runtime_stack_push(ret); break; } @@ -1298,7 +1355,23 @@ ASObject* v2=context->runtime_stack_pop(); ASObject* v1=context->runtime_stack_pop(); - ASObject* ret=abstract_d(function->getSystemState(),modulo(v1, v2)); + ASObject* ret; + // if both values are Integers or int Numbers the result is also an int Number + if( (v1->is<Integer>() || v1->is<UInteger>() || (v1->is<Number>() && !v1->as<Number>()->isfloat)) && + (v2->is<Integer>() || v2->is<UInteger>() || (v2->is<Number>() && !v2->as<Number>()->isfloat))) + { + int64_t num1=v1->toInt64(); + int64_t num2=v2->toInt64(); + LOG(LOG_CALLS,_("moduloI ") << num1 << '%' << num2); + v1->decRef(); + v2->decRef(); + if (num2 == 0) + ret=abstract_d(function->getSystemState(),Number::NaN); + else
View file
lightspark.tar.xz/src/scripting/abc_opcodes.cpp
Changed
@@ -119,6 +119,14 @@ return ret; } +int64_t ABCVm::convert_di(ASObject* o) +{ + LOG(LOG_CALLS, _("convert_di") ); + int64_t ret=o->toInt64(); + o->decRef(); + return ret; +} + ASObject* ABCVm::convert_s(ASObject* o) { LOG(LOG_CALLS, _("convert_s") ); @@ -502,7 +510,10 @@ ASObject* t=th->runtime_stack_pop(); LOG(LOG_CALLS, _("pushWith ") << t ); t->incRef(); - th->scope_stack.emplace_back(scope_entry(_MR(t), true)); + assert_and_throw(th->curr_scope_stack < th->max_scope_stack); + th->scope_stack[th->curr_scope_stack] = t; + th->scope_stack_dynamic[th->curr_scope_stack] = true; + th->curr_scope_stack++; } void ABCVm::pushScope(call_context* th) @@ -510,7 +521,10 @@ ASObject* t=th->runtime_stack_pop(); LOG(LOG_CALLS, _("pushScope ") << t ); t->incRef(); - th->scope_stack.emplace_back(scope_entry(_MR(t), false)); + assert_and_throw(th->curr_scope_stack < th->max_scope_stack); + th->scope_stack[th->curr_scope_stack] = t; + th->scope_stack_dynamic[th->curr_scope_stack] = false; + th->curr_scope_stack++; } Global* ABCVm::getGlobalScope(call_context* th) @@ -520,8 +534,8 @@ ret =th->parent_scope_stack->scope[0].object.getPtr(); else { - assert_and_throw(th->scope_stack.size() > 0); - ret =th->scope_stack[0].object.getPtr(); + assert_and_throw(th->curr_scope_stack > 0); + ret =th->scope_stack[0]; } assert_and_throw(ret->is<Global>()); LOG(LOG_CALLS,_("getGlobalScope: ") << ret); @@ -542,7 +556,16 @@ { LOG(LOG_CALLS,_("decrement_i")); - int n=o->toInt(); + int32_t n=o->toInt(); + o->decRef(); + return n-1; +} + +uint64_t ABCVm::decrement_di(ASObject* o) +{ + LOG(LOG_CALLS,_("decrement_di")); + + int64_t n=o->toInt64(); o->decRef(); return n-1; } @@ -826,8 +849,8 @@ global =th->parent_scope_stack->scope[0].object.getPtr(); else { - assert_and_throw(th->scope_stack.size() > 0); - global =th->scope_stack[0].object.getPtr(); + assert_and_throw(th->curr_scope_stack > 0); + global =th->scope_stack[0]; } QName qname = o_class->class_name; if (!global->hasPropertyByMultiname(qname, false, false)) @@ -1000,10 +1023,22 @@ ASObject* ABCVm::add(ASObject* val2, ASObject* val1) { //Implement ECMA add algorithm, for XML and default (see avm2overview) - if(val1->is<Number>() && val2->is<Number>()) + + // if both values are Integers or int Numbers the result is also an int Number + if( (val1->is<Integer>() || val1->is<UInteger>() || (val1->is<Number>() && !val1->as<Number>()->isfloat)) && + (val2->is<Integer>() || val1->is<UInteger>() || (val2->is<Number>() && !val2->as<Number>()->isfloat))) + { + int64_t num1=val1->toInt64(); + int64_t num2=val2->toInt64(); + LOG(LOG_CALLS,"addI " << num1 << '+' << num2); + val1->decRef(); + val2->decRef(); + return abstract_di(val1->getSystemState(), num1+num2); + } + else if(val1->is<Number>() && val2->is<Number>()) { - double num1=val1->as<Number>()->val; - double num2=val2->as<Number>()->val; + double num1=val1->as<Number>()->toNumber(); + double num2=val2->as<Number>()->toNumber(); LOG(LOG_CALLS,"addN " << num1 << '+' << num2); val1->decRef(); val2->decRef(); @@ -1425,18 +1460,19 @@ ASObject* o = NULL; //Find out the current 'this', when looking up over it, we have to consider all of it - for(it=th->scope_stack.rbegin();it!=th->scope_stack.rend();++it) + for(uint32_t i = th->curr_scope_stack; i > 0; i--) { + ASObject* s = th->scope_stack[i-1]; // XML_STRICT flag tells getVariableByMultiname to // ignore non-existing properties in XML obejcts // (normally it would return an empty XMLList if the // property does not exist). ASObject::GET_VARIABLE_OPTION opt=ASObject::XML_STRICT; - if(!it->considerDynamic) + if(!th->scope_stack_dynamic[i-1]) opt=(ASObject::GET_VARIABLE_OPTION)(opt | ASObject::SKIP_IMPL); - checkDeclaredTraits(it->object.getPtr()); - _NR<ASObject> prop=it->object->getVariableByMultiname(*name, opt); + checkDeclaredTraits(s); + _NR<ASObject> prop=s->getVariableByMultiname(*name, opt); if(!prop.isNull()) { prop->incRef(); @@ -1513,14 +1549,14 @@ vector<scope_entry>::reverse_iterator it; bool found=false; ASObject* ret=NULL; - for(it =th->scope_stack.rbegin();it!=th->scope_stack.rend();++it) + for(uint32_t i = th->curr_scope_stack; i > 0; i--) { - found=it->object->hasPropertyByMultiname(*name, it->considerDynamic, true); + found=th->scope_stack[i-1]->hasPropertyByMultiname(*name, th->scope_stack_dynamic[i-1], true); if(found) { //We have to return the object, not the property - ret=it->object.getPtr(); + ret=th->scope_stack[i-1]; break; } } @@ -1551,8 +1587,8 @@ ret =th->parent_scope_stack->scope[0].object.getPtr(); else { - assert_and_throw(th->scope_stack.size() > 0); - ret =th->scope_stack[0].object.getPtr(); + assert_and_throw(th->curr_scope_stack > 0); + ret =th->scope_stack[0]; } } } @@ -1571,13 +1607,13 @@ bool found=false; ASObject* ret=NULL; - for(it =th->scope_stack.rbegin();it!=th->scope_stack.rend();++it) + for(uint32_t i = th->curr_scope_stack; i > 0; i--) { - found=it->object->hasPropertyByMultiname(*name, it->considerDynamic, true); + found=th->scope_stack[i-1]->hasPropertyByMultiname(*name, th->scope_stack_dynamic[i-1], true); if(found) { //We have to return the object, not the property - ret=it->object.getPtr(); + ret=th->scope_stack[i-1]; break; } } @@ -1603,9 +1639,9 @@ else { LOG(LOG_NOT_IMPLEMENTED,"findPropStrict: " << *name << " not found"); - for(it=th->scope_stack.rbegin();it!=th->scope_stack.rend();++it) + for(uint32_t i = th->curr_scope_stack; i > 0; i--) { - _R<ASObject> r = it->object; + ASObject* r = th->scope_stack[i-1]; if (!r->is<Class_base>()) continue; if (r->as<Class_base>()->findBorrowedGettable(*name)) @@ -2021,7 +2057,7 @@ ret->setConstructorCallComplete(); obj->decRef(); - LOG(LOG_CALLS,_("End of constructing ") << ret); + LOG(LOG_CALLS,_("End of constructing ") << ret->toDebugString()); } bool ABCVm::hasNext2(call_context* th, int n, int m) @@ -2166,6 +2202,15 @@ return n+1; }
View file
lightspark.tar.xz/src/scripting/abctypes.h
Changed
@@ -105,6 +105,19 @@ { u8 kind; u30 name; + bool cachefilled; + nsNameAndKind nscached; + namespace_info():cachefilled(false) {} + ~namespace_info(){ cachefilled=false; } + const nsNameAndKind& getNS(ABCContext * c, uint32_t nsContextIndex) + { + if (!cachefilled) + { + cachefilled = true; + nscached = nsNameAndKind(c,nsContextIndex); + } + return nscached; + } }; struct ns_set_info
View file
lightspark.tar.xz/src/scripting/abcutils.h
Changed
@@ -60,7 +60,10 @@ uint32_t max_stack; int32_t argarrayposition; // position of argument array in locals ( -1 if no argument array needed) _NR<scope_entry_list> parent_scope_stack; - std::vector<scope_entry> scope_stack; + uint32_t max_scope_stack; + uint32_t curr_scope_stack; + ASObject** scope_stack; + bool* scope_stack_dynamic; method_info* mi; /* This is the function's inClass that is currently executing. It is used * by {construct,call,get,set}Super @@ -79,25 +82,25 @@ } inline void runtime_stack_push(ASObject* s) { - if(stack_index>=max_stack) + if(stack_index<max_stack) + stack[stack_index++]=s; + else handleError(kStackOverflowError); - stack[stack_index++]=s; } inline ASObject* runtime_stack_pop() { - if(stack_index==0) + if(stack_index) + return stack[--stack_index]; + else handleError(kStackUnderflowError); - ASObject* ret=stack[--stack_index]; - return ret; + return NULL; } inline ASObject* runtime_stack_peek() { - if(stack_index==0) - { - LOG(LOG_ERROR,_("Empty stack")); - return NULL; - } - return stack[stack_index-1]; + if(stack_index) + return stack[stack_index-1]; + LOG(LOG_ERROR,_("Empty stack")); + return NULL; } };
View file
lightspark.tar.xz/src/scripting/argconv.h
Changed
@@ -155,6 +155,12 @@ } template<> +inline int64_t lightspark::ArgumentConversion<int64_t>::toConcrete(ASObject* obj) +{ + return obj->toInt64(); +} + +template<> inline tiny_string lightspark::ArgumentConversion<tiny_string>::toConcrete(ASObject* obj) { return obj->toString();
View file
lightspark.tar.xz/src/scripting/class.cpp
Changed
@@ -190,7 +190,9 @@ case T_BOOLEAN: return abstract_b(this->getSystemState(),Boolean_concrete(args[0])); case T_NUMBER: - return abstract_d(this->getSystemState(),args[0]->toNumber()); + if (!args[0]->as<Number>()->isfloat) + return abstract_di(this->getSystemState(), args[0]->toInt64()); + return abstract_d(this->getSystemState(), args[0]->toNumber()); case T_INTEGER: return abstract_i(this->getSystemState(),args[0]->toInt()); case T_UINTEGER:
View file
lightspark.tar.xz/src/scripting/toplevel/ASString.cpp
Changed
@@ -534,7 +534,14 @@ assert_and_throw(implEnable); return Integer::stringToASInteger(getData().raw_buf(), 0); } - +int64_t ASString::toInt64() +{ + int64_t value; + bool valid=Integer::fromStringFlashCompatible(getData().raw_buf(), value, 0); + if (!valid) + return 0; + return value; +} uint32_t ASString::toUInt() { assert_and_throw(implEnable); @@ -654,18 +661,19 @@ ASFUNCTIONBODY(ASString,charCodeAt) { - number_t index; + int64_t index; + ARG_UNPACK (index, 0); // fast path if obj is ASString if (obj->is<ASString>()) { - if(index<0 || index>=obj->as<ASString>()->getData().numChars() || std::isinf(index) || std::isnan(index)) + if(index<0 || index>=(int64_t)obj->as<ASString>()->getData().numChars()) return abstract_d(obj->getSystemState(),Number::NaN); return abstract_i(obj->getSystemState(),obj->as<ASString>()->getData().charAt(index)); } tiny_string data = obj->toString(); - if(index<0 || index>=data.numChars() || std::isinf(index) || std::isnan(index)) + if(index<0 || index>=(int64_t)data.numChars()) return abstract_d(obj->getSystemState(),Number::NaN); else {
View file
lightspark.tar.xz/src/scripting/toplevel/ASString.h
Changed
@@ -93,6 +93,8 @@ number_t toNumber(); int32_t toInt(); uint32_t toUInt(); + int64_t toInt64(); + ASFUNCTION(generator); //Serialization interface void serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap,
View file
lightspark.tar.xz/src/scripting/toplevel/Array.cpp
Changed
@@ -38,11 +38,11 @@ void Array::sinit(Class_base* c) { CLASS_SETUP(c, ASObject, _constructor, CLASS_DYNAMIC_NOT_FINAL); - c->setVariableByQName("CASEINSENSITIVE","",abstract_d(c->getSystemState(),CASEINSENSITIVE),CONSTANT_TRAIT); - c->setVariableByQName("DESCENDING","",abstract_d(c->getSystemState(),DESCENDING),CONSTANT_TRAIT); - c->setVariableByQName("NUMERIC","",abstract_d(c->getSystemState(),NUMERIC),CONSTANT_TRAIT); - c->setVariableByQName("RETURNINDEXEDARRAY","",abstract_d(c->getSystemState(),RETURNINDEXEDARRAY),CONSTANT_TRAIT); - c->setVariableByQName("UNIQUESORT","",abstract_d(c->getSystemState(),UNIQUESORT),CONSTANT_TRAIT); + c->setVariableByQName("CASEINSENSITIVE","",abstract_di(c->getSystemState(),CASEINSENSITIVE),CONSTANT_TRAIT); + c->setVariableByQName("DESCENDING","",abstract_di(c->getSystemState(),DESCENDING),CONSTANT_TRAIT); + c->setVariableByQName("NUMERIC","",abstract_di(c->getSystemState(),NUMERIC),CONSTANT_TRAIT); + c->setVariableByQName("RETURNINDEXEDARRAY","",abstract_di(c->getSystemState(),RETURNINDEXEDARRAY),CONSTANT_TRAIT); + c->setVariableByQName("UNIQUESORT","",abstract_di(c->getSystemState(),UNIQUESORT),CONSTANT_TRAIT); // properties c->setDeclaredMethodByQName("length","",Class<IFunction>::getFunction(c->getSystemState(),_getLength),GETTER_METHOD,true); @@ -197,7 +197,7 @@ it->second.data->incRef(); } else - params[0] =abstract_d(obj->getSystemState(),it->second.data_i); + params[0] =abstract_di(obj->getSystemState(),it->second.data_i); params[1] = abstract_i(obj->getSystemState(),it->first); params[2] = th; th->incRef(); @@ -246,7 +246,7 @@ it->second.data->incRef(); } else - params[0] =abstract_d(obj->getSystemState(),it->second.data_i); + params[0] =abstract_di(obj->getSystemState(),it->second.data_i); params[1] = abstract_i(obj->getSystemState(),it->first); params[2] = th; th->incRef(); @@ -292,7 +292,7 @@ it->second.data->incRef(); } else - params[0] =abstract_d(obj->getSystemState(),it->second.data_i); + params[0] =abstract_di(obj->getSystemState(),it->second.data_i); params[1] = abstract_i(obj->getSystemState(),it->first); params[2] = th; th->incRef(); @@ -411,7 +411,7 @@ int ret=-1; if(argslen == 1 && th->data.empty()) - return abstract_d(obj->getSystemState(),-1); + return abstract_di(obj->getSystemState(),-1); size_t i = th->size()-1; @@ -648,7 +648,7 @@ dtype = sl.type; assert_and_throw(dtype==DATA_OBJECT || dtype==DATA_INT); if((dtype == DATA_OBJECT && sl.data->isEqualStrict(arg0.getPtr())) || - (dtype == DATA_INT && abstract_d(obj->getSystemState(),sl.data_i)->isEqualStrict(arg0.getPtr()))) + (dtype == DATA_INT && abstract_di(obj->getSystemState(),sl.data_i)->isEqualStrict(arg0.getPtr()))) { ret=it->first; break; @@ -1240,7 +1240,7 @@ ret->incRef(); break; case DATA_INT: - ret=abstract_d(this->getSystemState(),sl.data_i); + ret=abstract_di(this->getSystemState(),sl.data_i); break; } return _MNR(ret); @@ -1470,7 +1470,7 @@ } } else if(sl.type==DATA_INT) - return _MR(abstract_d(getSystemState(),sl.data_i)); + return _MR(abstract_di(getSystemState(),sl.data_i)); else throw UnsupportedException("Unexpected data type"); } @@ -1533,7 +1533,7 @@ } } case DATA_INT: - return _MR(abstract_d(getSystemState(),sl.data_i)); + return _MR(abstract_di(getSystemState(),sl.data_i)); } //We should be here only if data is an object and is NULL @@ -1643,7 +1643,7 @@ { ASObject* params[2]; - params[0] = abstract_d(getSystemState(),it->first); + params[0] = abstract_di(getSystemState(),it->first); params[0]->incRef(); params[1] = o; params[1]->incRef();
View file
lightspark.tar.xz/src/scripting/toplevel/Boolean.cpp
Changed
@@ -46,7 +46,7 @@ case T_BOOLEAN: return o->as<Boolean>()->val; case T_NUMBER: - return (o->as<Number>()->val != 0.0) && !std::isnan(o->as<Number>()->val); + return (o->as<Number>()->isfloat ? o->as<Number>()->dval != 0.0 && !std::isnan(o->as<Number>()->dval) : o->as<Number>()->ival != 0); case T_INTEGER: return o->as<Integer>()->val != 0; case T_UINTEGER:
View file
lightspark.tar.xz/src/scripting/toplevel/Boolean.h
Changed
@@ -44,6 +44,10 @@ { return val ? 1 : 0; } + int64_t toInt64() + { + return val ? 1 : 0; + } bool isEqual(ASObject* r); TRISTATE isLess(ASObject* r); ASFUNCTION(_constructor);
View file
lightspark.tar.xz/src/scripting/toplevel/Date.cpp
Changed
@@ -313,7 +313,7 @@ return abstract_d(obj->getSystemState(),Number::NaN); } GTimeSpan diff = g_date_time_get_utc_offset(th->datetime); - return abstract_d(obj->getSystemState(),-diff/G_TIME_SPAN_MINUTE); + return abstract_di(obj->getSystemState(),-diff/G_TIME_SPAN_MINUTE); } ASFUNCTIONBODY(Date,getUTCFullYear) @@ -322,7 +322,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),th->extrayears + g_date_time_get_year(th->datetimeUTC)); + return abstract_di(obj->getSystemState(),th->extrayears + g_date_time_get_year(th->datetimeUTC)); } ASFUNCTIONBODY(Date,getUTCMonth) @@ -331,7 +331,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_month(th->datetimeUTC)-1); + return abstract_di(obj->getSystemState(),g_date_time_get_month(th->datetimeUTC)-1); } ASFUNCTIONBODY(Date,getUTCDate) @@ -340,7 +340,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_day_of_month(th->datetimeUTC)); + return abstract_di(obj->getSystemState(),g_date_time_get_day_of_month(th->datetimeUTC)); } ASFUNCTIONBODY(Date,getUTCDay) @@ -349,7 +349,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_day_of_week(th->datetimeUTC)%7); + return abstract_di(obj->getSystemState(),g_date_time_get_day_of_week(th->datetimeUTC)%7); } ASFUNCTIONBODY(Date,getUTCHours) @@ -358,7 +358,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_hour(th->datetimeUTC)); + return abstract_di(obj->getSystemState(),g_date_time_get_hour(th->datetimeUTC)); } ASFUNCTIONBODY(Date,getUTCMinutes) @@ -367,7 +367,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_minute(th->datetimeUTC)); + return abstract_di(obj->getSystemState(),g_date_time_get_minute(th->datetimeUTC)); } ASFUNCTIONBODY(Date,getUTCSeconds) @@ -376,7 +376,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_second(th->datetimeUTC)); + return abstract_di(obj->getSystemState(),g_date_time_get_second(th->datetimeUTC)); } ASFUNCTIONBODY(Date,getUTCMilliseconds) @@ -385,7 +385,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),th->milliseconds % 1000); + return abstract_di(obj->getSystemState(),th->milliseconds % 1000); } ASFUNCTIONBODY(Date,getFullYear) @@ -394,7 +394,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),th->extrayears + g_date_time_get_year(th->datetime)); + return abstract_di(obj->getSystemState(),th->extrayears + g_date_time_get_year(th->datetime)); } ASFUNCTIONBODY(Date,getMonth) @@ -403,7 +403,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_month(th->datetime)-1); + return abstract_di(obj->getSystemState(),g_date_time_get_month(th->datetime)-1); } ASFUNCTIONBODY(Date,getDate) @@ -412,7 +412,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_day_of_month(th->datetime)); + return abstract_di(obj->getSystemState(),g_date_time_get_day_of_month(th->datetime)); } ASFUNCTIONBODY(Date,getDay) @@ -421,7 +421,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_day_of_week(th->datetime)%7); + return abstract_di(obj->getSystemState(),g_date_time_get_day_of_week(th->datetime)%7); } ASFUNCTIONBODY(Date,getHours) @@ -430,7 +430,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_hour(th->datetime)); + return abstract_di(obj->getSystemState(),g_date_time_get_hour(th->datetime)); } ASFUNCTIONBODY(Date,getMinutes) @@ -439,7 +439,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_minute(th->datetime)); + return abstract_di(obj->getSystemState(),g_date_time_get_minute(th->datetime)); } ASFUNCTIONBODY(Date,getSeconds) @@ -448,7 +448,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),g_date_time_get_second(th->datetime)); + return abstract_di(obj->getSystemState(),g_date_time_get_second(th->datetime)); } ASFUNCTIONBODY(Date,getMilliseconds) @@ -457,7 +457,7 @@ if(th->nan) { return abstract_d(obj->getSystemState(),Number::NaN); } - return abstract_d(obj->getSystemState(),th->milliseconds % 1000); + return abstract_di(obj->getSystemState(),th->milliseconds % 1000); } ASFUNCTIONBODY(Date,getTime) @@ -831,9 +831,9 @@ ASObject* Date::msSinceEpoch() { - return abstract_d(getSystemState(),getMsSinceEpoch()); + return abstract_di(getSystemState(),getMsSinceEpoch()); } -number_t Date::getMsSinceEpoch() +int64_t Date::getMsSinceEpoch() { return milliseconds+extrayears/400*MS_IN_400_YEARS; }
View file
lightspark.tar.xz/src/scripting/toplevel/Date.h
Changed
@@ -35,7 +35,7 @@ GDateTime *datetime; GDateTime *datetimeUTC; ASObject *msSinceEpoch(); - number_t getMsSinceEpoch(); + int64_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); static number_t parse(tiny_string str);
View file
lightspark.tar.xz/src/scripting/toplevel/Integer.h
Changed
@@ -46,6 +46,10 @@ { return val; } + int64_t toInt64() + { + return val; + } TRISTATE isLess(ASObject* r); bool isEqual(ASObject* o); ASFUNCTION(_constructor);
View file
lightspark.tar.xz/src/scripting/toplevel/Number.cpp
Changed
@@ -39,7 +39,7 @@ case T_BOOLEAN: return as<Boolean>()->val ? 1 : 0; case T_NUMBER: - return as<Number>()->val; + return as<Number>()->toNumber(); case T_INTEGER: return as<Integer>()->val; case T_UINTEGER: @@ -58,10 +58,11 @@ { case T_INTEGER: case T_UINTEGER: + case T_BOOLEAN: + return isfloat ? toNumber()==o->toNumber() : toInt() == o->toInt(); case T_NUMBER: case T_STRING: - case T_BOOLEAN: - return val==o->toNumber(); + return toNumber()==o->toNumber(); case T_NULL: case T_UNDEFINED: return false; @@ -72,22 +73,32 @@ TRISTATE Number::isLess(ASObject* o) { - if(std::isnan(val)) + if(isfloat && std::isnan(dval)) return TUNDEFINED; switch(o->getObjectType()) { case T_INTEGER: - return (val<o->as<Integer>()->val)?TTRUE:TFALSE; + if(isfloat) + return (dval<o->as<Integer>()->val)?TTRUE:TFALSE; + else + return (ival<o->as<Integer>()->val)?TTRUE:TFALSE; case T_UINTEGER: - return (val<o->as<UInteger>()->val)?TTRUE:TFALSE; + if(isfloat) + return (dval<o->as<UInteger>()->val)?TTRUE:TFALSE; + else + return (ival<o->as<UInteger>()->val)?TTRUE:TFALSE; case T_NUMBER: { const Number* i=static_cast<const Number*>(o); - if(std::isnan(i->val)) return TUNDEFINED; - return (val<i->val)?TTRUE:TFALSE; + if(i->isfloat) + { + if (std::isnan(i->dval)) return TUNDEFINED; + return (toNumber()<i->dval)?TTRUE:TFALSE; + } + return (toInt64()<i->ival)?TTRUE:TFALSE; } case T_BOOLEAN: - return (val<o->toNumber())?TTRUE:TFALSE; + return (isfloat ? dval<o->toNumber() : ival < o->toInt())?TTRUE:TFALSE; case T_UNDEFINED: //Undefined is NaN, so the result is undefined return TUNDEFINED; @@ -95,15 +106,17 @@ { double val2=o->toNumber(); if(std::isnan(val2)) return TUNDEFINED; - return (val<val2)?TTRUE:TFALSE; + return (toNumber()<val2)?TTRUE:TFALSE; } case T_NULL: - return (val<0)?TTRUE:TFALSE; + if(isfloat) + return (dval<0)?TTRUE:TFALSE; + return (ival<0)?TTRUE:TFALSE; default: { double val2=o->toPrimitive()->toNumber(); if(std::isnan(val2)) return TUNDEFINED; - return (val<val2)?TTRUE:TFALSE; + return (toNumber()<val2)?TTRUE:TFALSE; } } } @@ -174,28 +187,36 @@ int radix=10; ARG_UNPACK (radix,10); - if(radix==10 || std::isnan(th->val) || std::isinf(th->val)) + if(radix==10 || (th->isfloat && std::isnan(th->dval)) || (th->isfloat && std::isinf(th->dval))) { //see e 15.7.4.2 return abstract_s(obj->getSystemState(),th->toString()); } else { - return abstract_s(obj->getSystemState(),Number::toStringRadix(th->val, radix)); + return abstract_s(obj->getSystemState(),Number::toStringRadix(th->toNumber(), radix)); } } ASFUNCTIONBODY(Number,generator) { if(argslen==0) - return abstract_d(getSys(),0.); - else - return abstract_d(args[0]->getSystemState(),args[0]->toNumber()); + return abstract_di(getSys(),0); + + switch (args[0]->getObjectType()) + { + case T_INTEGER: + case T_BOOLEAN: + case T_UINTEGER: + return abstract_di(args[0]->getSystemState(),args[0]->toInt()); + default: + return abstract_d(args[0]->getSystemState(),args[0]->toNumber()); + } } tiny_string Number::toString() { - return Number::toString(val); + return Number::toString(isfloat ? dval : ival); } /* static helper function */ @@ -309,11 +330,26 @@ if(argslen==0) { // not constructed Numbers are set to NaN, so we have to set it to the default value during dynamic construction - if (std::isnan(th->val)) - th->val = 0.; + if (std::isnan(th->dval)) + { + th->ival = 0; + th->isfloat =false; + } return NULL; } - th->val=args[0]->toNumber(); + switch (args[0]->getObjectType()) + { + case T_INTEGER: + case T_BOOLEAN: + case T_UINTEGER: + th->ival = args[0]->toInt(); + th->isfloat = false; + break; + default: + th->dval=args[0]->toNumber(); + th->isfloat = true; + break; + } return NULL; } @@ -362,7 +398,7 @@ ASFUNCTIONBODY(Number,toExponential) { Number* th=obj->as<Number>(); - double v = th->val; + double v = th->toNumber(); int32_t fractionDigits; ARG_UNPACK(fractionDigits, 0); if (argslen == 0 || args[0]->is<Undefined>()) @@ -469,7 +505,7 @@ ASFUNCTIONBODY(Number,toPrecision) { Number* th=obj->as<Number>(); - double v = th->val; + double v = th->toNumber(); if (argslen == 0 || args[0]->is<Undefined>()) return abstract_s(obj->getSystemState(),toString(v)); @@ -509,12 +545,13 @@ ASFUNCTIONBODY(Number,_valueOf) { if(Class<Number>::getClass(obj->getSystemState())->prototype->getObj() == obj) - return abstract_d(obj->getSystemState(),0.); + return abstract_di(obj->getSystemState(),0); if(!obj->is<Number>()) throwError<TypeError>(kInvokeOnIncompatibleObjectError); - return abstract_d(obj->getSystemState(),obj->as<Number>()->val); + return obj->as<Number>()->isfloat ? abstract_d(obj->getSystemState(),obj->as<Number>()->dval) + : abstract_d(obj->getSystemState(),obj->as<Number>()->ival); } void Number::serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, @@ -524,9 +561,9 @@ if (out->getObjectEncoding() == ObjectEncoding::AMF0) { out->writeByte(amf0_number_marker); - out->serializeDouble(val); + out->serializeDouble(toNumber()); return; } out->writeByte(double_marker); - out->serializeDouble(val);
View file
lightspark.tar.xz/src/scripting/toplevel/Number.h
Changed
@@ -29,7 +29,8 @@ class Number : public ASObject { -friend ASObject* abstract_d(number_t i); +friend ASObject* abstract_d(SystemState* sys,number_t i); +friend ASObject* abstract_di(SystemState* sys,int32_t i); friend class ABCContext; friend class ABCVm; private: @@ -37,11 +38,15 @@ static tiny_string purgeExponentLeadingZeros(const tiny_string& exponentialForm); static int32_t countSignificantDigits(double v); public: - Number(Class_base* c, double v=(std::numeric_limits<double>::quiet_NaN())):ASObject(c),val(v){type=T_NUMBER;} + Number(Class_base* c, double v=Number::NaN):ASObject(c),dval(v),isfloat(true){type=T_NUMBER;} static const number_t NaN; - double val; - inline number_t toNumber() { return val; } - inline void finalize() { val=std::numeric_limits<double>::quiet_NaN();} + union { + number_t dval; + int64_t ival; + }; + bool isfloat; + inline number_t toNumber() { return isfloat ? dval : ival; } + inline void finalize() { dval=Number::NaN; isfloat = true;} ASFUNCTION(_constructor); ASFUNCTION(_toString); ASFUNCTION(toExponential); @@ -56,41 +61,50 @@ static tiny_string toPrecisionString(double v, int32_t precision); static bool isInteger(number_t val) { - return floor(val) == val; + return trunc(val) == val; } unsigned int toUInt() { - return (unsigned int)(val); + return isfloat ? (unsigned int)(dval) : ival; } + int64_t toInt64() + { + if (!isfloat) return ival; + if(std::isnan(dval) || std::isinf(dval)) + return INT64_MAX; + return (int64_t)dval; + } + /* ECMA-262 9.5 ToInt32 */ int32_t toInt() { + if (!isfloat) return ival; double posInt; /* step 2 */ - if(std::isnan(val) || std::isinf(val) || val == 0) + if(std::isnan(dval) || std::isinf(dval) || dval == 0.0) return 0; /* step 3 */ - posInt = floor(fabs(val)); + posInt = floor(fabs(dval)); /* step 4 */ if (posInt > 4294967295.0) posInt = fmod(posInt, 4294967296.0); /* step 5 */ if (posInt >= 2147483648.0) { // follow tamarin - if(val < 0.0) + if(dval < 0.0) return 0x80000000 - (int32_t)(posInt - 2147483648.0); else return 0x80000000 + (int32_t)(posInt - 2147483648.0); } - return (int32_t)copysign(posInt, val); + return (int32_t)(dval < 0.0 ? -posInt : posInt); } TRISTATE isLess(ASObject* o); bool isEqual(ASObject* o); static void buildTraits(ASObject* o){}; static void sinit(Class_base* c); ASFUNCTION(generator); - std::string toDebugString() { return toString()+"d"; } + std::string toDebugString() { return toString()+(isfloat ? "d" : "di"); } //Serialization interface void serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, std::map<const ASObject*, uint32_t>& objMap,
View file
lightspark.tar.xz/src/scripting/toplevel/UInteger.h
Changed
@@ -38,6 +38,7 @@ inline number_t toNumber() { return val; } inline void finalize() { val=0; } inline int32_t toInt() { return val; } + inline int64_t toInt64() { return val; } inline uint32_t toUInt() { return val; } TRISTATE isLess(ASObject* r); bool isEqual(ASObject* o);
View file
lightspark.tar.xz/src/scripting/toplevel/Vector.cpp
Changed
@@ -508,7 +508,7 @@ ASObject* arg0=args[0]; if(th->vec.size() == 0) - return abstract_d(obj->getSystemState(),-1); + return abstract_di(obj->getSystemState(),-1); size_t i = th->size()-1; @@ -1117,7 +1117,7 @@ { ASObject* params[2]; - params[0] = abstract_d(getSystemState(),i); + params[0] = abstract_di(getSystemState(),i); params[0]->incRef(); params[1] = o; params[1]->incRef();
View file
lightspark.tar.xz/src/scripting/toplevel/XML.cpp
Changed
@@ -2365,6 +2365,18 @@ tiny_string str = toString_priv(); return Integer::stringToASInteger(str.raw_buf(), 0); } +int64_t XML::toInt64() +{ + if (!hasSimpleContent()) + return 0; + + tiny_string str = toString_priv(); + int64_t value; + bool valid=Integer::fromStringFlashCompatible(str.raw_buf(), value, 0); + if (!valid) + return 0; + return value; +} bool XML::nodesEqual(XML *a, XML *b) const {
View file
lightspark.tar.xz/src/scripting/toplevel/XML.h
Changed
@@ -163,6 +163,7 @@ tiny_string toString(); const tiny_string toXMLString_internal(bool pretty=true, tiny_string defaultnsprefix = "", const char* indent = "", bool bfirst = true); int32_t toInt(); + int64_t toInt64(); bool hasSimpleContent() const; bool hasComplexContent() const; pugi::xml_node_type getNodeKind() const;
View file
lightspark.tar.xz/src/scripting/toplevel/XMLList.cpp
Changed
@@ -1100,6 +1100,18 @@ tiny_string str = toString(); return Integer::stringToASInteger(str.raw_buf(), 0); } +int64_t XMLList::toInt64() +{ + if (!hasSimpleContent()) + return 0; + + tiny_string str = toString_priv(); + int64_t value; + bool valid=Integer::fromStringFlashCompatible(str.raw_buf(), value, 0); + if (!valid) + return 0; + return value; +} ASFUNCTIONBODY(XMLList,_toString) {
View file
lightspark.tar.xz/src/scripting/toplevel/XMLList.h
Changed
@@ -107,6 +107,7 @@ tiny_string toString(); tiny_string toXMLString_internal(bool pretty=true); int32_t toInt(); + int64_t toInt64(); bool isEqual(ASObject* r); uint32_t nextNameIndex(uint32_t cur_index); _R<ASObject> nextName(uint32_t index);
View file
lightspark.tar.xz/src/scripting/toplevel/toplevel.cpp
Changed
@@ -103,7 +103,11 @@ } } -int Undefined::toInt() +int32_t Undefined::toInt() +{ + return 0; +} +int64_t Undefined::toInt64() { return 0; } @@ -168,8 +172,8 @@ newObj =cc->parent_scope_stack->scope[0].object.getPtr(); else { - assert_and_throw(cc->scope_stack.size() > 0); - newObj =cc->scope_stack[0].object.getPtr(); + assert_and_throw(cc->curr_scope_stack > 0); + newObj =cc->scope_stack[0]; } newObj->incRef(); } @@ -210,8 +214,8 @@ newObj =cc->parent_scope_stack->scope[0].object.getPtr(); else { - assert_and_throw(cc->scope_stack.size() > 0); - newObj =cc->scope_stack[0].object.getPtr(); + assert_and_throw(cc->curr_scope_stack > 0); + newObj =cc->scope_stack[0]; } newObj->incRef(); } @@ -382,6 +386,15 @@ //cc.code= new istringstream(mi->body->code); cc.parent_scope_stack=func_scope; cc.exec_pos=0; + + cc.max_scope_stack = mi->body->max_scope_depth; + cc.curr_scope_stack= 0; + cc.scope_stack=g_newa(ASObject*, cc.max_scope_stack); + cc.scope_stack_dynamic=g_newa(bool, cc.max_scope_stack); + + memset(cc.scope_stack,0,sizeof(ASObject*)*cc.max_scope_stack); + cc.stack_index=0; + call_context* saved_cc = getVm(getSystemState())->currentCallContext; cc.defaultNamespaceUri = saved_cc ? saved_cc->defaultNamespaceUri : (uint32_t)BUILTIN_STRINGS::EMPTY; @@ -496,7 +509,10 @@ cc.exec_pos = exc.target; cc.runtime_stack_clear(); cc.runtime_stack_push(excobj); - cc.scope_stack.clear(); + while (cc.curr_scope_stack) + { + cc.scope_stack[--cc.curr_scope_stack]->decRef(); + } break; } } @@ -658,7 +674,11 @@ return NullRef; } -int Null::toInt() +int32_t Null::toInt() +{ + return 0; +} +int64_t Null::toInt64() { return 0; } @@ -2549,7 +2569,7 @@ } if (name.normalizedName(getSystemState()) == "length") { - return _NR<ASObject>(abstract_d(getSystemState(),_length)); + return _NR<ASObject>(abstract_di(getSystemState(),_length)); } return getClass()->getVariableByMultiname(name, opt); }
View file
lightspark.tar.xz/src/scripting/toplevel/toplevel.h
Changed
@@ -667,6 +667,7 @@ ASFUNCTION(call); Undefined(); int32_t toInt(); + int64_t toInt64(); bool isEqual(ASObject* r); TRISTATE isLess(ASObject* r); ASObject *describeType() const; @@ -684,6 +685,7 @@ bool isEqual(ASObject* r); TRISTATE isLess(ASObject* r); int32_t toInt(); + int64_t toInt64(); _NR<ASObject> getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt); int32_t getVariableByMultiname_i(const multiname& name); void setVariableByMultiname(const multiname& name, ASObject* o, CONST_ALLOWED_FLAG allowConst);
View file
lightspark.tar.xz/src/swftypes.cpp
Changed
@@ -127,8 +127,25 @@ name_type = NAME_INT; break; case T_NUMBER: - name_d=n->as<Number>()->val; - name_type = NAME_NUMBER; + if (n->as<Number>()->isfloat) + { + name_d=n->as<Number>()->toNumber(); + name_type = NAME_NUMBER; + } + else + { + int64_t di = n->as<Number>()->toInt64(); + if (di > INT32_MAX || di < INT32_MIN) + { + name_d=n->as<Number>()->toNumber(); + name_type = NAME_NUMBER; + } + else + { + name_i= di; + name_type = NAME_INT; + } + } break; case T_QNAME: { @@ -1380,7 +1397,15 @@ ASObject* lightspark::abstract_d(SystemState* sys,number_t i) { Number* ret=Class<Number>::getInstanceSNoArgs(sys); - ret->val = i; + ret->dval = i; + ret->isfloat = true; + return ret; +} +ASObject* lightspark::abstract_di(SystemState* sys,int64_t i) +{ + Number* ret=Class<Number>::getInstanceSNoArgs(sys); + ret->ival = i; + ret->isfloat = false; return ret; } ASObject* lightspark::abstract_i(SystemState *sys, int32_t i)
View file
lightspark.tar.xz/src/swftypes.h
Changed
@@ -315,6 +315,7 @@ uint32_t nsId; uint32_t nsRealId; bool nameIsEmpty; + nsNameAndKind():nsId(0),nsRealId(0),nameIsEmpty(true) {} nsNameAndKind(SystemState *sys, const tiny_string& _name, NS_KIND _kind); nsNameAndKind(SystemState* sys,const char* _name, NS_KIND _kind); nsNameAndKind(SystemState* sys,uint32_t _nameId, NS_KIND _kind); @@ -1337,6 +1338,7 @@ ASObject* abstract_i(SystemState *sys, int32_t i); ASObject* abstract_ui(SystemState *sys, uint32_t i); ASObject* abstract_d(SystemState *sys, number_t i); +ASObject* abstract_di(SystemState *sys, int64_t i); ASString* abstract_s(SystemState *sys); ASString* abstract_s(SystemState *sys, const char* s, uint32_t len); ASString* abstract_s(SystemState *sys, const char* s);
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
.