diff --git a/part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/arrays/ArrayIndexReadExprNode.java b/part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/arrays/ArrayIndexReadExprNode.java index 3d52c99a..1ac42446 100644 --- a/part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/arrays/ArrayIndexReadExprNode.java +++ b/part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/arrays/ArrayIndexReadExprNode.java @@ -55,7 +55,7 @@ protected Object readStringPropertyOfObject(Object target, Object propertyName, * in code like {@code "a"[0]}, or {@code [1, 2][undefined]}. */ @Fallback - protected Object readPropertyOfObject(Object target, Object index, + protected Object readNonStringPropertyOfObject(Object target, Object index, @Cached ObjectPropertyReadNode objectPropertyReadNode) { return objectPropertyReadNode.executePropertyRead(target, index); } diff --git a/part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/properties/ObjectPropertyReadNode.java b/part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/properties/ObjectPropertyReadNode.java index 893d66a0..ca48467f 100644 --- a/part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/properties/ObjectPropertyReadNode.java +++ b/part-13/src/main/java/com/endoflineblog/truffle/part_13/nodes/exprs/properties/ObjectPropertyReadNode.java @@ -2,7 +2,6 @@ import com.endoflineblog.truffle.part_13.exceptions.EasyScriptException; import com.endoflineblog.truffle.part_13.nodes.exprs.strings.ReadTruffleStringPropertyNode; -import com.endoflineblog.truffle.part_13.runtime.ClassInstanceObject; import com.endoflineblog.truffle.part_13.runtime.Undefined; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -12,12 +11,12 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.object.DynamicObjectLibrary; import com.oracle.truffle.api.strings.TruffleString; /** - * A Node for reading the properties of a JavaScript object. + * A Node for reading a property of a JavaScript object. * Used by {@link PropertyReadExprNode} and {@link com.endoflineblog.truffle.part_13.nodes.exprs.arrays.ArrayIndexReadExprNode}. + * Identical to the class with the same name from part 11. */ public abstract class ObjectPropertyReadNode extends Node { public abstract Object executePropertyRead(Object target, Object property); @@ -33,27 +32,11 @@ protected Object readPropertyOfString(TruffleString target, Object property, target, property); } - /** - * The specialization for reading a property of a {@link com.endoflineblog.truffle.part_13.runtime.ClassInstanceObject}. - * Simply delegates to {@link PrototypePropertyReadNode}. - */ - @Specialization(limit = "1") - protected Object readPropertyOfClassInstance(ClassInstanceObject target, Object property, - @CachedLibrary("target.classPrototypeObject") DynamicObjectLibrary objectLibrary, - @Cached PrototypePropertyReadNode readStringPropertyNode) { - return readStringPropertyNode.executePropertyRead(target, property, - target.classPrototypeObject, objectLibrary); - } - - @Specialization(guards = { - "targetInteropLibrary.hasMembers(target)", - "propertyInteropLibrary.isString(property)" - }, limit = "1") - protected Object readProperty(Object target, Object property, - @CachedLibrary("target") InteropLibrary targetInteropLibrary, - @CachedLibrary("property") InteropLibrary propertyInteropLibrary) { + @Specialization(guards = "interopLibrary.hasMembers(target)", limit = "1") + protected Object readProperty(Object target, String propertyName, + @CachedLibrary("target") InteropLibrary interopLibrary) { try { - return targetInteropLibrary.readMember(target, propertyInteropLibrary.asString(property)); + return interopLibrary.readMember(target, propertyName); } catch (UnknownIdentifierException e) { return Undefined.INSTANCE; } catch (UnsupportedMessageException e) { diff --git a/part-13/src/main/java/com/endoflineblog/truffle/part_13/parsing/EasyScriptTruffleParser.java b/part-13/src/main/java/com/endoflineblog/truffle/part_13/parsing/EasyScriptTruffleParser.java index 1b5498f2..530b9380 100644 --- a/part-13/src/main/java/com/endoflineblog/truffle/part_13/parsing/EasyScriptTruffleParser.java +++ b/part-13/src/main/java/com/endoflineblog/truffle/part_13/parsing/EasyScriptTruffleParser.java @@ -555,9 +555,7 @@ private EasyScriptExprNode parseReference(String variableId) { return GlobalVarReferenceExprNodeGen.create(GlobalScopeObjectExprNodeGen.create(), variableId); } else { return frameMember instanceof FunctionArgument - // an int means this is a function parameter ? new ReadFunctionArgExprNode(((FunctionArgument) frameMember).argumentIndex) - // this means this is a local variable : LocalVarReferenceExprNodeGen.create(((LocalVariable) frameMember).variableIndex); } } diff --git a/part-13/src/main/java/com/endoflineblog/truffle/part_13/runtime/ClassInstanceObject.java b/part-13/src/main/java/com/endoflineblog/truffle/part_13/runtime/ClassInstanceObject.java index 1ad491e3..985d70d3 100644 --- a/part-13/src/main/java/com/endoflineblog/truffle/part_13/runtime/ClassInstanceObject.java +++ b/part-13/src/main/java/com/endoflineblog/truffle/part_13/runtime/ClassInstanceObject.java @@ -1,6 +1,8 @@ package com.endoflineblog.truffle.part_13.runtime; import com.endoflineblog.truffle.part_13.nodes.exprs.objects.NewExprNode; +import com.endoflineblog.truffle.part_13.nodes.exprs.properties.PrototypePropertyReadNode; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; @@ -48,9 +50,10 @@ boolean isMemberReadable(String member, } @ExportMessage - Object readMember(String member, @CachedLibrary("this.classPrototypeObject") DynamicObjectLibrary dynamicObjectLibrary) + Object readMember(String member, @CachedLibrary("this.classPrototypeObject") DynamicObjectLibrary dynamicObjectLibrary, + @Cached(uncached = "create()") PrototypePropertyReadNode prototypePropertyReadNode) throws UnknownIdentifierException { - Object value = dynamicObjectLibrary.getOrDefault(this.classPrototypeObject, member, null); + Object value = prototypePropertyReadNode.executePropertyRead(this, member, this.classPrototypeObject, dynamicObjectLibrary); if (value == null) { throw UnknownIdentifierException.create(member); } diff --git a/part-13/src/test/java/com/endoflineblog/truffle/part_13/FieldsTest.java b/part-13/src/test/java/com/endoflineblog/truffle/part_13/FieldsTest.java index 9feb8f0e..070bf8fb 100644 --- a/part-13/src/test/java/com/endoflineblog/truffle/part_13/FieldsTest.java +++ b/part-13/src/test/java/com/endoflineblog/truffle/part_13/FieldsTest.java @@ -7,6 +7,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class FieldsTest { @@ -47,4 +48,21 @@ void returning_this_from_a_method_returns_the_object() { ); assertTrue(result.asBoolean()); } + + @Test + void methods_can_be_called_through_polyglot_api() { + Value a = this.context.eval("ezs", "" + + "class A { " + + " returnThis() { " + + " return this; " + + " } " + + "} " + + "new A;" + ); + assertTrue(a.hasMember("returnThis")); + Value returnThis = a.getMember("returnThis"); + + Value result = returnThis.execute(); + assertFalse(result.isNull()); + } }