Skip to content

Commit

Permalink
2002-02-21 Miguel de Icaza <miguel@ximian.com>
Browse files Browse the repository at this point in the history
	* expression.cs (Binary.ResolveOperator): Remove redundant
	MemberLookup pn parent type.
	Optimize union call, we do not need a union if the types are the same.
	(Unary.ResolveOperator): REmove redundant MemberLookup on parent
	type.

	Specialize the use of MemberLookup everywhere, instead of using
	the default settings.

	(StackAlloc): Implement stackalloc keyword.

	* cs-parser.jay: Add rule to parse stackalloc.

	* driver.cs: Handle /h, /help, /?

Added two more tests, added an error test.

svn path=/trunk/mcs/; revision=2579
  • Loading branch information
migueldeicaza committed Feb 21, 2002
1 parent d293482 commit 058103a
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 25 deletions.
13 changes: 13 additions & 0 deletions mcs/errors/cs0255.cs
@@ -0,0 +1,13 @@
// cs0255.cs: Can not use stackalloc in finally or catch
// Line: 10
unsafe class X {
string s;

static void Main ()
{
try {
} catch {
char *ptr = stackalloc char [10U];
}
}
}
15 changes: 15 additions & 0 deletions mcs/mcs/ChangeLog
@@ -1,5 +1,20 @@
2002-02-21 Miguel de Icaza <miguel@ximian.com>

* expression.cs (Binary.ResolveOperator): Remove redundant
MemberLookup pn parent type.
Optimize union call, we do not need a union if the types are the same.
(Unary.ResolveOperator): REmove redundant MemberLookup on parent
type.

Specialize the use of MemberLookup everywhere, instead of using
the default settings.

(StackAlloc): Implement stackalloc keyword.

* cs-parser.jay: Add rule to parse stackalloc.

* driver.cs: Handle /h, /help, /?

* expression.cs (MakeByteBlob): Removed the hacks we had in place
before we supported unsafe code.

Expand Down
5 changes: 5 additions & 0 deletions mcs/mcs/TODO
Expand Up @@ -248,6 +248,11 @@ OPTIMIZATIONS
a single one that maps a TypeBuilder `t' to a set of classes
that implement an interface that supports FindMembers.

* MakeUnionSet Callers

If the types are the same, there is no need to compute the unionset,
we can just use the list from one of the types.

RECOMMENDATIONS
---------------

Expand Down
9 changes: 7 additions & 2 deletions mcs/mcs/cs-parser.jay
Expand Up @@ -146,6 +146,7 @@ namespace Mono.CSharp
%token SEALED
%token SHORT
%token SIZEOF
%token STACKALLOC
%token STATIC
%token STRING
%token STRUCT
Expand Down Expand Up @@ -758,9 +759,13 @@ variable_initializer
$$ = $1;
}
| array_initializer
{
{
$$ = $1;
}
}
| STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET
{
$$ = new StackAlloc ((string) $2, (Expression) $4, lexer.Location);
}
;

method_declaration
Expand Down
1 change: 1 addition & 0 deletions mcs/mcs/cs-tokenizer.cs
Expand Up @@ -212,6 +212,7 @@ static void InitTokens ()
keywords.Add ("set", Token.SET);
keywords.Add ("short", Token.SHORT);
keywords.Add ("sizeof", Token.SIZEOF);
keywords.Add ("stackalloc", Token.STACKALLOC);
keywords.Add ("static", Token.STATIC);
keywords.Add ("string", Token.STRING);
keywords.Add ("struct", Token.STRUCT);
Expand Down
15 changes: 11 additions & 4 deletions mcs/mcs/driver.cs
Expand Up @@ -305,7 +305,8 @@ static void MainDriver (string [] args)
{
int errors = 0, i;
string output_file = null;

bool parsing_options = true;

references = new ArrayList ();
link_paths = new ArrayList ();

Expand Down Expand Up @@ -354,12 +355,16 @@ static void MainDriver (string [] args)
continue;
}

if (arg.StartsWith ("-")){
if (parsing_options && (arg.StartsWith ("-") || arg.StartsWith ("/"))){
switch (arg){
case "-v":
yacc_verbose = true;
continue;

case "--":
parsing_options = false;
continue;

case "--parse":
parse_only = true;
continue;
Expand All @@ -380,6 +385,7 @@ static void MainDriver (string [] args)
RootContext.Optimize = true;
continue;

case "/?": case "/h": case "/help":
case "--help":
Usage (false);
return;
Expand Down Expand Up @@ -410,14 +416,15 @@ static void MainDriver (string [] args)
continue;
}

case "-o": case "--output":
case "-o":
case "--output":
if ((i + 1) >= argc){
Usage (true);
return;
}
output_file = args [++i];
continue;

case "--checked":
RootContext.Checked = true;
continue;
Expand Down
102 changes: 84 additions & 18 deletions mcs/mcs/expression.cs
Expand Up @@ -263,10 +263,7 @@ Expression ResolveOperator (EmitContext ec)

op_name = oper_names [(int) oper];

mg = MemberLookup (ec, expr_type, op_name, loc);

if (mg == null && expr_type.BaseType != null)
mg = MemberLookup (ec, expr_type.BaseType, op_name, loc);
mg = MemberLookup (ec, expr_type, op_name, MemberTypes.Method, AllBindingFlags, loc);

if (mg != null) {
Expression e = StaticCallExpr.MakeSimpleCall (
Expand Down Expand Up @@ -645,10 +642,11 @@ Expression ResolveOperator (EmitContext ec)
else
op_name = "op_Decrement";

mg = MemberLookup (ec, expr_type, op_name, loc);
mg = MemberLookup (ec, expr_type, op_name, MemberTypes.Method, AllBindingFlags, loc);

if (mg == null && expr_type.BaseType != null)
mg = MemberLookup (ec, expr_type.BaseType, op_name, loc);
mg = MemberLookup (ec, expr_type.BaseType, op_name,
MemberTypes.Method, AllBindingFlags, loc);

if (mg != null) {
method = StaticCallExpr.MakeSimpleCall (
Expand Down Expand Up @@ -1587,15 +1585,14 @@ Expression ResolveOperator (EmitContext ec)

string op = "op_" + oper;

left_expr = MemberLookup (ec, l, op, loc);
if (left_expr == null && l.BaseType != null)
left_expr = MemberLookup (ec, l.BaseType, op, loc);

right_expr = MemberLookup (ec, r, op, loc);
if (right_expr == null && r.BaseType != null)
right_expr = MemberLookup (ec, r.BaseType, op, loc);

MethodGroupExpr union = Invocation.MakeUnionSet (left_expr, right_expr);
MethodGroupExpr union;
left_expr = MemberLookup (ec, l, op, MemberTypes.Method, AllBindingFlags, loc);
if (r != l){
right_expr = MemberLookup (
ec, r, op, MemberTypes.Method, AllBindingFlags, loc);
union = Invocation.MakeUnionSet (left_expr, right_expr);
} else
union = (MethodGroupExpr) left_expr;

if (union != null) {
Arguments = new ArrayList ();
Expand Down Expand Up @@ -4737,7 +4734,8 @@ static bool IdenticalNameAndTypeName (EmitContext ec, Expression left_original,

if (decl_type.IsSubclassOf (TypeManager.enum_type)) {
Expression enum_member = MemberLookup (
ec, decl_type, "value__", loc);
ec, decl_type, "value__", MemberTypes.Field,
AllBindingFlags, loc);

Enum en = TypeManager.LookupEnum (decl_type);

Expand Down Expand Up @@ -5604,7 +5602,7 @@ public override Expression DoResolve (EmitContext ec)
return null;
}

member_lookup = MemberLookup (ec, base_type, "get_Item", loc);
member_lookup = MemberLookup (ec, base_type, "get_Item", MemberTypes.Method, AllBindingFlags, loc);
if (member_lookup == null)
return null;

Expand Down Expand Up @@ -5783,5 +5781,73 @@ public override Expression DoResolve (EmitContext ec)
return this;
}
}


//
// Implements the `stackalloc' keyword
//
public class StackAlloc : Expression {
Type otype;
string t;
Expression count;
Location loc;

public StackAlloc (string type, Expression count, Location l)
{
t = type;
this.count = count;
loc = l;
}

public override Expression DoResolve (EmitContext ec)
{
count = count.Resolve (ec);
if (count == null)
return null;

if (count.Type != TypeManager.int32_type){
count = ConvertImplicitRequired (ec, count, TypeManager.int32_type, loc);
if (count == null)
return null;
}

if (ec.InCatch || ec.InFinally){
Report.Error (255, loc,
"stackalloc can not be used in a catch or finally block");
return null;
}

otype = RootContext.LookupType (ec.TypeContainer, t, false, loc);

if (otype == null)
return null;

if (!TypeManager.VerifyUnManaged (otype, loc))
return null;

string ptr_name = otype.FullName + "*";
type = Type.GetType (ptr_name);
if (type == null){
ModuleBuilder mb = RootContext.ModuleBuilder;

type = mb.GetType (ptr_name);
}
eclass = ExprClass.Value;

return this;
}

public override void Emit (EmitContext ec)
{
int size = GetTypeSize (otype);
ILGenerator ig = ec.ig;

if (size == 0)
ig.Emit (OpCodes.Sizeof, otype);
else
IntConstant.EmitInt (ig, size);
count.Emit (ec);
ig.Emit (OpCodes.Mul);
ig.Emit (OpCodes.Localloc);
}
}
}
2 changes: 1 addition & 1 deletion mcs/tests/makefile
Expand Up @@ -11,7 +11,7 @@ TEST_SOURCES = \
test-41 test-42 test-43 test-44 test-45 test-46 test-47 test-48 test-49 test-50 \
test-51 test-52 test-53 test-54 test-55 test-56 test-57 test-59 \
test-61 test-62 test-63 test-64 test-65 test-66 test-67 test-68 test-69 test-70 \
test-71 test-72 test-73 test-74
test-71 test-72 test-73 test-74 test-75

UNSAFE_SOURCES = \
unsafe-1
Expand Down
36 changes: 36 additions & 0 deletions mcs/tests/test-75.cs
@@ -0,0 +1,36 @@
//
// This test probes using an operator overloaded in a parents' parent
//

class X {
public static bool called = false;

static public X operator + (X a, X b)
{
called = true;
return null;
}
}

class Y : X {
}

class Z : Y {
}

class driver {

static int Main ()
{
Z a = new Z ();
Z b = new Z ();
X c = a + b;

if (X.called)
return 0;

return 1;
}

}

25 changes: 25 additions & 0 deletions mcs/tests/unsafe-2.cs
@@ -0,0 +1,25 @@
//
// This test excercises stackalloc, some pointer arithmetic,
// and dereferences
//
using System;
unsafe class X {
static int Main ()
{
char *ptr = stackalloc char [10];
int i;

for (i = 0; i < 10; i++)
ptr [i] = (char) (i + 10);

for (i = 0; i < 10; i++){
if (*ptr != (char) (i + 10))
return 200 + i;
ptr++;
}
Console.WriteLine ("Ok");
return 0;
}
}


0 comments on commit 058103a

Please sign in to comment.