From 63821fe837e8b8897f72a8f437a91486b99f1685 Mon Sep 17 00:00:00 2001 From: Alexander Gorshenev Date: Mon, 13 Nov 2017 13:36:49 +0300 Subject: [PATCH] DoWhile serialization. --- .../backend/konan/serialization/KonanIr.proto | 27 ++++++-- .../konan/serialization/SerializeIr.kt | 69 ++++++++++++++++--- 2 files changed, 78 insertions(+), 18 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIr.proto b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIr.proto index e0d63af3e37..e18e4f32d0d 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIr.proto +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIr.proto @@ -86,9 +86,8 @@ message IrBreak { } message IrBlock { - required bool is_transparent_scope = 1; - required bool is_lambda_origin = 2; - repeated IrStatement statement = 3; + required bool is_lambda_origin = 1; + repeated IrStatement statement = 2; } message MemberAccessCommon { @@ -116,6 +115,10 @@ message IrCallableReference { required TypeMap type_map = 2; } +message IrComposite { + repeated IrStatement statement = 1; +} + message IrConst { oneof value { bool null = 1; @@ -141,6 +144,10 @@ message IrDelegatingConstructorCall { required MemberAccessCommon member_access = 2; } +message IrDoWhile { + required Loop loop = 1; +} + message IrEnumConstructorCall { required KotlinDescriptor descriptor = 1; required MemberAccessCommon member_access = 2; @@ -173,6 +180,13 @@ message IrInstanceInitializerCall { required KotlinDescriptor descriptor = 1; } +message Loop { + required int32 loop_id = 1; + required IrExpression condition = 2; + optional string label = 3; + optional IrExpression body = 4; +} + message IrReturn { required KotlinDescriptor return_target = 1; required IrExpression value = 2; @@ -217,10 +231,7 @@ message IrWhen { } message IrWhile { - required int32 loop_id = 1; - required IrExpression condition = 2; - optional string label = 3; - optional IrExpression body = 4; + required Loop loop = 1; } // TODO: we need an extension mechanism to accomodate new @@ -232,8 +243,10 @@ message IrOperation { IrCall call = 3; IrCallableReference callable_reference = 4; IrConst const = 5; + IrComposite composite = 26; IrContinue continue = 6; IrDelegatingConstructorCall delegating_constructor_call = 7; + IrDoWhile do_while = 25; IrEnumConstructorCall enum_constructor_call = 8; IrGetEnumValue get_enum_value = 9; IrGetField get_field = 10; diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeIr.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeIr.kt index 60500b62fbc..76340fbe9a7 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeIr.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeIr.kt @@ -141,7 +141,6 @@ internal class IrSerializer(val context: Context, block.origin == IrStatementOrigin.LAMBDA || block.origin == IrStatementOrigin.ANONYMOUS_FUNCTION val proto = KonanIr.IrBlock.newBuilder() - .setIsTransparentScope(block.isTransparentScope) .setIsLambdaOrigin(isLambdaOrigin) block.statements.forEach { proto.addStatement(serializeStatement(it)) @@ -149,6 +148,14 @@ internal class IrSerializer(val context: Context, return proto.build() } + fun serializeComposite(composite: IrComposite): KonanIr.IrComposite { + val proto = KonanIr.IrComposite.newBuilder() + composite.statements.forEach { + proto.addStatement(serializeStatement(it)) + } + return proto.build() + } + fun serializeCatch(catch: IrCatch): KonanIr.IrCatch { val proto = KonanIr.IrCatch.newBuilder() .setCatchParameter(serializeDeclaration(catch.catchParameter)) @@ -249,6 +256,13 @@ internal class IrSerializer(val context: Context, return proto.build() } + fun serializeDoWhile(expression: IrDoWhileLoop): KonanIr.IrDoWhile { + val proto = KonanIr.IrDoWhile.newBuilder() + .setLoop(serializeLoop(expression)) + + return proto.build() + } + fun serializeEnumConstructorCall(call: IrEnumConstructorCall): KonanIr.IrEnumConstructorCall { val proto = KonanIr.IrEnumConstructorCall.newBuilder() .setDescriptor(serializeDescriptor(call.descriptor)) @@ -386,8 +400,8 @@ internal class IrSerializer(val context: Context, return proto.build() } - fun serializeWhile(expression: IrWhileLoop): KonanIr.IrWhile { - val proto = KonanIr.IrWhile.newBuilder() + fun serializeLoop(expression: IrLoop): KonanIr.Loop { + val proto = KonanIr.Loop.newBuilder() .setCondition(serializeExpression(expression.condition)) val label = expression.label if (label != null) { @@ -401,8 +415,15 @@ internal class IrSerializer(val context: Context, if (body != null) { proto.setBody(serializeExpression(body)) } - return proto.build() + return proto.build() + } + + fun serializeWhile(expression: IrWhileLoop): KonanIr.IrWhile { + val proto = KonanIr.IrWhile.newBuilder() + .setLoop(serializeLoop(expression)) + + return proto.build() } fun serializeBreak(expression: IrBreak): KonanIr.IrBreak { @@ -445,10 +466,12 @@ internal class IrSerializer(val context: Context, is IrCall -> operationProto.setCall(serializeCall(expression)) is IrCallableReference -> operationProto.setCallableReference(serializeCallableReference(expression)) + is IrComposite -> operationProto.setComposite(serializeComposite(expression)) is IrConst<*> -> operationProto.setConst(serializeConst(expression)) is IrContinue -> operationProto.setContinue(serializeContinue(expression)) is IrDelegatingConstructorCall -> operationProto.setDelegatingConstructorCall(serializeDelegatingConstructorCall(expression)) + is IrDoWhileLoop -> operationProto.setDoWhile(serializeDoWhile(expression)) is IrGetField -> operationProto.setGetField(serializeGetField(expression)) is IrGetValue -> operationProto.setGetValue(serializeGetValue(expression)) is IrGetEnumValue @@ -749,7 +772,6 @@ internal class IrDeserializer(val context: Context, val block = IrBlockImpl(start, end, type, isLambdaOrigin, statements) - // TODO: Need to set isTransparentScope somehow return block } @@ -803,6 +825,15 @@ internal class IrDeserializer(val context: Context, return callable } + fun deserializeComposite(proto: KonanIr.IrComposite, start: Int, end: Int, type: KotlinType): IrComposite { + val statements = mutableListOf() + val statementProtos = proto.getStatementList() + statementProtos.forEach { + statements.add(deserializeStatement(it) as IrStatement) + } + return IrCompositeImpl(start, end, type, null, statements) + } + fun deserializeDelegatingConstructorCall(proto: KonanIr.IrDelegatingConstructorCall, start: Int, end: Int): IrDelegatingConstructorCall { val descriptor = deserializeDescriptor(proto.getDescriptor()) as ClassConstructorDescriptor val typeArgs = deserializeTypeMap(descriptor, proto.memberAccess.getTypeMap()) @@ -953,17 +984,13 @@ internal class IrDeserializer(val context: Context, return IrWhenImpl(start, end, type, null, branches) } - fun deserializeWhile(proto: KonanIr.IrWhile, start: Int, end: Int, type: KotlinType): IrWhileLoop { - // we create the IrLoop before deserializing the body, so that - // IrBreak statements have something to put into 'loop' field. - val loop = IrWhileLoopImpl(start, end, type, null) - + fun deserializeLoop(proto: KonanIr.Loop, start: Int, end: Int, type: KotlinType, loop: IrLoopBase): IrLoopBase { val loopId = proto.getLoopId() loopIndex.getOrPut(loopId){loop} - val condition = deserializeExpression(proto.getCondition()) val label = if (proto.hasLabel()) proto.getLabel() else null val body = if (proto.hasBody()) deserializeExpression(proto.getBody()) else null + val condition = deserializeExpression(proto.getCondition()) loop.label = label loop.condition = condition @@ -972,6 +999,22 @@ internal class IrDeserializer(val context: Context, return loop } + fun deserializeDoWhile(proto: KonanIr.IrDoWhile, start: Int, end: Int, type: KotlinType): IrDoWhileLoop { + // we create the loop before deserializing the body, so that + // IrBreak statements have something to put into 'loop' field. + val loop = IrDoWhileLoopImpl(start, end, type, null) + deserializeLoop(proto.loop, start, end, type, loop) + return loop + } + + fun deserializeWhile(proto: KonanIr.IrWhile, start: Int, end: Int, type: KotlinType): IrWhileLoop { + // we create the loop before deserializing the body, so that + // IrBreak statements have something to put into 'loop' field. + val loop = IrWhileLoopImpl(start, end, type, null) + deserializeLoop(proto.loop, start, end, type, loop) + return loop + } + fun deserializeBreak(proto: KonanIr.IrBreak, start: Int, end: Int, type: KotlinType): IrBreak { val label = if(proto.hasLabel()) proto.getLabel() else null val loopId = proto.getLoopId() @@ -1027,12 +1070,16 @@ internal class IrDeserializer(val context: Context, -> deserializeCall(proto.call, start, end, type) CALLABLE_REFERENCE -> deserializeCallableReference(proto.callableReference, start, end, type) + COMPOSITE + -> deserializeComposite(proto.composite, start, end, type) CONST -> deserializeConst(proto.const, start, end, type) CONTINUE -> deserializeContinue(proto.getContinue(), start, end, type) DELEGATING_CONSTRUCTOR_CALL -> deserializeDelegatingConstructorCall(proto.delegatingConstructorCall, start, end) + DO_WHILE + -> deserializeDoWhile(proto.doWhile, start, end, type) GET_ENUM_VALUE -> deserializeGetEnumValue(proto.getEnumValue, start, end) GET_FIELD