Skip to content

Commit

Permalink
Going to implement interface support
Browse files Browse the repository at this point in the history
  • Loading branch information
alexp-sssup committed Oct 27, 2009
1 parent 02f3ab2 commit 2071e67
Show file tree
Hide file tree
Showing 12 changed files with 271 additions and 89 deletions.
53 changes: 16 additions & 37 deletions abc.cpp
Expand Up @@ -131,9 +131,9 @@ void ABCVm::registerClasses()
Global.setVariableByQName("Sprite","flash.display",Class<Sprite>::getClass());
Global.setVariableByQName("Shape","flash.display",Class<Shape>::getClass());

Global.setVariableByQName("TextField","flash.text",new ASObject);
Global.setVariableByQName("TextFormat","flash.text",new ASObject);
Global.setVariableByQName("TextFieldType","flash.text",new ASObject);
Global.setVariableByQName("TextField","flash.text",Class<IInterface>::getClass("TextField"));
Global.setVariableByQName("TextFormat","flash.text",Class<IInterface>::getClass("TextFormat"));
Global.setVariableByQName("TextFieldType","flash.text",Class<IInterface>::getClass("TextFieldType"));

Global.setVariableByQName("XMLDocument","flash.xml",new ASObject);

Expand All @@ -143,27 +143,34 @@ void ABCVm::registerClasses()
Global.setVariableByQName("ByteArray","flash.utils",Class<ByteArray>::getClass());
Global.setVariableByQName("Dictionary","flash.utils",new ASObject);
Global.setVariableByQName("Proxy","flash.utils",new ASObject);
Global.setVariableByQName("Timer","flash.utils",new ASObject);
Global.setVariableByQName("Timer","flash.utils",Class<IInterface>::getClass("Timer"));
Global.setVariableByQName("getQualifiedClassName","flash.utils",new Function(getQualifiedClassName));

Global.setVariableByQName("Rectangle","flash.geom",new ASObject);
Global.setVariableByQName("Rectangle","flash.geom",Class<IInterface>::getClass("Rectangle"));
Global.setVariableByQName("Matrix","flash.geom",Class<IInterface>::getClass("Matrix"));
Global.setVariableByQName("Point","flash.geom",Class<IInterface>::getClass("Point"));

Global.setVariableByQName("EventDispatcher","flash.events",Class<EventDispatcher>::getClass());
Global.setVariableByQName("Event","flash.events",Class<Event>::getClass());
Global.setVariableByQName("MouseEvent","flash.events",Class<MouseEvent>::getClass());
Global.setVariableByQName("ProgressEvent","flash.events",Class<ProgressEvent>::getClass());
Global.setVariableByQName("IOErrorEvent","flash.events",Class<IOErrorEvent>::getClass());
Global.setVariableByQName("SecurityErrorEvent","flash.events",Class<FakeEvent>::getClass("SecurityErrorEvent"));
Global.setVariableByQName("TextEvent","flash.events",Class<FakeEvent>::getClass("TextEvent"));
Global.setVariableByQName("ErrorEvent","flash.events",Class<FakeEvent>::getClass("ErrorEvent"));
// Global.setVariableByQName("FocusEvent","flash.events",new FocusEvent);
// Global.setVariableByQName("KeyboardEvent","flash.events",new KeyboardEvent);
// Global.setVariableByQName("ProgressEvent","flash.events",new Event("ProgressEvent"));
// Global.setVariableByQName("IOErrorEvent","flash.events",new IOErrorEvent);

Global.setVariableByQName("LocalConnection","flash.net",new ASObject);
Global.setVariableByQName("URLRequest","flash.net",new URLRequest);
Global.setVariableByQName("URLVariables","flash.net",new ASObject);

Global.setVariableByQName("Capabilities","flash.system",new Capabilities);

Global.setVariableByQName("ContextMenu","flash.ui",Class<IInterface>::getClass("ContextMenu"));
Global.setVariableByQName("ContextMenuItem","flash.ui",Class<IInterface>::getClass("ContextMenuItem"));

Global.setVariableByQName("isNaN","",new Function(isNaN));
}

Expand Down Expand Up @@ -696,7 +703,7 @@ ABCContext::ABCContext(ABCVm* v,istream& in):vm(v),Global(&v->Global)
for(int i=0;i<class_count;i++)
{
in >> instances[i];
cout << "Class " << getString(instances[i].name) << endl;
cout << "Class " << *getMultiname(instances[i].name,NULL) << endl;
if(instances[i].supername)
cout << "Super " << *getMultiname(instances[i].supername,NULL) << endl;
if(instances[i].interface_count)
Expand Down Expand Up @@ -891,36 +898,6 @@ inline method_info* ABCContext::get_method(unsigned int m)
}
}

ASObject* ABCVm::nextValue(ASObject* index, ASObject* obj)
{
LOG(NOT_IMPLEMENTED,"nextValue");
abort();
}

void ABCVm::swap(call_context* th)
{
LOG(CALLS,"swap");
}

ASObject* ABCVm::newActivation(call_context* th,method_info* info)
{
LOG(CALLS,"newActivation");
//TODO: Should create a real activation object
//TODO: Should method traits be added to the activation context?
ASObject* act=new ASObject;
for(int i=0;i<info->body->trait_count;i++)
th->context->buildTrait(act,&info->body->traits[i]);

return act;
}

void ABCVm::popScope(call_context* th)
{
LOG(CALLS,"popScope");
th->scope_stack.back()->decRef();
th->scope_stack.pop_back();
}

//We follow the Boolean() algorithm, but return a concrete result, not a Boolean object
bool Boolean_concrete(ASObject* obj)
{
Expand Down Expand Up @@ -1882,6 +1859,8 @@ ASObject* isNaN(ASObject* obj,arguments* args)
{
if(args->at(0)->getObjectType()==T_UNDEFINED)
return abstract_b(true);
else if(args->at(0)->getObjectType()==T_INTEGER)
return abstract_b(false);
else
abort();
}
Expand Down
12 changes: 6 additions & 6 deletions abc_codesynt.cpp
Expand Up @@ -2353,8 +2353,9 @@ SyntheticFunction::synt_function method_info::synt_method()
stack_entry v1=static_stack_pop(Builder,static_stack,dynamic_stack,dynamic_stack_index);
stack_entry v2= static_stack_pop(Builder,static_stack,dynamic_stack,dynamic_stack_index);
constant = llvm::ConstantInt::get(int_type, t);
if(v1.second==STACK_INT)
v1.first=Builder.CreateCall(ex->FindFunctionNamed("abstract_i"),v1.first);

abstract_value(ex,Builder,v1);
abstract_value(ex,Builder,v2);
llvm::Value* cond=Builder.CreateCall3(ex->FindFunctionNamed("ifNGE"), v1.first, v2.first, constant);

syncStacks(ex,Builder,jitted,static_stack,dynamic_stack,dynamic_stack_index);
Expand Down Expand Up @@ -4304,10 +4305,9 @@ SyntheticFunction::synt_function method_info::synt_method()
LOG(TRACE, "synt lessequals" );
stack_entry v1=static_stack_pop(Builder,static_stack,dynamic_stack,dynamic_stack_index);
stack_entry v2=static_stack_pop(Builder,static_stack,dynamic_stack,dynamic_stack_index);
if(v1.second==STACK_INT)
v1.first=Builder.CreateCall(ex->FindFunctionNamed("abstract_i"),v1.first);
if(v2.second==STACK_INT)
v2.first=Builder.CreateCall(ex->FindFunctionNamed("abstract_i"),v2.first);

abstract_value(ex,Builder,v1);
abstract_value(ex,Builder,v2);
value=Builder.CreateCall2(ex->FindFunctionNamed("lessEquals"), v1.first, v2.first);
static_stack_push(static_stack,stack_entry(value,STACK_OBJECT));
push_index++;
Expand Down
76 changes: 70 additions & 6 deletions abc_opcodes.cpp
Expand Up @@ -214,7 +214,7 @@ void ABCVm::callProperty(call_context* th, int n, int m)
ASObject* obj=th->runtime_stack_pop();

//HACK osceno
if(name->name_s=="isWhiteListedUrl")
if(name->name_s=="isWhiteListedUrl" || name->name_s=="isAtLeastVersion")
{
LOG(NOT_IMPLEMENTED,"HACK osceno per youtube");
th->runtime_stack_push(new Boolean(true));
Expand Down Expand Up @@ -365,6 +365,13 @@ ASObject* ABCVm::getProperty(ASObject* obj, multiname* name)

number_t ABCVm::divide(ASObject* val2, ASObject* val1)
{
if(val1->getObjectType()==T_UNDEFINED ||
val2->getObjectType()==T_UNDEFINED)
{
//HACK
LOG(NOT_IMPLEMENTED,"subtract: HACK");
return 0;
}
double num1=val1->toNumber();
double num2=val2->toNumber();

Expand Down Expand Up @@ -622,7 +629,7 @@ void ABCVm::callPropVoid(call_context* th, int n, int m)
}
else if(o->getObjectType()==T_UNDEFINED)
{
LOG(NOT_IMPLEMENTED,"We got a Undefined function");
LOG(NOT_IMPLEMENTED,"We got a Undefined function onj type " << obj->prototype->class_name);
}
else if(o->getObjectType()==T_DEFINABLE)
{
Expand All @@ -636,7 +643,16 @@ void ABCVm::callPropVoid(call_context* th, int n, int m)
}
}
else
LOG(NOT_IMPLEMENTED,"Calling an undefined function");
{
if(obj->prototype)
{
LOG(NOT_IMPLEMENTED,"We got a Undefined function obj type " << obj->prototype->class_name);
}
else
{
LOG(NOT_IMPLEMENTED,"We got a Undefined function");
}
}

obj->actualPrototype=old_prototype;
obj->max_level=oldlevel;
Expand Down Expand Up @@ -675,7 +691,7 @@ number_t ABCVm::subtract_oi(ASObject* val2, intptr_t val1)
int num1=val1;

val2->decRef();
LOG(CALLS,"subtract " << num1 << '-' << num2);
LOG(CALLS,"subtract_oi " << num1 << '-' << num2);
return num1-num2;
}

Expand All @@ -691,17 +707,23 @@ number_t ABCVm::subtract_do(number_t val2, ASObject* val1)
number_t num1=val1->toNumber();

val1->decRef();
LOG(CALLS,"subtract " << num1 << '-' << num2);
LOG(CALLS,"subtract_do " << num1 << '-' << num2);
return num1-num2;
}

number_t ABCVm::subtract_io(intptr_t val2, ASObject* val1)
{
if(val1->getObjectType()==T_UNDEFINED)
{
//HACK
LOG(NOT_IMPLEMENTED,"subtract: HACK");
return 0;
}
int num2=val2;
int num1=val1->toInt();

val1->decRef();
LOG(CALLS,"subtract " << num1 << '-' << num2);
LOG(CALLS,"subtract_io " << num1 << '-' << num2);
return num1-num2;
}

Expand Down Expand Up @@ -1424,6 +1446,8 @@ void ABCVm::callSuperVoid(call_context* th, int n, int m)
LOG(CALLS,"callSuperVoid " << *name << ' ' << m);

ASObject* obj=th->runtime_stack_pop();

cout << "super name " << obj->actualPrototype->super->class_name << endl;
//HACK (nice) set the max level to the current actual prototype before looking up the member
assert(obj->actualPrototype);
int oldlevel=obj->max_level;
Expand Down Expand Up @@ -1735,3 +1759,43 @@ void ABCVm::asTypelate(call_context* th)
// th->runtime_stack_push(v);
}

ASObject* ABCVm::nextValue(ASObject* index, ASObject* obj)
{
LOG(NOT_IMPLEMENTED,"nextValue");
if(index->getObjectType()!=T_INTEGER)
{
LOG(ERROR,"Type mismatch");
abort();
}

ASObject* ret=obj->getValueAt(index->toInt()-1);
obj->decRef();
index->decRef();
ret->incRef();
return ret;
}

void ABCVm::swap(call_context* th)
{
LOG(CALLS,"swap");
}

ASObject* ABCVm::newActivation(call_context* th,method_info* info)
{
LOG(CALLS,"newActivation");
//TODO: Should create a real activation object
//TODO: Should method traits be added to the activation context?
ASObject* act=new ASObject;
for(int i=0;i<info->body->trait_count;i++)
th->context->buildTrait(act,&info->body->traits[i]);

return act;
}

void ABCVm::popScope(call_context* th)
{
LOG(CALLS,"popScope");
th->scope_stack.back()->decRef();
th->scope_stack.pop_back();
}

43 changes: 35 additions & 8 deletions asobjects.cpp
Expand Up @@ -54,6 +54,12 @@ Array::Array()
//ASObject::setVariableByQName("toString","",new Function(ASObject::_toString));
}

void Array::sinit(Class_base* c)
{
assert(c->constructor==NULL);
c->constructor=new Function(_constructor);
}

/*ASFUNCTIONBODY(Array,Array)
{
ASObject* ret=new ASArray();
Expand Down Expand Up @@ -590,11 +596,10 @@ Array::~Array()

ASFUNCTIONBODY(ASString,split)
{
abort();
/* ASString* th=static_cast<ASString*>(obj);
cout << th->data << endl;
Array* ret=new Array;
ret->_constructor(ret,NULL);
LOG(NOT_IMPLEMENTED,"ASString::split not really implemented");
ASString* th=static_cast<ASString*>(obj);
// cout << th->data << endl;
Array* ret=Class<Array>::getInstanceS(true);
ASObject* delimiter=args->at(0);
if(delimiter->getObjectType()==T_STRING)
{
Expand All @@ -614,7 +619,7 @@ ASFUNCTIONBODY(ASString,split)
else
abort();

return ret;*/
return ret->obj;
}

ASFUNCTIONBODY(ASString,String)
Expand Down Expand Up @@ -1027,8 +1032,11 @@ Math::Math()
setVariableByQName("PI","",new Number(M_PI));
setVariableByQName("sqrt","",new Function(sqrt));
setVariableByQName("atan2","",new Function(atan2));
setVariableByQName("max","",new Function(max));
setVariableByQName("abs","",new Function(abs));
setVariableByQName("sin","",new Function(sin));
setVariableByQName("floor","",new Function(floor));
setVariableByQName("round","",new Function(round));
setVariableByQName("random","",new Function(random));
}

Expand All @@ -1039,6 +1047,19 @@ ASFUNCTIONBODY(Math,atan2)
return new Number(::atan2(n1,n2));
}

ASFUNCTIONBODY(Math,max)
{
double n1=args->at(0)->toNumber();
double n2=args->at(1)->toNumber();
return new Number(::max(n1,n2));
}

ASFUNCTIONBODY(Math,sin)
{
double n=args->at(0)->toNumber();
return new Number(::sin(n*M_PI/180));
}

ASFUNCTIONBODY(Math,abs)
{
double n=args->at(0)->toNumber();
Expand All @@ -1051,6 +1072,12 @@ ASFUNCTIONBODY(Math,floor)
return new Integer(::floor(n));
}

ASFUNCTIONBODY(Math,round)
{
double n=args->at(0)->toNumber();
return new Integer(::round(n));
}

ASFUNCTIONBODY(Math,sqrt)
{
double n=args->at(0)->toNumber();
Expand Down Expand Up @@ -1133,11 +1160,11 @@ Class_base::~Class_base()
constructor->decRef();
}

IInterface* Class_inherit::getInstance()
IInterface* Class_inherit::getInstance(bool construct)
{
//TODO: Ask our super for the interface to ret
assert(super);
IInterface* ret=super->getInstance();
IInterface* ret=super->getInstance(construct);
ret->obj->max_level=max_level;
ret->obj->prototype->decRef();
ret->obj->prototype=this;
Expand Down

0 comments on commit 2071e67

Please sign in to comment.