diff --git a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/BallerinaValues.java b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/BallerinaValues.java index 643067a6b0d5..2d71f870918d 100644 --- a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/BallerinaValues.java +++ b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/BallerinaValues.java @@ -18,10 +18,7 @@ package org.ballerinalang.jvm; import org.ballerinalang.jvm.types.BField; -import org.ballerinalang.jvm.types.BObjectType; import org.ballerinalang.jvm.types.BRecordType; -import org.ballerinalang.jvm.types.BType; -import org.ballerinalang.jvm.types.TypeTags; import org.ballerinalang.jvm.values.MapValue; import org.ballerinalang.jvm.values.MapValueImpl; import org.ballerinalang.jvm.values.ObjectValue; @@ -58,31 +55,15 @@ public static MapValue createRecordValue(String pkgName, String */ public static ObjectValue createObjectValue(String pkgName, String objectTypeName, Object... fieldValues) { ValueCreator valueCreator = ValueCreator.getValueCreator(pkgName); - ObjectValue objectValue = valueCreator.createObjectValue(objectTypeName); - int valCount = 0; - BObjectType objectType = objectValue.getType(); - for (BField field : objectType.getFields().values()) { - Object value; - if (fieldValues.length >= valCount + 1) { - value = fieldValues[valCount]; - } else { - BType fieldType = field.getFieldType(); - if (fieldType.getTag() == TypeTags.OBJECT_TYPE_TAG) { - // This is a hack to avoid self references. This should be fixed properly. - if (objectTypeName.equals(fieldType.getName())) { - continue; - } - value = createObjectValue(fieldType.getPackage().toString(), fieldType.getName()); - } else if (fieldType.getTag() == TypeTags.RECORD_TYPE_TAG) { - value = createRecordValue(fieldType.getPackage().toString(), fieldType.getName()); - } else { - value = fieldType.getEmptyValue(); - } - } - objectValue.set(field.name, value); - valCount++; + Object[] fields = new Object[fieldValues.length * 2]; + + // Adding boolean values for each arg + for (int i = 0, j = 0; i < fieldValues.length; i++) { + fields[j++] = fieldValues[i]; + fields[j++] = true; } - return objectValue; + //passing scheduler, strand and properties as null for the moment, but better to expose them via this method + return valueCreator.createObjectValue(objectTypeName, null, null, null, fields); } /** diff --git a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/ValueCreator.java b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/ValueCreator.java index ac4f87a842f8..62cbe63323f6 100644 --- a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/ValueCreator.java +++ b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/ValueCreator.java @@ -17,6 +17,8 @@ */ package org.ballerinalang.jvm.values; +import org.ballerinalang.jvm.Scheduler; +import org.ballerinalang.jvm.Strand; import org.ballerinalang.jvm.util.exceptions.BallerinaException; import java.util.HashMap; @@ -51,5 +53,6 @@ public static ValueCreator getValueCreator(String key) { public abstract MapValue createRecordValue(String recordTypeName); - public abstract ObjectValue createObjectValue(String objectTypeName); + public abstract ObjectValue createObjectValue(String objectTypeName, Scheduler scheduler, Strand parent, + Map properties, Object[] args); } diff --git a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal index 9abce5f81564..d547e6863c2f 100644 --- a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal +++ b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal @@ -400,7 +400,7 @@ function generateCastToByte(jvm:MethodVisitor mv, bir:BType sourceType) { // do nothing } else if (sourceType is bir:BTypeAny || sourceType is bir:BTypeAnyData || - sourceType is bir:BUnionType || + sourceType is bir:BUnionType || sourceType is bir:BJSONType) { mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToByte", io:sprintf("(L%s;)I", OBJECT), false); } else { diff --git a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_constants.bal b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_constants.bal index 913396c3d90b..276c9f43c83a 100644 --- a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_constants.bal +++ b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_constants.bal @@ -226,6 +226,7 @@ const string FUTURE_VALUE = "org/ballerinalang/jvm/values/FutureValue"; const string TYPEDESC_VALUE = "org/ballerinalang/jvm/values/TypedescValue"; const string OBJECT = "java/lang/Object"; +const string MATH = "java/lang/Math"; const string MAP = "java/util/Map"; const string LINKED_HASH_MAP = "java/util/LinkedHashMap"; const string ARRAY_LIST = "java/util/ArrayList"; diff --git a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal index 387b752bef0c..fc6bc444f20a 100644 --- a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal +++ b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal @@ -132,7 +132,7 @@ public function generateValueCreatorMethods(jvm:ClassWriter cw, bir:TypeDef?[] t foreach var optionalTypeDef in typeDefs { bir:TypeDef typeDef = getTypeDef(optionalTypeDef); bir:BType bType = typeDef.typeValue; - if (bType is bir:BObjectType) { + if (bType is bir:BObjectType && !bType.isAbstract) { objectTypeDefs[i] = typeDef; i += 1; } @@ -184,19 +184,45 @@ function generateRecordValueCreateMethod(jvm:ClassWriter cw, bir:TypeDef?[] reco function generateObjectValueCreateMethod(jvm:ClassWriter cw, bir:TypeDef?[] objectTypeDefs, string pkgName) { jvm:MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "createObjectValue", - io:sprintf("(L%s;)L%s;", STRING_VALUE, OBJECT_VALUE), (), ()); - + io:sprintf("(L%s;L%s;L%s;L%s;[L%s;)L%s;", STRING_VALUE, SCHEDULER, STRAND, MAP, OBJECT, OBJECT_VALUE), (), ()); + + BalToJVMIndexMap indexMap = new; + + bir:VariableDcl selfVar = { typeValue: "any", + name: { value: "self" }, + kind: "ARG" }; + bir:VariableDcl var1 = { typeValue: "string", + name: { value: "var1" }, + kind: "ARG" }; + bir:VariableDcl scheduler = { typeValue: "any", + name: { value: "scheduler" }, + kind: "ARG" }; + bir:VariableDcl parent = { typeValue: "any", + name: { value: "parent" }, + kind: "ARG" }; + bir:VariableDcl properties = { typeValue: "any", + name: { value: "properties" }, + kind: "ARG" }; + bir:VariableDcl args = { typeValue: "any", + name: { value: "args" }, + kind: "ARG" }; + _ = indexMap.getIndex(selfVar); + int var1Index = indexMap.getIndex(var1); + int schedulerIndex = indexMap.getIndex(scheduler); + int parentIndex = indexMap.getIndex(parent); + int propertiesIndex = indexMap.getIndex(properties); + int argsIndex = indexMap.getIndex(args); + mv.visitCode(); - int fieldNameRegIndex = 1; jvm:Label defaultCaseLabel = new jvm:Label(); // sort the fields before generating switch case NodeSorter sorter = new(); sorter.sortByHash(objectTypeDefs); - jvm:Label[] labels = createLabelsforSwitch(mv, fieldNameRegIndex, objectTypeDefs, defaultCaseLabel); - jvm:Label[] targetLabels = createLabelsForEqualCheck(mv, fieldNameRegIndex, objectTypeDefs, labels, + jvm:Label[] labels = createLabelsforSwitch(mv, var1Index, objectTypeDefs, defaultCaseLabel); + jvm:Label[] targetLabels = createLabelsForEqualCheck(mv, var1Index, objectTypeDefs, labels, defaultCaseLabel); int i = 0; @@ -213,12 +239,55 @@ function generateObjectValueCreateMethod(jvm:ClassWriter cw, bir:TypeDef?[] obje mv.visitFieldInsn(GETSTATIC, typeOwnerClass, fieldName, io:sprintf("L%s;", BTYPE)); mv.visitTypeInsn(CHECKCAST, OBJECT_TYPE); mv.visitMethodInsn(INVOKESPECIAL, className, "", io:sprintf("(L%s;)V", OBJECT_TYPE), false); + + bir:VariableDcl tempVar = { typeValue: typeDef.typeValue, + name: { value: "tempVar" }, + kind: "LOCAL" }; + int tempVarIndex = indexMap.getIndex(tempVar); + mv.visitVarInsn(ASTORE, tempVarIndex); + + mv.visitTypeInsn(NEW, STRAND); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, schedulerIndex); + mv.visitVarInsn(ALOAD, parentIndex); + mv.visitVarInsn(ALOAD, propertiesIndex); + mv.visitMethodInsn(INVOKESPECIAL, STRAND, "", io:sprintf("(L%s;L%s;L%s;)V", SCHEDULER, STRAND, MAP), false); + bir:VariableDcl strandVar = { typeValue: "any", + name: { value: "strandVar" }, + kind: "LOCAL" }; + int strandVarIndex = indexMap.getIndex(strandVar); + mv.visitVarInsn(ASTORE, strandVarIndex); + + mv.visitVarInsn(ALOAD, tempVarIndex); + mv.visitVarInsn(ALOAD, strandVarIndex); + + mv.visitLdcInsn("__init"); + mv.visitVarInsn(ALOAD, argsIndex); + + string methodDesc = io:sprintf("(L%s;L%s;[L%s;)L%s;", STRAND, STRING_VALUE, OBJECT, OBJECT); + mv.visitMethodInsn(INVOKEINTERFACE, OBJECT_VALUE, "call", methodDesc, true); + + bir:VariableDcl tempResult = { typeValue: "any", + name: { value: "tempResult" }, + kind: "LOCAL" }; + int tempResultIndex = indexMap.getIndex(tempResult); + mv.visitVarInsn(ASTORE, tempResultIndex); + mv.visitVarInsn(ALOAD, tempResultIndex); + mv.visitTypeInsn(INSTANCEOF, ERROR_VALUE); + jvm:Label noErrorLabel = new jvm:Label(); + mv.visitJumpInsn(IFEQ, noErrorLabel); + mv.visitVarInsn(ALOAD, tempResultIndex); + mv.visitTypeInsn(CHECKCAST, ERROR_VALUE); + mv.visitInsn(ATHROW); + mv.visitLabel(noErrorLabel); + mv.visitVarInsn(ALOAD, tempVarIndex); mv.visitInsn(ARETURN); + i += 1; } - createDefaultCase(mv, defaultCaseLabel, fieldNameRegIndex); - mv.visitMaxs(objectTypeDefs.length() + 10, objectTypeDefs.length() + 10); + createDefaultCase(mv, defaultCaseLabel, var1Index); + mv.visitMaxs(objectTypeDefs.length() + 100, objectTypeDefs.length() + 100); mv.visitEnd(); } diff --git a/stdlib/http/src/main/java/org/ballerinalang/net/http/HttpDispatcher.java b/stdlib/http/src/main/java/org/ballerinalang/net/http/HttpDispatcher.java index 2ebcb58f4daf..84d07a07a15d 100644 --- a/stdlib/http/src/main/java/org/ballerinalang/net/http/HttpDispatcher.java +++ b/stdlib/http/src/main/java/org/ballerinalang/net/http/HttpDispatcher.java @@ -148,7 +148,8 @@ public static HttpResource findResource(HTTPServicesRegistry servicesRegistry, H public static Object[] getSignatureParameters(HttpResource httpResource, HttpCarbonMessage httpCarbonMessage, MapValue endpointConfig) { //TODO Think of keeping struct type globally rather than creating for each request - ObjectValue listenerEndpoint = BallerinaValues.createObjectValue(PROTOCOL_PACKAGE_HTTP, HTTP_LISTENER_ENDPOINT); + ObjectValue listenerEndpoint = BallerinaValues.createObjectValue(PROTOCOL_PACKAGE_HTTP, HTTP_LISTENER_ENDPOINT, + 9090, endpointConfig); // sending a dummy port here as it gets initialized later - fix ObjectValue httpCaller = BallerinaValues.createObjectValue(PROTOCOL_PACKAGE_HTTP, CALLER); ObjectValue inRequest = BallerinaValues.createObjectValue(PROTOCOL_PACKAGE_HTTP, REQUEST); ObjectValue inRequestEntity = BallerinaValues.createObjectValue(PROTOCOL_PACKAGE_MIME, ENTITY); diff --git a/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/GetParentDirectory.java b/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/GetParentDirectory.java index c6776621d21b..b33adebd881c 100644 --- a/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/GetParentDirectory.java +++ b/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/GetParentDirectory.java @@ -96,7 +96,7 @@ public static Object getParentDirectory(Strand strand, ObjectValue self) { Path parent = path.getParent(); if (parent != null) { ObjectValue pathObject = BallerinaValues.createObjectValue(Constants.PACKAGE_PATH, - Constants.PATH_STRUCT); + Constants.PATH_STRUCT, ""); pathObject.call(strand, Constants.INIT_FUNCTION_NAME, parent.toString(), true); return pathObject; } else { diff --git a/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/List.java b/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/List.java index b2d187244c66..724157a069df 100644 --- a/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/List.java +++ b/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/List.java @@ -101,7 +101,7 @@ public static Object list(Strand strand, ObjectValue self) { try { Files.list(path).forEach(p -> { ObjectValue pathObj = BallerinaValues.createObjectValue(Constants.PACKAGE_PATH, - Constants.PATH_STRUCT); + Constants.PATH_STRUCT, ""); pathObj.call(strand, Constants.INIT_FUNCTION_NAME, p.toString(), true); long index = filesList.size(); filesList.add((index), pathObj); diff --git a/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/Resolve.java b/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/Resolve.java index d8aae677ce60..c58a0c775261 100644 --- a/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/Resolve.java +++ b/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/Resolve.java @@ -90,7 +90,7 @@ public static ObjectValue resolve(Strand strand, ObjectValue self, ArrayValue pa } ObjectValue parentPathStruct = BallerinaValues.createObjectValue(Constants.PACKAGE_PATH, Constants - .PATH_STRUCT); + .PATH_STRUCT, ""); parentPathStruct.call(strand, Constants.INIT_FUNCTION_NAME, newPath.toString(), true); return parentPathStruct; } diff --git a/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/ToAbsolutePath.java b/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/ToAbsolutePath.java index da5b26162d27..8559b00e1b21 100644 --- a/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/ToAbsolutePath.java +++ b/stdlib/internal/src/main/java/org/ballerinalang/stdlib/internal/file/ToAbsolutePath.java @@ -23,7 +23,6 @@ import org.ballerinalang.connector.api.BLangConnectorSPIUtil; import org.ballerinalang.jvm.BallerinaValues; import org.ballerinalang.jvm.Strand; -import org.ballerinalang.jvm.values.MapValue; import org.ballerinalang.jvm.values.ObjectValue; import org.ballerinalang.model.types.TypeKind; import org.ballerinalang.model.values.BMap; @@ -77,11 +76,11 @@ public void execute(Context context) { context.setReturnValues(absolutePath); } - public static MapValue toAbsolutePath(Strand strand, ObjectValue self) { + public static ObjectValue toAbsolutePath(Strand strand, ObjectValue self) { Path path = (Path) self.getNativeData(Constants.PATH_DEFINITION_NAME); - MapValue absolutePath = - BallerinaValues.createRecord(BallerinaValues.createRecordValue(Constants.PACKAGE_PATH, - Constants.PATH_STRUCT), getAbsolutePath(path).toString()); + ObjectValue absolutePath = + BallerinaValues.createObjectValue(Constants.PACKAGE_PATH, + Constants.PATH_STRUCT, getAbsolutePath(path).toString()); return absolutePath; } } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/closures/ClosureNegativeTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/closures/ClosureNegativeTest.java index fe137a492eee..733a5d1b5f97 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/closures/ClosureNegativeTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/closures/ClosureNegativeTest.java @@ -37,9 +37,9 @@ public void testPrivateFieldAccess() { BAssertUtil.validateError(compileResult, index++, "undefined symbol 'methodInt3'", 17, 49); BAssertUtil.validateError(compileResult, index++, "cannot assign a value to function argument 'a'", 29, 9); BAssertUtil.validateError(compileResult, index++, "cannot assign a value to function argument 'fOut'", 34, 17); - BAssertUtil.validateError(compileResult, index++, "redeclared symbol 'a'", 50, 9); + BAssertUtil.validateError(compileResult, index++, "redeclared symbol 'a'", 50, 13); BAssertUtil.validateError(compileResult, index++, "cannot assign a value to function argument 'a'", 56, 13); - BAssertUtil.validateError(compileResult, index++, "redeclared symbol 'a'", 64, 17); + BAssertUtil.validateError(compileResult, index++, "redeclared symbol 'a'", 64, 21); BAssertUtil.validateError(compileResult, index++, "undefined symbol 'l'", 81, 58); BAssertUtil.validateError(compileResult, index++, "undefined symbol 'm'", 81, 62); BAssertUtil.validateError(compileResult, index++, "undefined symbol 'n'", 81, 66); diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/closures/closure.bal b/tests/jballerina-unit-test/src/test/resources/test-src/closures/closure.bal index ba89c4c32922..96ad74fe6757 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/closures/closure.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/closures/closure.bal @@ -236,10 +236,10 @@ function test15() returns int { return foo.call(7); } -function testClosureWithTupleTypes((string, float, string) g) returns (function (string, (string, float, string)) returns (string)){ - return function (string x, (string, float, string) y) returns (string) { - var (i, j, k) = y; - var (l, m, n) = g; +function testClosureWithTupleTypes([string, float, string] g) returns (function (string, [string, float, string]) returns (string)){ + return function (string x, [string, float, string] y) returns (string) { + var [i, j, k] = y; + var [l, m, n] = g; return x + i + j + k + l + m + n; }; } @@ -248,23 +248,23 @@ function test16() returns string { string a = "Hello"; float b = 11.1; string c = "World !!!"; - var foo = testClosureWithTupleTypes((a, b, c)); + var foo = testClosureWithTupleTypes([a, b, c]); string i = "Ballerina"; float j = 15.0; string k = "Program !!!"; - return foo.call("Im", (i, j, k)); + return foo.call("Im", [i, j, k]); } -function testClosureWithTupleTypesOrder((string, float, string) g) returns (function ((string, float, string), string) returns (string)){ +function testClosureWithTupleTypesOrder([string, float, string] g) returns (function ([string, float, string], string) returns (string)){ string i = "HelloInner"; float j = 44.8; string k = "World Inner!!!"; - (string, float, string) r = (i, j, k); + [string, float, string] r = [i, j, k]; - return function ((string, float, string) y, string x) returns (string) { - var (a, b, c) = g; - var (d, e, f) = y; - var (i1, j1, k1) = r; + return function ([string, float, string] y, string x) returns (string) { + var [a, b, c] = g; + var [d, e, f] = y; + var [i1, j1, k1] = r; return x + a + b + c + d + e + f + i1 + j1 + k1; }; @@ -279,8 +279,8 @@ function test17() returns string { float b = 11.1; string c = "World !!!"; - var foo = testClosureWithTupleTypesOrder((a, b, c)); - return foo.call((d, e, f), "I'm"); + var foo = testClosureWithTupleTypesOrder([a, b, c]); + return foo.call([d, e, f], "I'm"); } function globalVarAccessAndModifyTest() returns (int) { @@ -592,14 +592,14 @@ function testMultiLevelBlockStatements2() returns (function(int[], int[], int[]) } -function test28() returns (int, int) { +function test28() returns [int, int] { var foo = testMultiLevelBlockStatements1(); var baz = foo.call(); var bar = testMultiLevelBlockStatements2(); int[] i = [1,2]; int[] j = [1,2,3]; int[] k = [1,2,3,4]; - return (baz.call(4), bar.call(i,j,k)); + return [baz.call(4), bar.call(i,j,k)]; } @@ -629,7 +629,7 @@ function function4(string firstParameter) returns (function (string) returns boo }; } -function test29() returns (boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean) { +function test29() returns [boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean] { var a1 = function1("ABC"); boolean b10 = a1.call("ABC"); boolean b11 = a1.call("GHJ"); @@ -646,7 +646,7 @@ function test29() returns (boolean, boolean, boolean, boolean, boolean, boolean, boolean b40 = a4.call("ABC"); boolean b41 = a4.call("ERWWS"); - return (b10, b11, b20, b21, b30, b31, b40, b41); + return [b10, b11, b20, b21, b30, b31, b40, b41]; } function test30() returns int|string { diff --git a/tests/jballerina-unit-test/src/test/resources/testng.xml b/tests/jballerina-unit-test/src/test/resources/testng.xml index 7e35067ac2a5..888ad6b7f5a7 100644 --- a/tests/jballerina-unit-test/src/test/resources/testng.xml +++ b/tests/jballerina-unit-test/src/test/resources/testng.xml @@ -39,6 +39,7 @@ + @@ -93,6 +94,7 @@ + @@ -117,7 +119,6 @@ -