public NameProvider(ClassReaderSource classSource) { super(classSource); occupiedTopLevelNames.add("JavaObject"); occupiedTopLevelNames.add("JavaArray"); occupiedTopLevelNames.add("JavaString"); occupiedTopLevelNames.add("JavaClass"); classNames.put(RuntimeObject.class.getName(), "JavaObject"); classNames.put(String.class.getName(), "JavaString"); classNames.put(RuntimeClass.class.getName(), "JavaClass"); classNames.put(RuntimeArray.class.getName(), "JavaArray"); memberFieldNames.put(new FieldReference(RuntimeObject.class.getName(), "classReference"), "header"); memberFieldNames.put(new FieldReference(RuntimeArray.class.getName(), "size"), "size"); memberFieldNames.put(new FieldReference(String.class.getName(), "characters"), "characters"); memberFieldNames.put(new FieldReference(String.class.getName(), "hashCode"), "hashCode"); occupiedClassNames.put(RuntimeObject.class.getName(), new HashSet<>(Arrays.asList("header"))); occupiedClassNames.put(RuntimeArray.class.getName(), new HashSet<>(Arrays.asList("length"))); }
public ValueEmitter getField(String className, String fieldName, ValueType type) { return getField(new FieldReference(className, fieldName), type); }
public ProgramEmitter setField(Class<?> cls, String fieldName, ValueEmitter value) { return setField(new FieldReference(cls.getName(), fieldName), value); }
public ProgramEmitter setField(String className, String fieldName, ValueEmitter value) { return setField(new FieldReference(className, fieldName), value); }
private String classFieldName(String field) { return context.getNames().forMemberField(new FieldReference(RuntimeClass.class.getName(), field)); }
@Override public FieldReference getReference() { if (reference == null && owner != null) { reference = new FieldReference(getOwnerName(), getName()); } return reference; }
private String fieldName(String className, String fieldName) { return context.getNames().forMemberField(new FieldReference(className, fieldName)); }
private FieldReference expectField() throws IOException, ListingParseException { expect(ListingToken.IDENTIFIER); String s = (String) lexer.getTokenValue(); int index = s.lastIndexOf('.'); if (index < 0) { throw new ListingParseException("Unparseable field", lexer.getTokenStart()); } lexer.nextToken(); return new FieldReference(s.substring(0, index), s.substring(index + 1)); }
private void generateIsSuperclassFunction(String className) { List<TagRegistry.Range> ranges = tagRegistry.getRanges(className); if (ranges.isEmpty()) { isSupertypeWriter.println("return INT32_C(0);"); return; } String tagName = context.getNames().forMemberField(new FieldReference( RuntimeClass.class.getName(), "tag")); isSupertypeWriter.println("int32_t tag = cls->" + tagName + ";"); int lower = ranges.get(0).lower; int upper = ranges.get(ranges.size() - 1).upper; isSupertypeWriter.println("if (tag < " + lower + " || tag >= " + upper + ") return INT32_C(0);"); for (int i = 1; i < ranges.size(); ++i) { lower = ranges.get(i - 1).upper; upper = ranges.get(i).lower; isSupertypeWriter.println("if (tag >= " + lower + " && tag < " + upper + ") return INT32_C(0);"); } isSupertypeWriter.println("return INT32_C(1);"); }
public FieldReference getCached(FieldReference reference) { FieldReference result = fieldRefenceCache.get(reference); if (result == null) { result = reference; String classNameCached = getCached(reference.getClassName()); String fieldNameCached = getCached(reference.getFieldName()); if (classNameCached != reference.getClassName() || fieldNameCached != reference.getFieldName()) { result = new FieldReference(classNameCached, fieldNameCached); } fieldRefenceCache.put(result, result); } return result; }
private void generateReleaseStack() { if (stackVariable == null) { throw new IllegalStateException("Call to ShadowStack.releaseStack must be dominated by " + "Mutator.allocStack"); } int offset = classGenerator.getFieldOffset(new FieldReference(WasmRuntime.class.getName(), "stack")); WasmExpression oldValue = new WasmGetLocal(stackVariable); oldValue = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SUB, oldValue, new WasmInt32Constant(4)); result = new WasmStoreInt32(4, new WasmInt32Constant(offset), oldValue, WasmInt32Subtype.INT32); }
private WasmExpression generateArrayLength(WasmExpression array) { int sizeOffset = classGenerator.getFieldOffset(new FieldReference(RuntimeArray.class.getName(), "size")); WasmExpression ptr = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, array, new WasmInt32Constant(sizeOffset)); ptr.setLocation(array.getLocation()); WasmExpression length = new WasmLoadInt32(4, ptr, WasmInt32Subtype.INT32); length.setLocation(array.getLocation()); return length; }
@Override public void visit(GetFieldInstruction insn) { String className = classNameMapper.map(insn.getField().getClassName()); insn.setField(referenceCache.getCached(new FieldReference(className, insn.getField().getFieldName()))); }
private void generateIsSuperArrayFunction(ValueType itemType) { String itemTypeName = context.getNames().forMemberField(new FieldReference( RuntimeClass.class.getName(), "itemType")); isSupertypeWriter.println("JavaClass* itemType = cls->" + itemTypeName + ";"); isSupertypeWriter.println("if (itemType == NULL) return INT32_C(0);"); if (itemType instanceof ValueType.Primitive) { isSupertypeWriter.println("return itemType == &" + context.getNames().forClassInstance(itemType) + ";"); } else { isSupertypeWriter.println("return " + context.getNames().forSupertypeFunction(itemType) + "(itemType);"); } }
private void generateIsArray(WasmLocal subtypeVar, WasmClassGenerator classGenerator, ValueType itemType, List<WasmExpression> body) { int itemOffset = classGenerator.getFieldOffset(new FieldReference(RuntimeClass.class.getName(), "itemType")); WasmExpression itemExpression = new WasmGetLocal(subtypeVar); itemExpression = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, itemExpression, new WasmInt32Constant(itemOffset)); itemExpression = new WasmLoadInt32(4, itemExpression, WasmInt32Subtype.INT32); body.add(new WasmSetLocal(subtypeVar, itemExpression)); WasmExpression itemCondition = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.EQ, new WasmGetLocal(subtypeVar), new WasmInt32Constant(0)); WasmConditional itemTest = new WasmConditional(itemCondition); itemTest.setType(WasmType.INT32); itemTest.getThenBlock().getBody().add(new WasmInt32Constant(0)); WasmCall delegateToItem = new WasmCall(classGenerator.names.forSupertypeFunction(itemType)); delegateToItem.getArguments().add(new WasmGetLocal(subtypeVar)); itemTest.getElseBlock().getBody().add(delegateToItem); body.add(new WasmReturn(itemTest)); }
@Override public void visit(PutFieldInstruction insn) { String className = classNameMapper.map(insn.getField().getClassName()); if (className != insn.getField().getClassName()) { insn.setField(referenceCache.getCached(new FieldReference(className, insn.getField().getFieldName()))); } } @Override
public ProgramEmitter setField(String name, ValueEmitter value) { if (!(type instanceof ValueType.Object)) { throw new EmitException("Can't get field of non-object type: " + type); } String className = ((ValueType.Object) type).getClassName(); PutFieldInstruction insn = new PutFieldInstruction(); insn.setField(new FieldReference(className, name)); insn.setFieldType(type); insn.setInstance(variable); insn.setValue(value.getVariable()); pe.addInstruction(insn); return pe; }
public ValueEmitter getField(String name, ValueType type) { if (!(this.type instanceof ValueType.Object)) { throw new EmitException("Can't get field of non-object type: " + type); } String className = ((ValueType.Object) this.type).getClassName(); Variable var = pe.getProgram().createVariable(); GetFieldInstruction insn = new GetFieldInstruction(); insn.setField(new FieldReference(className, name)); insn.setFieldType(type); insn.setReceiver(var); insn.setInstance(variable); pe.addInstruction(insn); return pe.var(var, type); }
private void generateStringToJavaScript(GeneratorContext context, SourceWriter writer) throws IOException { FieldReference charsField = new FieldReference("java.lang.String", "characters"); writer.append("var result = \"\";").softNewLine(); writer.append("var data = ").append(context.getParameterName(1)).append('.') .appendField(charsField).append(".data;").softNewLine(); writer.append("for (var i = 0; i < data.length; i = (i + 1) | 0) {").indent().softNewLine(); writer.append("result += String.fromCharCode(data[i]);").softNewLine(); writer.outdent().append("}").softNewLine(); writer.append("return result;").softNewLine(); } }
private void renderRuntimeUnwrapString() throws IOException { FieldReference stringChars = new FieldReference(STRING_CLASS, "characters"); writer.append("function $rt_ustr(str) {").indent().softNewLine(); writer.append("if (str === null) {").indent().softNewLine(); writer.append("return null;").softNewLine(); writer.outdent().append("}").softNewLine(); writer.append("var data = str.").appendField(stringChars).append(".data;").softNewLine(); writer.append("var result = \"\";").softNewLine(); writer.append("for (var i = 0; i < data.length; i = (i + 1) | 0) {").indent().softNewLine(); writer.append("result += String.fromCharCode(data[i]);").softNewLine(); writer.outdent().append("}").softNewLine(); writer.append("return result;").softNewLine(); writer.outdent().append("}").newLine(); }