Skip to content

Commit

Permalink
Name- mangle overloaded methods/functions
Browse files Browse the repository at this point in the history
Resolves #121
Part of #125
  • Loading branch information
mukul-rathi committed Apr 25, 2020
1 parent 1a04e8e commit b888dd2
Show file tree
Hide file tree
Showing 30 changed files with 167 additions and 106 deletions.
12 changes: 10 additions & 2 deletions src/frontend/desugaring/desugar_class_and_function_defns.ml
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
open Desugar_expr
open Ast.Ast_types
open Core
open Desugar_env

let borrowed_param_vars params =
List.filter_map
~f:(fun (TParam (_, param_name, _, maybeBorrowed)) ->
match maybeBorrowed with Some Borrowed -> Some param_name | None -> None)
params

let get_param_types params =
List.map ~f:(fun (TParam (param_type, _, _, _)) -> param_type) params

let desugar_function_defn class_defns
(Typing.Typed_ast.TFunction
(func_name, maybe_borrowed_ref_ret, ret_type, params, body_expr)) =
desugar_block_expr class_defns (borrowed_param_vars params) body_expr
|> fun desugared_body_expr ->
Desugared_ast.TFunction
(func_name, maybe_borrowed_ref_ret, ret_type, params, desugared_body_expr)
( name_mangle_function func_name (get_param_types params)
, maybe_borrowed_ref_ret
, ret_type
, params
, desugared_body_expr )

let desugar_method_defn class_defns
(Typing.Typed_ast.TMethod
Expand All @@ -23,7 +31,7 @@ let desugar_method_defn class_defns
desugar_block_expr class_defns (borrowed_param_vars params) body_expr
|> fun desugared_body_expr ->
Desugared_ast.TMethod
( method_name
( name_mangle_method method_name (get_param_types params)
, maybe_borrowed_ref_ret
, ret_type
, params
Expand Down
24 changes: 24 additions & 0 deletions src/frontend/desugaring/desugar_env.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,27 @@ let get_class_field_capabilities class_name field_name class_defns =
~f:(fun (TCapability (_, capability_name)) ->
elem_in_list capability_name field_capability_names)
capabilities

let name_mangle_param_types param_types =
String.concat
(List.map
~f:(function
| TEVoid -> "v"
| TEInt -> "i"
| TEBool -> "b"
| TEClass class_name ->
let class_name_str = Class_name.to_string class_name in
Fmt.str "%d%s" (String.length class_name_str) class_name_str)
param_types)

let name_mangle_method meth_name param_types =
Method_name.of_string
(Fmt.str "_%s%s"
(Method_name.to_string meth_name)
(name_mangle_param_types param_types))

let name_mangle_function func_name param_types =
Function_name.of_string
(Fmt.str "_%s%s"
(Function_name.to_string func_name)
(name_mangle_param_types param_types))
5 changes: 5 additions & 0 deletions src/frontend/desugaring/desugar_env.mli
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ val get_class_field_capabilities :
Class_name.t -> Field_name.t -> Typing.Typed_ast.class_defn list -> capability list

val elem_in_list : 'a -> 'a list -> bool

val name_mangle_method : Method_name.t -> type_expr list -> Method_name.t
(** Name mangle method names to distinguish between overloaded methods *)

val name_mangle_function : Function_name.t -> type_expr list -> Function_name.t
10 changes: 6 additions & 4 deletions src/frontend/desugaring/desugar_expr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ let rec desugar_expr class_defns borrowed_vars expr =
| Typing.Typed_ast.Consume (loc, id) ->
desugar_identifier class_defns borrowed_vars id
|> fun desugared_id -> Desugared_ast.Consume (loc, desugared_id)
| Typing.Typed_ast.MethodApp (loc, type_expr, obj_name, obj_class, method_name, args) ->
| Typing.Typed_ast.MethodApp
(loc, type_expr, method_params, obj_name, obj_class, method_name, args) ->
List.map ~f:(desugar_expr class_defns borrowed_vars) args
|> fun desugared_args ->
get_class_capabilities obj_class class_defns
Expand All @@ -74,12 +75,13 @@ let rec desugar_expr class_defns borrowed_vars expr =
, obj_name
, obj_capabilities
, obj_class
, method_name
, name_mangle_method method_name method_params
, desugared_args )
| Typing.Typed_ast.FunctionApp (loc, type_expr, func_name, args) ->
| Typing.Typed_ast.FunctionApp (loc, type_expr, func_params, func_name, args) ->
List.map ~f:(desugar_expr class_defns borrowed_vars) args
|> fun desugared_args ->
Desugared_ast.FunctionApp (loc, type_expr, func_name, desugared_args)
Desugared_ast.FunctionApp
(loc, type_expr, name_mangle_function func_name func_params, desugared_args)
| Typing.Typed_ast.Printf (loc, format_str, args) ->
List.map ~f:(desugar_expr class_defns borrowed_vars) args
|> fun desugared_args -> Desugared_ast.Printf (loc, format_str, desugared_args)
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/desugaring/free_obj_vars_expr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ let rec free_obj_vars_expr class_defns = function
|> fun free_vars_assigned_expr ->
free_obj_vars_identifier class_defns identifier @ free_vars_assigned_expr
| Consume (_, id) -> free_obj_vars_identifier class_defns id
| MethodApp (_, _, obj_name, obj_class, _, args_exprs) ->
| MethodApp (_, _, _, obj_name, obj_class, _, args_exprs) ->
(obj_name, obj_class, get_class_capabilities obj_class class_defns)
:: union_free_vars_lists (List.map ~f:(free_obj_vars_expr class_defns) args_exprs)
| FunctionApp (_, _, _, args_exprs) ->
| FunctionApp (_, _, _, _, args_exprs) ->
union_free_vars_lists (List.map ~f:(free_obj_vars_expr class_defns) args_exprs)
| Printf (_, _, args_exprs) ->
union_free_vars_lists (List.map ~f:(free_obj_vars_expr class_defns) args_exprs)
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/typing/pprint_tast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ let rec pprint_expr ppf ~indent expr =
| Consume (loc, id) ->
print_expr "Consume" ;
pprint_expr ppf ~indent:new_indent (Identifier (loc, id))
| MethodApp (_, type_expr, var_name, obj_class, method_name, args) ->
| MethodApp (_, type_expr, _, var_name, obj_class, method_name, args) ->
print_expr
(Fmt.str "ObjMethod: (Class: %s) %s.%s"
(Class_name.to_string obj_class)
(Var_name.to_string var_name)
(Method_name.to_string method_name)) ;
pprint_type_expr ppf ~indent:new_indent type_expr ;
pprint_args ppf ~indent:new_indent args
| FunctionApp (_, type_expr, func_name, args) ->
| FunctionApp (_, type_expr, _, func_name, args) ->
print_expr "Function App" ;
pprint_type_expr ppf ~indent:new_indent type_expr ;
Fmt.pf ppf "%sFunction: %s@." new_indent (Function_name.to_string func_name) ;
Expand Down
15 changes: 11 additions & 4 deletions src/frontend/typing/type_expr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,23 @@ let rec type_expr class_defns function_defns (expr : Parsed_ast.expr) env =
type_args type_with_defns args_exprs env
>>= fun (typed_args_exprs, args_types) ->
get_matching_method_type method_name args_types class_defn loc
>>| fun (_param_types, return_type) ->
>>| fun (param_types, return_type) ->
( Typed_ast.MethodApp
(loc, return_type, var_name, class_name, method_name, typed_args_exprs)
( loc
, return_type
, param_types
, var_name
, class_name
, method_name
, typed_args_exprs )
, return_type )
| Parsed_ast.FunctionApp (loc, func_name, args_exprs) ->
type_args type_with_defns args_exprs env
>>= fun (typed_args_exprs, args_types) ->
get_matching_function_type func_name args_types function_defns loc
>>| fun (_param_types, return_type) ->
(Typed_ast.FunctionApp (loc, return_type, func_name, typed_args_exprs), return_type)
>>| fun (param_types, return_type) ->
( Typed_ast.FunctionApp (loc, return_type, param_types, func_name, typed_args_exprs)
, return_type )
| Parsed_ast.Printf (loc, format_str, args) ->
(* Defer type checking of the overall printf expr to llvm codegen - as checked then
for free *)
Expand Down
12 changes: 10 additions & 2 deletions src/frontend/typing/typed_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,16 @@ type expr =
| Let of loc * type_expr * Var_name.t * expr
| Assign of loc * type_expr * identifier * expr
| Consume of loc * identifier (* Type is associated with the identifier *)
| MethodApp of loc * type_expr * Var_name.t * Class_name.t * Method_name.t * expr list
| FunctionApp of loc * type_expr * Function_name.t * expr list
| MethodApp of
loc
* type_expr
* type_expr list
* Var_name.t
* Class_name.t
* Method_name.t
* expr list
(* [type_expr list] is types of params, used to distinguish between overloaded methodss *)
| FunctionApp of loc * type_expr * type_expr list * Function_name.t * expr list
| Printf of loc * string * expr list
(* no need for type_expr annotation as obviously TEVoid *)
| FinishAsync of loc * type_expr * async_expr list * block_expr
Expand Down
11 changes: 9 additions & 2 deletions src/frontend/typing/typed_ast.mli
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@ type expr =
| Let of loc * type_expr * Var_name.t * expr
| Assign of loc * type_expr * identifier * expr
| Consume of loc * identifier (** Type is associated with the identifier *)
| MethodApp of loc * type_expr * Var_name.t * Class_name.t * Method_name.t * expr list
| FunctionApp of loc * type_expr * Function_name.t * expr list
| MethodApp of
loc
* type_expr
* type_expr list
* Var_name.t
* Class_name.t
* Method_name.t
* expr list
| FunctionApp of loc * type_expr * type_expr list * Function_name.t * expr list
| Printf of loc * string * expr list
(** no need for type_expr annotation as obviously TEVoid *)
| FinishAsync of loc * type_expr * async_expr list * block_expr
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/independent_threads.ll.expected
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ declare i32 @pthread_equal(%pthread_t*, %pthread_t*)

declare %pthread_t* @pthread_self()

define i32 @f(i32) {
define i32 @_fi(i32) {
entry:
%x = alloca i32
store i32 %0, i32* %x
Expand Down Expand Up @@ -63,7 +63,7 @@ entry:
define i8* @_async0(i8*) {
entry:
%1 = bitcast i8* %0 to %function_arg_type*
%2 = call i32 @f(i32 5)
%2 = call i32 @_fi(i32 5)
ret i8* null
}

Expand Down
6 changes: 3 additions & 3 deletions tests/e2e/recursive_method.ll.expected
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ declare i32 @pthread_equal(%pthread_t*, %pthread_t*)

declare %pthread_t* @pthread_self()

define i32 @_Foo_setg(%Foo*, i32) {
define i32 @_Foo__setgi(%Foo*, i32) {
entry:
%_ret_val = alloca i32
%this = alloca %Foo*
Expand Down Expand Up @@ -66,7 +66,7 @@ then: ; preds = %enterLock
%16 = load %Foo*, %Foo** %this
%17 = load i32, i32* %x
%neg = sub i32 0, %17
%18 = call i32 @_Foo_setg(%Foo* %16, i32 %neg)
%18 = call i32 @_Foo__setgi(%Foo* %16, i32 %neg)
br label %ifcont

else: ; preds = %enterLock
Expand Down Expand Up @@ -167,7 +167,7 @@ entry:
%12 = bitcast %function_arg_type* %9 to i8*
%13 = call i32 @pthread_create(%pthread_t** %pthreadPtr, i8* null, i8* (i8*)* @_async0, i8* %12)
%14 = load %Foo*, %Foo** %_var_y0
%15 = call i32 @_Foo_setg(%Foo* %14, i32 10)
%15 = call i32 @_Foo__setgi(%Foo* %14, i32 10)
%16 = load %Foo*, %Foo** %_var_y0
%17 = getelementptr inbounds %Foo, %Foo* %16, i32 0, i32 4
%18 = load %Foo*, %Foo** %_var_y0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ let%expect_test "Call function on object without all required capabilities prese
" ;
[%expect
{|
Line:9 Position:7 Potential data race: Function test's argument capability constraints not satisfied. |}]
Line:9 Position:7 Potential data race: Function _test3Foo's argument capability constraints not satisfied. |}]
2 changes: 1 addition & 1 deletion tests/frontend/expect/data_race_checker/bad_method_call.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ let%expect_test "Access method without all required capabilities" =
" ;
[%expect
{|
Line:10 Position:13 Potential data race: _var_x0's method id's capability constraints not satisfied. |}]
Line:10 Position:13 Potential data race: _var_x0's method _idi's capability constraints not satisfied. |}]
4 changes: 2 additions & 2 deletions tests/frontend/expect/data_race_checker/bad_subord_access.ml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ let%expect_test "Return subordinate state from non-encapsulated method" =
" ;
[%expect
{|
Potential Data Race in Foo's method return_g: Subordinate state returned by non-encapsulated method |}]
Potential Data Race in Foo's method _return_g: Subordinate state returned by non-encapsulated method |}]

let%expect_test "Pass subordinate state to non-encapsulated method" =
print_data_race_checker_ast
Expand All @@ -73,4 +73,4 @@ let%expect_test "Pass subordinate state to non-encapsulated method" =
" ;
[%expect
{|
Potential Data Race in Foo's method return_g: Subordinate arguments passed into non-encapsulated method: x |}]
Potential Data Race in Foo's method _return_g3Foo: Subordinate arguments passed into non-encapsulated method: x |}]
8 changes: 4 additions & 4 deletions tests/frontend/expect/data_race_checker/good_block_exprs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ let%expect_test "Block of exprs" =
[%expect
{|
Program
└── Function: f
└── Function: _fi
└── Return type: Int
└──Param: x
└──Type expr: Int
Expand All @@ -26,13 +26,13 @@ let%expect_test "Block of exprs" =
└──Type expr: Int
└──Expr: Function App
└──Type expr: Int
└──Function: f
└──Function: _fi
└──Expr: Int:4
└──Expr: Function App
└──Type expr: Int
└──Function: f
└──Function: _fi
└──Expr: Int:5
└──Expr: Function App
└──Type expr: Int
└──Function: f
└──Function: _fi
└──Expr: Int:6 |}]
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ let%expect_test "Function capability guards correct" =
└──Modifier: Const
└──Type expr: Int
└──Capabilities: Baz
└── Function: f
└── Function: _f3Foo
└── Return type: Int
└──Param: y
└──Type expr: Class: Foo
Expand Down Expand Up @@ -83,7 +83,7 @@ let%expect_test "Function multiple capability guards" =
└──Modifier: Const
└──Type expr: Int
└──Capabilities: Baz
└── Function: f
└── Function: _f3Foo
└── Return type: Int
└──Param: y
└──Type expr: Class: Foo
Expand Down Expand Up @@ -139,7 +139,7 @@ let%expect_test "Method capability guards correct" =
└──Modifier: Const
└──Type expr: Int
└──Capabilities: Baz
└── Method: test
└── Method: _test3Foo
└── Return type: Int
└──Param: y
└──Type expr: Class: Foo
Expand Down
10 changes: 5 additions & 5 deletions tests/frontend/expect/data_race_checker/good_class_defn.ml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ let%expect_test "Class definition with methods" =
└──Modifier: Var
└──Type expr: Int
└──Capabilities: Bar
└── Method: set_f
└── Method: _set_fi
└── Return type: Int
└──Param: x
└──Type expr: Int
Expand Down Expand Up @@ -105,7 +105,7 @@ let%expect_test "Class definition with methods call toplevel function" =
└──Modifier: Var
└──Type expr: Int
└──Capabilities: Bar
└── Method: get_f
└── Method: _get_f
└── Return type: Int
└──Param: Void
└── Used capabilities
Expand All @@ -114,12 +114,12 @@ let%expect_test "Class definition with methods call toplevel function" =
└──Type expr: Int
└──Expr: Function App
└──Type expr: Int
└──Function: id
└──Function: _idi
└──Expr: Objfield: (Class: Foo) this.f
└──Type expr: Int
└──Capabilities:
└──Capability: Linear Bar
└── Function: id
└── Function: _idi
└── Return type: Int
└──Param: x
└──Type expr: Int
Expand All @@ -133,7 +133,7 @@ let%expect_test "Class definition with methods call toplevel function" =
└──Type expr: Class: Foo
└──Expr: Constructor for: Foo
└──Type expr: Class: Foo
└──Expr: ObjMethod: (Class: Foo) _var_x0.get_f
└──Expr: ObjMethod: (Class: Foo) _var_x0._get_f
└── Possible Capabilities:
└── Possible Capability: Linear Bar
└──Type expr: Int
Expand Down

0 comments on commit b888dd2

Please sign in to comment.