use of java.lang.invoke.MethodHandle in project es6draft by anba.
the class Properties method createInternalObjectLayout.
private static CompactLayout createInternalObjectLayout(Class<?> holder) {
try {
Lookup lookup = MethodHandles.publicLookup();
CompatibilityExtension extension = holder.getAnnotation(CompatibilityExtension.class);
CompatibilityOption option = extension != null ? extension.value() : null;
Object prototypeValue = CompactLayout.EMPTY;
ArrayList<PropertyLayout> properties = new ArrayList<>();
boolean hasProto = false;
for (Field field : holder.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers()))
continue;
Value value = field.getAnnotation(Value.class);
Prototype prototype = field.getAnnotation(Prototype.class);
assert value == null || prototype == null;
if (value != null) {
properties.add(new ValueLayout(value, getRawValue(field)));
}
if (prototype != null) {
assert !hasProto && (hasProto = true);
prototypeValue = getRawValue(field);
}
}
for (Method method : holder.getDeclaredMethods()) {
if (!Modifier.isStatic(method.getModifiers()))
continue;
Function function = method.getAnnotation(Function.class);
Accessor accessor = method.getAnnotation(Accessor.class);
AliasFunction[] aliases = method.getAnnotationsByType(AliasFunction.class);
TailCall tailCall = method.getAnnotation(TailCall.class);
Value value = method.getAnnotation(Value.class);
assert function == null || (accessor == null && value == null);
assert accessor == null || (function == null && value == null);
assert value == null || (function == null && accessor == null);
assert aliases.length == 0 || function != null;
assert tailCall == null || function != null;
if (value != null) {
MethodHandle mh = getComputedValueMethodHandle(lookup, method);
properties.add(new ValueLayout(value, mh));
} else if (accessor != null) {
MethodHandle mh = getStaticMethodHandle(lookup, method);
properties.add(new AccessorLayout(accessor, mh));
} else if (function != null) {
MethodHandle mh = getStaticMethodHandle(lookup, method);
if (tailCall == null) {
properties.add(new FunctionLayout(function, mh));
} else {
properties.add(new FunctionLayout(function, tailCall, mh));
}
for (AliasFunction a : aliases) {
properties.add(new AliasFunctionLayout(a, function));
}
}
}
return new CompactLayout(prototypeValue, properties, option);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException(e);
}
}
use of java.lang.invoke.MethodHandle in project es6draft by anba.
the class Properties method createExternalValues.
private static <OWNER> void createExternalValues(ExecutionContext cx, ScriptObject target, OWNER owner, ObjectLayout layout, Converter converter) {
for (Entry<Value, Object> entry : layout.values.entrySet()) {
Value val = entry.getKey();
assert entry.getValue() instanceof MethodHandle;
Object value = resolveValue(cx, converter, (MethodHandle) entry.getValue(), owner);
defineProperty(cx, target, val.name(), val.symbol(), val.attributes(), value);
}
}
use of java.lang.invoke.MethodHandle in project es6draft by anba.
the class Properties method createExternalFunctions.
private static void createExternalFunctions(ExecutionContext cx, OrdinaryObject target, ObjectLayout layout, Converter converter) {
for (Entry<Function, MethodHandle> entry : layout.functions.entrySet()) {
MethodHandle handle = getStaticMethodHandle(cx, converter, entry.getValue());
createExternalFunction(cx, target, entry.getKey(), handle);
}
}
use of java.lang.invoke.MethodHandle in project es6draft by anba.
the class Properties method getInstanceMethodHandle.
private static <OWNER> MethodHandle getInstanceMethodHandle(ExecutionContext cx, Converter converter, MethodHandle unreflect, OWNER owner) {
// var-args collector flag is not preserved when applying method handle combinators
boolean varargs = unreflect.isVarargsCollector();
MethodHandle handle = unreflect.bindTo(owner);
boolean callerContext = isCallerSensitive(handle);
final int fixedArguments = callerContext ? 1 : 0;
handle = bindContext(handle, cx);
handle = convertArguments(handle, fixedArguments, varargs, converter);
handle = convertReturn(handle, converter);
handle = catchExceptions(handle, converter);
handle = toCanonical(handle, fixedArguments, varargs, null);
if (!callerContext) {
handle = MethodHandles.dropArguments(handle, 0, ExecutionContext.class, Object.class);
} else {
handle = MethodHandles.dropArguments(handle, 1, Object.class);
}
assert handle.type().parameterCount() == 3;
assert handle.type().parameterType(0) == ExecutionContext.class;
assert handle.type().parameterType(1) == Object.class;
assert handle.type().parameterType(2) == Object[].class;
assert handle.type().returnType() == Object.class;
return handle;
}
use of java.lang.invoke.MethodHandle in project es6draft by anba.
the class Properties method getStaticMethodHandle.
private static MethodHandle getStaticMethodHandle(ExecutionContext cx, Converter converter, MethodHandle unreflect, MethodKind methodKind) {
// var-args collector flag is not preserved when applying method handle combinators
boolean varargs = unreflect.isVarargsCollector();
MethodHandle handle = unreflect;
boolean callerContext = isCallerSensitive(handle);
final int fixedArguments = callerContext ? 2 : 1;
final int constructorArgument = callerContext ? 1 : 0;
handle = bindContext(handle, cx);
if (methodKind == MethodKind.Default) {
handle = convertThis(handle, callerContext, converter);
} else if (methodKind == MethodKind.Call) {
handle = MethodHandles.insertArguments(handle, constructorArgument, (Constructor) null);
handle = convertThis(handle, callerContext, converter);
} else {
assert methodKind == MethodKind.Construct;
handle = MethodHandles.insertArguments(handle, constructorArgument + 1, (Object) null);
}
handle = convertArguments(handle, fixedArguments, varargs, converter);
if (methodKind != MethodKind.Construct) {
handle = convertReturn(handle, converter);
} else {
handle = convertConstructReturn(handle, converter);
}
handle = catchExceptions(handle, converter);
handle = toCanonical(handle, fixedArguments, varargs, null);
if (!callerContext) {
handle = MethodHandles.dropArguments(handle, 0, ExecutionContext.class);
}
if (methodKind != MethodKind.Construct) {
assert handle.type().parameterCount() == 3;
assert handle.type().parameterType(0) == ExecutionContext.class;
assert handle.type().parameterType(1) == Object.class;
assert handle.type().parameterType(2) == Object[].class;
assert handle.type().returnType() == Object.class;
} else {
assert handle.type().parameterCount() == 3;
assert handle.type().parameterType(0) == ExecutionContext.class;
assert handle.type().parameterType(1) == Constructor.class;
assert handle.type().parameterType(2) == Object[].class;
assert handle.type().returnType() == ScriptObject.class;
}
return handle;
}
Aggregations