Permalink
Browse files

Work on pointers. Fix a bug. Add a optimizations.

  • Loading branch information...
1 parent 8d5983e commit 930184e0a9c68a0634cd41a8283e7d949ee2c6aa @VladD2 VladD2 committed Aug 23, 2012
@@ -516,8 +516,8 @@ namespace Nemerle.Compiler
log (EMIT, $"{ emit: $expr");
Util.cassert (expr != null);
Util.locate (expr.Location,
- match (expr) {
-
+ match (expr)
+ {
/* -- SEQUENCING --------------------------------------------------- */
/* emits a sequence of expressions */
@@ -979,11 +979,7 @@ namespace Nemerle.Compiler
emit_tuple_function_conversion (expr.FixedType(), t, field);
- | PointerIndexer(ptr, index) =>
- //assert2(false);
- emit(ptr);
- emit_ptr_indexing(ptr.Type, index);
-
+ | PointerIndexer(ptr, index) => emit_ptr_indexing(expr.NeedAddress, ptr, index);
// load an array element
| ArrayIndexer (array_obj, [index]) =>
emit_exprs ([array_obj, index]);
@@ -2265,31 +2261,45 @@ namespace Nemerle.Compiler
| _ => assert(false);
}
- private emit_ptr_indexing(type : TypeVar, index : TExpr) : void
+ private emit_ptr_indexing(needAddress : bool, ptr : TExpr, index : TExpr) : void
{
+ def type = ptr.Type;
+
assert(type.IsPointer);
-
- emit(index);
+ emit(ptr);
def size = get_elem_size(type);
- _ilg.Emit(OpCodes.Conv_I);
-
- emit_index_multiplier(size);
+ match (index)
+ {
+ | TExpr.Literal(Literal.Integer(0, _, _)) => ()
+ | TExpr.Literal(Literal.Integer(val, is_negative, _treat_as)) =>
+ def byteOffset = (size / 8) * (val :> int) * if (is_negative) -1 else 1;
+
+ _ilg.Emit(OpCodes.Conv_I);
+ emit_i4(byteOffset);
+ _ilg.Emit(OpCodes.Add);
+
+ | _ =>
+ emit(index);
+ _ilg.Emit(OpCodes.Conv_I);
+ emit_index_multiplier(size);
- when (size > 8)
- _ilg.Emit(OpCodes.Mul);
+ when (size > 8)
+ _ilg.Emit(OpCodes.Mul);
- _ilg.Emit(OpCodes.Add);
-
- match (size)
- {
- | 8 => _ilg.Emit(OpCodes.Ldind_U1);
- | 16 => _ilg.Emit(OpCodes.Ldind_U2);
- | 32 => _ilg.Emit(OpCodes.Ldind_U4);
- | 64 => _ilg.Emit(OpCodes.Ldind_I8);
- | _ => assert(false);
- }
+ _ilg.Emit(OpCodes.Add);
+ }
+
+ unless (needAddress)
+ match (size)
+ {
+ | 8 => _ilg.Emit(OpCodes.Ldind_U1);
+ | 16 => _ilg.Emit(OpCodes.Ldind_U2);
+ | 32 => _ilg.Emit(OpCodes.Ldind_U4);
+ | 64 => _ilg.Emit(OpCodes.Ldind_I8);
+ | _ => assert(false);
+ }
}
/**
@@ -2356,28 +2366,25 @@ namespace Nemerle.Compiler
}
}
+ emit_i4(x : int) : void
+ {
+ | -1 => _ilg.Emit (OpCodes.Ldc_I4_M1)
+ | 0 => _ilg.Emit (OpCodes.Ldc_I4_0)
+ | 1 => _ilg.Emit (OpCodes.Ldc_I4_1)
+ | 2 => _ilg.Emit (OpCodes.Ldc_I4_2)
+ | 3 => _ilg.Emit (OpCodes.Ldc_I4_3)
+ | 4 => _ilg.Emit (OpCodes.Ldc_I4_4)
+ | 5 => _ilg.Emit (OpCodes.Ldc_I4_5)
+ | 6 => _ilg.Emit (OpCodes.Ldc_I4_6)
+ | 7 => _ilg.Emit (OpCodes.Ldc_I4_7)
+ | 8 => _ilg.Emit (OpCodes.Ldc_I4_8)
+ | k when (k >= -128 && k <= 127) => _ilg.Emit (OpCodes.Ldc_I4_S, k :> sbyte)
+ | k => _ilg.Emit (OpCodes.Ldc_I4, k)
+ }
- /**
- * Emits a literal
- */
+ /// Emits a literal
private emit_literal (l : Literal) : void
{
- def emit_i4 (x) {
- | -1 => _ilg.Emit (OpCodes.Ldc_I4_M1)
- | 0 => _ilg.Emit (OpCodes.Ldc_I4_0)
- | 1 => _ilg.Emit (OpCodes.Ldc_I4_1)
- | 2 => _ilg.Emit (OpCodes.Ldc_I4_2)
- | 3 => _ilg.Emit (OpCodes.Ldc_I4_3)
- | 4 => _ilg.Emit (OpCodes.Ldc_I4_4)
- | 5 => _ilg.Emit (OpCodes.Ldc_I4_5)
- | 6 => _ilg.Emit (OpCodes.Ldc_I4_6)
- | 7 => _ilg.Emit (OpCodes.Ldc_I4_7)
- | 8 => _ilg.Emit (OpCodes.Ldc_I4_8)
- | k when (k >= -128 && k <= 127) =>
- _ilg.Emit (OpCodes.Ldc_I4_S, k :> sbyte)
- | k => _ilg.Emit (OpCodes.Ldc_I4, k)
- }
-
match (l) {
| Literal.Void => ()
| Literal.Null => _ilg.Emit (OpCodes.Ldnull)
@@ -9,21 +9,23 @@ using Nemerle.Unsafe;
module Program
{
- mutable i = 0;
-
- ary = array[42, 2, 3];
- str = "abc";
- mutable _ptr : char*;
-
Test1() : void
{
pinned (p1 = str)
{
+ WriteLine(p1[1].ToString());
+ WriteLine((p1[3] : int).ToString());
WriteLine(p1[0]);
UnsafeMethod(p1);
- }
+ }
}
+ mutable i = 0;
+
+ ary = array[42, 2, 3];
+ str = "abc";
+ mutable _ptr : char*;
+
TupleTest1(_tup : int * string) : void
{
}
@@ -71,15 +73,44 @@ module Program
}
}
+ Test3(ptrIn : int*) : void
+ {
+ WriteLine("Test3()");
+ WriteLine(*ptrIn);
+ mutable ptr = ptrIn;
+ ptr += 10000;
+ WriteLine(ptr[-10000]);
+ ptr = ptrIn + 100;
+ WriteLine(ptr[-100]);
+ ptr = ptrIn + 3;
+ WriteLine(ptr[-2]);
+ ptr = ptrIn + 3;
+ WriteLine(ptr[-1]);
+ ptr = ptrIn;
+ WriteLine(ptr[1 - 1]);
+ WriteLine(ptr[0]);
+ WriteLine(ptr[1]);
+ WriteLine(ptr[2]);
+ ptr = ptrIn + -6;
+ WriteLine(ptr[8]);
+ ptr = ptrIn + -10000;
+ WriteLine(ptr[10000]);
+ }
+
+
Main() : void
{
Test1();
Test2();
+ pinned (p = ary)
+ Test3(p);
}
}
/*
BEGIN-OUTPUT
+b
+0
a
a
b
@@ -95,5 +126,17 @@ c
end for
42
3
+Test3()
+42
+42
+42
+2
+3
+42
+42
+2
+3
+3
+42
END-OUTPUT
*/
@@ -81,7 +81,6 @@ namespace Nemerle.Unsafe
| _ => Message.FatalError(args.Location, "Expected 'name = expr'.");
}
- // TODO: Add implementation here.
}
}
}
@@ -8,21 +8,23 @@ using Nemerle.Unsafe;
module Program
{
- mutable i = 0;
-
- ary = array[42, 2, 3];
- str = "abc";
- mutable _ptr : char*;
-
Test1() : void
{
pinned (p1 = str)
{
+ WriteLine(p1[3].ToString());
+ WriteLine((p1[3] : int).ToString());
WriteLine(p1[0]);
UnsafeMethod(p1);
- }
+ }
}
+ mutable i = 0;
+
+ ary = array[42, 2, 3];
+ str = "abc";
+ mutable _ptr : char*;
+
TupleTest1(_tup : int * string) : void
{
}
@@ -70,9 +72,36 @@ module Program
}
}
+ Test3(ptrIn : int*) : void
+ {
+ WriteLine("Test3()");
+ WriteLine(*ptrIn);
+ mutable ptr = ptrIn;
+ ptr += 10000;
+ WriteLine(ptr[-10000]);
+ ptr = ptrIn + 100;
+ WriteLine(ptr[-100]);
+ ptr = ptrIn + 3;
+ WriteLine(ptr[-2]);
+ ptr = ptrIn + 3;
+ WriteLine(ptr[-1]);
+ ptr = ptrIn;
+ WriteLine(ptr[1 - 1]);
+ WriteLine(ptr[0]);
+ WriteLine(ptr[1]);
+ WriteLine(ptr[2]);
+ ptr = ptrIn + -6;
+ WriteLine(ptr[8]);
+ ptr = ptrIn + -10000;
+ WriteLine(ptr[10000]);
+ }
+
+
Main() : void
{
Test1();
Test2();
+ pinned (p = ary)
+ Test3(p);
}
}
@@ -14,8 +14,24 @@ unsafe class Program
static int[] ary = new int[] { 1, 2, 3 };
//static int[] ary = new int[0];
+ byte Test3(byte* ptr)
+ {
+ return ptr[-3];
+ }
+
+ static void Test4(char* ptr)
+ {
+ var c = ptr[3];
+ Console.WriteLine(c.ToString());
+ }
+
static void Main(string[] args)
{
+ fixed (char* p = "abc")
+ Test4(p);
+
+ return;
+
var x = 1;
//typeof(int).MakePointerType()
//Console.WriteLine(ary[x]);

0 comments on commit 930184e

Please sign in to comment.