Skip to content
This repository has been archived by the owner on Jul 3, 2019. It is now read-only.

Separate passing tests from failing tests. #214

Merged
merged 4 commits into from Apr 6, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/avm2/compiler/builder.js
Expand Up @@ -1121,7 +1121,7 @@ var c4TraceLevel = c4Options.register(new Option("tc4", "tc4", "number", 0, "Com
var key = pop();
assert (isConstant(key) && isString(key.value));
key = constant(Multiname.getPublicQualifiedName(key.value));
properties.unshift(new KeyValuePair(key, value));
properties.push(new KeyValuePair(key, value));
}
push(new NewObject(properties));
break;
Expand Down
15 changes: 9 additions & 6 deletions src/avm2/compiler/inferrer.js
Expand Up @@ -253,18 +253,20 @@ var TraitsType = (function () {
}
}

traitsType.prototype.getTrait = function (mn, followSuperType) {
traitsType.prototype.getTrait = function (mn, isSetter, followSuperType) {
assert (arguments.length === 3);

if (followSuperType && this.isInstanceInfo()) {
var that = this;
do {
var trait = that.getTrait(mn);
var trait = that.getTrait(mn, isSetter, false);
if (!trait) {
that = that.super();
}
} while (!trait && that);
return trait;
} else {
return findTraitByName(this.traits, mn);
return findTraitByName(this.traits, mn, isSetter);
}
};

Expand Down Expand Up @@ -674,7 +676,8 @@ var Verifier = (function() {
// Try to find it in the scope stack.
for (var i = scope.length - 1; i >= 0; i--) {
if (scope[i] instanceof TraitsType) {
var trait = scope[i].getTrait(mn, true);
// TODO: Should we be looking for getter / setter traits?
var trait = scope[i].getTrait(mn, false, true);
if (trait) {
ti().scopeDepth = scope.length - i - 1;
return scope[i];
Expand Down Expand Up @@ -743,7 +746,7 @@ var Verifier = (function() {

function getProperty(obj, mn) {
if (obj instanceof TraitsType && mn instanceof Multiname) {
var trait = obj.getTrait(mn, true);
var trait = obj.getTrait(mn, false, true);
writer && writer.debugLn("getProperty(" + mn + ") -> " + trait);
if (trait) {
ti().trait = trait;
Expand All @@ -765,7 +768,7 @@ var Verifier = (function() {

function setProperty(obj, mn) {
if (obj instanceof TraitsType && mn instanceof Multiname) {
var trait = obj.getTrait(mn, true);
var trait = obj.getTrait(mn, true, true);
writer && writer.debugLn("setProperty(" + mn + ") -> " + trait);
if (trait) {
ti().trait = trait;
Expand Down
160 changes: 82 additions & 78 deletions src/avm2/runtime.js
Expand Up @@ -1182,6 +1182,45 @@ var Runtime = (function () {
}
}

if (instance) {
this.applyProtectedBindings(instance.prototype, cls);
this.applyInterfaceBindings(instance.prototype, cls);
}

// Run the static initializer.
this.createFunction(classInfo.init, scope).call(cls);

// Seal constant traits in the class object.
compatibility && this.sealConstantTraits(cls, ci.traits);

// TODO: Seal constant traits in the instance object. This should be done after
// the instance constructor has executed.

if (traceClasses.value) {
domain.loadedClasses.push(cls);
domain.traceLoadedClasses();
}

return cls;
};

runtime.prototype.createInterface = function createInterface(classInfo) {
var ii = classInfo.instanceInfo;
release || assert(ii.isInterface());
if (traceExecution.value) {
var str = "Creating interface " + ii.name;
if (ii.interfaces.length) {
str += " implements " + ii.interfaces.map(function (name) {
return name.getName();
}).join(", ");
}
print(str);
}
return new Interface(classInfo);
};

runtime.prototype.applyProtectedBindings = function applyProtectedBindings(obj, cls) {

// Deal with the protected namespace bullshit. In AS3, if you have the following code:
//
// class A {
Expand All @@ -1207,56 +1246,54 @@ var Runtime = (function () {
// Then we need a binding from protected$A$foo -> protected$C$foo, and
// protected$B$foo -> protected$C$foo.

function applyProtectedTraits(cls) {
var map = Object.create(null);
var map = Object.create(null);

// Walks up the inheritance hierarchy and collects the last defining namespace for each
// protected member as well as all the protected namespaces from the first definition.
(function gather(cls) {
if (cls.baseClass) {
gather(cls.baseClass);
}
var ii = cls.classInfo.instanceInfo;
for (var i = 0; i < ii.traits.length; i++) {
var trait = ii.traits[i];
if (trait.isProtected()) {
var name = trait.name.getName();
if (!map[name]) {
map[name] = {definingNamespace: ii.protectedNs, namespaces: [], trait: trait};
}
map[name].definingNamespace = ii.protectedNs;
// Walks up the inheritance hierarchy and collects the last defining namespace for each
// protected member as well as all the protected namespaces from the first definition.
(function gather(cls) {
if (cls.baseClass) {
gather(cls.baseClass);
}
var ii = cls.classInfo.instanceInfo;
for (var i = 0; i < ii.traits.length; i++) {
var trait = ii.traits[i];
if (trait.isProtected()) {
var name = trait.name.getName();
if (!map[name]) {
map[name] = {definingNamespace: ii.protectedNs, namespaces: [], trait: trait};
}
map[name].definingNamespace = ii.protectedNs;
}
for (var name in map) {
map[name].namespaces.push(ii.protectedNs);
}
})(cls);

var openMethods = instance.prototype[VM_OPEN_METHODS];
var vmBindings = instance.prototype[VM_BINDINGS];
}
for (var name in map) {
var definingNamespace = map[name].definingNamespace;
var protectedQn = Multiname.getQualifiedName(new Multiname([definingNamespace], name));
var namespaces = map[name].namespaces;
var trait = map[name].trait;
for (var i = 0; i < namespaces.length; i++) {
var qn = Multiname.getQualifiedName(new Multiname([namespaces[i]], name));
if (qn !== protectedQn) {
Counter.count("Protected Aliases");
defineNonEnumerableGetter(instance.prototype, qn, makeForwardingGetter(protectedQn));
defineNonEnumerableSetter(instance.prototype, qn, makeForwardingSetter(protectedQn));
vmBindings.push(qn);
if (trait.isMethod()) {
openMethods[qn] = openMethods[protectedQn];
}
map[name].namespaces.push(ii.protectedNs);
}
})(cls);

var openMethods = obj[VM_OPEN_METHODS];
var vmBindings = obj[VM_BINDINGS];
for (var name in map) {
var definingNamespace = map[name].definingNamespace;
var protectedQn = Multiname.getQualifiedName(new Multiname([definingNamespace], name));
var namespaces = map[name].namespaces;
var trait = map[name].trait;
for (var i = 0; i < namespaces.length; i++) {
var qn = Multiname.getQualifiedName(new Multiname([namespaces[i]], name));
if (qn !== protectedQn) {
Counter.count("Protected Aliases");
defineNonEnumerableGetter(obj, qn, makeForwardingGetter(protectedQn));
defineNonEnumerableSetter(obj, qn, makeForwardingSetter(protectedQn));
vmBindings.push(qn);
if (trait.isMethod()) {
openMethods[qn] = openMethods[protectedQn];
}
}
}
}
};

if (instance) {
applyProtectedTraits(cls);
}
runtime.prototype.applyInterfaceBindings = function applyInterfaceBindings(obj, cls) {
var domain = this.domain;

cls.implementedInterfaces = [];

Expand Down Expand Up @@ -1296,7 +1333,6 @@ var Runtime = (function () {
cls.implementedInterfaces.push(interface);
applyInterfaceTraits(ii.interfaces);

var bindings = instance.prototype;
var interfaceTraits = ii.traits;
for (var k = 0, l = interfaceTraits.length; k < l; k++) {
var interfaceTrait = interfaceTraits[k];
Expand All @@ -1313,47 +1349,15 @@ var Runtime = (function () {
}
}(interfaceTraitBindingQn);
Counter.count("Interface Aliases");
defineNonEnumerableGetter(bindings, interfaceTraitQn, getter);
defineNonEnumerableGetter(obj, interfaceTraitQn, getter);
}
}
}
// Apply traits of all interfaces along the inheritance chain.
var tmp = cls;
while (tmp) {
applyInterfaceTraits(tmp.classInfo.instanceInfo.interfaces);
tmp = tmp.baseClass;
}

// Run the static initializer.
this.createFunction(classInfo.init, scope).call(cls);

// Seal constant traits in the class object.
compatibility && this.sealConstantTraits(cls, ci.traits);

// TODO: Seal constant traits in the instance object. This should be done after
// the instance constructor has executed.

if (traceClasses.value) {
domain.loadedClasses.push(cls);
domain.traceLoadedClasses();
}

return cls;
};

runtime.prototype.createInterface = function createInterface(classInfo) {
var ii = classInfo.instanceInfo;
release || assert(ii.isInterface());
if (traceExecution.value) {
var str = "Creating interface " + ii.name;
if (ii.interfaces.length) {
str += " implements " + ii.interfaces.map(function (name) {
return name.getName();
}).join(", ");
}
print(str);
while (cls) {
applyInterfaceTraits(cls.classInfo.instanceInfo.interfaces);
cls = cls.baseClass;
}
return new Interface(classInfo);
};

/**
Expand Down
3 changes: 0 additions & 3 deletions src/avm2/tests/regress/correctness/functions-0.as

This file was deleted.

16 changes: 16 additions & 0 deletions src/avm2/tests/regress/correctness/pass/classes-1.as
@@ -0,0 +1,16 @@
package {
public class A {
function A() {
trace("Construct A");
}
}

var a = new A();
trace("-- SHOULD NOT CONSTRUCT AGAIN --");
A(a);
A(a);
A(a);
A(a);
A(a);
trace("-- DONE --");
}
34 changes: 34 additions & 0 deletions src/avm2/tests/regress/correctness/pass/flow.as
@@ -0,0 +1,34 @@
function quickSort(arrayInput, left, right) {
var i = left;
var j = right;
var pivotPoint = arrayInput[Math.round((left+right)*.5)];
while (i<=j) {
while (arrayInput[i]<pivotPoint) {
i++;
}
while (arrayInput[j]>pivotPoint) {
j--;
}
if (i<=j) {
var tempStore = arrayInput[i];
arrayInput[i] = arrayInput[j];
i++;
arrayInput[j] = tempStore;
j--;
}
}
if (left<j) {
quickSort(arrayInput, left, j);
}
if (i<right) {
quickSort(arrayInput, i, right);
}
return;
}

var a = [];
for (var i = 0; i < 100; i++) {
a.push(100 - i);
}
quickSort(a, 0, a.length - 1);
trace(a);
4 changes: 4 additions & 0 deletions src/avm2/tests/regress/correctness/pass/functions-0.as
@@ -0,0 +1,4 @@
// TODO: Method lengths should be correct, even before methods are first called.
// trace(Math.pow.length);
trace(Math.pow(4, 2));
trace(Math.pow.length);
39 changes: 39 additions & 0 deletions src/avm2/tests/regress/correctness/pass/interface-0.as
@@ -0,0 +1,39 @@
package {

interface IA
{
function foo() : void;
}

interface IB
{
function bar() : void;
}

class A implements IA
{
public function foo() : void
{
trace('bar');
}
}

class B extends A implements IB
{
public override function foo() : void
{
trace('bar');
}

public function bar() : void
{
trace('bar');
}
}

var ia : IA = new B();

ia.foo();

trace("-- DONE --");
}
@@ -1,7 +1,10 @@
package {
class A {
static function foo() {
return new A();
return new A().toString();
}
function toString() {
return "HELLO";
}
}
var f = A.foo;
Expand Down
7 changes: 7 additions & 0 deletions src/avm2/tests/regress/correctness/pass/phi-0.as
@@ -0,0 +1,7 @@
package {
function foo() {
var o = {"A": (1 || 2), "B" : 3};
trace(o.A);
}
foo();
}