Remove positive is_typechecker guards
[hiphop-php.git] / hphp / hack / src / hhbc / emitter / emit_memoize_helpers.rs
blob6a8622e6cfef977635b3d5fe90eb0bf666595033
1 // Copyright (c) Facebook, Inc. and its affiliates.
2 //
3 // This source code is licensed under the MIT license found in the
4 // LICENSE file in the "hack" directory of this source tree.
6 use emit_fatal::raise_fatal_runtime;
7 use ffi::Str;
8 use hhas_param::HhasParam;
9 use hhbc_ast::{FcallArgs, FcallFlags};
10 use hhbc_id::function;
11 use instruction_sequence::{instr, InstrSeq, Result};
12 use label::Label;
13 use local::Local;
14 use oxidized::{aast::FunParam, ast::Expr, pos::Pos};
16 use ffi::Slice;
18 pub const MEMOIZE_SUFFIX: &str = "$memoize_impl";
20 pub fn get_memo_key_list<'arena>(
21     alloc: &'arena bumpalo::Bump,
22     local: local::Id,
23     index: usize,
24     name: impl AsRef<str>,
25 ) -> Vec<InstrSeq<'arena>> {
26     vec![
27         instr::getmemokeyl(alloc, Local::Named(Str::new_str(alloc, name.as_ref()))),
28         instr::setl(alloc, Local::Unnamed(local + index)),
29         instr::popc(alloc),
30     ]
33 pub fn param_code_sets<'arena>(
34     alloc: &'arena bumpalo::Bump,
35     params: &[(HhasParam<'arena>, Option<(Label, Expr)>)],
36     local: local::Id,
37 ) -> InstrSeq<'arena> {
38     InstrSeq::gather(
39         alloc,
40         params
41             .iter()
42             .enumerate()
43             .map(|(i, (param, _))| get_memo_key_list(alloc, local, i, &param.name.unsafe_as_str()))
44             .flatten()
45             .collect(),
46     )
49 pub fn param_code_gets<'arena>(
50     alloc: &'arena bumpalo::Bump,
51     params: &[(HhasParam<'arena>, Option<(Label, Expr)>)],
52 ) -> InstrSeq<'arena> {
53     InstrSeq::gather(
54         alloc,
55         params
56             .iter()
57             .map(|(param, _)| {
58                 instr::cgetl(
59                     alloc,
60                     Local::Named(Str::new_str(alloc, param.name.unsafe_as_str())),
61                 )
62             })
63             .collect(),
64     )
67 pub fn check_memoize_possible<Ex, En>(
68     pos: &Pos,
69     params: &[FunParam<Ex, En>],
70     is_method: bool,
71 ) -> Result<()> {
72     if !is_method && params.iter().any(|param| param.is_variadic) {
73         return Err(raise_fatal_runtime(
74             pos,
75             String::from("<<__Memoize>> cannot be used on functions with variable arguments"),
76         ));
77     }
78     Ok(())
81 pub fn get_implicit_context_memo_key<'arena>(
82     alloc: &'arena bumpalo::Bump,
83     local: local::Id,
84 ) -> InstrSeq<'arena> {
85     InstrSeq::gather(
86         alloc,
87         vec![
88             instr::nulluninit(alloc),
89             instr::nulluninit(alloc),
90             instr::fcallfuncd(
91                 alloc,
92                 FcallArgs::new(
93                     FcallFlags::default(),
94                     1,
95                     Slice::empty(),
96                     Slice::empty(),
97                     None,
98                     0,
99                     None,
100                 ),
101                 function::from_raw_string(
102                     alloc,
103                     "HH\\ImplicitContext\\_Private\\get_implicit_context_memo_key",
104                 ),
105             ),
106             instr::setl(alloc, Local::Unnamed(local)),
107             instr::popc(alloc),
108         ],
109     )