diff --git a/src/proto_alpha/lib_protocol/src/michelson_v1_gas.ml b/src/proto_alpha/lib_protocol/src/michelson_v1_gas.ml index d59e95859..6f731bc2b 100644 --- a/src/proto_alpha/lib_protocol/src/michelson_v1_gas.ml +++ b/src/proto_alpha/lib_protocol/src/michelson_v1_gas.ml @@ -313,6 +313,8 @@ module Cost_of = struct | Concat_bytes -> alloc_cost 1 | Slice_string -> alloc_cost 1 | Slice_bytes -> alloc_cost 1 + | String_size -> alloc_cost 1 + | Bytes_size -> alloc_cost 1 | Add_seconds_to_timestamp -> alloc_cost 1 | Add_timestamp_to_seconds -> alloc_cost 1 | Sub_timestamp_seconds -> alloc_cost 1 diff --git a/src/proto_alpha/lib_protocol/src/script_interpreter.ml b/src/proto_alpha/lib_protocol/src/script_interpreter.ml index ca9a3acf5..864326a0e 100644 --- a/src/proto_alpha/lib_protocol/src/script_interpreter.ml +++ b/src/proto_alpha/lib_protocol/src/script_interpreter.ml @@ -429,6 +429,9 @@ let rec interp else Lwt.return (Gas.consume ctxt (Interp_costs.slice_string 0)) >>=? fun ctxt -> logged_return (Item (None, rest), ctxt) + | String_size, Item (s, rest) -> + Lwt.return (Gas.consume ctxt Interp_costs.push) >>=? fun ctxt -> + logged_return (Item (Script_int.(abs (of_int (String.length s))), rest), ctxt) (* bytes operations *) | Concat_bytes, Item (ss, rest) -> Lwt.return (Gas.consume ctxt (Interp_costs.concat_bytes ss)) >>=? fun ctxt -> @@ -444,6 +447,9 @@ let rec interp else Lwt.return (Gas.consume ctxt (Interp_costs.slice_string 0)) >>=? fun ctxt -> logged_return (Item (None, rest), ctxt) + | Bytes_size, Item (s, rest) -> + Lwt.return (Gas.consume ctxt Interp_costs.push) >>=? fun ctxt -> + logged_return (Item (Script_int.(abs (of_int (MBytes.length s))), rest), ctxt) (* currency operations *) | Add_tez, Item (x, Item (y, rest)) -> Lwt.return (Gas.consume ctxt Interp_costs.int64_op) >>=? fun ctxt -> diff --git a/src/proto_alpha/lib_protocol/src/script_ir_translator.ml b/src/proto_alpha/lib_protocol/src/script_ir_translator.ml index d5b36d20d..6807c812b 100644 --- a/src/proto_alpha/lib_protocol/src/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/src/script_ir_translator.ml @@ -157,8 +157,10 @@ let number_of_generated_growing_types : type b a. (b, a) instr -> int = function | Big_map_mem -> 0 | Concat_string -> 0 | Slice_string -> 0 + | String_size -> 0 | Concat_bytes -> 0 | Slice_bytes -> 0 + | Bytes_size -> 0 | Add_seconds_to_timestamp -> 0 | Add_timestamp_to_seconds -> 0 | Sub_timestamp_seconds -> 0 @@ -2126,6 +2128,10 @@ and parse_instr loc annot >>=? fun annot -> typed ctxt loc Slice_string (Item_t (Option_t ((String_t tname, None), None, None), rest, annot)) + | Prim (loc, I_SIZE, [], annot), + Item_t (String_t _, rest, _) -> + parse_var_annot loc annot >>=? fun annot -> + typed ctxt loc String_size (Item_t (Nat_t None, rest, annot)) (* bytes operations *) | Prim (loc, I_CONCAT, [], annot), Item_t (List_t (Bytes_t tname, _), rest, list_annot) -> @@ -2139,6 +2145,10 @@ and parse_instr loc annot >>=? fun annot -> typed ctxt loc Slice_bytes (Item_t (Option_t ((Bytes_t tname, None), None, None), rest, annot)) + | Prim (loc, I_SIZE, [], annot), + Item_t (Bytes_t _, rest, _) -> + parse_var_annot loc annot >>=? fun annot -> + typed ctxt loc Bytes_size (Item_t (Nat_t None, rest, annot)) (* currency operations *) | Prim (loc, I_ADD, [], annot), Item_t (Mutez_t tn1, Item_t (Mutez_t tn2, rest, _), _) -> @@ -2671,7 +2681,7 @@ and parse_instr Lwt.return @@ serialize_ty_for_error ctxt ta >>=? fun (ta, ctxt) -> Lwt.return @@ serialize_ty_for_error ctxt tb >>=? fun (tb, _ctxt) -> fail (Undefined_binop (loc, name, ta, tb)) - | Prim (loc, (I_NEG | I_ABS | I_NOT | I_CONCAT + | Prim (loc, (I_NEG | I_ABS | I_NOT | I_CONCAT | I_SIZE | I_EQ | I_NEQ | I_LT | I_GT | I_LE | I_GE as name), [], _), Item_t (t, _, _) -> diff --git a/src/proto_alpha/lib_protocol/src/script_typed_ir.ml b/src/proto_alpha/lib_protocol/src/script_typed_ir.ml index ad3f8c0eb..98889455e 100644 --- a/src/proto_alpha/lib_protocol/src/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/src/script_typed_ir.ml @@ -206,11 +206,15 @@ and ('bef, 'aft) instr = (string list * 'rest, string * 'rest) instr | Slice_string : (n num * (n num * (string * 'rest)), string option * 'rest) instr + | String_size : + (string * 'rest, n num * 'rest) instr (* bytes operations *) | Concat_bytes : (MBytes.t list * 'rest, MBytes.t * 'rest) instr | Slice_bytes : (n num * (n num * (MBytes.t * 'rest)), MBytes.t option * 'rest) instr + | Bytes_size : + (MBytes.t * 'rest, n num * 'rest) instr (* timestamp operations *) | Add_seconds_to_timestamp : (z num * (Script_timestamp.t * 'rest),