mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 22:10:15 +03:00
Coerce values obtained from polyglot calls (#5832)
Coerce values obtained from polyglot calls to fix #5177. # Important Notes Adds `IntHolder` class into the `test/Tests` project to simulate access to a class with integer field.
This commit is contained in:
parent
1687dccda4
commit
e3f0888c5f
@ -7,6 +7,7 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||
import org.enso.interpreter.Constants;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
|
||||
import org.enso.interpreter.node.expression.builtin.text.util.ExpectStringNode;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
|
||||
@ -16,6 +17,7 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
description = "Gets a member by name from a polyglot object.",
|
||||
autoRegister = false)
|
||||
public class GetMemberNode extends Node {
|
||||
private @Child HostValueToEnsoNode fromHost = HostValueToEnsoNode.build();
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
private @Child ExpectStringNode expectStringNode = ExpectStringNode.build();
|
||||
@ -23,7 +25,8 @@ public class GetMemberNode extends Node {
|
||||
|
||||
Object execute(Object object, Object member_name) {
|
||||
try {
|
||||
return library.readMember(object, expectStringNode.execute(member_name));
|
||||
var value = library.readMember(object, expectStringNode.execute(member_name));
|
||||
return fromHost.execute(value);
|
||||
} catch (UnsupportedMessageException | UnknownIdentifierException e) {
|
||||
err.enter();
|
||||
throw new PanicException(e.getMessage(), this);
|
||||
|
@ -10,6 +10,7 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||
import org.enso.interpreter.Constants;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
|
||||
import org.enso.interpreter.node.expression.builtin.mutable.CoerceArrayNode;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
|
||||
@ -19,7 +20,7 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
description = "Instantiates a polyglot constructor.",
|
||||
autoRegister = false)
|
||||
public abstract class InstantiateNode extends Node {
|
||||
|
||||
@Child private HostValueToEnsoNode fromHost = HostValueToEnsoNode.build();
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
private final BranchProfile err = BranchProfile.create();
|
||||
@ -34,7 +35,8 @@ public abstract class InstantiateNode extends Node {
|
||||
Object doExecute(
|
||||
Object constructor, Object arguments, @Cached("build()") CoerceArrayNode coerce) {
|
||||
try {
|
||||
return library.instantiate(constructor, coerce.execute(arguments));
|
||||
var value = library.instantiate(constructor, coerce.execute(arguments));
|
||||
return fromHost.execute(value);
|
||||
} catch (UnsupportedMessageException | ArityException | UnsupportedTypeException e) {
|
||||
err.enter();
|
||||
throw new PanicException(e.getMessage(), this);
|
||||
|
@ -0,0 +1,11 @@
|
||||
package org.enso.base_test_helpers;
|
||||
|
||||
public final class IntHolder {
|
||||
public final int value;
|
||||
public final Integer boxed;
|
||||
|
||||
public IntHolder(int value) {
|
||||
this.value = value;
|
||||
this.boxed = value;
|
||||
}
|
||||
}
|
@ -3,9 +3,12 @@ from Standard.Base import all
|
||||
from Standard.Test import Test, Test_Suite
|
||||
import Standard.Test.Extensions
|
||||
|
||||
polyglot java import java.time.LocalDate
|
||||
polyglot java import java.lang.Double
|
||||
polyglot java import java.lang.Integer
|
||||
polyglot java import java.lang.String
|
||||
polyglot java import java.time.LocalDate
|
||||
polyglot java import java.util.function.Function
|
||||
polyglot java import org.enso.base_test_helpers.IntHolder
|
||||
|
||||
spec = Test.group "Polyglot" <|
|
||||
Test.specify "should be able to invoke a polyglot method by name and pass arguments" <|
|
||||
@ -19,9 +22,32 @@ spec = Test.group "Polyglot" <|
|
||||
Polyglot.new String ["42"] . should_equal "42"
|
||||
Polyglot.new String ["42"].to_array . should_equal "42"
|
||||
|
||||
Test.specify "use Integer created by constructor" <|
|
||||
Polyglot.new Integer [42] . should_equal 42
|
||||
|
||||
Test.specify "use Double created by constructor" <|
|
||||
Polyglot.new Double [42] . should_equal 42
|
||||
|
||||
Test.specify "use Integer read from Polyglot object" <|
|
||||
(Polyglot.get_member js_meaning "meaning") . should_equal 42
|
||||
|
||||
Test.specify "access Integer field from Polyglot object" <|
|
||||
js_meaning.meaning . should_equal 42
|
||||
|
||||
Test.specify "use Integer obtained from a call" <|
|
||||
Integer.parseInt "42" . should_equal 42
|
||||
|
||||
Test.specify "use Integer obtained from a read" <|
|
||||
hold = IntHolder.new (6 * 7)
|
||||
hold.value . should_equal 42
|
||||
hold.boxed . should_equal 42
|
||||
|
||||
Test.specify "should be able to execute a polyglot function object along with corresponding arguments" <|
|
||||
fun = Function.identity
|
||||
Polyglot.execute fun ["42"] . should_equal "42"
|
||||
Polyglot.execute fun ["42"].to_array . should_equal "42"
|
||||
|
||||
foreign js js_meaning = """
|
||||
return { meaning : 6 * 7 };
|
||||
|
||||
main = Test_Suite.run_main spec
|
||||
|
Loading…
Reference in New Issue
Block a user