From 0ac36edd589fe56756ad8a833847e410a603eba6 Mon Sep 17 00:00:00 2001 From: Nick Benton Date: Wed, 14 Feb 2018 12:04:06 -0800 Subject: [PATCH] extend parsing etc. to cope with hhas instructions that hackc doesn't directly emit Summary: Add parsing for some instructions (e.g. AssertRATStk) that are not directly produced by hackc, but appear when hackc is invoked by hhvm in repo mode, and a missing mode for BareThis. Reviewed By: CatherineGasnier Differential Revision: D6987377 fbshipit-source-id: d463722b2ad8d5ff939820fa08c67ed54dcc12bf --- hphp/hack/src/hhbc/Hhas_parser_actions.ml | 1 + hphp/hack/src/hhbc/hhas_lexer.mll | 5 +- hphp/hack/src/hhbc/hhas_parser.mly | 7 + hphp/hack/src/hhbc/hhbc_ast.ml | 1 + hphp/hack/src/hhbc/hhbc_hhas.ml | 5 + hphp/hack/test/semdiff/exns_05.semdiff.exp | 18 ++ hphp/hack/test/semdiff/exns_06.semdiff.exp | 257 +++++++++++++++++++++++++++++ 7 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 hphp/hack/test/semdiff/exns_05.semdiff.exp create mode 100644 hphp/hack/test/semdiff/exns_06.semdiff.exp diff --git a/hphp/hack/src/hhbc/Hhas_parser_actions.ml b/hphp/hack/src/hhbc/Hhas_parser_actions.ml index 131014d5542..fcd261dd20f 100644 --- a/hphp/hack/src/hhbc/Hhas_parser_actions.ml +++ b/hphp/hack/src/hhbc/Hhas_parser_actions.ml @@ -643,6 +643,7 @@ let barethisopofiarg arg = match arg with | IAId "Notice" -> Notice | IAId "NoNotice" -> NoNotice + | IAId "NeverNull" -> NeverNull | _ -> report_error "bad bare this op" diff --git a/hphp/hack/src/hhbc/hhas_lexer.mll b/hphp/hack/src/hhbc/hhas_lexer.mll index dfe0abee114..c35c48ef9d1 100644 --- a/hphp/hack/src/hhbc/hhas_lexer.mll +++ b/hphp/hack/src/hhbc/hhas_lexer.mll @@ -47,7 +47,8 @@ let white = [' ' '\t']+ let newline = '\r' | '\n' | "\r\n" let sillyend = ';' digit+ let inoutend = '$' ['0' - '9' ';']+ '$' "inout" -let id = '?'? (digit* ['a'-'z' 'A'-'Z' '_'] (['a'-'z' 'A'-'Z' '0'-'9' '_' '\\' '$' '#' '@' '\x7f'-'\xff' ] | "::")* inoutend? sillyend?) +let id = '?'? (digit* ['a'-'z' 'A'-'Z' '_'] + (['a'-'z' 'A'-'Z' '0'-'9' '_' '\\' '$' '#' '@' '\x7f'-'\xff' ] | "::")* inoutend? sillyend?) let vname = (['\x21'-'\xff'] # [';' ')' ','])* let escapequote = "\\\"" let comment = '#' [^ '\r' '\n']* newline @@ -56,6 +57,7 @@ let quote = '"' let nontriple = (nonquote | quote nonquote | quote quote nonquote)* quote? quote? let triplequoted = quote quote quote nontriple quote quote quote let doccomment = ".doc" white triplequoted ';' +let assertconstraint = id '<'? '=' id rule read = parse @@ -90,6 +92,7 @@ rule read = | ".static" {STATICDIRECTIVE} | ".require" {REQUIREDIRECTIVE} | ".srcloc" {SRCLOCDIRECTIVE} + | assertconstraint {ASSERTCONSTRAINT (Lexing.lexeme lexbuf)} | id {ID (Lexing.lexeme lexbuf)} | triplequoted as lxm {TRIPLEQUOTEDSTRING (String.sub lxm 3 (String.length lxm - 6))} | escapequote {read_php_escaped_string (Buffer.create 17) lexbuf} diff --git a/hphp/hack/src/hhbc/hhas_parser.mly b/hphp/hack/src/hhbc/hhas_parser.mly index 5de4cd4efe5..e860dde0906 100644 --- a/hphp/hack/src/hhbc/hhas_parser.mly +++ b/hphp/hack/src/hhbc/hhas_parser.mly @@ -21,6 +21,7 @@ open Hhas_parser_actions %token DOUBLE %token TRIPLEQUOTEDSTRING %token INCLUDESDIRECTIVE +%token ASSERTCONSTRAINT %token FUNCTIONDIRECTIVE MAINDIRECTIVE CLASSDIRECTIVE DECLVARSDIRECTIVE %token CONSTANTREFSDIRECTIVE FUNCTIONREFSDIRECTIVE CLASSREFSDIRECTIVE %token DATADECLDIRECTIVE NUMITERSDIRECTIVE NUMCLSREFSLOTSDIRECTIVE @@ -524,17 +525,23 @@ instruction: ; iarg: | ID {IAId $1} + | ASSERTCONSTRAINT {IAString $1} | vname {IAId $1} | INT {IAInt64 $1} | STRING {IAString $1} | DOUBLE {IADouble $1} | AT ID {IAArrayno $2} + | ID COLON INT PLUS INT {IAMemberkey ($1,IAArglist[IAInt64 $3; IAInt64 $5])} | ID COLON iarg {IAMemberkey ($1,$3)} | MINUS ID {match to_inf_nan $2 with | None -> report_error "bad negated pseudo-float" | Some s -> IADouble ("-" ^ s)} | LANGLE iarglist RANGLE {IAArglist $2} | LANGLE iterbreaklist RANGLE {IAArglist $2} + | ID LPAR iarglist RPAR + {let inner_string_list = List.map + (function | IAString s -> s | _ -> report_error "bad AssertRATL list") $3 in + IAString ($1 ^ "(" ^ String.concat "," inner_string_list ^ ")")} ; iarglist: | /* empty */ {[]} diff --git a/hphp/hack/src/hhbc/hhbc_ast.ml b/hphp/hack/src/hhbc/hhbc_ast.ml index 252d5f8784a..03eeeddfb17 100644 --- a/hphp/hack/src/hhbc/hhbc_ast.ml +++ b/hphp/hack/src/hhbc/hhbc_ast.ml @@ -507,6 +507,7 @@ type instruct_include_eval_define = type bare_this_op = | Notice | NoNotice + | NeverNull type class_kind = | KClass diff --git a/hphp/hack/src/hhbc/hhbc_hhas.ml b/hphp/hack/src/hhbc/hhbc_hhas.ml index 08380f9be5c..364def60c1c 100644 --- a/hphp/hack/src/hhbc/hhbc_hhas.ml +++ b/hphp/hack/src/hhbc/hhbc_hhas.ml @@ -546,6 +546,7 @@ let string_of_barethis_op i = match i with | Notice -> "Notice" | NoNotice -> "NoNotice" + | NeverNull -> "NeverNull" let string_of_op_silence op = match op with @@ -596,6 +597,10 @@ let string_of_misc instruction = | OODeclExists ck -> sep ["OODeclExists"; string_of_class_kind ck] | Silence (local, op) -> sep ["Silence"; string_of_local_id local; string_of_op_silence op] + | AssertRATL (local, s) -> + sep ["AssertRATL"; string_of_local_id local; s] + | AssertRATStk (n, s) -> + sep ["AssertRATStk"; string_of_int n; s] | _ -> failwith "instruct_misc Not Implemented" let iterator_instruction_name_prefix instruction = diff --git a/hphp/hack/test/semdiff/exns_05.semdiff.exp b/hphp/hack/test/semdiff/exns_05.semdiff.exp new file mode 100644 index 00000000000..63a04c8f0ae --- /dev/null +++ b/hphp/hack/test/semdiff/exns_05.semdiff.exp @@ -0,0 +1,18 @@ +Semdiff succeeded +comparing key lop +Semdiff succeeded +comparing key goo +Semdiff succeeded +comparing key blah +Semdiff succeeded +comparing key baz +Semdiff succeeded +comparing key bar +Semdiff succeeded +comparing key foo +Semdiff succeeded +Distance = 0 +Size = 397 +Similarity = 100.00 +Edits = + diff --git a/hphp/hack/test/semdiff/exns_06.semdiff.exp b/hphp/hack/test/semdiff/exns_06.semdiff.exp new file mode 100644 index 00000000000..2c3a7a69a25 --- /dev/null +++ b/hphp/hack/test/semdiff/exns_06.semdiff.exp @@ -0,0 +1,257 @@ +Semdiff succeeded +comparing key lop +Semdiff failed +pc=31;24, pc'=;8, i=FPushCtorD 1 "Exception" i'=} .catch { asn={}{} +Assumed= +[;0,;0-><{}{}>] +[;1,;1-><{}{}>] +[;2,;2-><{}{}>] +[;3,;3-><{}{}>] +[;4,;4-><{}{}>] +[;5,;5-><{}{}>] +[;6,;6-><{}{}>] +[;7,;7-><{}{}>] + +Todo=[31;21,;8->{}{}] +[31;21,;8->{}{}] +[31;21,;8->{}{}] +[31;21,;8->{}{}] +[31;21,;8->{}{}] + +comparing key goo +Semdiff failed +pc=14;37, pc'=;7, i=String "fh1\n" i'=} .catch { asn={}{} +Assumed= +[;0,;0-><{}{}>] +[;3,;1-><{}{}>] +[;4,;2-><{}{}>] +[;5,;3-><{}{}>] +[;6,;4-><{}{}>] +[;7,;5-><{}{}>] +[;8,;6-><{}{}>] + +Todo=[14;34,;7->{}{}] +[14;34,;7->{}{}] +[14;34,;7->{}{}] +[14;34,;7->{}{}] +[14;34,;7->{}{}] + +comparing key blah +Semdiff failed +pc=;48, pc'=;10, i=String "end outer loop\n" i'=} .catch { asn={}{} +Assumed= +[;0,;0-><{}{}>] +[;1,;1-><{}{}>] +[;2,;2-><{}{}>] +[;3,;3-><{}{}>] +[;4,;4-><{}{}>] +[;5,;5-><{}{}>] +[;6,;6-><{}{}>] +[;7,;7-><{}{}>] +[;8,;8-><{}{}>] +[;9,;9-><{}{}>] + +Todo=[;44,;10->{}{}] +[;44,;10->{}{}] +[;44,;10->{}{}] +[;44,;10->{}{}] +[;44,;10->{}{}] +[;44,;10->{}{}] +[;44,;10->{}{}] +[;44,;10->{}{}] + +comparing key baz +Semdiff failed +pc=31;24, pc'=;7, i=FPushCtorD 1 "Exception" i'=} .catch { asn={}{} +Assumed= +[;0,;0-><{}{}>] +[;2,;1-><{}{}>] +[;3,;2-><{}{}>] +[;4,;3-><{}{}>] +[;5,;4-><{}{}>] +[;6,;5-><{}{}>] +[;7,;6-><{}{}>] + +Todo=[31;21,;7->{}{}] +[31;21,;7->{}{}] +[31;21,;7->{}{}] +[31;21,;7->{}{}] +[31;21,;7->{}{}] + +comparing key bar +Semdiff failed +pc=13;32, pc'=;7, i=String "in finally\n" i'=} .catch { asn={}{} +Assumed= +[;0,;0-><{}{}>] +[;2,;1-><{}{}>] +[;3,;2-><{}{}>] +[;4,;3-><{}{}>] +[;5,;4-><{}{}>] +[;6,;5-><{}{}>] +[;7,;6-><{}{}>] + +Todo=[13;29,;7->{}{}] +[13;29,;7->{}{}] +[13;29,;7->{}{}] +[13;29,;7->{}{}] +[13;29,;7->{}{}] + +comparing key foo +Semdiff succeeded +Distance = 120 +Size = 397 +Similarity = 69.85 +Edits = + +for lop: +- .try_fault F1 { ++ .try { +- } ++ } .catch { +- FPushCtorD 1 "Exception" +- String "two" +- FPassCE 0 Cell +- FCall 1 +- PopR +- Throw +- } +- String "outer finally\n" +- Print +- PopC +- Null +- RetC +- F1: +- Unwind ++ } ++ } +- UnsetL _0 +- UnsetL _1 +for goo: +- .try_fault F2 { +- .try_fault F3 { +- } ++ } .catch { ++ .try_fault F2 { ++ .try { +- Jmp L0 ++ Jmp L3 +- } ++ L3: +- L0: ++ Dup +- String "fh2\n" ++ InstanceOfD "Exception" ++ JmpZ L2 ++ SetL $e ++ PopC ++ String "ch\n" +- Null ++ Jmp L0 +- RetC ++ L2: +- F3: ++ Throw +- UnsetL _1 ++ } +- UnsetL _2 ++ } +- String "fh1\n" ++ L0: ++ String "fh2\n" +- Unwind ++ Null ++ RetC +- UnsetL _1 +- UnsetL _2 +for blah: +- .try_fault F4 { ++ .try { +- } +- .try { +- String "end outer loop\n" +- Print +- PopC +- FPushCtorD 1 "Exception" +- String "two" +- FPassCE 0 Cell +- FCall 1 +- PopR +- Throw +- Jmp L0 +- Dup +- InstanceOfD "Exception" +- JmpZ L1 +- SetL $e +- PopC +- String "catch\n" +- Print +- PopC +- CGetL $e +- FPushObjMethodD 0 "getMessage" NullThrows +- FCall 0 +- UnboxR +- Print +- PopC +- Jmp L0 +- L1: +- Throw +- } +- L0: +- Null +- RetC +- F4: +- UnsetL _1 +- UnsetL _2 +- Jmp L2 +- Jmp L2 ++ Throw +- L2: ++ } +- Unwind +for baz: +- .try_fault F0 { ++ .try { +- .try_fault F1 { +- } ++ } .catch { ++ .try_fault F1 { ++ UnsetL _1 +- String "end" ++ } +- Print +- PopC +- Null +- RetC +- FPushCtorD 1 "Exception" +- String "two" +- FPassCE 0 Cell +- FCall 1 +- PopR +- Throw +- Unwind +- F0: +- UnsetL _0 +- UnsetL _1 +for bar: +- .try_fault F2 { +- } ++ } .catch { ++ .try_fault F1 { ++ UnsetL _1 ++ UnsetL _2 +- Jmp L0 ++ } +- } .catch { +- F2: ++ F1: +- UnsetL _1 ++ Dup +- UnsetL _2 ++ InstanceOfD "Exception" +- String "in finally\n" ++ JmpZ L2 ++ SetL $e ++ PopC ++ String "in catch\n" ++ L2: ++ Throw -- 2.11.4.GIT