Support generating ext_hhvm files with ARM ABI
ARM's convention for returning bigger-than-a-register types is different; there's a register reserved for the purpose of passing the return-value pointer. On x64, it just gets added as a hidden first parameter.
Esse commit está contido em:
@@ -2,8 +2,14 @@ set(files)
|
||||
set(CXX_SOURCES)
|
||||
set(C_SOURCES)
|
||||
set(CXX_HEADERS)
|
||||
set(EXT_HHVM_ARCH "x64")
|
||||
|
||||
macro(EXT_HHVM_FILE SOURCES HEADERS REL)
|
||||
exec_program("uname -m" OUTPUT_VARIABLE UNAME_M)
|
||||
if (UNAME_M STREQUAL "aarch64")
|
||||
set(EXT_HHVM_ARCH "arm")
|
||||
endif()
|
||||
|
||||
macro(EXT_HHVM_FILE SOURCES HEADERS REL EHHVM_ARCH)
|
||||
set(f_SRC "${HPHP_HOME}/hphp/${REL}")
|
||||
set(f_OBJ "${HPHP_HOME}/hphp/CMakeFiles/hphp_runtime_static.dir/${REL}.o")
|
||||
list(APPEND ${SOURCES} "${f_SRC}.ext_hhvm.cpp")
|
||||
@@ -11,7 +17,8 @@ macro(EXT_HHVM_FILE SOURCES HEADERS REL)
|
||||
add_custom_command(OUTPUT "${f_SRC}.ext_hhvm.cpp" "${f_SRC}.ext_hhvm.h"
|
||||
DEPENDS ${f_SRC} gen-ext-hhvm
|
||||
COMMAND "${HPHP_HOME}/hphp/tools/gen-ext-hhvm/gen-ext-hhvm.sh"
|
||||
ARGS ${f_OBJ} "${f_SRC}.ext_hhvm.cpp" "${f_SRC}.ext_hhvm.h"
|
||||
ARGS ${EHHVM_ARCH} ${f_OBJ}
|
||||
"${f_SRC}.ext_hhvm.cpp" "${f_SRC}.ext_hhvm.h"
|
||||
WORKING_DIRECTORY "${HPHP_HOME}/hphp/tools/gen-ext-hhvm"
|
||||
COMMENT "Generating ext_hhvm wrapper for ${REL}")
|
||||
endmacro()
|
||||
@@ -23,10 +30,10 @@ foreach (f ${files})
|
||||
string(LENGTH ${f} f_LEN)
|
||||
math(EXPR f_REL_LEN "${f_LEN} - ${HPHP_DIR_LEN}")
|
||||
string(SUBSTRING ${f} ${HPHP_DIR_LEN} ${f_REL_LEN} f_REL)
|
||||
EXT_HHVM_FILE(CXX_SOURCES CXX_HEADERS ${f_REL})
|
||||
EXT_HHVM_FILE(CXX_SOURCES CXX_HEADERS ${f_REL} ${EXT_HHVM_ARCH})
|
||||
endif()
|
||||
endforeach()
|
||||
EXT_HHVM_FILE(CXX_SOURCES CXX_HEADERS "runtime/base/builtin_functions.cpp")
|
||||
EXT_HHVM_FILE(CXX_SOURCES CXX_HEADERS "runtime/base/builtin_functions.cpp" ${EXT_HHVM_ARCH})
|
||||
|
||||
foreach (dir ${RECURSIVE_SOURCE_SUBDIRS})
|
||||
auto_sources(files "*.cpp" "RECURSE" "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
@@ -99,7 +99,7 @@ enterTCHelper:
|
||||
ret
|
||||
.cfi_endproc
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#elif defined(__AARCH64_EL__)
|
||||
#elif defined(__AARCH64EL__)
|
||||
.globl enterTCHelper
|
||||
enterTCHelper:
|
||||
brk 0
|
||||
|
||||
@@ -34,6 +34,12 @@ using folly::fbstring;
|
||||
std::unordered_map<fbstring, const PhpFunc*> g_mangleMap;
|
||||
std::unordered_map<fbstring, const PhpClass*> g_classMap;
|
||||
|
||||
// Functions with return types that don't fit in registers are handled
|
||||
// differently on ARM. Instead of using a pointer-to-return-value-space hidden
|
||||
// first parameter like on x64, the pointer is passed in a register reserved for
|
||||
// this purpose, not part of the normal argument sequence.
|
||||
bool g_armMode = false;
|
||||
|
||||
constexpr char* g_allIncludes = R"(
|
||||
#include "runtime/ext_hhvm/ext_hhvm.h"
|
||||
#include "runtime/base/builtin_functions.h"
|
||||
@@ -83,7 +89,7 @@ void emitRemappedFuncDecl(const PhpFunc& func,
|
||||
|
||||
bool isFirstParam = true;
|
||||
|
||||
if (isTypeCppIndirectPass(func.returnCppType)) {
|
||||
if (!g_armMode && isTypeCppIndirectPass(func.returnCppType)) {
|
||||
if (func.returnCppType == "HPHP::Variant") {
|
||||
out << "TypedValue* _rv";
|
||||
} else {
|
||||
@@ -266,7 +272,7 @@ void emitCallExpression(const PhpFunc& func, const fbstring& prefix,
|
||||
out << prefix << func.getUniqueName() << '(';
|
||||
|
||||
bool isFirstParam = true;
|
||||
if (isTypeCppIndirectPass(func.returnCppType)) {
|
||||
if (!g_armMode && isTypeCppIndirectPass(func.returnCppType)) {
|
||||
isFirstParam = false;
|
||||
if (func.returnCppType == "HPHP::Variant") {
|
||||
out << "rv";
|
||||
@@ -418,7 +424,7 @@ void emitExtCall(const PhpFunc& func, std::ostream& out, const char* ind) {
|
||||
}
|
||||
out << ind << type << " defVal" << k;
|
||||
if (type != "Variant" ||
|
||||
(param.defVal != "null" && param.defVal != "null_varant")) {
|
||||
(param.defVal != "null" && param.defVal != "null_variant")) {
|
||||
out << " = ";
|
||||
out << (param.defVal == "null" ? "uninit_null()" : param.defVal);
|
||||
}
|
||||
@@ -426,6 +432,17 @@ void emitExtCall(const PhpFunc& func, std::ostream& out, const char* ind) {
|
||||
}
|
||||
}
|
||||
|
||||
// Put the return-value-space pointer into x8
|
||||
if (g_armMode) {
|
||||
out << ind << "asm volatile (\"mov x8, %0\\n\" : : \"r\"(";
|
||||
if (func.returnCppType == "HPHP::Variant") {
|
||||
out << "rv";
|
||||
} else {
|
||||
out << "&(rv->m_data)";
|
||||
}
|
||||
out << ") : \"x8\");\n";
|
||||
}
|
||||
|
||||
out << ind << call_prefix;
|
||||
emitCallExpression(func, func.className.empty() ? "fh_" : "th_", out);
|
||||
out << call_suffix;
|
||||
@@ -667,17 +684,22 @@ void processSymbol(const fbstring& symbol, std::ostream& header,
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
if (argc < 4) {
|
||||
if (argc < 5) {
|
||||
std::cout << "Usage: " << argv[0]
|
||||
<< " <output .h file> <output .cpp file> <*.idl.json>...\n"
|
||||
<< " <x64|arm> <output .h> <output .cpp> <*.idl.json>...\n"
|
||||
<< "Pipe mangled C++ symbols to stdin.\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_armMode = (strcmp(argv[1], "arm") == 0);
|
||||
|
||||
std::ofstream header(argv[2]);
|
||||
std::ofstream cpp(argv[3]);
|
||||
|
||||
fbvector<PhpFunc> funcs;
|
||||
fbvector<PhpClass> classes;
|
||||
|
||||
for (auto i = 3; i < argc; ++i) {
|
||||
for (auto i = 4; i < argc; ++i) {
|
||||
try {
|
||||
parseIDL(argv[i], funcs, classes);
|
||||
} catch (const std::exception& exc) {
|
||||
@@ -696,9 +718,6 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream header(argv[1]);
|
||||
std::ofstream cpp(argv[2]);
|
||||
|
||||
header << "namespace HPHP {\n\n";
|
||||
cpp << g_allIncludes << "\n";
|
||||
cpp << "namespace HPHP {\n\n";
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
# $1 Object file to read symbols from
|
||||
# $2 ext_hhvm.cpp source to generate
|
||||
# $3 ext_hhvm.h header to generate
|
||||
readelf -s -W $1 | grep 'FUNC.*GLOBAL' | \
|
||||
# $1 Machine architecture (currently: "x64" or "arm")
|
||||
# $2 Object file to read symbols from
|
||||
# $3 ext_hhvm.cpp source to generate
|
||||
# $4 ext_hhvm.h header to generate
|
||||
readelf -s -W $2 | grep 'FUNC.*GLOBAL' | \
|
||||
sed -e 's/^.*DEFAULT[0-9 ]*//' | \
|
||||
$HPHP_HOME/hphp/tools/gen-ext-hhvm/gen-ext-hhvm \
|
||||
$3 $2 $HPHP_HOME/hphp/idl/*.idl.json
|
||||
$1 $4 $3 $HPHP_HOME/hphp/idl/*.idl.json
|
||||
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário