List of usage examples for org.objectweb.asm Opcodes INVOKEINTERFACE
int INVOKEINTERFACE
To view the source code for org.objectweb.asm Opcodes INVOKEINTERFACE.
Click Source Link
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ExactInvocation.java
private static boolean hasReceiver(int op) { return op == Opcodes.INVOKEVIRTUAL || op == Opcodes.INVOKEINTERFACE; }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ExactInvocation.java
@Override protected void generate(Location loc, CodeEmitter code, List<BytecodeExpression> args) { Preconditions.checkArgument(args.size() == getArgumentTypes().size(), "exactInvoker argument length mismatch: %s != expected %s", args.size(), getArgumentTypes().size()); for (BytecodeExpression arg : args) { code.exec(arg);/* ww w . j av a2s . co m*/ } code.getMethodVisitor().visitMethodInsn(op, ownerInternalName, methodName, desc, op == Opcodes.INVOKEINTERFACE); }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ExpressionHandler.java
@Override public BytecodeExpression list(Location loc, final List<BytecodeExpression> args) { List<TypeWidget> types = Lists.newArrayList(); for (BytecodeExpression e : args) { types.add(e.getType());// w ww. j a v a 2 s. co m } final TypeWidget unified = unify(types).boxed(); final ListTypeWidget out = new ListTypeWidget(NotNullableTypeWidget.create(unified)); return new BaseTypeExpression(out) { @Override public void generate(CodeEmitter code) { MethodVisitor mv = code.getMethodVisitor(); code.exec(out.construct(constant(args.size()))); for (BytecodeExpression expr : args) { Label skip = new Label(); mv.visitInsn(Opcodes.DUP); code.exec(expr); final TypeWidget type = expr.getType(); boolean nullable = code.cast(unified, type, skip); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Collection.class), "add", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getType(Object.class)), true); if (nullable) { // we're either going to POP the DUPed List OR the result of add mv.visitLabel(skip); } mv.visitInsn(Opcodes.POP); } } }; }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ExpressionHandler.java
@Override public BytecodeExpression invokeExact(Location loc, String methodName, Class<?> owner, TypeWidget returnType, List<BytecodeExpression> args) { return ExactInvocation.boundInvoke(owner.isInterface() ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, methodName, adapt(owner, false), returnType, args).invoke(loc); }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ExpressionHandler.java
@Override public BytecodeExpression in(Location loc, final BytecodeExpression left, final BytecodeExpression right) { return new BaseTypeExpression(BaseTypeAdapter.BOOLEAN) { @Override// ww w. j a va 2 s . co m public void generate(CodeEmitter code) { Label done = new Label(); Label anyIsNull = new Label(); CodeEmitter.BinaryCoercion coerce = code.binaryCoercion(right, Collection.class, left, Object.class, anyIsNull, anyIsNull, anyIsNull); MethodVisitor mv = code.getMethodVisitor(); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Collection.class), "contains", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getType(Object.class)), true); if (coerce.leftNullable || coerce.rightNullable) { mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(anyIsNull); mv.visitInsn(Opcodes.ICONST_0); mv.visitLabel(done); } } }; }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ExpressionHandler.java
@Override public BytecodeExpression scatter(Location location, BytecodeExpression runtime, BytecodeExpression iterable, CallableInvocable function) {/*from w w w . j a v a 2s . co m*/ BytecodeExpression callables = transform(location, iterable, function); TypeWidget resultType; boolean async = false; if (function.getResultType().isPromise()) { async = true; resultType = new ListTypeWidget(function.getResultType().getPromiseAdapter().getResultType()); } else { resultType = new ListTypeWidget(function.getResultType()); } ListenableFutureResultType futureResultType = new ListenableFutureResultType(resultType); return ExactInvocation.boundInvoke(Opcodes.INVOKEINTERFACE, async ? "scatterAsync" : "scatter", adapt(GambitRuntime.class, false), futureResultType, runtime, callables).invoke(location); }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ExpressionHandler.java
@Override public BytecodeExpression fork(Location location, BytecodeExpression runtime, CallableInvocable function, List<BytecodeExpression> arguments) { TypeWidget resultType;//ww w. java 2 s . c o m boolean async = false; if (function.getResultType().isPromise()) { async = true; resultType = function.getResultType().getPromiseAdapter().getResultType(); } else { resultType = function.getResultType(); } ListenableFutureResultType futureResultType = new ListenableFutureResultType(resultType); return ExactInvocation.boundInvoke(Opcodes.INVOKEINTERFACE, async ? "forkAsync" : "fork", adapt(GambitRuntime.class, false), futureResultType, runtime, cast(adapt(Callable.class, false), function.invoke(location, arguments))).invoke(location); }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.FuturePromiseAdapter.java
@Override public BytecodeExpression resolve(ScopedBuilder scope, BytecodeExpression timeout, BytecodeExpression target) { // long getRemaining(TimeUnit units); BytecodeExpression units = scope.constant(TimeUnit.NANOSECONDS); return new BytecodeCastExpression(valueType, ExactInvocation.boundInvoke( Opcodes.INVOKEINTERFACE, "get", scope.adapt(Future.class, false), AnyTypeWidget.getInstance(), target, ExactInvocation.boundInvoke(Opcodes.INVOKEINTERFACE, "getRemaining", BaseTypeAdapter.TIMEOUT_CORE, BaseTypeAdapter.INT64, timeout, units).invoke(Location.NONE), units).invoke(Location.NONE)); }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.PhysicalExprOperatorCompiler.java
public BytecodeExpression evaluateExpression(final BytecodeExpression program, final BytecodeExpression context, final OperatorNode<PhysicalExprOperator> expr) { switch (expr.getOperator()) { case ASYNC_INVOKE: case INVOKE: { GambitCreator.Invocable invocable = expr.getArgument(0); List<OperatorNode<PhysicalExprOperator>> args = expr.getArgument(1); List<BytecodeExpression> arguments = evaluateExpressions(program, context, args); BytecodeExpression result = scope.invoke(expr.getLocation(), invocable, arguments); if (expr.getOperator() == PhysicalExprOperator.ASYNC_INVOKE) { return scope.resolve(expr.getLocation(), getTimeout(context, expr.getLocation()), result); }//from w w w . j a v a 2 s . c o m return result; } case CALL: { TypeWidget outputType = expr.getArgument(0); String name = expr.getArgument(1); List<OperatorNode<PhysicalExprOperator>> arguments = expr.getArgument(2); List<BytecodeExpression> argumentExprs = evaluateExpressions(program, context, arguments); return scope.call(expr.getLocation(), outputType, name, argumentExprs); } case CONSTANT: { TypeWidget t = expr.getArgument(0); Object cval = expr.getArgument(1); return scope.constant(t, cval); } case ROOT_CONTEXT: { return scope.propertyValue(expr.getLocation(), program, "rootContext"); } case CURRENT_CONTEXT: return context; case TRACE_CONTEXT: { OperatorNode<PhysicalExprOperator> attrs = expr.getArgument(0); final BytecodeExpression metricDimension = asMetricDimension(program, context, attrs); return scope.invokeExact(expr.getLocation(), "start", TaskContext.class, context.getType(), context, metricDimension); } case TIMEOUT_MAX: { final BytecodeExpression timeout = scope.cast(BaseTypeAdapter.INT64, evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(0))); final BytecodeExpression units = evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(1)); return scope.invokeExact(expr.getLocation(), "timeout", TaskContext.class, context.getType(), context, timeout, units); } case TIMEOUT_GUARD: { final BytecodeExpression min = scope.cast(BaseTypeAdapter.INT64, evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(0))); final BytecodeExpression minUnits = evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(1)); final BytecodeExpression max = scope.cast(BaseTypeAdapter.INT64, evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(2))); final BytecodeExpression maxUnits = evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(3)); return scope.invokeExact(expr.getLocation(), "timeout", TaskContext.class, context.getType(), context, min, minUnits, max, maxUnits); } case END_CONTEXT: { final BytecodeExpression output = evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(0)); GambitCreator.ScopeBuilder child = scope.scope(); BytecodeExpression result = child.evaluateInto(output); child.exec( child.invokeExact(expr.getLocation(), "end", TaskContext.class, BaseTypeAdapter.VOID, context)); return child.complete(result); } case VALUE: { OperatorValue value = expr.getArgument(0); return resolveValue(expr.getLocation(), program, context, value); } case CAST: { final TypeWidget outputType = expr.getArgument(0); OperatorNode<PhysicalExprOperator> input = expr.getArgument(1); final BytecodeExpression output = evaluateExpression(program, context, input); return scope.cast(expr.getLocation(), outputType, output); } case FOREACH: { BytecodeExpression inputExpr = evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(0)); OperatorNode<FunctionOperator> function = expr.getArgument(1); TypeWidget itemType = inputExpr.getType().getIterableAdapter().getValue(); GambitCreator.Invocable functionImpl = compileFunction(program.getType(), context.getType(), ImmutableList.of(itemType), function); return scope.transform(expr.getLocation(), inputExpr, functionImpl.prefix(program, context)); } case FIRST: { BytecodeExpression inputExpr = evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(0)); return scope.first(expr.getLocation(), inputExpr); } case SINGLETON: { OperatorNode<PhysicalExprOperator> value = expr.getArgument(0); BytecodeExpression targetExpression = evaluateExpression(program, context, value); return scope.invokeExact(expr.getLocation(), "singleton", ProgramInvocation.class, new ListTypeWidget(targetExpression.getType()), program, scope.cast(AnyTypeWidget.getInstance(), targetExpression)); } case LENGTH: { BytecodeExpression inputExpr = evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(0)); return scope.length(expr.getLocation(), inputExpr); } case PROPREF: { OperatorNode<PhysicalExprOperator> target = expr.getArgument(0); String propertyName = expr.getArgument(1); BytecodeExpression targetExpr = evaluateExpression(program, context, target); return scope.propertyValue(expr.getLocation(), targetExpr, propertyName); } case INDEX: { OperatorNode<PhysicalExprOperator> target = expr.getArgument(0); OperatorNode<PhysicalExprOperator> index = expr.getArgument(1); BytecodeExpression targetExpr = evaluateExpression(program, context, target); BytecodeExpression indexExpr = evaluateExpression(program, context, index); return scope.indexValue(expr.getLocation(), targetExpr, indexExpr); } case WITH_CONTEXT: { GambitCreator.ScopeBuilder contextScope = scope.scope(); PhysicalExprOperatorCompiler compiler = new PhysicalExprOperatorCompiler(contextScope); BytecodeExpression ctxExpr = contextScope.evaluateInto(compiler.evaluateExpression(program, context, expr.<OperatorNode<PhysicalExprOperator>>getArgument(0))); OperatorNode<PhysicalExprOperator> exprTarget = expr.getArgument(1); BytecodeExpression resultExpr = compiler.evaluateExpression(program, ctxExpr, OperatorNode.create(PhysicalExprOperator.END_CONTEXT, exprTarget)); return contextScope.complete(resultExpr); } case CONCAT: { List<OperatorNode<PhysicalExprOperator>> iterables = expr.getArgument(0); List<BytecodeExpression> exprs = evaluateExpressions(program, context, iterables); List<TypeWidget> types = Lists.newArrayList(); for (BytecodeExpression e : exprs) { types.add(e.getType().getIterableAdapter().getValue()); } return scope .cast(expr.getLocation(), new IterableTypeWidget(scope.unify(types)), ExactInvocation .boundInvoke(Opcodes.INVOKESTATIC, "concat", scope.adapt(Iterables.class, false), scope.adapt(Iterable.class, false), scope.cast(scope.adapt(Iterable.class, false), scope.list(expr.getLocation(), exprs))) .invoke(expr.getLocation())); } case ENFORCE_TIMEOUT: { List<BytecodeExpression> localExprs = Lists.newArrayList(); List<TypeWidget> types = Lists.newArrayList(); List<String> localNames = expr.getOperator().localsFor(expr); localExprs.add(program); localExprs.add(context); for (String local : localNames) { BytecodeExpression arg = scope.local(expr.getLocation(), local); localExprs.add(arg); types.add(arg.getType()); } CallableInvocable invocation = compileCallable(program.getType(), context.getType(), types, OperatorNode.create(FunctionOperator.FUNCTION, localNames, expr.getArgument(0))); final BytecodeExpression timeout = getTimeout(context, expr.getLocation()); return scope.resolve(expr.getLocation(), timeout, scope.fork(expr.getLocation(), getRuntime(scope, program, context), invocation, localExprs)); } case LOCAL: { String localName = expr.getArgument(0); return scope.local(expr.getLocation(), localName); } case EQ: case NEQ: { OperatorNode<PhysicalExprOperator> left = expr.getArgument(0); OperatorNode<PhysicalExprOperator> right = expr.getArgument(1); final BytecodeExpression leftExpr = evaluateExpression(program, context, left); final BytecodeExpression rightExpr = evaluateExpression(program, context, right); return expr.getOperator() == PhysicalExprOperator.EQ ? scope.eq(expr.getLocation(), leftExpr, rightExpr) : scope.neq(expr.getLocation(), leftExpr, rightExpr); } case BOOLEAN_COMPARE: { final BinaryComparison booleanComparison = expr.getArgument(0); OperatorNode<PhysicalExprOperator> left = expr.getArgument(1); OperatorNode<PhysicalExprOperator> right = expr.getArgument(2); final BytecodeExpression leftExpr = evaluateExpression(program, context, left); final BytecodeExpression rightExpr = evaluateExpression(program, context, right); return scope.compare(expr.getLocation(), booleanComparison, leftExpr, rightExpr); } case BINARY_MATH: { final ArithmeticOperation arithmeticOperation = expr.getArgument(0); OperatorNode<PhysicalExprOperator> left = expr.getArgument(1); OperatorNode<PhysicalExprOperator> right = expr.getArgument(2); final BytecodeExpression leftExpr = evaluateExpression(program, context, left); final BytecodeExpression rightExpr = evaluateExpression(program, context, right); return scope.arithmetic(expr.getLocation(), arithmeticOperation, leftExpr, rightExpr); } case COMPARE: { OperatorNode<PhysicalExprOperator> left = expr.getArgument(0); OperatorNode<PhysicalExprOperator> right = expr.getArgument(1); final BytecodeExpression leftExpr = evaluateExpression(program, context, left); final BytecodeExpression rightExpr = evaluateExpression(program, context, right); return scope.compare(expr.getLocation(), leftExpr, rightExpr); } case MULTICOMPARE: { List<OperatorNode<PhysicalExprOperator>> exprs = expr.getArgument(0); List<BytecodeExpression> expressions = evaluateExpressions(program, context, exprs); return scope.composeCompare(expressions); } case COALESCE: { List<OperatorNode<PhysicalExprOperator>> exprs = expr.getArgument(0); List<BytecodeExpression> expressions = evaluateExpressions(program, context, exprs); return scope.coalesce(expr.getLocation(), expressions); } case IF: { OperatorNode<PhysicalExprOperator> test = expr.getArgument(0); OperatorNode<PhysicalExprOperator> ifTrue = expr.getArgument(1); OperatorNode<PhysicalExprOperator> ifFalse = expr.getArgument(2); return handleIfTail(program, context, scope.createCase(), test, ifTrue, ifFalse); } case STREAM_EXECUTE: { OperatorNode<PhysicalExprOperator> input = expr.getArgument(0); OperatorNode<StreamOperator> stream = expr.getArgument(1); return streamExecute(program, context, input, stream); } case STREAM_CREATE: { OperatorNode<StreamOperator> t = expr.getArgument(0); return compileStreamCreate(program, context, t); } case STREAM_COMPLETE: { OperatorNode<PhysicalExprOperator> streamExpression = expr.getArgument(0); BytecodeExpression streamExpr = evaluateExpression(program, context, streamExpression); return scope.invoke(expr.getLocation(), ExactInvocation.boundInvoke(Opcodes.INVOKEVIRTUAL, "complete", streamExpr.getType(), // ideally this would unify the types of the input streams new ListTypeWidget(AnyTypeWidget.getInstance()), streamExpr)); } case RECORD: { List<String> names = expr.getArgument(0); List<OperatorNode<PhysicalExprOperator>> exprs = expr.getArgument(1); List<BytecodeExpression> evaluated = evaluateExpressions(program, context, exprs); GambitCreator.RecordBuilder recordBuilder = scope.record(); for (int i = 0; i < names.size(); ++i) { recordBuilder.add(expr.getLocation(), names.get(i), evaluated.get(i)); } return recordBuilder.build(); } case RECORD_AS: { TypeWidget recordType = expr.getArgument(0); List<String> names = expr.getArgument(1); List<OperatorNode<PhysicalExprOperator>> exprs = expr.getArgument(2); List<BytecodeExpression> evaluated = evaluateExpressions(program, context, exprs); Map<String, BytecodeExpression> sets = Maps.newLinkedHashMap(); for (int i = 0; i < names.size(); ++i) { sets.put(names.get(i), evaluated.get(i)); } if (!recordType.hasProperties()) { throw new ProgramCompileException(expr.getLocation(), "Type passed to RECORD_AS has no properties", recordType.getTypeName()); } return recordType.getPropertyAdapter().construct(sets); } case PROJECT: { List<OperatorNode<PhysicalProjectOperator>> operations = expr.getArgument(0); GambitCreator.RecordBuilder recordBuilder; if ("map".equals(expr.getAnnotation("project:type"))) { recordBuilder = scope.dynamicRecord(); } else { recordBuilder = scope.record(); } for (OperatorNode<PhysicalProjectOperator> op : operations) { switch (op.getOperator()) { case FIELD: { OperatorNode<PhysicalExprOperator> fieldValue = op.getArgument(0); String fieldName = op.getArgument(1); recordBuilder.add(expr.getLocation(), fieldName, evaluateExpression(program, context, fieldValue)); break; } case MERGE: { OperatorNode<PhysicalExprOperator> fieldValue = op.getArgument(0); recordBuilder.merge(expr.getLocation(), evaluateExpression(program, context, fieldValue)); break; } default: throw new UnsupportedOperationException("Unknown PhysicalProjectOperator: " + op.getOperator()); } } return recordBuilder.build(); } case NULL: { TypeWidget type = expr.getArgument(0); return scope.nullFor(type); } case GENERATE_KEYS: { List<String> names = expr.getArgument(0); List<OperatorNode<PhysicalExprOperator>> valueLists = expr.getArgument(1); List<BytecodeExpression> insns = Lists.newArrayListWithCapacity(names.size() * 2); for (int i = 0; i < names.size(); ++i) { insns.add(scope.constant(names.get(i))); BytecodeExpression keyExpr = evaluateExpression(program, context, valueLists.get(i)); insns.add(scope.cast(AnyTypeWidget.getInstance(), keyExpr)); } BytecodeExpression arr = scope.array(expr.getLocation(), BaseTypeAdapter.ANY, insns); GambitCreator.Invocable factory = scope.constructor(keyCursorFor(scope, names), arr.getType()); return scope.invoke(expr.getLocation(), factory, arr); } case OR: { List<OperatorNode<PhysicalExprOperator>> args = expr.getArgument(0); return scope.or(expr.getLocation(), evaluateExpressions(program, context, args)); } case AND: { List<OperatorNode<PhysicalExprOperator>> args = expr.getArgument(0); return scope.and(expr.getLocation(), evaluateExpressions(program, context, args)); } case IN: { OperatorNode<PhysicalExprOperator> left = expr.getArgument(0); OperatorNode<PhysicalExprOperator> right = expr.getArgument(1); return scope.in(expr.getLocation(), evaluateExpression(program, context, left), evaluateExpression(program, context, right)); } case CONTAINS: { OperatorNode<PhysicalExprOperator> left = expr.getArgument(0); OperatorNode<PhysicalExprOperator> right = expr.getArgument(1); return scope.contains(expr.getLocation(), evaluateExpression(program, context, left), evaluateExpression(program, context, right)); } case MATCHES: { OperatorNode<PhysicalExprOperator> left = expr.getArgument(0); OperatorNode<PhysicalExprOperator> right = expr.getArgument(1); return scope.matches(expr.getLocation(), evaluateExpression(program, context, left), evaluateExpression(program, context, right)); } case NOT: { OperatorNode<PhysicalExprOperator> target = expr.getArgument(0); return scope.not(expr.getLocation(), evaluateExpression(program, context, target)); } case NEGATE: { OperatorNode<PhysicalExprOperator> target = expr.getArgument(0); return scope.negate(expr.getLocation(), evaluateExpression(program, context, target)); } case IS_NULL: { OperatorNode<PhysicalExprOperator> target = expr.getArgument(0); return scope.isNull(expr.getLocation(), evaluateExpression(program, context, target)); } case BOOL: { OperatorNode<PhysicalExprOperator> target = expr.getArgument(0); return scope.bool(expr.getLocation(), evaluateExpression(program, context, target)); } case ARRAY: { List<OperatorNode<PhysicalExprOperator>> args = expr.getArgument(0); return scope.list(expr.getLocation(), evaluateExpressions(program, context, args)); } case CATCH: { OperatorNode<PhysicalExprOperator> primary = expr.getArgument(0); OperatorNode<PhysicalExprOperator> fallback = expr.getArgument(1); return scope.fallback(expr.getLocation(), evaluateExpression(program, context, primary), evaluateExpression(program, context, fallback)); } case NEW: { TypeWidget type = expr.getArgument(0); List<OperatorNode<PhysicalExprOperator>> valueLists = expr.getArgument(1); List<BytecodeExpression> exprs = evaluateExpressions(program, context, valueLists); List<TypeWidget> types = Lists.newArrayList(); for (BytecodeExpression e : exprs) { types.add(e.getType()); } return scope.invoke(expr.getLocation(), scope.constructor(type, types), exprs); } case INJECT_MEMBERS: { OperatorNode<PhysicalExprOperator> value = expr.getArgument(0); final BytecodeExpression result = evaluateExpression(program, context, value); final BytecodeExpression injector = getInjector(program, context); return new BaseTypeExpression(result.getType()) { @Override public void generate(CodeEmitter code) { code.exec(result); code.dup(result.getType()); code.exec(injector); code.swap(injector.getType(), result.getType()); code.getMethodVisitor().visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Injector.class), "injectMembers", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object.class)), true); } }; } default: throw new ProgramCompileException("Unimplemented PhysicalExprOperator: " + expr.toString()); } }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.TypesHandler.java
@Override public GambitCreator.Invocable findExactInvoker(Class<?> owner, String methodName, TypeWidget returnType, List<TypeWidget> argumentTypes) { return ExactInvocation.exactInvoke(owner.isInterface() ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, methodName, adapt(owner, false), returnType, argumentTypes); }