Projects
Essentials
lightspark
Sign Up
Log In
Username
Password
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); + } + else + ret=abstract_d(function->getSystemState(),modulo(v1, v2)); context->runtime_stack_push(ret); break; } @@ -1593,8 +1665,8 @@ obj = context->parent_scope_stack->scope[t].object.getPtr(); else { - assert_and_throw(t-parentsize <context->scope_stack.size()); - obj=context->scope_stack[t-parentsize].object.getPtr(); + assert_and_throw(t-parentsize <context->curr_scope_stack); + obj=context->scope_stack[t-parentsize]; } obj->incRef(); context->runtime_stack_push(obj);
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 + ret = abstract_di(function->getSystemState(), num1%num2); + } + else + ret=abstract_d(function->getSystemState(),modulo(v1, v2)); context->runtime_stack_push(ret); break; }
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; } +uint64_t ABCVm::increment_di(ASObject* o) +{ + LOG(LOG_CALLS,_("increment_di")); + + int64_t n=o->toInt64(); + o->decRef(); + return n+1; +} + ASObject* ABCVm::nextValue(ASObject* index, ASObject* obj) { LOG(LOG_CALLS,"nextValue"); @@ -2325,8 +2370,11 @@ if (!th->parent_scope_stack.isNull()) ret->class_scope = th->parent_scope_stack->scope; - for (auto it = th->scope_stack.begin(); it != th->scope_stack.end(); it++) - ret->class_scope.push_back(*it); + for(uint32_t i = 0 ; i < th->curr_scope_stack; i++) + { + th->scope_stack[i]->incRef(); + ret->class_scope.push_back(scope_entry(_MR(th->scope_stack[i]),th->scope_stack_dynamic[i])); + } LOG(LOG_CALLS,_("Building class traits")); for(unsigned int i=0;i<th->context->classes[n].trait_count;i++) @@ -2416,8 +2464,11 @@ //cinit must inherit the current scope if (!th->parent_scope_stack.isNull()) cinit->acquireScope(th->parent_scope_stack->scope); - for (auto it = th->scope_stack.begin(); it != th->scope_stack.end(); it++) - cinit->addToScope(*it); + for(uint32_t i = 0 ; i < th->curr_scope_stack; i++) + { + th->scope_stack[i]->incRef(); + cinit->addToScope(scope_entry(_MR(th->scope_stack[i]),th->scope_stack_dynamic[i])); + } ASObject* ret2=NULL; try @@ -2489,7 +2540,8 @@ void ABCVm::popScope(call_context* th) { LOG(LOG_CALLS,_("popScope")); - th->scope_stack.pop_back(); + assert_and_throw(th->curr_scope_stack); + th->curr_scope_stack--; } bool ABCVm::lessThan(ASObject* obj1, ASObject* obj2) @@ -2585,8 +2637,11 @@ f->func_scope = _R<scope_entry_list>(new scope_entry_list()); if (!th->parent_scope_stack.isNull()) f->func_scope->scope=th->parent_scope_stack->scope; - for (auto it = th->scope_stack.begin(); it != th->scope_stack.end(); it++) - f->addToScope(*it); + for(uint32_t i = 0 ; i < th->curr_scope_stack; i++) + { + th->scope_stack[i]->incRef(); + f->addToScope(scope_entry(_MR(th->scope_stack[i]),th->scope_stack_dynamic[i])); + } //Bind the function to null, as this is not a class method f->bind(NullRef,-1); @@ -2597,8 +2652,8 @@ ASObject* ABCVm::getScopeObject(call_context* th, int n) { - assert_and_throw(th->scope_stack.size() > (size_t)n); - ASObject* ret=th->scope_stack[(size_t)n].object.getPtr(); + assert_and_throw(th->curr_scope_stack > (size_t)n); + ASObject* ret=th->scope_stack[(size_t)n]; ret->incRef(); LOG(LOG_CALLS, _("getScopeObject: ") << ret ); return ret;
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); + out->serializeDouble(toNumber()); }
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
.