Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion lldb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ if (LLDB_ENABLE_LUA)
CACHE STRING "Path where Lua modules are installed, relative to install prefix")
endif ()

if (LLDB_ENABLE_PYTHON OR LLDB_ENABLE_LUA)
if (LLDB_ENABLE_PYTHON OR LLDB_ENABLE_LUA OR LLDB_ENABLE_JAVASCRIPT)
add_subdirectory(bindings)
endif ()

Expand Down Expand Up @@ -150,6 +150,16 @@ if (LLDB_ENABLE_LUA)
finish_swig_lua("lldb-lua" "${lldb_lua_bindings_dir}" "${LLDB_LUA_CPATH}")
endif()

if (LLDB_ENABLE_JAVASCRIPT)
if(LLDB_BUILD_FRAMEWORK)
set(lldb_javascript_target_dir "${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework/Resources/JavaScript")
else()
set(lldb_javascript_target_dir "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib/javascript")
endif()
get_target_property(lldb_javascript_bindings_dir swig_wrapper_javascript BINARY_DIR)
finish_swig_javascript("lldb-javascript" "${lldb_javascript_bindings_dir}" "${lldb_javascript_target_dir}")
endif()

set(LLDB_INCLUDE_UNITTESTS ON)
if (NOT TARGET llvm_gtest)
set(LLDB_INCLUDE_UNITTESTS OFF)
Expand Down
4 changes: 4 additions & 0 deletions lldb/bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,7 @@ endif()
if (LLDB_ENABLE_LUA)
add_subdirectory(lua)
endif()

if (LLDB_ENABLE_JAVASCRIPT)
add_subdirectory(javascript)
endif()
69 changes: 69 additions & 0 deletions lldb/bindings/javascript/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapJavaScript.cpp
DEPENDS ${SWIG_SOURCES}
DEPENDS ${SWIG_INTERFACES}
DEPENDS ${SWIG_HEADERS}
DEPENDS lldb-sbapi-dwarf-enums
COMMAND ${SWIG_EXECUTABLE}
${SWIG_COMMON_FLAGS}
-I${CMAKE_CURRENT_SOURCE_DIR}
-javascript
-v8
-w503
-outdir ${CMAKE_CURRENT_BINARY_DIR}
-o ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapJavaScript.cpp
${CMAKE_CURRENT_SOURCE_DIR}/javascript.swig
VERBATIM
COMMENT "Building LLDB JavaScript wrapper")

add_custom_target(swig_wrapper_javascript ALL DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapJavaScript.cpp
)

function(create_javascript_package swig_target working_dir pkg_dir)
cmake_parse_arguments(ARG "NOINIT" "" "FILES" ${ARGN})
add_custom_command(TARGET ${swig_target} POST_BUILD VERBATIM
COMMAND ${CMAKE_COMMAND} -E make_directory ${pkg_dir}
WORKING_DIRECTORY ${working_dir})
endfunction()

function(finish_swig_javascript swig_target lldb_javascript_bindings_dir lldb_javascript_target_dir)
add_custom_target(${swig_target} ALL VERBATIM
COMMAND ${CMAKE_COMMAND} -E make_directory ${lldb_javascript_target_dir}
DEPENDS swig_wrapper_javascript liblldb
COMMENT "LLDB JavaScript API")
if(LLDB_BUILD_FRAMEWORK)
set(LIBLLDB_SYMLINK_DEST "${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework/LLDB")
else()
set(LIBLLDB_SYMLINK_DEST "${LLVM_SHLIB_OUTPUT_INTDIR}/liblldb${CMAKE_SHARED_LIBRARY_SUFFIX}")
endif()
if(WIN32)
set(LIBLLDB_SYMLINK_OUTPUT_FILE "lldb.dll")
else()
set(LIBLLDB_SYMLINK_OUTPUT_FILE "lldb.so")
endif()
create_relative_symlink(${swig_target} ${LIBLLDB_SYMLINK_DEST}
${lldb_javascript_target_dir} ${LIBLLDB_SYMLINK_OUTPUT_FILE})
set(lldb_javascript_library_target "${swig_target}-library")
add_custom_target(${lldb_javascript_library_target})
add_dependencies(${lldb_javascript_library_target} ${swig_target})

# Ensure we do the JavaScript post-build step when building lldb.
add_dependencies(lldb ${swig_target})

if(LLDB_BUILD_FRAMEWORK)
set(LLDB_JAVASCRIPT_INSTALL_PATH ${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/Resources/JavaScript)
else()
set(LLDB_JAVASCRIPT_INSTALL_PATH lib/javascript)
endif()
install(DIRECTORY ${lldb_javascript_target_dir}/
DESTINATION ${LLDB_JAVASCRIPT_INSTALL_PATH}
COMPONENT ${lldb_javascript_library_target})

set(lldb_javascript_library_install_target "install-${lldb_javascript_library_target}")
if (NOT LLVM_ENABLE_IDE)
add_llvm_install_targets(${lldb_javascript_library_install_target}
COMPONENT ${lldb_javascript_library_target}
DEPENDS ${lldb_javascript_library_target})
endif()
endfunction()
8 changes: 8 additions & 0 deletions lldb/bindings/javascript/javascript-swigsafecast.swig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Safe casting for JavaScript SWIG bindings
*/

// This file provides safe type casting between LLDB types
// Similar to lua-swigsafecast.swig and python-swigsafecast.swig

// TODO: Implement safe casting functions as needed
48 changes: 48 additions & 0 deletions lldb/bindings/javascript/javascript-typemaps.swig
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
JavaScript-specific typemaps for LLDB
*/

%header %{
#include <v8.h>
%}

// Typemap for char ** (string arrays) - used in LaunchSimple, Launch, etc.
// Converts JavaScript arrays to C string arrays
%typemap(in) char ** {
if ($input->IsArray()) {
v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast($input);
uint32_t length = array->Length();
$1 = (char **)malloc((length + 1) * sizeof(char *));

for (uint32_t i = 0; i < length; i++) {
v8::Local<v8::Value> element;
if (array->Get(SWIGV8_CURRENT_CONTEXT(), i).ToLocal(&element)) {
if (element->IsString()) {
v8::String::Utf8Value str(SWIGV8_CURRENT_CONTEXT()->GetIsolate(), element);
$1[i] = strdup(*str);
} else {
free($1);
SWIG_exception_fail(SWIG_TypeError, "Array elements must be strings");
}
}
}
$1[length] = NULL;
} else if ($input->IsNull() || $input->IsUndefined()) {
$1 = NULL;
} else {
SWIG_exception_fail(SWIG_TypeError, "Expected array of strings or null");
}
}

%typemap(freearg) char ** {
if ($1) {
for (int i = 0; $1[i] != NULL; i++) {
free($1[i]);
}
free($1);
}
}

%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) char ** {
$1 = $input->IsArray() || $input->IsNull() || $input->IsUndefined();
}
12 changes: 12 additions & 0 deletions lldb/bindings/javascript/javascript-wrapper.swig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
JavaScript-specific wrapper functions for LLDB
*/

// This file will contain JavaScript-specific wrapper code
// to bridge between LLDB's C++ API and JavaScript/V8

// TODO: Add wrapper functions for:
// - Breakpoint callbacks
// - Watchpoint callbacks
// - Custom commands
// - Data formatters
30 changes: 30 additions & 0 deletions lldb/bindings/javascript/javascript.swig
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
lldb.swig
This is the input file for SWIG, to create the appropriate C++ wrappers and
functions for JavaScript (V8/Node.js), to enable them to call the
liblldb Script Bridge functions.
*/

%module lldb

%include <std_string.i>
%include "javascript-typemaps.swig"
%include "macros.swig"
%include "headers.swig"

%{
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
#include "../bindings/javascript/javascript-swigsafecast.swig"
#include "../source/Plugins/ScriptInterpreter/JavaScript/SWIGJavaScriptBridge.h"

// required headers for typemaps
#include "lldb/Host/File.h"

using namespace lldb_private;
using namespace lldb;
%}

%include "interfaces.swig"
%include "javascript-wrapper.swig"
71 changes: 71 additions & 0 deletions lldb/cmake/modules/FindV8.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#.rst:
# FindV8
# ------
#
# Find V8 JavaScript engine
#
# This module will search for V8 in standard system locations, or use
# user-specified paths. Users can override the search by setting:
# -DV8_INCLUDE_DIR=/path/to/v8/include
# -DV8_LIBRARIES=/path/to/libv8.so (or libv8_monolith.a)
#
# The module defines:
# V8_FOUND - System has V8
# V8_INCLUDE_DIR - V8 include directory
# V8_LIBRARIES - V8 libraries to link against

if(V8_LIBRARIES AND V8_INCLUDE_DIR)
set(V8_FOUND TRUE)
if(NOT V8_FIND_QUIETLY)
message(STATUS "Found V8: ${V8_INCLUDE_DIR}")
message(STATUS "Found V8 library: ${V8_LIBRARIES}")
set(V8_FIND_QUIETLY TRUE CACHE BOOL "Suppress repeated V8 find messages" FORCE)
endif()
else()
# Try to find system V8
find_path(V8_INCLUDE_DIR
NAMES v8.h
PATHS
# Standard system locations
/usr/include
/usr/local/include
/opt/v8/include
# Homebrew on macOS
/opt/homebrew/include
/usr/local/opt/v8/include
PATH_SUFFIXES
v8
DOC "V8 include directory"
)

find_library(V8_LIBRARIES
NAMES v8_monolith v8 v8_libbase v8_libplatform
PATHS
# Standard system locations
/usr/lib
/usr/local/lib
/opt/v8/lib
# Homebrew on macOS
/opt/homebrew/lib
/usr/local/opt/v8/lib
DOC "V8 library"
)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(V8
FOUND_VAR
V8_FOUND
REQUIRED_VARS
V8_INCLUDE_DIR
V8_LIBRARIES)

if(V8_FOUND)
mark_as_advanced(V8_LIBRARIES V8_INCLUDE_DIR)
message(STATUS "Found V8: ${V8_INCLUDE_DIR}")
if(V8_LIBRARIES)
message(STATUS "Found V8 library: ${V8_LIBRARIES}")
else()
message(STATUS "V8 headers found (library may need to be built or specified manually)")
endif()
endif()
endif()
1 change: 1 addition & 0 deletions lldb/cmake/modules/LLDBConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ add_optional_dependency(LLDB_ENABLE_CURSES "Enable curses support in LLDB" Curse
add_optional_dependency(LLDB_ENABLE_LZMA "Enable LZMA compression support in LLDB" LibLZMA LIBLZMA_FOUND)
add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" LuaAndSwig LUAANDSWIG_FOUND)
add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonAndSwig PYTHONANDSWIG_FOUND)
add_optional_dependency(LLDB_ENABLE_JAVASCRIPT "Enable JavaScript scripting support in LLDB" V8 V8_FOUND)
add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION ${LLDB_LIBXML2_VERSION})
add_optional_dependency(LLDB_ENABLE_FBSDVMCORE "Enable libfbsdvmcore support in LLDB" FBSDVMCore FBSDVMCore_FOUND QUIET)

Expand Down
5 changes: 4 additions & 1 deletion lldb/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ with GDB there is a cheat sheet listing common tasks and their LLDB equivalent
in the `GDB to LLDB command map <https://lldb.llvm.org/use/map.html>`_.

There are also multiple resources on how to script LLDB using Python: the
:doc:`use/python-reference` is a great starting point for that.
:doc:`use/python-reference` is a great starting point for that. LLDB also
supports scripting with JavaScript through the V8 engine (see
`JavaScript Reference <use/javascript-reference.html>`_).

Compiler Integration Benefits
-----------------------------
Expand Down Expand Up @@ -148,6 +150,7 @@ interesting areas to contribute to lldb.

use/python
use/python-reference
use/javascript-reference
Python API <python_api>
Python Extensions <python_extensions>

Expand Down
2 changes: 2 additions & 0 deletions lldb/docs/resources/build.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ CMake configuration error.
+-------------------+--------------------------------------------------------------+--------------------------+
| Lua | Lua scripting. Lua 5.3 and 5.4 are supported. | ``LLDB_ENABLE_LUA`` |
+-------------------+--------------------------------------------------------------+--------------------------+
| JavaScript | JavaScript scripting via V8 engine. Experimental. | ``LLDB_ENABLE_JAVASCRIPT``|
+-------------------+--------------------------------------------------------------+--------------------------+

Depending on your platform and package manager, one might run any of the
commands below.
Expand Down
Loading
Loading