public MethodReference getCached(String className, MethodDescriptor descriptor) { return referenceCache .computeIfAbsent(className, key -> new HashMap<>()) .computeIfAbsent(descriptor, key -> new MethodReference(className, descriptor)); }
@Override public MethodReference getReference() { if (owner == null) { return null; } if (reference == null) { reference = new MethodReference(owner.getName(), descriptor); } return reference; }
public static MethodReference parse(Method method) { ValueType[] signature = Stream.concat(Arrays.stream(method.getParameterTypes()).map(ValueType::parse), Stream.of(ValueType.parse(method.getReturnType()))).toArray(ValueType[]::new); return new MethodReference(method.getDeclaringClass().getName(), method.getName(), signature); }
public static MethodReference parseIfPossible(String string) { int index = string.lastIndexOf('.'); if (index < 1) { return null; } String className = string.substring(0, index); MethodDescriptor desc = MethodDescriptor.parseIfPossible(string.substring(index + 1)); return desc != null ? new MethodReference(className, desc) : null; }
private void reachGetLength(DependencyAgent agent, MethodDependency method) { method.getVariable(1).addConsumer(type -> { if (!type.getName().startsWith("[")) { MethodReference cons = new MethodReference(IllegalArgumentException.class, "<init>", void.class); agent.linkMethod(cons).use(); } }); }
private ValueEmitter appendArgument(ValueEmitter sb, ValueType type, ValueEmitter argument) { if (!(type instanceof ValueType.Primitive)) { type = ValueType.object("java.lang.Object"); } MethodReference method = referenceCache.getCached(new MethodReference(STRING_BUILDER, "append", type, ValueType.object(STRING_BUILDER))); return sb.invokeSpecial(method, argument); }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { MethodDependency addMethod = agent.linkMethod(new MethodReference(PlatformQueue.class, "wrap", Object.class, PlatformObject.class)); addMethod.getVariable(1).connect(method.getResult()); }
@Override public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) { InvocationExpr expr = new InvocationExpr(); MethodReference method = new MethodReference(WasmRuntime.class.getName(), invocation.getMethod().getDescriptor()); expr.setMethod(method); expr.setType(InvocationType.SPECIAL); expr.getArguments().addAll(invocation.getArguments()); return manager.generate(expr); } }
private void generateAllocStack(Expr sizeExpr) { if (stackVariable != null) { throw new IllegalStateException("Call to ShadowStack.allocStack must be done only once"); } stackVariable = getTemporary(WasmType.INT32); stackVariable.setName("__stack__"); InvocationExpr expr = new InvocationExpr(); expr.setType(InvocationType.SPECIAL); expr.setMethod(new MethodReference(WasmRuntime.class, "allocStack", int.class, Address.class)); expr.getArguments().add(sizeExpr); expr.acceptVisitor(this); result = new WasmSetLocal(stackVariable, result); }
private WasmExpression allocateObject(String className, TextLocation location) { int tag = classGenerator.getClassPointer(ValueType.object(className)); String allocName = context.names.forMethod(new MethodReference(Allocator.class, "allocate", RuntimeClass.class, Address.class)); WasmCall call = new WasmCall(allocName); call.getArguments().add(new WasmInt32Constant(tag)); call.setLocation(location); return call; }
private static Variable unbox(Variable var, Class<?> boxed, Class<?> primitive) { InvokeInstruction insn = new InvokeInstruction(); insn.setInstance(var); insn.setType(InvocationType.VIRTUAL); insn.setMethod(new MethodReference(boxed, primitive.getName() + "Value", primitive)); var = generator.program.createVariable(); insn.setReceiver(var); generator.add(insn); return var; }
private void attachConstructor(DependencyAgent agent, String type, CallLocation location) { MethodReference ref = new MethodReference(type, "<init>", ValueType.VOID); MethodDependency methodDep = agent.linkMethod(ref); methodDep.addLocation(location); methodDep.getVariable(0).propagate(agent.getType(type)); methodDep.use(); } }
private void generateGetLength(GeneratorContext context, SourceWriter writer) throws IOException { String array = context.getParameterName(1); writer.append("if (" + array + " === null || " + array + ".constructor.$meta.item === undefined) {") .softNewLine().indent(); MethodReference cons = new MethodReference("java.lang.IllegalArgumentException", "<init>", ValueType.VOID); writer.append("$rt_throw(").appendInit(cons).append("());").softNewLine(); writer.outdent().append("}").softNewLine(); writer.append("return " + array + ".data.length;").softNewLine(); }
private Variable box(Variable var, Class<?> primitive, Class<?> wrapper) { InvokeInstruction insn = new InvokeInstruction(); insn.setMethod(new MethodReference(wrapper, "valueOf", primitive, wrapper)); insn.setType(InvocationType.SPECIAL); insn.setArguments(var); var = program.createVariable(); insn.setReceiver(var); add(insn); return var; }
private void generateAllocateStringArray(GenerationContext context, CodeWriter writer) { writer.println("static JavaArray* teavm_allocateStringArray(int32_t size) {").indent(); String allocateArrayName = context.getNames().forMethod(new MethodReference(Allocator.class, "allocateArray", RuntimeClass.class, int.class, Address.class)); String stringClassName = context.getNames().forClassInstance(ValueType.arrayOf( ValueType.object(String.class.getName()))); writer.println("return (JavaArray*) " + allocateArrayName + "(&" + stringClassName + ", size);"); writer.outdent().println("}"); }
@Override public void started(DependencyAgent agent) { allClasses = agent.createNode(); allClasses.addConsumer(c -> { if (agent.getClassSource().isSuperType("java.lang.Throwable", c.getName()).orElse(false)) { MethodDependency methodDep = agent.linkMethod(new MethodReference(c.getName(), GET_MESSAGE)); methodDep.getVariable(0).propagate(c); methodDep.use(); } }); agent.linkClass("java.lang.Throwable"); }
private void generateThrowCCE(GenerationContext context, CodeWriter writer) { writer.println("static void* throwClassCastException() {").indent(); String methodName = context.getNames().forMethod(new MethodReference(ExceptionHandling.class, "throwClassCastException", void.class)); writer.println(methodName + "();"); writer.println("return NULL;"); writer.outdent().println("}"); }
private MethodReference getAsyncReference(MethodReference methodRef) { ValueType[] signature = new ValueType[methodRef.parameterCount() + 2]; for (int i = 0; i < methodRef.parameterCount(); ++i) { signature[i] = methodRef.getDescriptor().parameterType(i); } signature[methodRef.parameterCount()] = ValueType.parse(AsyncCallback.class); signature[methodRef.parameterCount() + 1] = ValueType.VOID; return new MethodReference(methodRef.getClassName(), methodRef.getName(), signature); }
private void renderRuntimeCreateException() throws IOException { writer.append("function $rt_createException(message)").ws().append("{").indent().softNewLine(); writer.append("return "); writer.appendInit(new MethodReference(RuntimeException.class, "<init>", String.class, void.class)); writer.append("(message);").softNewLine(); writer.outdent().append("}").newLine(); }
private void renderRuntimeIntern() throws IOException { writer.append("function $rt_intern(str) {").indent().softNewLine(); ClassReader stringCls = classSource.get(STRING_CLASS); if (stringCls != null && stringCls.getMethod(STRING_INTERN_METHOD) != null) { writer.append("return ").appendMethodBody(new MethodReference(STRING_CLASS, STRING_INTERN_METHOD)) .append("(str);").softNewLine(); } else { writer.append("return str;").softNewLine(); } writer.outdent().append("}").newLine(); }