Commit 2f3700e8 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Fix LLVM backend (ExprAppend)

parent c1435610
......@@ -929,6 +929,26 @@ def _prim_substring_reference(prim, ctx):
return SDLSubstringValue(arr_ptr, count_val, asn1ty)
@reference.register(ogAST.ExprAppend)
def _expr_append_reference(expr, ctx):
''' Generate the IR for an append reference '''
apnd = SDLAppendValue()
# Append expressions can be recursive -> Flatten them
if isinstance(expr.left, ogAST.ExprAppend):
# Get an SDLAppendValue for recursive Append constructs
inner_left = expression(expr.left, ctx)
apnd.apnd_list.extend(inner_left.apnd_list)
else:
apnd.apnd_list.append(expr.left)
if isinstance(expr.right, ogAST.ExprAppend):
inner_right = expression(expr.right, ctx)
apnd.apnd_list.extend(inner_right.apnd_list)
else:
apnd.apnd_list.append(expr.right)
apnd.exprType = expr.exprType
return apnd
@singledispatch
def expression(expr, ctx):
''' Generate the IR for an expression node '''
......@@ -1223,21 +1243,9 @@ def _expr_not(expr, ctx):
@expression.register(ogAST.ExprAppend)
def _expr_append(expr, ctx):
''' Generate the IR for an append reference '''
apnd = SDLAppendValue()
# Append expressions can be recursive -> Flatten them
if isinstance(expr.left, ogAST.ExprAppend):
# Get an SDLAppendValue for recursive Append constructs
inner_left = expression(expr.left)
apnd.apnd_list.extend(inner_left.apnd_list)
else:
apnd.apnd_list.append(expr.left)
if isinstance(expr.left, ogAST.ExprAppend):
inner_right = expression(expr.right)
apnd.apnd_list.extend(inner_right.apnd_list)
else:
apnd.apnd_list.append(expr.right)
return apnd
''' Generate the IR for an append expression '''
return reference(expr, ctx)
#@expression.register(ogAST.ExprAppend)
#def _expr_append(expr, ctx):
# ''' Generate the IR for a append expression '''
......@@ -1559,7 +1567,7 @@ def _prim_sequence(prim, ctx):
seq_asn1ty = ctx.dataview[prim.exprType.ReferencedTypeName]
for field_name, field_expr in prim.value.viewitems():
# Workarround for unknown types in nested sequences
# Workaround for unknown types in nested sequences
#field_expr.exprType = seq_asn1ty.type.Children[field_name.replace('_', '-')].type
field_expr.exprType = ctx.basic_asn1type_of(prim.exprType).Children[\
field_name.replace('_', '-')].type
......@@ -1859,6 +1867,7 @@ class SDLAppendValue():
''' Store an array concatenation value (e.g. "a//b") '''
def __init__(self):
self.apnd_list = []
self.exprType = None
###############################################################################
# Operators
......@@ -1897,7 +1906,64 @@ def sdl_assign(a_ptr, b_val, ctx):
ctx.builder.store(b_val.count_val, a_count_ptr)
elif isinstance(b_val, SDLAppendValue):
print 'Assign Append', b_val
bty = ctx.basic_asn1type_of(b_val.exprType)
res_llty = ctx.lltype_of(b_val.exprType)
res_ptr = a_ptr
total_size = lc.Constant.int(ctx.i64, 0)
# Get pointer to data and nCount (if any) fields
if bty.Min != bty.Max:
res_len_ptr = ctx.builder.gep(res_ptr, [ctx.zero, ctx.zero])
res_arr_ptr = ctx.builder.gep(res_ptr, [ctx.zero, ctx.one])
elem_llty = res_llty.elements[1].element
else:
# Fixed-size
res_len_ptr = None
res_arr_ptr = ctx.builder.gep(res_ptr, [ctx.zero, ctx.zero])
elem_llty = res_llty.elements[0].element
# Size of a single element (needed for memcpy):
elem_size_val = lc.Constant.sizeof(elem_llty)
# Append (memcpy) each of the elements of the append list
for each in b_val.apnd_list:
each_ptr = expression(each, ctx)
if isinstance(each_ptr, SDLSubstringValue):
each_arr_ptr = each_ptr.arr_ptr
each_count_val = each_ptr.count_val
else:
each_bty = ctx.basic_asn1type_of(each.exprType)
if each_bty.Min != each_bty.Max:
# Non-fixed size, get pointer to array of element
each_len_ptr = ctx.builder.gep(each_ptr,
[ctx.zero, ctx.zero])
each_arr_ptr = ctx.builder.gep(each_ptr,
[ctx.zero, ctx.one])
each_count_val = ctx.builder.load(each_len_ptr)
total_size = total_size.add(
ctx.builder.zext(each_count_val, ctx.i64))
else:
# Fixed size
each_arr_ptr = each_ptr
each_count_val = lc.Constant.int(ctx.i64,
int(each_bty.Min))
total_size = total_size.add(
ctx.builder.zext(each_count_val, ctx.i64))
sdl_call('memcpy', [
ctx.builder.bitcast(res_arr_ptr, ctx.i8_ptr),
ctx.builder.bitcast(each_arr_ptr, ctx.i8_ptr),
ctx.builder.mul(elem_size_val,
ctx.builder.zext(each_count_val, ctx.i64)),
lc.Constant.int(ctx.i32, 0),
lc.Constant.int(ctx.i1, 0)
], ctx)
# Move pointer to the end of the string for the next element
res_arr_ptr = ctx.builder.gep(res_ptr,
[ctx.zero,
ctx.one if res_len_ptr else ctx.zero,
total_size])
if res_len_ptr:
# Store the resulting size of the concatenation, if needed (nCount)
ctx.builder.store(total_size, res_len_ptr)
elif is_struct_ptr(a_ptr) or is_array_ptr(a_ptr):
size = lc.Constant.sizeof(a_ptr.type.pointee)
......
......@@ -2,7 +2,7 @@
 
# Resource object code
#
# Created: Sun Oct 26 11:44:05 2014
# Created: Sun Oct 26 11:45:10 2014
# by: The Resource Compiler for PySide (Qt v4.8.6)
#
# WARNING! All changes made in this file will be lost!
......@@ -1316,6 +1316,7 @@ def append_expression(root, context):
else:
attrs = {'Min': str(int(right.Min) + int(left.Min)),
'Max': str(int(right.Max) + int(left.Max))}
# It is wrong to set the type as inheriting from the left side FIXME
expr.exprType = type('Apnd', (left,), attrs)
#expr.exprType = expr.left.exprType
......@@ -3687,6 +3688,12 @@ def assign(root, context):
ogAST.PrimSequenceOf,
ogAST.PrimStringLiteral)):
expr.right.exprType = expr.left.exprType
# XXX I don't understand why we don't set the type of right
# to the same value as left in case of ExprAppend
# Setting it - I did not see any place in the Ada backend where
# this could cause a bug (and regression is OK)
if isinstance(expr.right, ogAST.ExprAppend):
expr.right.exprType = expr.left.exprType
return expr, errors, warnings
......
# $ANTLR 3.1.3 Mar 17, 2009 19:23:44 sdl92.g 2014-10-26 11:44:07
# $ANTLR 3.1.3 Mar 17, 2009 19:23:44 sdl92.g 2014-10-26 11:45:13
import sys
from antlr3 import *
......
# $ANTLR 3.1.3 Mar 17, 2009 19:23:44 sdl92.g 2014-10-26 11:44:06
# $ANTLR 3.1.3 Mar 17, 2009 19:23:44 sdl92.g 2014-10-26 11:45:11
 
import sys
from antlr3 import *
......
......@@ -6,7 +6,7 @@ TASTE-Peek-id ::= INTEGER (0..4294967295)
TASTE-Peek-id-list ::= SEQUENCE (SIZE (1..10)) OF TASTE-Peek-id
VariableString ::= OCTET STRING (SIZE (1..10))
FixedString ::= OCTET STRING (SIZE (5))
FixedString ::= OCTET STRING (SIZE (4))
SeqBool ::= SEQUENCE (SIZE(1..5)) OF BOOLEAN
SeqBoolFix ::= SEQUENCE (SIZE(2)) OF BOOLEAN
......
......@@ -3,18 +3,18 @@ PROCESS orchestrator
/* CIF COMMENT (405, 192), (71, 35) */
COMMENT 'Hello';
/* CIF TEXT (39, 94), (293, 263) */
dcl fixed FixedString := 'Hello';
dcl fixed FixedString := 'Helo';
/* CIF ENDTEXT */
/* CIF START (456, 110), (70, 35) */
START;
/* CIF PROCEDURECALL (352, 160), (277, 35) */
CALL writeln(fixed(0,2)//fixed(2,4)//' world')
CALL writeln(fixed(0,2)//fixed(2,3)//' word')
/* CIF COMMENT (649, 160), (173, 53) */
COMMENT 'FIXME: string world
cannot be longer than
6 chars !?';
/* CIF TASK (410, 210), (159, 35) */
TASK fixed := 'Hel' // 'lp';
/* CIF TASK (398, 210), (183, 35) */
TASK fixed := 'H' // 'e' // 'p!';
/* CIF PROCEDURECALL (428, 260), (124, 35) */
CALL writeln(fixed);
/* CIF NEXTSTATE (455, 310), (70, 35) */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment