Hermes: Is it possible to easily add a custom native function?

Created on 14 May 2020  Â·  7Comments  Â·  Source: facebook/hermes

Does hermes support the adding of a native function like lua does? I know geko has JS_FN_HELP and javascript core has jsc::addFunction.

question

Most helpful comment

I believe the issue is you're not building your file hermes/tools/fuzzer/fuzzer.cpp
with RTTI on.

Using std::function::target requires having RTTI on, as shown by this comment in decorator.h:

HostFunctionType& getHostFunction(const jsi::Function& f) override {
  HostFunctionType& dhf = plain_.getHostFunction(f);
  // This will fail if a cpp file including this header is not compiled
  // with RTTI.
  return dhf.target<DecoratedHostFunction>()->plainHF_;
};

It's easy to fix, in your CMake file add this line:

set(HERMES_ENABLE_RTTI ON)

Right next to the line for enabling exception handling.

All 7 comments

Yes, it is supported. The JSI API exposes the concept of a "host function" - a function written in native code. There are some examples in the test suite here.

Ok tried to use that but now im getting this error

FAILED: tools/fuzzer/CMakeFiles/hermes-fuzz.dir/fuzzer.cpp.o
/usr/bin/c++  -DHERMESVM_ALLOW_COMPRESSED_POINTERS -DHERMESVM_GC_NONCONTIG_GENERATIONAL -DHERMES_ENABLE_DEBUGGER -DHERMES_RELEASE_VERSION=\"0.5.0\" -DHERMES_SLOW_DEBUG -I/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/external
-I/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/external/flowparser/include -I/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/public -I/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/include -Iinclude -I/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/external/llvh/include -I/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/external/llvh/gen/include -Iexternal/llvh/include -I/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/API -I/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/API/jsi -I/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/API/jsi/jsi -I/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/API/jsi/jsi/.. -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wno-init-list-lifetime -fvisibility=hidden -g    -fexceptions -fno-rtti -Wno-non-virtual-dtor -std=c++11 -MD -MT tools/fuzzer/CMakeFiles/hermes-fuzz.dir/fuzzer.cpp.o -MF tools/fuzzer/CMakeFiles/hermes-fuzz.dir/fuzzer.cpp.o.d -o tools/fuzzer/CMakeFiles/hermes-fuzz.dir/fuzzer.cpp.o
-c /mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/tools/fuzzer/fuzzer.cpp
In file included from /mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/tools/fuzzer/fuzzer.cpp:18:
/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/API/jsi/jsi/decorator.h: In member function ‘facebook::jsi::HostFunctionType& facebook::jsi::RuntimeDecorator<Plain, Base>::getHostFunction(const facebook::jsi::Function&)’:
/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/API/jsi/jsi/decorator.h:213:16: error: ‘using HostFunctionType = class std::function<facebook::jsi::Value(facebook::jsi::Runtime&, const facebook::jsi::Value&, const facebook::jsi::Value*, long unsigned int)>’ {aka ‘class std::function<facebook::jsi::Value(facebook::jsi::Runtime&, const facebook::jsi::Value&, const facebook::jsi::Value*, long unsigned int)>’} has no member named ‘target’
  213 |     return dhf.target<DecoratedHostFunction>()->plainHF_;
      |                ^~~~~~
/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/API/jsi/jsi/decorator.h:213:44: error: expected primary-expression before ‘>’ token
  213 |     return dhf.target<DecoratedHostFunction>()->plainHF_;
      |                                            ^
/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/API/jsi/jsi/decorator.h:213:46: error: expected primary-exp
ression before ‘)’ token
  213 |     return dhf.target<DecoratedHostFunction>()->plainHF_;
      |                                              ^
[8/359] Building CXX object lib/VM/CMakeFiles/hermesVMRuntime.dir/JSObject.cpp.o
/mnt/d/exp/reaserch/facebook/hermes-work/fuzzingBuild/hermes/lib/VM/JSObject.cpp:741:18: warning: always_inline function
 might not be inlinable [-Wattributes]
  741 | CallResult<bool> getOwnComputedPrimitiveDescriptorImpl(
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ninja: build stopped: subcommand failed.

here is my cmake file

include_directories(${HERMES_SOURCE_DIR}/API)
include_directories(${HERMES_SOURCE_DIR}/API/jsi)
include_directories(${HERMES_SOURCE_DIR}/API/jsi/jsi)
include_directories(${HERMES_JSI_DIR})


set(HERMES_ENABLE_EH ON)
set(CXX_STANDARD 14)
set(jsi_compile_flags "")
set(CXX_STANDARD_REQUIRED ON)
list(APPEND jsi_compile_flags "-Wno-non-virtual-dtor")
add_hermes_tool(hermes-fuzz
  fuzzer.cpp
  ${ALL_HEADER_FILES}
  LINK_LIBS hermesapi
  )

I believe the issue is you're not building your file hermes/tools/fuzzer/fuzzer.cpp
with RTTI on.

Using std::function::target requires having RTTI on, as shown by this comment in decorator.h:

HostFunctionType& getHostFunction(const jsi::Function& f) override {
  HostFunctionType& dhf = plain_.getHostFunction(f);
  // This will fail if a cpp file including this header is not compiled
  // with RTTI.
  return dhf.target<DecoratedHostFunction>()->plainHF_;
};

It's easy to fix, in your CMake file add this line:

set(HERMES_ENABLE_RTTI ON)

Right next to the line for enabling exception handling.

For the last 2 days i have had this bug

[505/506] Linking CXX executable bin/hermes-fuzz
FAILED: bin/hermes-fuzz
: && /usr/bin/clang++  -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -fvisibility=hidden -g  -fsanitize-coverage=trace-pc-guard tools/fuzzer/CMakeFiles/hermes-fuzz.dir/fuzzer.cpp.o  -o bin/hermes-fuzz  API/hermes/libhermesapi.a  external/llvh/lib/Support/libLLVHSupport.a  API/hermes/libhermesapi.a  jsi/libjsi.a  lib/VM/libhermesVMRuntime.a  lib/ADT/libhermesADT.a  lib/Platform/libhermesPlatform.a  lib/BCGen/HBC/libhermesHBCBackend.a  lib/Inst/libhermesInst.a  lib/BCGen/libhermesBackend.a  lib/libhermesFrontend.a  lib/FrontEndDefs/libhermesFrontEndDefs.a  lib/libhermesOptimizer.a  lib/SourceMap/libhermesSourceMap.a  lib/Parser/libhermesParser.a  lib/AST/libhermesAST.a  lib/Support/libhermesSupport.a  lib/Regex/libhermesRegex.a  lib/Platform/Unicode/libhermesPlatformUnicode.a  external/llvh/lib/Support/libLLVHSupport.a  external/llvh/lib/Demangle/libLLVHDemangle.a  -lpthread  external/dtoa/libdtoa.a  /usr/lib/x86_64-linux-gnu/libicuuc.so  /usr/lib/x86_64-linux-gnu/libicui18n.so  /usr/lib/x86_64-linux-gnu/libicudata.so  /usr/lib/x86_64-linux-gnu/libicuuc.so  /usr/lib/x86_64-linux-gnu/libicui18n.so  /usr/lib/x86_64-linux-gnu/libicudata.so && :
/usr/bin/ld: tools/fuzzer/CMakeFiles/hermes-fuzz.dir/fuzzer.cpp.o:(.rodata._ZTIN4llvm2cl15OptionValueCopyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE[_ZTIN4llvm2cl15OptionValueCopyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/usr/bin/ld: tools/fuzzer/CMakeFiles/hermes-fuzz.dir/fuzzer.cpp.o:(.rodata._ZTIN4llvm2cl15OptionValueCopyIbEE[_ZTIN4llvm2cl15OptionValueCopyIbEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

cmake:

include_directories(${HERMES_SOURCE_DIR}/API)
include_directories(${HERMES_JSI_DIR})
set(HERMES_ENABLE_EH ON)
set(HERMES_ENABLE_RTTI ON)
set(LLVM_ENABLE_RTTI ON)


set(HERMES_LINK_COMPONENTS LLVHSupport)

add_hermes_tool(hermes-fuzz
  fuzzer.cpp
  ${ALL_HEADER_FILES}
  LINK_LIBS hermesapi
  )

set_target_properties(hermes-fuzz PROPERTIES
  CXX_STANDARD 14
  CXX_STANDARD_REQUIRED ON
  )

target_link_options(hermes-fuzz PUBLIC "SHELL: -fsanitize-coverage=trace-pc-guard")
target_compile_options(hermes-fuzz PUBLIC "SHELL: -fsanitize-coverage=trace-pc-guard")

target_link_libraries(hermes-fuzz
  hermesapi
)

I think something is disabling the rtti

In this case, the linker error is undefined reference to 'typeinfo for llvm::cl::GenericOptionValue'.
GenericOptionValue is defined in llvh/lib/Support/CommandLine.cpp.

So in order to link against the RTTI for that class, you need to compile LLVM with
RTTI on as well. When you do LINK_LIBS hermesapi you don't transitively pass on the cmake
variables HERMES_ENABLE_RTTI above. Changing LLVM to compile with RTTI shouldn't
be necessary for fuzzing, and I'm not sure what is changing to require it.

However, to get to the meat of the issue, it looks like you're trying to make a libfuzzing target
for Hermes, right? We are working on that right now, @neildhar is helping with that.

Note that set(LLVM_ENABLE_RTTI ON) has no effect, since Hermes has its own fork of LLVM, which isn't controlled by LLVM_ENABLE_RTTI.

Ok i got it working, but yes i am working on a fuzzer for hermes.
Would be nice if i could find a way to turn on jit.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

haozhun picture haozhun  Â·  6Comments

jacque006 picture jacque006  Â·  4Comments

AMorgaut picture AMorgaut  Â·  6Comments

Gregoirevda picture Gregoirevda  Â·  3Comments

mathiasbynens picture mathiasbynens  Â·  6Comments