Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add object init invocation to value creator #15944

Merged
merged 19 commits into from
Jun 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f79dee5
Merge branch 'jballerina' of https://github.com/ballerina-platform/ba…
lankavitharana Jun 20, 2019
8e9b001
Merge branch 'jballerina' of https://github.com/ballerina-platform/ba…
lankavitharana Jun 21, 2019
de623bb
Merge branch 'jballerina' of https://github.com/ballerina-platform/ba…
lankavitharana Jun 23, 2019
7cf8d8f
Merge branch 'jballerina' of https://github.com/ballerina-platform/ba…
lankavitharana Jun 23, 2019
2356663
Add object init invocation to value creator
lankavitharana Jun 23, 2019
1fd5d0a
Fix checkstyle issue
lankavitharana Jun 23, 2019
9a640a1
Refactor HttpClient usage
chamil321 Jun 24, 2019
03cf557
Merge branch 'chamil_http_fix' into testFix
lankavitharana Jun 25, 2019
92faaeb
Fix create object invocation locations with proper parameters
lankavitharana Jun 25, 2019
871730d
Fix error msg
lankavitharana Jun 26, 2019
4ad7f54
Merge http fixes from pull 15981
lankavitharana Jun 26, 2019
5c849c5
Merge branch 'jballerina' of https://github.com/ballerina-platform/ba…
lankavitharana Jun 26, 2019
7a3fa8b
Fix closure tests
lankavitharana Jun 26, 2019
aca5fd3
Merge branch 'jballerina' of https://github.com/ballerina-platform/ba…
lankavitharana Jun 26, 2019
8007e77
Add invocations test package to testng
lankavitharana Jun 26, 2019
f718d83
Merge branch 'jballerina' of https://github.com/ballerina-platform/ba…
lankavitharana Jun 27, 2019
2f7d31d
Fix ballerina internal native impls
lankavitharana Jun 27, 2019
66bf2de
Merge with branch and resolve conflicts
lankavitharana Jun 27, 2019
dc27bd1
Fix checkstyle issue
lankavitharana Jun 27, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -58,31 +55,15 @@ public static MapValue<String, Object> 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);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -51,5 +53,6 @@ public static ValueCreator getValueCreator(String key) {

public abstract MapValue<String, Object> createRecordValue(String recordTypeName);

public abstract ObjectValue createObjectValue(String objectTypeName);
public abstract ObjectValue createObjectValue(String objectTypeName, Scheduler scheduler, Strand parent,
Map<String, Object> properties, Object[] args);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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, "<init>", 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, "<init>", 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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String, Object> 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
}
Expand All @@ -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;
};
Expand All @@ -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) {
Expand Down Expand Up @@ -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)];
}


Expand Down Expand Up @@ -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");
Expand All @@ -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 {
Expand Down
3 changes: 2 additions & 1 deletion tests/jballerina-unit-test/src/test/resources/testng.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<package name="org.ballerinalang.test.annotations.*"/>
<package name="org.ballerinalang.test.imports.*"/>
<package name="org.ballerinalang.test.parser.*"/>
<package name="org.ballerinalang.test.closures.*"/>
<!-- <package name="org.ballerinalang.test.privacy.*"/> -->
<package name="org.ballerinalang.test.dataflow.*"/>
<package name="org.ballerinalang.test.variable.shadowing.*"/>
Expand Down Expand Up @@ -93,6 +94,7 @@
<package name="org.ballerinalang.test.expressions.ternary.*"/>
<package name="org.ballerinalang.test.expressions.typeof.*"/>
<package name="org.ballerinalang.test.expressions.stamp.*"/>
<package name="org.ballerinalang.test.expressions.invocations.*"/>
<package name="org.ballerinalang.test.object.*" />
<package name="org.ballerinalang.test.dataflow.analysis.*" />
<package name="org.ballerinalang.test.documentation.*" />
Expand All @@ -115,7 +117,6 @@
</methods>
</class>
<class name="org.ballerinalang.test.functions.FunctionsWithDefaultableArguments" />
<class name="org.ballerinalang.test.closures.VarMutabilityClosureTest" />
<class name="org.ballerinalang.test.worker.WorkerCallingFunction"/>
<class name="org.ballerinalang.test.worker.BasicForkTest"/>
<class name="org.ballerinalang.test.worker.BasicWorkerTest"/>
Expand Down