Skip to content

Commit

Permalink
Disallow using 'super' in all context except method calls.
Browse files Browse the repository at this point in the history
  • Loading branch information
skinny85 committed Apr 20, 2024
1 parent a930017 commit 456ad1b
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ protected Object readIndexOrProperty(Object target, Object indexOrProperty) {

@Override
public Object evaluateAsReceiver(VirtualFrame frame) {
return this.getArrayExpr().executeGeneric(frame);
EasyScriptExprNode arrayExpr = this.getArrayExpr();
return arrayExpr instanceof SuperExprNode
? arrayExpr.evaluateAsReceiver(frame)
: arrayExpr.executeGeneric(frame);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,13 @@ public SuperExprNode(ClassPrototypeObject classPrototype) {

@Override
public Object executeGeneric(VirtualFrame frame) {
// executeGeneric() simply returns 'this'
// (that will be the method that property access Nodes use to establish the method call receiver,
// in their evaluateAsReceiver() methods)
return this.thisExprNode.executeGeneric(frame);
throw new EasyScriptException("'super' is not allowed here");
}

@Override
public Object evaluateAsReceiver(VirtualFrame frame) {
// receiver should be 'this' for a 'super()' call
return this.executeGeneric(frame);
return this.thisExprNode.executeGeneric(frame);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ protected Object readProperty(Object target) {

@Override
public Object evaluateAsReceiver(VirtualFrame frame) {
return this.getTargetExpr().executeGeneric(frame);
EasyScriptExprNode targetExpr = this.getTargetExpr();
return targetExpr instanceof SuperExprNode
? targetExpr.evaluateAsReceiver(frame)
: targetExpr.executeGeneric(frame);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,28 +94,6 @@ void super_is_static_not_dynamic() {
assertEquals("Base", result.asString());
}

@Test
void writing_to_super_writes_to_this() {
Value result = this.context.eval("ezs", "" +
"class Base { " +
" constructor() { " +
" this.x = 11; " +
" } " +
"} " +
"class Derived extends Base { " +
" setSuperX(x) {" +
" super.x = x; " +
" } " +
"} " +
"const obj = new Derived(); " +
"let x = obj.x; " +
"obj.setSuperX(3); " +
"x + obj.x;"
);

assertEquals(14, result.asInt());
}

@Test
void object_class_can_be_instantiated() {
Value result = this.context.eval("ezs", "" +
Expand Down Expand Up @@ -192,6 +170,63 @@ void extending_non_existent_class_is_an_error() {
}
}

@Test
void writing_to_super_is_an_error() {
try {
this.context.eval("ezs", "" +
"class Class { " +
" setSuperX(x) {" +
" super.x = x; " +
" } " +
"} " +
"new Class().setSuperX(3); "
);
fail("expected PolyglotException to be thrown");
} catch (PolyglotException e) {
assertTrue(e.isGuestException());
assertFalse(e.isInternalError());
assertEquals("'super' is not allowed here", e.getMessage());
}
}

@Test
void reading_from_super_is_an_error() {
try {
this.context.eval("ezs", "" +
"class Class { " +
" getSuperX() {" +
" return super.x; " +
" } " +
"} " +
"new Class().getSuperX(); "
);
fail("expected PolyglotException to be thrown");
} catch (PolyglotException e) {
assertTrue(e.isGuestException());
assertFalse(e.isInternalError());
assertEquals("'super' is not allowed here", e.getMessage());
}
}

@Test
void super_cannot_be_used_by_itself() {
try {
this.context.eval("ezs", "" +
"class Class { " +
" getSuper() {" +
" return super; " +
" } " +
"} " +
"new Class().getSuper(); "
);
fail("expected PolyglotException to be thrown");
} catch (PolyglotException e) {
assertTrue(e.isGuestException());
assertFalse(e.isInternalError());
assertEquals("'super' is not allowed here", e.getMessage());
}
}

@Test
public void benchmark_returns_its_input() {
var input = 100;
Expand Down

0 comments on commit 456ad1b

Please sign in to comment.