2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_COMPILER_EMITTER_H_
18 #define incl_HPHP_COMPILER_EMITTER_H_
20 #include "hphp/compiler/expression/expression.h"
21 #include "hphp/compiler/statement/statement.h"
22 #include "hphp/compiler/statement/use_trait_statement.h"
23 #include "hphp/compiler/statement/trait_prec_statement.h"
24 #include "hphp/compiler/statement/trait_alias_statement.h"
25 #include "hphp/compiler/statement/typedef_statement.h"
27 #include "hphp/runtime/vm/func.h"
28 #include "hphp/runtime/vm/unit.h"
29 #include "hphp/util/hash.h"
33 DECLARE_BOOST_TYPES(ClosureExpression
);
34 DECLARE_BOOST_TYPES(MethodStatement
);
35 DECLARE_BOOST_TYPES(InterfaceStatement
);
36 DECLARE_BOOST_TYPES(ListAssignment
);
37 DECLARE_BOOST_TYPES(FunctionScope
);
38 DECLARE_BOOST_TYPES(FileScope
);
39 DECLARE_BOOST_TYPES(FunctionCall
);
40 DECLARE_BOOST_TYPES(SimpleFunctionCall
);
41 DECLARE_BOOST_TYPES(SwitchStatement
);
42 DECLARE_BOOST_TYPES(ForEachStatement
);
43 class StaticClassName
;
44 class HhbcExtFuncInfo
;
45 class HhbcExtClassInfo
;
48 ///////////////////////////////////////////////////////////////////////////////
50 // Forward declarations.
54 // Helper for creating unit MetaInfo.
55 struct MetaInfoBuilder
{
56 void add(int pos
, Unit::MetaInfo::Kind kind
,
57 bool mVector
, int arg
, Id data
);
58 void addKnownDataType(DataType dt
,
63 void deleteInfo(Offset bcOffset
);
64 void setForUnit(UnitEmitter
&) const;
67 typedef std::vector
<Unit::MetaInfo
> Vec
;
68 typedef std::map
<Offset
,Vec
> Map
;
74 Emitter(ConstructPtr node
, UnitEmitter
& ue
, EmitterVisitor
& ev
)
75 : m_node(node
), m_ue(ue
), m_ev(ev
) {}
76 UnitEmitter
& getUnitEmitter() { return m_ue
; }
77 ConstructPtr
getNode() { return m_node
; }
78 EmitterVisitor
& getEmitterVisitor() { return m_ev
; }
79 void setTempLocation(LocationPtr loc
) { m_tempLoc
= loc
; }
80 LocationPtr
getTempLocation() { return m_tempLoc
; }
81 void incStat(int counter
, int value
) {
82 if (RuntimeOption::EnableEmitterStats
) {
83 IncStat(counter
, value
);
88 StrOff(Id s
, Label
* d
) : str(s
), dest(d
) {}
94 IterPair(IterKind k
, Id i
) : kind(k
), id(i
) {}
98 #define O(name, imm, pop, push, flags) \
103 #define TWO(typ1, typ2) \
105 #define THREE(typ1, typ2, typ3) \
106 typ1 a1, typ2 a2, typ3 a3
107 #define FOUR(typ1, typ2, typ3, typ4) \
108 typ1 a1, typ2 a2, typ3 a3, typ4 a4
109 #define MA std::vector<uchar>
110 #define BLA std::vector<Label*>&
111 #define SLA std::vector<StrOff>&
112 #define ILA std::vector<IterPair>&
118 #define SA const StringData*
119 #define AA ArrayData*
121 #define OA unsigned char
145 EmitterVisitor
& m_ev
;
146 LocationPtr m_tempLoc
;
149 struct SymbolicStack
{
153 CLS_UNNAMED_LOCAL
, // loc is an unnamed local
154 CLS_NAMED_LOCAL
, // loc is a normal program local
155 CLS_STRING_NAME
, // name is the string to use
168 * Symbolic stack (m_symStack)
170 * The symbolic stack is used to keep track of the flavor descriptors
171 * of values along with other contextual information. Each position in
172 * the symbolic stack can encode a "symbolic flavor" and a "marker".
173 * Most symbolic flavors correspond with flavor descriptors in the HHBC
174 * spec, but some symbolic flavors used in the symbolic stack (ex. "L")
175 * do not correspond with a flavor descriptor from the spec. Markers
176 * provide contextual information and are used by the emitter in various
177 * situations to determine the appropriate bytecode instruction to use.
179 * Note that not all positions on the symbolic stack correspond to a
180 * value on the actual evaluation stack as described in the HHBC spec.
183 explicit SymEntry(char s
= 0)
185 , metaType(META_NONE
)
191 , unnamedLocalStart(InvalidAbsoluteOffset
)
192 , clsBaseType(CLS_INVALID
)
200 const StringData
* name
; // META_LITSTR
201 DataType dt
; // META_DATA_TYPE
203 const StringData
* className
;
204 int64_t intval
; // used for L and I symbolic flavors
206 // If intval is an unnamed local temporary, this offset is the start
207 // of the region we are using it (which we will need to have a
208 // fault funclet for).
209 Offset unnamedLocalStart
;
211 // When class bases are emitted, we need to delay class lookup for
212 // evaluation order reasons, but may have to do some evaluation
213 // early. How this works depends on the type of class base---see
214 // emitResolveClsBase for details.
215 ClassBaseType clsBaseType
;
217 std::vector
<SymEntry
> m_symStack
;
220 * Actual stack (m_actualStack)
222 * The actual stack represents the evaluation stack as described in the
223 * HHBC spec. Each position in m_actualStack contains the index of the
224 * corresponding symbolic value in m_symStack.
226 std::vector
<int> m_actualStack
;
228 // The number of Func descriptors (in HHVM terms, ActRecs) currently on the
233 int* m_actualStackHighWaterPtr
;
234 int* m_fdescHighWaterPtr
;
236 SymbolicStack() : m_fdescCount(0) {}
238 std::string
pretty() const;
241 void setInt(int64_t v
);
242 void setString(const StringData
* s
);
243 void setKnownCls(const StringData
* s
, bool nonNull
);
245 bool getNotRef() const;
246 void setKnownType(DataType dt
, bool predicted
= false);
248 DataType
getKnownType(int index
= -1, bool noRef
= true) const;
249 void setClsBaseType(ClassBaseType
);
250 void setUnnamedLocal(int index
, int localId
, Offset startOffset
);
253 char get(int index
) const;
254 const StringData
* getName(int index
) const;
255 const StringData
* getClsName(int index
) const;
256 bool isCls(int index
) const;
257 bool isTypePredicted(int index
= -1 /* stack top */) const;
258 void set(int index
, char sym
);
259 unsigned size() const;
264 * Erase a stack element depth below the top. This is used for some
265 * instructions that pull elements out of the middle, and for our
266 * ClassBaseType virtual elements.
268 void consumeBelowTop(int depth
);
270 int getActualPos(int vpos
) const;
271 char getActual(int index
) const;
272 void setActual(int index
, char sym
);
273 void insertAt(int depth
, char sym
);
274 int sizeActual() const;
276 ClassBaseType
getClsBaseType(int index
) const;
277 int getLoc(int index
) const;
278 int64_t getInt(int index
) const;
279 Offset
getUnnamedLocStart(int index
) const;
287 Label() : m_off(InvalidAbsoluteOffset
) {}
288 explicit Label(Emitter
& e
) : m_off(InvalidAbsoluteOffset
) {
291 Offset
getAbsoluteOffset() const { return m_off
; }
292 // Sets the Label to the bytecode offset of given by e,
293 // fixes up any instructions that have already been
294 // emitted that reference this Label, and fixes up the
295 // EmitterVisitor's jump target info
296 void set(Emitter
& e
);
297 // If a Label is has not been set, it is the Emitter's
298 // resposibility to call bind on the Label each time it
299 // prepares to emit an instruction that uses the Label
300 void bind(EmitterVisitor
& ev
, Offset instrAddr
, Offset offAddr
);
301 bool isSet() { return m_off
!= InvalidAbsoluteOffset
; }
305 std::vector
<std::pair
<Offset
, Offset
> > m_emittedOffs
;
306 // m_evalStack is used to store the eval stack of the
307 // first forward jump we see that references this label
308 SymbolicStack m_evalStack
;
314 virtual void emit(Emitter
& e
) = 0;
319 Funclet(Thunklet
* body
, Label
* entry
) : m_body(body
), m_entry(entry
) {}
324 class EmitterVisitor
{
325 friend class UnsetUnnamedLocalThunklet
;
327 explicit EmitterVisitor(UnitEmitter
& ue
);
330 bool visit(ConstructPtr c
);
331 bool visitImpl(ConstructPtr c
);
332 void visitKids(ConstructPtr c
);
333 void visit(FileScopePtr file
);
334 void assignLocalVariableIds(FunctionScopePtr fs
);
335 void fixReturnType(Emitter
& e
, FunctionCallPtr fn
,
336 Func
* builtinFunc
= nullptr);
337 typedef std::vector
<int> IndexChain
;
338 void visitListAssignmentLHS(Emitter
& e
, ExpressionPtr exp
,
339 IndexChain
& indexChain
,
340 std::vector
<IndexChain
*>& chainList
);
341 void visitIfCondition(ExpressionPtr cond
, Emitter
& e
, Label
& tru
, Label
& fals
,
342 bool truFallthrough
);
343 const SymbolicStack
& getEvalStack() const { return m_evalStack
; }
344 SymbolicStack
& getEvalStack() { return m_evalStack
; }
345 void setEvalStack(const SymbolicStack
& es
) {
347 m_evalStackIsUnknown
= false;
349 bool evalStackIsUnknown() { return m_evalStackIsUnknown
; }
350 void popEvalStack(char symFlavor
, int arg
= -1, int pos
= -1);
351 void popSymbolicLocal(Op opcode
, int arg
= -1, int pos
= -1);
352 void popEvalStackLMany();
353 void popEvalStackMany(int len
, char symFlavor
);
354 void popEvalStackCVMany(int len
);
355 void pushEvalStack(char symFlavor
);
356 void peekEvalStack(char symFlavor
, int depthActual
);
357 void pokeEvalStack(char symFlavor
, int depthActual
);
358 void prepareEvalStack();
359 void recordJumpTarget(Offset target
, const SymbolicStack
& evalStack
);
360 void recordJumpTarget(Offset target
) {
361 recordJumpTarget(target
, m_evalStack
);
363 void restoreJumpTargetEvalStack();
365 bool isJumpTarget(Offset target
);
366 void setPrevOpcode(Op op
) { m_prevOpcode
= op
; }
367 Op
getPrevOpcode() const { return m_prevOpcode
; }
368 bool currentPositionIsReachable() {
369 return (m_ue
.bcPos() == m_curFunc
->base()
370 || isJumpTarget(m_ue
.bcPos())
371 || (instrFlags(getPrevOpcode()) & TF
) == 0);
374 class IncludeTimeFatalException
: public Exception
{
377 IncludeTimeFatalException(ConstructPtr node
, const char* fmt
, ...)
378 : Exception(), m_node(node
) {
379 va_list ap
; va_start(ap
, fmt
); format(fmt
, ap
); va_end(ap
);
381 virtual ~IncludeTimeFatalException() throw() {}
382 EXCEPTION_COMMON_IMPL(IncludeTimeFatalException
);
385 void pushIterScope(Id id
, IterKind kind
) {
386 m_pendingIters
.emplace_back(id
, kind
);
388 void popIterScope() { m_pendingIters
.pop_back(); }
391 typedef std::pair
<StringData
*, bool> ClosureUseVar
; // (name, byRef)
392 typedef std::vector
<ClosureUseVar
> ClosureUseVarVec
;
393 typedef std::vector
<std::pair
<Id
,IterKind
> > PendingIterVec
;
394 typedef std::pair
<StringData
*, ExpressionPtr
> NonScalarPair
;
395 typedef std::vector
<NonScalarPair
> NonScalarVec
;
396 typedef std::pair
<Id
, int> StrCase
;
398 class PostponedMeth
{
400 PostponedMeth(MethodStatementPtr m
, FuncEmitter
* fe
, bool top
,
401 ClosureUseVarVec
* useVars
)
402 : m_meth(m
), m_fe(fe
), m_top(top
), m_closureUseVars(useVars
) {}
403 MethodStatementPtr m_meth
;
406 ClosureUseVarVec
* m_closureUseVars
;
409 class PostponedCtor
{
411 PostponedCtor(InterfaceStatementPtr is
, FuncEmitter
* fe
)
412 : m_is(is
), m_fe(fe
) {}
413 InterfaceStatementPtr m_is
;
417 class PostponedNonScalars
{
419 PostponedNonScalars(InterfaceStatementPtr is
, FuncEmitter
* fe
,
421 : m_is(is
), m_fe(fe
), m_vec(v
) {}
425 InterfaceStatementPtr m_is
;
430 class PostponedClosureCtor
{
432 PostponedClosureCtor(ClosureUseVarVec
& v
, ClosureExpressionPtr e
,
434 : m_useVars(v
), m_expr(e
), m_fe(fe
) {}
435 ClosureUseVarVec m_useVars
;
436 ClosureExpressionPtr m_expr
;
440 class ControlTargets
{
442 ControlTargets(Id itId
, bool itRef
, Label
& brkTarg
, Label
& cntTarg
)
443 : m_itId(itId
), m_itRef(itRef
), m_brkTarg(brkTarg
), m_cntTarg(cntTarg
)
447 Label
& m_brkTarg
; // Jump here for "break;" (after doing IterFree)
448 Label
& m_cntTarg
; // Jump here for "continue;"
451 class ControlTargetPusher
{
453 ControlTargetPusher(EmitterVisitor
* e
, Id itId
, bool itRef
, Label
& brkTarg
,
454 Label
& cntTarg
) : m_e(e
) {
455 e
->m_controlTargets
.push_front(ControlTargets(itId
, itRef
, brkTarg
,
458 ~ControlTargetPusher() {
459 m_e
->m_controlTargets
.pop_front();
465 class ExnHandlerRegion
{
467 ExnHandlerRegion(Offset start
, Offset end
) : m_start(start
),
469 ~ExnHandlerRegion() {
470 for (std::vector
<std::pair
<StringData
*, Label
*> >::const_iterator it
=
471 m_catchLabels
.begin(); it
!= m_catchLabels
.end(); it
++) {
477 std::set
<StringData
*, string_data_lt
> m_names
;
478 std::vector
<std::pair
<StringData
*, Label
*> > m_catchLabels
;
483 FaultRegion(Offset start
, Offset end
, Id iterId
, IterKind kind
)
494 Label m_func
; // note: a pointer to this is handed out to the Funclet
499 FPIRegion(Offset start
, Offset end
, Offset fpOff
)
500 : m_start(start
), m_end(end
), m_fpOff(fpOff
) {}
506 struct SwitchState
: private boost::noncopyable
{
507 SwitchState() : nonZeroI(-1), defI(-1) {}
508 std::map
<int64_t, int> cases
; // a map from int (or litstr id) to case index
509 std::vector
<StrCase
> caseOrder
; // for string switches, a list of the
510 // <litstr id, case index> in the order
511 // they appear in the source
517 void emitFatal(Emitter
& e
, const char* message
);
520 static const size_t kMinStringSwitchCases
= 8;
522 FuncEmitter
* m_curFunc
;
527 std::deque
<PostponedMeth
> m_postponedMeths
;
528 std::deque
<PostponedCtor
> m_postponedCtors
;
529 std::deque
<PostponedNonScalars
> m_postponedPinits
;
530 std::deque
<PostponedNonScalars
> m_postponedSinits
;
531 std::deque
<PostponedNonScalars
> m_postponedCinits
;
532 std::deque
<PostponedClosureCtor
> m_postponedClosureCtors
;
533 PendingIterVec m_pendingIters
;
534 hphp_hash_set
<std::string
> m_generatorEmitted
;
535 hphp_hash_set
<std::string
> m_topMethodEmitted
;
536 SymbolicStack m_evalStack
;
537 bool m_evalStackIsUnknown
;
538 hphp_hash_map
<Offset
, SymbolicStack
> m_jumpTargetEvalStacks
;
539 int m_actualStackHighWater
;
540 int m_fdescHighWater
;
541 typedef tbb::concurrent_hash_map
<const StringData
*, int,
542 StringDataHashCompare
> EmittedClosures
;
543 static EmittedClosures s_emittedClosures
;
544 std::deque
<ControlTargets
> m_controlTargets
;
545 std::deque
<Funclet
> m_funclets
;
546 std::deque
<ExnHandlerRegion
*> m_exnHandlers
;
547 std::deque
<FaultRegion
*> m_faultRegions
;
548 std::deque
<FPIRegion
*> m_fpiRegions
;
549 std::vector
<HphpArray
*> m_staticArrays
;
550 std::set
<std::string
,stdltistr
> m_hoistables
;
551 LocationPtr m_tempLoc
;
552 std::map
<StringData
*, Label
, string_data_lt
> m_gotoLabels
;
553 std::vector
<Label
> m_yieldLabels
;
554 MetaInfoBuilder m_metaInfo
;
556 bool checkIfStackEmpty(const char* forInstruction
) const;
557 void unexpectedStackSym(char sym
, const char* where
) const;
559 int scanStackForLocation(int iLast
);
560 void buildVectorImm(std::vector
<uchar
>& vectorImm
,
561 int iFirst
, int iLast
, bool allowW
,
563 enum class PassByRefKind
{
568 PassByRefKind
getPassByRefKind(ExpressionPtr exp
);
569 void emitAGet(Emitter
& e
);
570 void emitCGetL2(Emitter
& e
);
571 void emitCGetL3(Emitter
& e
);
572 void emitCGet(Emitter
& e
);
573 void emitVGet(Emitter
& e
);
574 void emitIsset(Emitter
& e
);
575 void emitIsNull(Emitter
& e
);
576 void emitIsArray(Emitter
& e
);
577 void emitIsObject(Emitter
& e
);
578 void emitIsString(Emitter
& e
);
579 void emitIsInt(Emitter
& e
);
580 void emitIsDouble(Emitter
& e
);
581 void emitIsBool(Emitter
& e
);
582 void emitEmpty(Emitter
& e
);
583 void emitUnset(Emitter
& e
, ExpressionPtr exp
= ExpressionPtr());
584 void emitVisitAndUnset(Emitter
& e
, ExpressionPtr exp
);
585 void emitSet(Emitter
& e
);
586 void emitSetOp(Emitter
& e
, int op
);
587 void emitBind(Emitter
& e
);
588 void emitIncDec(Emitter
& e
, unsigned char cop
);
589 void emitPop(Emitter
& e
);
590 void emitConvertToCell(Emitter
& e
);
591 void emitFreePendingIters(Emitter
& e
);
592 void emitConvertToCellIfVar(Emitter
& e
);
593 void emitConvertToCellOrLoc(Emitter
& e
);
594 void emitConvertSecondToCell(Emitter
& e
);
595 void emitConvertToVar(Emitter
& e
);
596 void emitFPass(Emitter
& e
, int paramID
, PassByRefKind passByRefKind
);
597 void emitVirtualLocal(int localId
, DataType dt
= KindOfUnknown
);
598 template<class Expr
> void emitVirtualClassBase(Emitter
&, Expr
* node
);
599 void emitResolveClsBase(Emitter
& e
, int pos
);
600 void emitClsIfSPropBase(Emitter
& e
);
601 Id
emitVisitAndSetUnnamedL(Emitter
& e
, ExpressionPtr exp
);
602 void emitPushAndFreeUnnamedL(Emitter
& e
, Id tempLocal
, Offset start
);
603 void emitContinuationSwitch(Emitter
& e
, int ncase
);
604 DataType
analyzeSwitch(SwitchStatementPtr s
, SwitchState
& state
);
605 void emitIntegerSwitch(Emitter
& e
, SwitchStatementPtr s
,
606 std::vector
<Label
>& caseLabels
, Label
& done
,
607 const SwitchState
& state
);
608 void emitStringSwitch(Emitter
& e
, SwitchStatementPtr s
,
609 std::vector
<Label
>& caseLabels
, Label
& done
,
610 const SwitchState
& state
);
611 void emitIterBreak(Emitter
& e
, uint64_t n
, Label
& targ
);
613 void markElem(Emitter
& e
);
614 void markNewElem(Emitter
& e
);
615 void markProp(Emitter
& e
);
616 void markSProp(Emitter
& e
);
617 void markName(Emitter
& e
);
618 void markNameSecond(Emitter
& e
);
619 void markGlobalName(Emitter
& e
);
621 void emitNameString(Emitter
& e
, ExpressionPtr n
, bool allowLiteral
= false);
622 void emitAssignment(Emitter
& e
, ExpressionPtr c
, int op
, bool bind
);
623 void emitListAssignment(Emitter
& e
, ListAssignmentPtr lst
);
624 void postponeMeth(MethodStatementPtr m
, FuncEmitter
* fe
, bool top
,
625 ClosureUseVarVec
* useVars
= nullptr);
626 void postponeCtor(InterfaceStatementPtr m
, FuncEmitter
* fe
);
627 void postponePinit(InterfaceStatementPtr m
, FuncEmitter
* fe
, NonScalarVec
* v
);
628 void postponeSinit(InterfaceStatementPtr m
, FuncEmitter
* fe
, NonScalarVec
* v
);
629 void postponeCinit(InterfaceStatementPtr m
, FuncEmitter
* fe
, NonScalarVec
* v
);
630 void emitPostponedMeths();
631 void emitPostponedCtors();
632 void emitPostponedPSinit(PostponedNonScalars
& p
, bool pinit
);
633 void emitPostponedPinits();
634 void emitPostponedSinits();
635 void emitPostponedCinits();
636 void emitPostponedClosureCtors();
637 enum CallUserFuncFlags
{
638 CallUserFuncNone
= -1,
639 CallUserFuncPlain
= 0,
640 CallUserFuncArray
= 1,
641 CallUserFuncSafe
= 2,
642 CallUserFuncReturn
= 4,
643 CallUserFuncForward
= 8,
644 CallUserFuncSafeArray
= CallUserFuncSafe
| CallUserFuncArray
,
645 CallUserFuncSafeReturn
= CallUserFuncSafe
| CallUserFuncReturn
,
646 CallUserFuncForwardArray
= CallUserFuncForward
| CallUserFuncArray
649 bool emitCallUserFunc(Emitter
& e
, SimpleFunctionCallPtr node
);
650 Func
* canEmitBuiltinCall(const std::string
& name
, int numParams
);
651 void emitFuncCall(Emitter
& e
, FunctionCallPtr node
);
652 void emitFuncCallArg(Emitter
& e
, ExpressionPtr exp
, int paramId
);
653 void emitBuiltinCallArg(Emitter
& e
, ExpressionPtr exp
, int paramId
,
655 void emitBuiltinDefaultArg(Emitter
& e
, Variant
& v
, DataType t
, int paramId
);
656 PreClass::Hoistable
emitClass(Emitter
& e
, ClassScopePtr cNode
,
658 void emitTypedef(Emitter
& e
, TypedefStatementPtr
);
659 void emitForeach(Emitter
& e
, ForEachStatementPtr fe
);
660 void emitRestoreErrorReporting(Emitter
& e
, Id oldLevelLoc
);
661 void emitMakeUnitFatal(Emitter
& e
, const std::string
& message
);
663 void addFunclet(Thunklet
* body
, Label
* entry
);
664 void emitFunclets(Emitter
& e
);
666 struct FaultIterInfo
{
670 void newFaultRegion(Offset start
, Offset end
, Thunklet
* t
,
671 FaultIterInfo
= FaultIterInfo
{ -1, KindOfIter
});
673 void newFPIRegion(Offset start
, Offset end
, Offset fpOff
);
674 void copyOverExnHandlers(FuncEmitter
* fe
);
675 void copyOverFPIRegions(FuncEmitter
* fe
);
676 void saveMaxStackCells(FuncEmitter
* fe
);
677 void finishFunc(Emitter
& e
, FuncEmitter
* fe
);
679 void initScalar(TypedValue
& tvVal
, ExpressionPtr val
);
680 bool requiresDeepInit(ExpressionPtr initExpr
) const;
682 void emitClassTraitPrecRule(PreClassEmitter
* pce
, TraitPrecStatementPtr rule
);
683 void emitClassTraitAliasRule(PreClassEmitter
* pce
,
684 TraitAliasStatementPtr rule
);
685 void emitClassUseTrait(PreClassEmitter
* pce
, UseTraitStatementPtr useStmt
);
688 void emitAllHHBC(AnalysisResultPtr ar
);
691 Unit
* hphp_compiler_parse(const char* code
, int codeLen
, const MD5
& md5
,
692 const char* filename
);
693 Unit
* hphp_build_native_func_unit(const HhbcExtFuncInfo
* builtinFuncs
,
694 ssize_t numBuiltinFuncs
);
695 Unit
* hphp_build_native_class_unit(const HhbcExtClassInfo
* builtinClasses
,
696 ssize_t numBuiltinClasses
);
699 ///////////////////////////////////////////////////////////////////////////////
703 #endif // incl_HPHP_COMPILER_EMITTER_H_