From 91453472e5727eae0893f8a8669d0ae828056253 Mon Sep 17 00:00:00 2001 From: Fabio Niephaus Date: Thu, 20 Jun 2019 17:37:59 +0200 Subject: [PATCH] Extend PolyglotPlugin - Let PrimGetMembersNode return an ArrayObject - Introduce PrimGetMemberSizeNode, PrimIsMemberInvocableNode, and PrimIsMemberReadableNode --- .../squeak/nodes/plugins/PolyglotPlugin.java | 60 ++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/src/de.hpi.swa.graal.squeak/src/de/hpi/swa/graal/squeak/nodes/plugins/PolyglotPlugin.java b/src/de.hpi.swa.graal.squeak/src/de/hpi/swa/graal/squeak/nodes/plugins/PolyglotPlugin.java index 3a732d448..73dc9d32a 100644 --- a/src/de.hpi.swa.graal.squeak/src/de/hpi/swa/graal/squeak/nodes/plugins/PolyglotPlugin.java +++ b/src/de.hpi.swa.graal.squeak/src/de/hpi/swa/graal/squeak/nodes/plugins/PolyglotPlugin.java @@ -294,11 +294,39 @@ protected PrimGetMembersNode(final CompiledMethodObject method) { super(method); } + @Specialization(guards = {"lib.hasMembers(receiver)"}, limit = "2") + protected final ArrayObject doGetMembers(final Object receiver, + @CachedLibrary("receiver") final InteropLibrary lib, + @CachedLibrary(limit = "2") final InteropLibrary membersLib, + @CachedLibrary(limit = "2") final InteropLibrary memberNameLib) { + try { + final Object members = lib.getMembers(receiver, true); + final int size = (int) membersLib.getArraySize(members); + final NativeObject[] byteStrings = new NativeObject[size]; + for (int i = 0; i < size; i++) { + final Object memberName = membersLib.readArrayElement(members, i); + byteStrings[i] = method.image.asByteString(memberNameLib.asString(memberName)); + } + return method.image.asArrayOfNativeObjects(byteStrings); + } catch (final UnsupportedMessageException | InvalidArrayIndexException e) { + throw SqueakException.illegalState(e); + } + } + } + + @GenerateNodeFactory + @SqueakPrimitive(names = "primitiveGetMemberSize") + protected abstract static class PrimGetMemberSizeNode extends AbstractPrimitiveNode implements UnaryPrimitive { + protected PrimGetMemberSizeNode(final CompiledMethodObject method) { + super(method); + } + @Specialization(guards = {"lib.hasMembers(receiver)"}, limit = "2") protected static final Object doGetMembers(final Object receiver, - @CachedLibrary("receiver") final InteropLibrary lib) { + @CachedLibrary("receiver") final InteropLibrary lib, + @CachedLibrary(limit = "2") final InteropLibrary sizeLib) { try { - return lib.getMembers(receiver, true); + return sizeLib.getArraySize(lib.getMembers(receiver, true)); } catch (final UnsupportedMessageException e) { throw SqueakException.illegalState(e); } @@ -457,6 +485,20 @@ protected final ArrayObject doList(@SuppressWarnings("unused") final Object rece } } + @GenerateNodeFactory + @SqueakPrimitive(names = "primitiveIsMemberInvocable") + protected abstract static class PrimIsMemberInvocableNode extends AbstractPrimitiveNode implements BinaryPrimitive { + protected PrimIsMemberInvocableNode(final CompiledMethodObject method) { + super(method); + } + + @Specialization(guards = {"member.isByteType()"}) + protected static final boolean doIsMemberInvocable(final Object receiver, final NativeObject member, + @CachedLibrary(limit = "2") final InteropLibrary lib) { + return BooleanObject.wrap(lib.isMemberInvocable(receiver, member.asStringUnsafe())); + } + } + @GenerateNodeFactory @SqueakPrimitive(names = "primitiveInvoke") protected abstract static class PrimInvokeNode extends AbstractPrimitiveNode implements TernaryPrimitive { @@ -741,6 +783,20 @@ protected static final boolean isArrayElementReadable(final InteropLibrary lib, } } + @GenerateNodeFactory + @SqueakPrimitive(names = "primitiveIsMemberReadable") + protected abstract static class PrimIsMemberReadableNode extends AbstractPrimitiveNode implements BinaryPrimitive { + protected PrimIsMemberReadableNode(final CompiledMethodObject method) { + super(method); + } + + @Specialization(guards = {"member.isByteType()"}) + protected static final boolean doIsMemberReadable(final Object receiver, final NativeObject member, + @CachedLibrary(limit = "2") final InteropLibrary lib) { + return BooleanObject.wrap(lib.isMemberReadable(receiver, member.asStringUnsafe())); + } + } + @GenerateNodeFactory @SqueakPrimitive(names = "primitiveReadMember") protected abstract static class PrimReadMemberNode extends AbstractPrimitiveNode implements BinaryPrimitive {