Skip to content

Commit e062204

Browse files
committed
add javascript support
1 parent 10afda0 commit e062204

25 files changed

+1586
-4
lines changed

lldb/CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ if (LLDB_ENABLE_LUA)
9595
CACHE STRING "Path where Lua modules are installed, relative to install prefix")
9696
endif ()
9797

98-
if (LLDB_ENABLE_PYTHON OR LLDB_ENABLE_LUA)
98+
if (LLDB_ENABLE_PYTHON OR LLDB_ENABLE_LUA OR LLDB_ENABLE_JAVASCRIPT)
9999
add_subdirectory(bindings)
100100
endif ()
101101

@@ -150,6 +150,16 @@ if (LLDB_ENABLE_LUA)
150150
finish_swig_lua("lldb-lua" "${lldb_lua_bindings_dir}" "${LLDB_LUA_CPATH}")
151151
endif()
152152

153+
if (LLDB_ENABLE_JAVASCRIPT)
154+
if(LLDB_BUILD_FRAMEWORK)
155+
set(lldb_javascript_target_dir "${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework/Resources/JavaScript")
156+
else()
157+
set(lldb_javascript_target_dir "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib/javascript")
158+
endif()
159+
get_target_property(lldb_javascript_bindings_dir swig_wrapper_javascript BINARY_DIR)
160+
finish_swig_javascript("lldb-javascript" "${lldb_javascript_bindings_dir}" "${lldb_javascript_target_dir}")
161+
endif()
162+
153163
set(LLDB_INCLUDE_UNITTESTS ON)
154164
if (NOT TARGET llvm_gtest)
155165
set(LLDB_INCLUDE_UNITTESTS OFF)

lldb/bindings/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@ endif()
5757
if (LLDB_ENABLE_LUA)
5858
add_subdirectory(lua)
5959
endif()
60+
61+
if (LLDB_ENABLE_JAVASCRIPT)
62+
add_subdirectory(javascript)
63+
endif()
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
add_custom_command(
2+
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapJavaScript.cpp
3+
DEPENDS ${SWIG_SOURCES}
4+
DEPENDS ${SWIG_INTERFACES}
5+
DEPENDS ${SWIG_HEADERS}
6+
DEPENDS lldb-sbapi-dwarf-enums
7+
COMMAND ${SWIG_EXECUTABLE}
8+
${SWIG_COMMON_FLAGS}
9+
-I${CMAKE_CURRENT_SOURCE_DIR}
10+
-javascript
11+
-v8
12+
-w503
13+
-outdir ${CMAKE_CURRENT_BINARY_DIR}
14+
-o ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapJavaScript.cpp
15+
${CMAKE_CURRENT_SOURCE_DIR}/javascript.swig
16+
VERBATIM
17+
COMMENT "Building LLDB JavaScript wrapper")
18+
19+
add_custom_target(swig_wrapper_javascript ALL DEPENDS
20+
${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapJavaScript.cpp
21+
)
22+
23+
function(create_javascript_package swig_target working_dir pkg_dir)
24+
cmake_parse_arguments(ARG "NOINIT" "" "FILES" ${ARGN})
25+
add_custom_command(TARGET ${swig_target} POST_BUILD VERBATIM
26+
COMMAND ${CMAKE_COMMAND} -E make_directory ${pkg_dir}
27+
WORKING_DIRECTORY ${working_dir})
28+
endfunction()
29+
30+
function(finish_swig_javascript swig_target lldb_javascript_bindings_dir lldb_javascript_target_dir)
31+
add_custom_target(${swig_target} ALL VERBATIM
32+
COMMAND ${CMAKE_COMMAND} -E make_directory ${lldb_javascript_target_dir}
33+
DEPENDS swig_wrapper_javascript liblldb
34+
COMMENT "LLDB JavaScript API")
35+
if(LLDB_BUILD_FRAMEWORK)
36+
set(LIBLLDB_SYMLINK_DEST "${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework/LLDB")
37+
else()
38+
set(LIBLLDB_SYMLINK_DEST "${LLVM_SHLIB_OUTPUT_INTDIR}/liblldb${CMAKE_SHARED_LIBRARY_SUFFIX}")
39+
endif()
40+
if(WIN32)
41+
set(LIBLLDB_SYMLINK_OUTPUT_FILE "lldb.dll")
42+
else()
43+
set(LIBLLDB_SYMLINK_OUTPUT_FILE "lldb.so")
44+
endif()
45+
create_relative_symlink(${swig_target} ${LIBLLDB_SYMLINK_DEST}
46+
${lldb_javascript_target_dir} ${LIBLLDB_SYMLINK_OUTPUT_FILE})
47+
set(lldb_javascript_library_target "${swig_target}-library")
48+
add_custom_target(${lldb_javascript_library_target})
49+
add_dependencies(${lldb_javascript_library_target} ${swig_target})
50+
51+
# Ensure we do the JavaScript post-build step when building lldb.
52+
add_dependencies(lldb ${swig_target})
53+
54+
if(LLDB_BUILD_FRAMEWORK)
55+
set(LLDB_JAVASCRIPT_INSTALL_PATH ${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/Resources/JavaScript)
56+
else()
57+
set(LLDB_JAVASCRIPT_INSTALL_PATH lib/javascript)
58+
endif()
59+
install(DIRECTORY ${lldb_javascript_target_dir}/
60+
DESTINATION ${LLDB_JAVASCRIPT_INSTALL_PATH}
61+
COMPONENT ${lldb_javascript_library_target})
62+
63+
set(lldb_javascript_library_install_target "install-${lldb_javascript_library_target}")
64+
if (NOT LLVM_ENABLE_IDE)
65+
add_llvm_install_targets(${lldb_javascript_library_install_target}
66+
COMPONENT ${lldb_javascript_library_target}
67+
DEPENDS ${lldb_javascript_library_target})
68+
endif()
69+
endfunction()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
Safe casting for JavaScript SWIG bindings
3+
*/
4+
5+
// This file provides safe type casting between LLDB types
6+
// Similar to lua-swigsafecast.swig and python-swigsafecast.swig
7+
8+
// TODO: Implement safe casting functions as needed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
JavaScript-specific typemaps for LLDB
3+
*/
4+
5+
%header %{
6+
#include <v8.h>
7+
%}
8+
9+
// Typemap for char ** (string arrays) - used in LaunchSimple, Launch, etc.
10+
// Converts JavaScript arrays to C string arrays
11+
%typemap(in) char ** {
12+
if ($input->IsArray()) {
13+
v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast($input);
14+
uint32_t length = array->Length();
15+
$1 = (char **)malloc((length + 1) * sizeof(char *));
16+
17+
for (uint32_t i = 0; i < length; i++) {
18+
v8::Local<v8::Value> element;
19+
if (array->Get(SWIGV8_CURRENT_CONTEXT(), i).ToLocal(&element)) {
20+
if (element->IsString()) {
21+
v8::String::Utf8Value str(SWIGV8_CURRENT_CONTEXT()->GetIsolate(), element);
22+
$1[i] = strdup(*str);
23+
} else {
24+
free($1);
25+
SWIG_exception_fail(SWIG_TypeError, "Array elements must be strings");
26+
}
27+
}
28+
}
29+
$1[length] = NULL;
30+
} else if ($input->IsNull() || $input->IsUndefined()) {
31+
$1 = NULL;
32+
} else {
33+
SWIG_exception_fail(SWIG_TypeError, "Expected array of strings or null");
34+
}
35+
}
36+
37+
%typemap(freearg) char ** {
38+
if ($1) {
39+
for (int i = 0; $1[i] != NULL; i++) {
40+
free($1[i]);
41+
}
42+
free($1);
43+
}
44+
}
45+
46+
%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) char ** {
47+
$1 = $input->IsArray() || $input->IsNull() || $input->IsUndefined();
48+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
JavaScript-specific wrapper functions for LLDB
3+
*/
4+
5+
// This file will contain JavaScript-specific wrapper code
6+
// to bridge between LLDB's C++ API and JavaScript/V8
7+
8+
// TODO: Add wrapper functions for:
9+
// - Breakpoint callbacks
10+
// - Watchpoint callbacks
11+
// - Custom commands
12+
// - Data formatters
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
lldb.swig
3+
4+
This is the input file for SWIG, to create the appropriate C++ wrappers and
5+
functions for JavaScript (V8/Node.js), to enable them to call the
6+
liblldb Script Bridge functions.
7+
*/
8+
9+
%module lldb
10+
11+
%include <std_string.i>
12+
%include "javascript-typemaps.swig"
13+
%include "macros.swig"
14+
%include "headers.swig"
15+
16+
%{
17+
#include "llvm/Support/Error.h"
18+
#include "llvm/Support/FormatVariadic.h"
19+
#include "../bindings/javascript/javascript-swigsafecast.swig"
20+
#include "../source/Plugins/ScriptInterpreter/JavaScript/SWIGJavaScriptBridge.h"
21+
22+
// required headers for typemaps
23+
#include "lldb/Host/File.h"
24+
25+
using namespace lldb_private;
26+
using namespace lldb;
27+
%}
28+
29+
%include "interfaces.swig"
30+
%include "javascript-wrapper.swig"

lldb/cmake/modules/FindV8.cmake

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#.rst:
2+
# FindV8
3+
# ------
4+
#
5+
# Find V8 JavaScript engine
6+
#
7+
# This module will search for V8 in standard system locations, or use
8+
# user-specified paths. Users can override the search by setting:
9+
# -DV8_INCLUDE_DIR=/path/to/v8/include
10+
# -DV8_LIBRARIES=/path/to/libv8.so (or libv8_monolith.a)
11+
#
12+
# The module defines:
13+
# V8_FOUND - System has V8
14+
# V8_INCLUDE_DIR - V8 include directory
15+
# V8_LIBRARIES - V8 libraries to link against
16+
17+
if(V8_LIBRARIES AND V8_INCLUDE_DIR)
18+
set(V8_FOUND TRUE)
19+
if(NOT V8_FIND_QUIETLY)
20+
message(STATUS "Found V8: ${V8_INCLUDE_DIR}")
21+
message(STATUS "Found V8 library: ${V8_LIBRARIES}")
22+
set(V8_FIND_QUIETLY TRUE CACHE BOOL "Suppress repeated V8 find messages" FORCE)
23+
endif()
24+
else()
25+
# Try to find system V8
26+
find_path(V8_INCLUDE_DIR
27+
NAMES v8.h
28+
PATHS
29+
# Standard system locations
30+
/usr/include
31+
/usr/local/include
32+
/opt/v8/include
33+
# Homebrew on macOS
34+
/opt/homebrew/include
35+
/usr/local/opt/v8/include
36+
PATH_SUFFIXES
37+
v8
38+
DOC "V8 include directory"
39+
)
40+
41+
find_library(V8_LIBRARIES
42+
NAMES v8_monolith v8 v8_libbase v8_libplatform
43+
PATHS
44+
# Standard system locations
45+
/usr/lib
46+
/usr/local/lib
47+
/opt/v8/lib
48+
# Homebrew on macOS
49+
/opt/homebrew/lib
50+
/usr/local/opt/v8/lib
51+
DOC "V8 library"
52+
)
53+
54+
include(FindPackageHandleStandardArgs)
55+
find_package_handle_standard_args(V8
56+
FOUND_VAR
57+
V8_FOUND
58+
REQUIRED_VARS
59+
V8_INCLUDE_DIR
60+
V8_LIBRARIES)
61+
62+
if(V8_FOUND)
63+
mark_as_advanced(V8_LIBRARIES V8_INCLUDE_DIR)
64+
message(STATUS "Found V8: ${V8_INCLUDE_DIR}")
65+
if(V8_LIBRARIES)
66+
message(STATUS "Found V8 library: ${V8_LIBRARIES}")
67+
else()
68+
message(STATUS "V8 headers found (library may need to be built or specified manually)")
69+
endif()
70+
endif()
71+
endif()

lldb/cmake/modules/LLDBConfig.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ add_optional_dependency(LLDB_ENABLE_CURSES "Enable curses support in LLDB" Curse
6262
add_optional_dependency(LLDB_ENABLE_LZMA "Enable LZMA compression support in LLDB" LibLZMA LIBLZMA_FOUND)
6363
add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" LuaAndSwig LUAANDSWIG_FOUND)
6464
add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonAndSwig PYTHONANDSWIG_FOUND)
65+
add_optional_dependency(LLDB_ENABLE_JAVASCRIPT "Enable JavaScript scripting support in LLDB" V8 V8_FOUND)
6566
add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION ${LLDB_LIBXML2_VERSION})
6667
add_optional_dependency(LLDB_ENABLE_FBSDVMCORE "Enable libfbsdvmcore support in LLDB" FBSDVMCore FBSDVMCore_FOUND QUIET)
6768

lldb/docs/index.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ with GDB there is a cheat sheet listing common tasks and their LLDB equivalent
2727
in the `GDB to LLDB command map <https://lldb.llvm.org/use/map.html>`_.
2828

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

3234
Compiler Integration Benefits
3335
-----------------------------
@@ -148,6 +150,7 @@ interesting areas to contribute to lldb.
148150

149151
use/python
150152
use/python-reference
153+
use/javascript-reference
151154
Python API <python_api>
152155
Python Extensions <python_extensions>
153156

0 commit comments

Comments
 (0)