forked from facebook/hhvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfunc.h
More file actions
1525 lines (1287 loc) · 44 KB
/
Copy pathfunc.h
File metadata and controls
1525 lines (1287 loc) · 44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_VM_FUNC_H_
#define incl_HPHP_VM_FUNC_H_
#include "hphp/runtime/base/atomic-countable.h"
#include "hphp/runtime/base/attr.h"
#include "hphp/runtime/base/datatype.h"
#include "hphp/runtime/base/rds.h"
#include "hphp/runtime/base/tracing.h"
#include "hphp/runtime/base/type-string.h"
#include "hphp/runtime/base/typed-value.h"
#include "hphp/runtime/base/user-attributes.h"
#include "hphp/runtime/vm/indexed-string-map.h"
#include "hphp/runtime/vm/iter.h"
#include "hphp/runtime/vm/reified-generics-info.h"
#include "hphp/runtime/vm/rx.h"
#include "hphp/runtime/vm/type-constraint.h"
#include "hphp/runtime/vm/unit.h"
#include "hphp/util/fixed-vector.h"
#include "hphp/util/low-ptr.h"
#include <atomic>
#include <utility>
#include <vector>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
struct ActRec;
struct Class;
struct NamedEntity;
struct PreClass;
struct StringData;
struct StructuredLogEntry;
template <typename T> struct AtomicVector;
/*
* Signature for native functions called by the hhvm using the hhvm
* calling convention that provides raw access to the ActRec.
*/
using ArFunction = TypedValue* (*)(ActRec* ar);
/*
* Signature for native functions expecting the platform ABI calling
* convention. This must always be casted to a proper signature before
* calling, so make something up to prevent accidental mixing with other
* function pointer types.
*/
struct NativeArgs; // never defined
using NativeFunction = void(*)(NativeArgs*);
/*
* Vector of pairs (param index, offset of corresponding DV funclet).
*/
using DVFuncletsVec = std::vector<std::pair<int, Offset>>;
///////////////////////////////////////////////////////////////////////////////
// EH table.
/*
* Exception handler table entry.
*/
struct EHEnt {
Offset m_base;
Offset m_past;
int m_iterId;
int m_parentIndex;
Offset m_handler;
Offset m_end;
EHEnt()
: m_base()
, m_past()
, m_iterId()
, m_parentIndex()
, m_handler()
, m_end()
{}
template<class SerDe> void serde(SerDe& sd);
};
///////////////////////////////////////////////////////////////////////////////
/*
* Metadata about a PHP function or method.
*
* The Func class cannot be safely extended, because variable amounts of memory
* associated with the Func are allocated before and after the actual object.
*
* All Funcs are also followed by a variable number of function prologue
* pointers. Six are statically allocated as part of the Func object, but more
* may follow, depending on the value of getMaxNumPrologues().
*
* +--------------------------------+ Func* address
* | Func object |
* | |
* | prologues at end of Func |
* +--------------------------------+ Func* address
* | [additional prologues] |
* +--------------------------------+ high address
*
*/
struct Func final {
friend struct FuncEmitter;
/////////////////////////////////////////////////////////////////////////////
// Types.
/*
* Parameter default value info.
*/
struct ParamInfo {
enum class Flags {
InOut, // Is this an `inout' parameter?
Variadic, // Is this a `...' parameter?
NativeArg, // Does this use a NativeArg?
AsVariant, // Native function takes as const Variant&
AsTypedValue // Native function takes as TypedValue
};
ParamInfo();
bool hasDefaultValue() const;
bool hasScalarDefaultValue() const;
bool isInOut() const;
bool isVariadic() const;
bool isNativeArg() const;
bool isTakenAsVariant() const;
bool isTakenAsTypedValue() const;
void setFlag(Flags flag);
template<class SerDe> void serde(SerDe& sd);
// Typehint for builtins.
MaybeDataType builtinType{folly::none};
// Flags as defined by the Flags enum.
uint8_t flags{0};
// DV initializer funclet offset.
Offset funcletOff{kInvalidOffset};
// Set to Uninit if there is no DV, or if there's a nonscalar DV.
TypedValue defaultValue;
// Eval-able PHP code.
LowStringPtr phpCode{nullptr};
// User-annotated type.
LowStringPtr userType{nullptr};
// offset of dvi funclet from cti section base.
Offset ctiFunclet{kInvalidOffset};
TypeConstraint typeConstraint;
UserAttributeMap userAttributes;
};
/*
* Static variable info.
*/
struct SVInfo {
template<class SerDe> void serde(SerDe& sd) { sd(name); }
LowStringPtr name;
};
using ParamInfoVec = VMFixedVector<ParamInfo>;
using SVInfoVec = VMFixedVector<SVInfo>;
using EHEntVec = VMFixedVector<EHEnt>;
using UpperBoundVec = VMCompactVector<TypeConstraint>;
using ParamUBMap = vm_flat_map<uint32_t, UpperBoundVec>;
/////////////////////////////////////////////////////////////////////////////
// Creation and destruction.
Func(Unit& unit, const StringData* name, Attr attrs);
Func(Unit& unit, const StringData* name, Attr attrs,
const StringData *methCallerCls, const StringData *methCallerMeth);
~Func();
/*
* Allocate memory for a function, including the variable number of prologues
* that follow.
*/
static void* allocFuncMem(int numParams);
/*
* Destruct and free a Func*.
*/
static void destroy(Func* func);
/*
* Address of the end of the Func's variable-length memory allocation.
*/
const void* mallocEnd() const;
/*
* Duplicate this function.
*
* Funcs are cloned for a number of reasons---most notably, methods on
* Classes are cloned from the methods defined on their respective
* PreClasses.
*
* We also clone methods from traits when we transclude the trait in its user
* Classes in repo mode.
*/
Func* clone(Class* cls, const StringData* name = nullptr) const;
/*
* Reset this function's cls and attrs.
*
* Used to change the Class scope of a closure method.
*/
void rescope(Class* ctx);
/*
* Free up a PreFunc for re-use as a cloned Func.
*
* @requires: isPreFunc()
*/
void freeClone();
/*
* Verify that a Func's data is coherent.
*
* FIXME: Currently this method does almost nothing.
*/
bool validate() const;
/////////////////////////////////////////////////////////////////////////////
// FuncId manipulation.
/*
* Get this function's ID.
*
* We allocate a unique 32-bit ID to almost all Funcs. The Func* can be
* retrieved by using this ID as an index into a global vector. This lets
* the JIT store references to Funcs more compactly.
*
* Funcs which do not represent actual runtime functions (namely, Funcs on
* PreClasses) are not assigned an ID.
*/
FuncId getFuncId() const;
/*
* Reserve the next available FuncId for `this', and add `this' to the
* function table.
*/
void setNewFuncId();
/*
* The next available FuncId. For observation only; does not reserve.
*/
static FuncId nextFuncId();
/*
* Lookup a Func* by its ID.
*/
static const Func* fromFuncId(FuncId id);
/*
* Whether `id' actually keys a Func*.
*/
static bool isFuncIdValid(FuncId id);
/////////////////////////////////////////////////////////////////////////////
// Basic info. [const]
/*
* The Unit the function is defined in.
*/
Unit* unit() const;
/*
* The various Class contexts of a method.
*
* cls(): The Class context of the method. This is usually the Class
* which implements the method, but for closure methods (i.e.,
* the __invoke() method on a closure object), it is instead the
* Class that the Closure object is scoped to.
*
* preClass(): The PreClass of the method's cls(). For closures, this still
* corresponds to the Closure subclass, rather than to the
* scoped Class.
*
* When isFromTrait() is true, preClass() refers to different
* entities in repo vs. non-repo mode. In repo mode, traits are
* flattened ahead of time, and preClass() refers to the class
* which imported the trait. In non-repo mode, trait methods
* are cloned into trait users, but preClass() will still refer
* to the trait which defined the method.
*
* baseCls(): The first Class in the inheritance hierarchy which declares
* this method.
*
* implCls(): The Class which implements the method. Just like cls(), but
* ignores closure scope (so it returns baseCls() for closures).
*
* It is possible for cls() to be nullptr on a method---this occurs when a
* closure method is scoped to a null class context (e.g., if the closure is
* created in a non-method function scope). In this case, only the `cls' is
* changed; the `preClass' and `baseCls' will continue to refer to the
* PreClass and Class of the closure object.
*
* The converse also occurs---a function can have a `cls' (and `baseCls')
* without being a method. This happens when a pseudomain is included from a
* class context.
*
* Consequently, none of these methods should be used to test whether the
* function is a method; for that purpose, see isMethod().
*/
Class* cls() const;
PreClass* preClass() const;
bool hasBaseCls() const;
Class* baseCls() const;
Class* implCls() const;
/*
* The function's short name (e.g., foo).
*/
const StringData* name() const;
StrNR nameStr() const;
/*
* The function's fully class-qualified, name (e.g., C::foo).
*/
const StringData* fullName() const;
StrNR fullNameStr() const;
/*
* The function's named entity. Only valid for non-methods.
*
* @requires: shared()->m_preClass == nullptr
*/
NamedEntity* getNamedEntity();
const NamedEntity* getNamedEntity() const;
/**
* meth_caller
*/
const StringData* methCallerClsName() const;
const StringData* methCallerMethName() const;
/////////////////////////////////////////////////////////////////////////////
// File info. [const]
/*
* The filename where the function was originally defined.
*
* In repo mode, we flatten traits into the classes they're used in, so we
* need this to track the original file for backtraces and errors.
*/
const StringData* originalFilename() const;
/*
* The original filename if it is defined, the unit's filename otherwise.
*/
const StringData* filename() const;
/*
* Start and end line of the function.
*
* It'd be nice if these were called lineStart and lineEnd or something, but
* we're not allowed to have nice things.
*/
int line1() const;
int line2() const;
/*
* The system- or user-defined doc comment accompanying the function.
*/
const StringData* docComment() const;
/////////////////////////////////////////////////////////////////////////////
// Bytecode. [const]
/*
* Get the function's main entrypoint.
*/
PC getEntry() const;
/*
* Get the offsets of the start (base) and end (past) of the function's
* bytecode, relative to the start of the unit.
*/
Offset base() const;
Offset past() const;
/*
* Whether a given PC or Offset (from the beginning of the unit) is within
* the function's bytecode stream.
*/
bool contains(PC pc) const;
bool contains(Offset offset) const;
/*
* Return a vector of pairs of (param index, corresponding DV funclet
* offset).
*/
DVFuncletsVec getDVFunclets() const;
/*
* Is there a main or default value entrypoint at the given offset?
*/
bool isEntry(Offset offset) const;
bool isDVEntry(Offset offset) const;
/*
* Number of params required when entering at the given offset.
*
* Return -1 if an invalid offset is provided.
*/
int getEntryNumParams(Offset offset) const;
int getDVEntryNumParams(Offset offset) const;
/*
* Get the correct entrypoint (whether the main entry or a DV funclet) when
* `numArgsPassed' arguments are passed to the function.
*
* This is the DV funclet offset of the numArgsPassed-th parameter, or the
* next parameter that has a DV funclet.
*/
Offset getEntryForNumArgs(int numArgsPassed) const;
// CTI entry points
Offset ctiEntry() const;
void setCtiFunclet(int i, Offset);
void setCtiEntry(Offset entry, uint32_t size);
/////////////////////////////////////////////////////////////////////////////
// Return type. [const]
/*
* CPP builtin's return type. Returns folly::none if function is not a CPP
* builtin.
*
* There are a number of caveats regarding this value:
*
* - If the return type is folly::none, the return is a Variant.
*
* - If the return type is a string, array-like, object, ref, or resource
* type, null may also be returned.
*
* - Likewise, if the function is marked AttrParamCoerceModeNull, null
* might also be returned.
*
* - This list of caveats may be incorrect and/or incomplete.
*/
MaybeDataType hniReturnType() const;
/*
* Return type inferred by HHBBC's static analysis. TGen if no data is
* available.
*/
RepoAuthType repoReturnType() const;
/*
* For async functions, the statically inferred inner type of the returned
* WH based on HHBBC's analysis.
*/
RepoAuthType repoAwaitedReturnType() const;
/*
* For builtins, whether the return value is returned in registers (as
* opposed to indirect return, via tvBuiltinReturn).
*
* Not well-defined if this function is not a builtin.
*/
bool isReturnByValue() const;
/*
* The TypeConstraint of the return.
*/
const TypeConstraint& returnTypeConstraint() const;
/*
* The user-annotated Hack return type.
*/
const StringData* returnUserType() const;
bool hasReturnWithMultiUBs() const;
const UpperBoundVec& returnUBs() const;
/////////////////////////////////////////////////////////////////////////////
// Parameters. [const]
/*
* Const reference to the parameter info table.
*
* ParamInfo objects pulled from the table will also be const.
*/
const ParamInfoVec& params() const;
/*
* Number of parameters (including `...') accepted by the function.
*/
uint32_t numParams() const;
/*
* Number of parameters, not including `...', accepted by the function.
*/
uint32_t numNonVariadicParams() const;
/*
* Number of required parameters, i.e. all arguments starting from
* the returned position have default value.
*/
uint32_t numRequiredParams() const;
/*
* Whether the function is declared with a `...' parameter.
*/
bool hasVariadicCaptureParam() const;
/*
* Whether the arg-th parameter was declared inout.
*/
bool isInOut(int32_t arg) const;
/*
* Whether any of the parameters to this function are inout parameters.
*/
bool takesInOutParams() const;
/*
* Returns the number of inout parameters taken by func.
*/
uint32_t numInOutParams() const;
/*
* Returns the number of inout parameters for the given number of
* arguments.
*/
uint32_t numInOutParamsForArgs(int32_t numArgs) const;
bool hasParamsWithMultiUBs() const;
const ParamUBMap& paramUBs() const;
/////////////////////////////////////////////////////////////////////////////
// Locals, iterators, and stack. [const]
/*
* Number of locals, iterators, or named locals.
*/
int numLocals() const;
int numIterators() const;
Id numNamedLocals() const;
/*
* Find the integral ID assigned to a named local.
*/
Id lookupVarId(const StringData* name) const;
/*
* Find the name of the local with the given ID.
*/
const StringData* localVarName(Id id) const;
/*
* Array of named locals. Includes parameter names.
* May contain nullptrs for unammed locals that mixed in with named ones.
*
* Should not be indexed past numNamedLocals() - 1.
*/
LowStringPtr const* localNames() const;
/*
* Number of stack slots used by locals and iterator cells.
*/
int numSlotsInFrame() const;
/*
* Access to the maximum stack cells this function can use. This is
* used for stack overflow checks.
*
* The maximum cells for a function includes all its locals, all cells
* for its iterators, and all temporary eval stack slots. It does not
* include its own ActRec, because whoever called it must have(+) included
* the stack slot space reserved for this ActRec. The reason it must still
* count its parameter locals is that the caller may or may not pass any of
* the parameters, regardless of how many are declared.
*
* + Except in a re-entry situation. That must be handled
* specially in bytecode.cpp.
*/
int maxStackCells() const;
/*
* Checks if $this belong to a class that is not a subclass of cls().
*/
bool hasForeignThis() const;
void setHasForeignThis(bool);
/////////////////////////////////////////////////////////////////////////////
// Definition context. [const]
/*
* Is the function a pseudomain (i.e., the function implicitly defined by the
* text after <?hh in a file)?
*/
bool isPseudoMain() const;
/*
* Is this function a method defined on a class?
*
* Note that trait methods may not satisfy isMethod().
*/
bool isMethod() const;
/*
* Was this function imported from a trait?
*
* Note that this returns false for a trait method in the trait it was
* originally declared.
*/
bool isFromTrait() const;
/*
* Is this function declared with `public', `static', or `abstract'?
*/
bool isPublic() const;
bool isStatic() const;
bool isAbstract() const;
/*
* Whether a function is called non-statically. Generally this means
* isStatic(), but eg static closures are still called with a valid
* this pointer.
*/
bool isStaticInPrologue() const;
/*
* Whether a method is guaranteed to have a valid this in the body.
* A method which is !isStatic() || isClosureBody() is guaranteed to
* be called with a valid this, but closures swap out the closure
* object for the closure context in the prologue, so may not have
* a this in the body.
*/
bool hasThisInBody() const;
/*
* Does this function have the __NoContext attribute?
*/
bool hasNoContextAttr() const;
/*
* Is this Func owned by a PreClass?
*
* A PreFunc may be "adopted" by a Class when clone() is called, but only the
* owning PreClass is allowed to free it.
*/
bool isPreFunc() const;
/*
* Is this func a memoization wrapper?
*/
bool isMemoizeWrapper() const;
/*
* Is this func a memoization wrapper with LSB parameter set?
*/
bool isMemoizeWrapperLSB() const;
/*
* Is this string the name of a memoize implementation.
*/
static bool isMemoizeImplName(const StringData*);
/*
* Is this function a memoization implementation.
*/
bool isMemoizeImpl() const;
/*
* Assuming this func is a memoization wrapper, the name of the function it is
* wrapping.
*
* Pre: isMemoizeWrapper()
*/
const StringData* memoizeImplName() const;
/*
* Given the name of a memoization wrapper function, return the generated name
* of the function it wraps. This is static so it can be used in contexts
* where the actual Func* is not available.
*/
static const StringData* genMemoizeImplName(const StringData*);
/*
* Given a meth_caller, return the class name or method name
*/
static std::pair<const StringData*, const StringData*> getMethCallerNames(
const StringData* name);
/////////////////////////////////////////////////////////////////////////////
// Builtins. [const]
/*
* Is the function a builtin, whether PHP or C++?
*/
bool isBuiltin() const;
/*
* Is this function a C++ builtin (ie HNI function)?.
*
* @implies: isBuiltin()
*/
bool isCPPBuiltin() const;
/*
* The function returned by arFuncPtr() takes an ActRec*, unpacks it,
* and usually dispatches to a nativeFuncPtr() with a specific signature.
*
* All C++ builtins have an ArFunction, with no exceptions.
*
* Most HNI functions share a single ArFunction, which performs
* unpacking and dispatch. The exception is HNI functions declared
* with NeedsActRec, which do not have NativeFunctions, but have unique
* ArFunctions which do all their work.
*/
ArFunction arFuncPtr() const;
/*
* The nativeFuncPtr is a type-punned function pointer to the unerlying
* function which takes the actual argument types, and does the actual work.
*
* These are the functions with names prefixed by f_ or t_.
*
* All C++ builtins have NativeFunctions, with the ironic exception of HNI
* functions declared with NeedsActRec.
*/
NativeFunction nativeFuncPtr() const;
/////////////////////////////////////////////////////////////////////////////
// Closures. [const]
/*
* Is this function the body (i.e., __invoke() method) of a Closure object?
*
* (All PHP anonymous functions are Closure objects.)
*/
bool isClosureBody() const;
/////////////////////////////////////////////////////////////////////////////
// Resumables. [const]
/*
* Is this function asynchronous? (May also be a generator.)
*/
bool isAsync() const;
/*
* Is this function a generator? (May also be async.)
*/
bool isGenerator() const;
/*
* Is this function a generator which yields both key and value?
*
* @implies: isGenerator()
*/
bool isPairGenerator() const;
/*
* @returns: !isGenerator() && isAsync()
*/
bool isAsyncFunction() const;
/*
* @returns: isGenerator() && !isAsync()
*/
bool isNonAsyncGenerator() const;
/*
* @returns: isGenerator() && isAsync()
*/
bool isAsyncGenerator() const;
/*
* Is this a resumable function?
*
* @returns: isGenerator() || isAsync()
*/
bool isResumable() const;
/////////////////////////////////////////////////////////////////////////////
// Reactivity. [const]
/*
* What is the level of reactivity of this function?
*/
RxLevel rxLevel() const;
/*
* Is this the version of the function body with reactivity disabled via
* if (Rx\IS_ENABLED) ?
*/
bool isRxDisabled() const;
/*
* Is this function conditionally reactive?
*/
bool isRxConditional() const;
/////////////////////////////////////////////////////////////////////////////
// Methods. [const]
/*
* Index of this function in the method table of its Class.
*/
Slot methodSlot() const;
/*
* Whether this function has a private implementation on a parent class.
*/
bool hasPrivateAncestor() const;
/////////////////////////////////////////////////////////////////////////////
// Magic methods. [const]
/*
* Is this a compiler-generated function?
*
* This includes special methods like 86pinit and 86sinit as well
* as all closures.
*/
bool isGenerated() const;
/*
* Is `name' the name of a special initializer function?
*/
static bool isSpecial(const StringData* name);
/////////////////////////////////////////////////////////////////////////////
// Persistence. [const]
/*
* Whether this function is uniquely named across the codebase.
*
* It's legal in PHP to define multiple functions in different pseudomains
* with the same name, so long as both are not required in the same request.
*
* Note that if EvalJitEnableRenameFunction is set, no Func is unique.
*/
bool isUnique() const;
/*
* Whether we can load this function once and persist it across requests.
*
* Persistence is possible when a Func is defined in a pseudomain that has no
* side-effects (except other persistent definitions).
*
* @implies: isUnique()
*/
bool isPersistent() const;
bool isInterceptable() const;
/*
* Given that func would be called when func->name() is invoked on cls,
* determine if it would also be called when invoked on any descendant
* of cls.
*/
bool isImmutableFrom(const Class* cls) const;
/////////////////////////////////////////////////////////////////////////////
// Other attributes. [const]
/*
* Get the system attributes of the function.
*/
Attr attrs() const;
/*
* Get the user-declared attributes of the function.
*/
const UserAttributeMap& userAttributes() const;
/*
* Whether to ignore this function's frame in backtraces.
*/
bool isNoInjection() const;
/*
* Whether this function's frame should be skipped when searching for context
* (e.g., array_map evaluates its callback in the context of its caller).
*/
bool isSkipFrame() const;
/*
* Whether this function's frame should be skipped with searching for a
* context for array provenance
*/
bool isProvenanceSkipFrame() const;
/*
* Whether the function can be constant-folded at callsites where it is
* passed constant arguments.
*/
bool isFoldable() const;
/*
* Supports async eager return optimization?
*/
bool supportsAsyncEagerReturn() const;
/*
* Is this func allowed to be called dynamically?
*/
bool isDynamicallyCallable() const;
/*
* If this function is called dynamically should we raise sampled warnings?
*
* N.B. When errors are enabled for dynamic calls this overrides that behavior
* for functions which specify it.
*/
folly::Optional<int64_t> dynCallSampleRate() const;
/*
* Is this a meth_caller func?
*/
bool isMethCaller() const;
/*
* Indicates that a function does not make any explicit calls to other PHP
* functions. It may still call other user-level functions via re-entry
* (e.g., for autoload), and it may make calls to builtins using FCallBuiltin.
*/
bool isPhpLeafFn() const;
/*
* Does this function has reified generics?
*/
bool hasReifiedGenerics() const;
/*
* Returns a ReifiedGenericsInfo containing how many generics this func has,
* indices of its reified generics, and which ones are soft reified
*/
const ReifiedGenericsInfo& getReifiedGenericsInfo() const;
/////////////////////////////////////////////////////////////////////////////
// Unit table entries. [const]
const EHEntVec& ehtab() const;
/*
* Find the first EHEnt that covers a given offset, or return null.
*/
const EHEnt* findEH(Offset o) const;
/*
* Same as non-static findEH(), but takes as an operand any ehtab-like
* container.
*/
template<class Container>
static const typename Container::value_type*
findEH(const Container& ehtab, Offset o);
bool shouldSampleJit() const { return m_shouldSampleJit; }
/////////////////////////////////////////////////////////////////////////////
// JIT data.
/*
* Get the RDS handle for the function with this function's name.
*
* We can burn these into the TC even when functions are not persistent,
* since only a single name-to-function mapping will exist per request.
*/
rds::Handle funcHandle() const;
/*
* Get, set and reset the function body code pointer.
*/
unsigned char* getFuncBody() const;
void setFuncBody(unsigned char* fb);
void resetFuncBody();
/*
* Get and set the `index'-th function prologue.
*/
uint8_t* getPrologue(int index) const;
void setPrologue(int index, unsigned char* tca);
/*