package com.oracle.truffle.js.runtime.builtins;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.js.runtime.JSContext;
import com.oracle.truffle.js.runtime.objects.JSObject;
import com.oracle.truffle.js.runtime.objects.Undefined;
public abstract class JSPrimitive extends JSNonProxy implements PrototypeSupplier {
protected JSPrimitive() {
}
@TruffleBoundary
@Override
public final Object getHelper(DynamicObject store, Object thisObj, Object key, Node encapsulatingNode) {
assert this == JSNumber.INSTANCE || this == JSString.INSTANCE || this == JSBoolean.INSTANCE || this == JSBigInt.INSTANCE;
Object propertyValue = super.getHelper(store, thisObj, key, encapsulatingNode);
if (key instanceof String && allowJavaMembersFor(thisObj)) {
JSContext context = JSObject.getJSContext(store);
if (context.isOptionNashornCompatibilityMode() && context.getRealm().isJavaInteropEnabled()) {
if (propertyValue == null) {
return getJavaProperty(thisObj, (String) key, context);
}
}
}
return propertyValue;
}
private static Object getJavaProperty(Object thisObj, String name, JSContext context) {
String thisStr = (String) thisObj;
Object boxedString = context.getRealm().getEnv().asBoxedGuestValue(thisStr);
try {
return InteropLibrary.getFactory().getUncached().readMember(boxedString, name);
} catch (UnknownIdentifierException | UnsupportedMessageException e) {
return Undefined.instance;
}
}
@TruffleBoundary
@Override
public Object getMethodHelper(DynamicObject store, Object thisObj, Object key, Node encapsulatingNode) {
if (key instanceof String && allowJavaMembersFor(thisObj)) {
JSContext context = JSObject.getJSContext(store);
if (context.isOptionNashornCompatibilityMode() && context.getRealm().isJavaInteropEnabled()) {
if (hasOwnProperty(store, key)) {
Object method = getJavaMethod(thisObj, (String) key, context);
if (method != null) {
return method;
}
}
}
}
return super.getMethodHelper(store, thisObj, key, encapsulatingNode);
}
private static Object getJavaMethod(Object thisObj, String name, JSContext context) {
String thisStr = (String) thisObj;
Object boxedString = context.getRealm().getEnv().asBoxedGuestValue(thisStr);
try {
return InteropLibrary.getFactory().getUncached().readMember(boxedString, name);
} catch (UnknownIdentifierException | UnsupportedMessageException e) {
return null;
}
}
private static boolean allowJavaMembersFor(Object thisObj) {
return thisObj instanceof String;
}
}