2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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 #include "hphp/runtime/vm/hhbc-codec.h"
18 #include "hphp/runtime/vm/unit-emitter.h"
19 #include "hphp/runtime/vm/unit.h"
23 MemberKey
decode_member_key(PC
& pc
, Either
<const Unit
*, const UnitEmitter
*> u
) {
24 auto const mcode
= static_cast<MemberCode
>(decode_byte(pc
));
27 case MEC
: case MEL
: case MPC
: case MPL
:
28 return MemberKey
{mcode
, decode_iva(pc
)};
31 return MemberKey
{mcode
, decode_raw
<int64_t>(pc
)};
33 case MET
: case MPT
: case MQT
: {
34 auto const id
= decode_raw
<Id
>(pc
);
35 auto const str
= u
.match(
36 [id
](const Unit
* u
) { return u
->lookupLitstrId(id
); },
37 [id
](const UnitEmitter
* ue
) { return ue
->lookupLitstr(id
); }
39 return MemberKey
{mcode
, str
};
48 void encode_member_key(MemberKey mk
, UnitEmitter
& ue
) {
49 ue
.emitByte(mk
.mcode
);
52 case MEC
: case MEL
: case MPC
: case MPL
:
57 ue
.emitInt64(mk
.int64
);
60 case MET
: case MPT
: case MQT
:
61 ue
.emitInt32(ue
.mergeLitstr(mk
.litstr
));
70 ///////////////////////////////////////////////////////////////////////////////
72 void encodeLocalRange(UnitEmitter
& ue
, const LocalRange
& range
) {
73 ue
.emitIVA(range
.first
);
74 ue
.emitIVA(range
.count
);
77 LocalRange
decodeLocalRange(const unsigned char*& pc
) {
78 auto const first
= decode_iva(pc
);
79 auto const restCount
= decode_iva(pc
);
80 return LocalRange
{uint32_t(first
), uint32_t(restCount
)};
83 ///////////////////////////////////////////////////////////////////////////////
85 void encodeFCallArgsBase(UnitEmitter
& ue
, const FCallArgsBase
& fca
,
86 const uint8_t* byRefs
, bool hasAsyncEagerOffset
) {
87 auto constexpr kFirstNumArgsBit
= FCallArgsBase::kFirstNumArgsBit
;
88 bool smallNumArgs
= ((fca
.numArgs
+ 1) << kFirstNumArgsBit
) <= 0xff;
89 auto flags
= uint8_t{fca
.flags
};
90 assertx(!(flags
& ~FCallArgsBase::kInternalFlags
));
91 if (smallNumArgs
) flags
|= (fca
.numArgs
+ 1) << kFirstNumArgsBit
;
92 if (fca
.numRets
!= 1) flags
|= FCallArgsBase::HasInOut
;
93 if (byRefs
!= nullptr) flags
|= FCallArgsBase::EnforceReffiness
;
94 if (hasAsyncEagerOffset
) flags
|= FCallArgsBase::HasAsyncEagerOffset
;
97 if (!smallNumArgs
) ue
.emitIVA(fca
.numArgs
);
98 if (fca
.numRets
!= 1) ue
.emitIVA(fca
.numRets
);
100 if (byRefs
!= nullptr) {
101 auto const numBytes
= (fca
.numArgs
+ 7) / 8;
102 for (auto i
= 0; i
< numBytes
; ++i
) ue
.emitByte(byRefs
[i
]);
106 FCallArgs
decodeFCallArgs(PC
& pc
) {
107 auto const flags
= decode_byte(pc
);
108 auto const numArgs
= (flags
>> FCallArgs::kFirstNumArgsBit
)
109 ? (flags
>> FCallArgs::kFirstNumArgsBit
) - 1 : decode_iva(pc
);
110 auto const numRets
= (flags
& FCallArgs::HasInOut
) ? decode_iva(pc
) : 1;
111 auto const byRefs
= (flags
& FCallArgs::EnforceReffiness
) ? pc
: nullptr;
112 if (byRefs
!= nullptr) pc
+= (numArgs
+ 7) / 8;
113 auto const asyncEagerOffset
= (flags
& FCallArgs::HasAsyncEagerOffset
)
114 ? decode_ba(pc
) : kInvalidOffset
;
116 static_cast<FCallArgs::Flags
>(flags
& FCallArgs::kInternalFlags
),
117 numArgs
, numRets
, byRefs
, asyncEagerOffset
121 ///////////////////////////////////////////////////////////////////////////////