Skip to content

Commit

Permalink
Fixed super() and super.method() call bug
Browse files Browse the repository at this point in the history
  • Loading branch information
qtnc committed Jul 20, 2019
1 parent 04c3c66 commit e354533
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 14 deletions.
4 changes: 2 additions & 2 deletions benchmark/binary_trees.swan
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var minDepth = 4
var maxDepth = 12
var stretchDepth = maxDepth + 1

var start = System.clock
var start = clock()

print("stretch tree of depth " + stretchDepth + " check: " +
"" + Tree(0, stretchDepth).check)
Expand All @@ -44,4 +44,4 @@ while (depth < stretchDepth) {
}

print( "long lived tree of depth " + maxDepth + " check: " + longLivedTree.check)
print(format("elapsed: %1", (System.clock - start)))
print(format("elapsed: %1", (clock() - start)))
4 changes: 2 additions & 2 deletions benchmark/fib.swan
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ function fib (n) {
}


var start = System.clock
var start = clock()
for i in 1...5 {
print(fib(28))
}
print(format("elapsed: %1", (System.clock - start)))
print(format("elapsed: %1", (clock() - start)))
4 changes: 2 additions & 2 deletions benchmark/for.swan
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
var list = []

var start = System.clock
var start = clock()
for i in 0..2500000: list.add(i)

var sum = 0
for i in list: sum += i

print(sum)
print("elapsed: "+(System.clock - start))
print("elapsed: "+(clock() - start))
4 changes: 2 additions & 2 deletions benchmark/method_call.swan
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class NthToggle is Toggle {
}
}

var start = System.clock
var start = clock()
var n = 250000
var val = true
var toggle = Toggle(val)
Expand Down Expand Up @@ -67,4 +67,4 @@ for i in 0..n {

print(ntoggle.value)

print("elapsed: " + (System.clock - start))
print("elapsed: " + (clock() - start))
13 changes: 11 additions & 2 deletions src/swan/parser/ParserCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ struct SuperExpression: Expression {
QToken superToken;
SuperExpression (const QToken& t): superToken(t) {}
const QToken& nearestToken () override { return superToken; }
void compile (QCompiler& compiler) override { compiler.writeOp(OP_LOAD_THIS); }
void compile (QCompiler& compiler) override;
};

struct GenericMethodSymbolExpression: Expression {
Expand Down Expand Up @@ -2652,6 +2652,15 @@ if (!isStatic) compiler.writeOpArg<uint_method_symbol_t>(OP_CALL_METHOD_1, compi
compiler.writeOpArg<uint_field_index_t>(OP_STORE_STATIC_FIELD, fieldSlot);
}}

void SuperExpression::compile (QCompiler& compiler) {
auto cls = compiler.getCurClass();
if (!cls) compiler.compileError(superToken, "Can't use 'super' outside of a class");
else if (cls->parents.empty()) compiler.compileError(superToken, "Can't use 'super' when having no superclass");
else {
make_shared<NameExpression>(cls->parents[0])->optimize()->compile(compiler);
compiler.writeOp(OP_LOAD_THIS);
}}

bool LiteralSequenceExpression::isAssignable () {
if (items.size()<1) return false;
for (auto& item: items) {
Expand Down Expand Up @@ -2964,7 +2973,7 @@ string sName = string(setter->token.start, setter->token.length) + ("=");
int symbol = compiler.vm.findMethodSymbol(sName);
left->compile(compiler);
assignedValue->compile(compiler);
compiler.writeOpArg<uint_method_symbol_t>(OP_CALL_METHOD_2, symbol);
compiler.writeOpArg<uint_method_symbol_t>(super? OP_CALL_SUPER_2 : OP_CALL_METHOD_2, symbol);
return;
}
compiler.compileError(right->nearestToken(), ("Bad operand for '.' operator in assignment"));
Expand Down
8 changes: 4 additions & 4 deletions src/swan/vm/Fiber_calls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ if (!re) error<call_error>("%s has no method %s", cls.name, vm.methodSymbols[sym
void QFiber::callSuperSymbol (int symbol, int nArgs) {
uint32_t newStackBase = stack.size() -nArgs;
QV receiver = stack.at(newStackBase);
QClass* cls = receiver.getClass(vm) .parent;
QClass* cls = stack.at(newStackBase -1).asObject<QClass>();
stack.erase(stack.begin() + newStackBase -1);
QV method = cls->findMethod(symbol);
bool re = callFunc(method, nArgs);
if (!re) {
error<call_error>("%s has no method %s", cls->name, vm.methodSymbols[symbol]);
}}
if (!re) error<call_error>("%s has no method %s", cls->name, vm.methodSymbols[symbol]);
}

inline bool QFiber::callFunc (QV& method, int nArgs) {
uint32_t newStackBase = stack.size() -nArgs;
Expand Down

0 comments on commit e354533

Please sign in to comment.