Drop to support NaCl platform.
Because NaCl and PNaCl are already sunset status. see https://bugs.chromium.org/p/chromium/issues/detail?id=239656#c160 configure.ac: Patch for this file was provided by @nobu. [Feature #14041][ruby-core:83497][fix GH-1726] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60374 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
08524bc594
commit
0e2d2e6a79
3
NEWS
3
NEWS
@ -237,6 +237,9 @@ with all sufficient information, see the ChangeLog file or Redmine
|
|||||||
|
|
||||||
=== Supported platform changes
|
=== Supported platform changes
|
||||||
|
|
||||||
|
* Drop to support NaCl platform
|
||||||
|
* https://bugs.chromium.org/p/chromium/issues/detail?id=239656#c160
|
||||||
|
|
||||||
=== Implementation improvements
|
=== Implementation improvements
|
||||||
|
|
||||||
* (This might not be a "user visible feature change" but) Hash class's
|
* (This might not be a "user visible feature change" but) Hash class's
|
||||||
|
@ -261,12 +261,6 @@ rescue Exception => err
|
|||||||
error err.message, message
|
error err.message, message
|
||||||
end
|
end
|
||||||
|
|
||||||
# NativeClient is special. The binary is cross-compiled. But runs on the build environment.
|
|
||||||
# So RUBY_PLATFORM in this process is not useful to detect it.
|
|
||||||
def nacl?
|
|
||||||
@ruby and File.basename(@ruby.split(/\s/).first)['sel_ldr']
|
|
||||||
end
|
|
||||||
|
|
||||||
def assert_check(testsrc, message = '', opt = '', **argh)
|
def assert_check(testsrc, message = '', opt = '', **argh)
|
||||||
show_progress(message) {
|
show_progress(message) {
|
||||||
result = get_result_string(testsrc, opt, **argh)
|
result = get_result_string(testsrc, opt, **argh)
|
||||||
|
@ -52,7 +52,7 @@ assert_equal 'ok', %q{
|
|||||||
STDIN.reopen(rw)
|
STDIN.reopen(rw)
|
||||||
STDIN.reopen(save)
|
STDIN.reopen(save)
|
||||||
rw.close
|
rw.close
|
||||||
File.unlink(tmpname) unless RUBY_PLATFORM['nacl']
|
File.unlink(tmpname)
|
||||||
:ok
|
:ok
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ assert_equal 'ok', %q{
|
|||||||
STDIN.print "a"
|
STDIN.print "a"
|
||||||
STDIN.reopen(save)
|
STDIN.reopen(save)
|
||||||
rw.close
|
rw.close
|
||||||
File.unlink(tmpname) unless RUBY_PLATFORM['nacl']
|
File.unlink(tmpname)
|
||||||
:ok
|
:ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,10 +65,8 @@ assert_equal ':a3c', ':"a#{1+2}c".inspect'
|
|||||||
assert_equal 'Symbol', ':"a#{1+2}c".class'
|
assert_equal 'Symbol', ':"a#{1+2}c".class'
|
||||||
|
|
||||||
# xstring
|
# xstring
|
||||||
unless nacl?
|
assert_equal "foo\n", %q(`echo foo`)
|
||||||
assert_equal "foo\n", %q(`echo foo`)
|
assert_equal "foo\n", %q(s = "foo"; `echo #{s}`)
|
||||||
assert_equal "foo\n", %q(s = "foo"; `echo #{s}`)
|
|
||||||
end
|
|
||||||
|
|
||||||
# regexp
|
# regexp
|
||||||
assert_equal '', '//.source'
|
assert_equal '', '//.source'
|
||||||
|
182
configure.ac
182
configure.ac
@ -89,120 +89,6 @@ target_cpu=x64
|
|||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([RUBY_NACL],
|
|
||||||
[
|
|
||||||
AS_CASE(["${host_os}"],
|
|
||||||
[nacl], [
|
|
||||||
ac_cv_exeext=.nexe
|
|
||||||
host_vendor=chromium
|
|
||||||
ac_cv_host=chromium
|
|
||||||
AC_MSG_CHECKING([wheather \$NACL_SDK_ROOT is set])
|
|
||||||
AS_IF([test x"${NACL_SDK_ROOT}" = x], [
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
AC_MSG_ERROR([You need to set \$NACL_SDK_ROOT environment variable to build for NativeClient])
|
|
||||||
])
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
|
|
||||||
nacl_cv_build_variant=glibc
|
|
||||||
AC_ARG_WITH(newlib,
|
|
||||||
AS_HELP_STRING([--with-newlib], [uses newlib version of NativeClient SDK]),
|
|
||||||
[AS_CASE([$withval],
|
|
||||||
[no], [nacl_cv_build_variant=glibc],
|
|
||||||
[yes], [nacl_cv_build_variant=newlib])])
|
|
||||||
|
|
||||||
AS_CASE(["$target_cpu"],
|
|
||||||
[x86_64], [nacl_cv_cpu_nick=x86
|
|
||||||
nacl_cv_cpu_nick2=x86_64],
|
|
||||||
[i?86], [nacl_cv_cpu_nick=x86
|
|
||||||
nacl_cv_cpu_nick2=x86_32],
|
|
||||||
[le32], [nacl_cv_cpu_nick=pnacl
|
|
||||||
nacl_cv_cpu_nick2=pnacl
|
|
||||||
ac_cv_exeext=.pexe],
|
|
||||||
[nacl_cv_cpu_nick=$target_cpu])
|
|
||||||
AS_CASE(["$build_os"],
|
|
||||||
[linux*], [nacl_cv_os_nick=linux],
|
|
||||||
[darwin*], [nacl_cv_os_nick=mac],
|
|
||||||
[cygwin*|mingw*], [nacl_cv_os_nick=win],
|
|
||||||
[nacl_cv_os_nick=$build_os])
|
|
||||||
|
|
||||||
host="$host_cpu-chromium-$host_os-"
|
|
||||||
ac_tool_prefix="$host_cpu-nacl-"
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([NativeClient toolchain])
|
|
||||||
AS_IF([test x"$nacl_cv_cpu_nick" = xpnacl], [
|
|
||||||
NACL_TOOLCHAIN="${nacl_cv_os_nick}_pnacl"
|
|
||||||
ac_tool_prefix=pnacl-
|
|
||||||
], [test -d \
|
|
||||||
"${NACL_SDK_ROOT}/toolchain/${nacl_cv_os_nick}_${nacl_cv_cpu_nick}_${nacl_cv_build_variant}"], [
|
|
||||||
NACL_TOOLCHAIN="${nacl_cv_os_nick}_${nacl_cv_cpu_nick}_${nacl_cv_build_variant}"
|
|
||||||
], [test -d \
|
|
||||||
"${NACL_SDK_ROOT}/toolchain/${nacl_cv_os_nick}_x86_${nacl_cv_cpu_nick}/${nacl_cv_build_variant}"], [
|
|
||||||
NACL_TOOLCHAIN="${nacl_cv_os_nick}_x86_${nacl_cv_cpu_nick}/${nacl_cv_build_variant}"
|
|
||||||
], [
|
|
||||||
AS_CASE(
|
|
||||||
["${nacl_cv_build_variant}"],
|
|
||||||
[glibc], [AS_IF([test \
|
|
||||||
-d "${NACL_SDK_ROOT}/toolchain/${nacl_cv_os_nick}_${nacl_cv_cpu_nick}_newlib" \
|
|
||||||
-a -d "${NACL_SDK_ROOT}/toolchain/${nacl_cv_os_nick}_${nacl_cv_cpu_nick}"], [
|
|
||||||
NACL_TOOLCHAIN="${nacl_cv_os_nick}_${nacl_cv_cpu_nick}"
|
|
||||||
])],
|
|
||||||
[newlib], [ NACL_TOOLCHAIN="${nacl_cv_os_nick}_${nacl_cv_cpu_nick}" ])
|
|
||||||
])
|
|
||||||
AS_IF([test ! -e "${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/${ac_tool_prefix}gcc"], [
|
|
||||||
AS_IF([test "${build_cpu}" = i686 -a -e "${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/nacl-gcc"], [
|
|
||||||
ac_tool_prefix=nacl-
|
|
||||||
])
|
|
||||||
AS_IF([test "${build_cpu}" = x86_64 -a -e "${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/nacl-gcc"], [
|
|
||||||
ac_tool_prefix=nacl64-
|
|
||||||
])
|
|
||||||
])
|
|
||||||
AS_IF([test -z "${NACL_TOOLCHAIN}"], [
|
|
||||||
AC_MSG_ERROR([Unrecognized --host and --build combination or NaCl SDK is not installed])
|
|
||||||
])
|
|
||||||
AC_MSG_RESULT(${NACL_TOOLCHAIN})
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([path to SDK])
|
|
||||||
AS_IF([! echo -- "${PATH}" | grep -F "${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/bin" > /dev/null], [
|
|
||||||
PATH="${PATH}:${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/bin"
|
|
||||||
])
|
|
||||||
AC_MSG_RESULT(${NACL_SDK_ROOT}/toolchain/${NACL_TOOLCHAIN}/bin)
|
|
||||||
|
|
||||||
RUBY_APPEND_OPTIONS(XCFLAGS, '-I$(NACL_SDK_ROOT)/include')
|
|
||||||
AS_IF([test x"${nacl_cv_cpu_nick}" = xpnacl], [
|
|
||||||
RUBY_APPEND_OPTIONS(XCFLAGS, '-isystem $(NACL_SDK_ROOT)/include/pnacl')
|
|
||||||
], [test x"${nacl_cv_build_variant}" = xnewlib], [
|
|
||||||
RUBY_APPEND_OPTIONS(XCFLAGS, '-isystem $(NACL_SDK_ROOT)/include/newlib')
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([nacl library path])
|
|
||||||
AS_IF([test -d "${NACL_SDK_ROOT}/lib/${nacl_cv_build_variant}_${nacl_cv_cpu_nick2}/Release"], [
|
|
||||||
nacl_cv_libpath="${nacl_cv_build_variant}_${nacl_cv_cpu_nick2}"
|
|
||||||
], [test -d "${NACL_SDK_ROOT}/lib/${nacl_cv_cpu_nick2}/Release"], [
|
|
||||||
nacl_cv_libpath="${nacl_cv_cpu_nick2}"
|
|
||||||
], [
|
|
||||||
AC_MSG_ERROR([not found])
|
|
||||||
])
|
|
||||||
AC_MSG_RESULT([${nacl_cv_libpath}])
|
|
||||||
RUBY_APPEND_OPTIONS(XLDFLAGS, '-L$(NACL_SDK_ROOT)/'"lib/${nacl_cv_libpath}/Release")
|
|
||||||
|
|
||||||
AC_SUBST(NACL_TOOLCHAIN)
|
|
||||||
AC_SUBST(NACL_SDK_ROOT)
|
|
||||||
AC_SUBST(NACL_SDK_VARIANT, "${nacl_cv_build_variant}")
|
|
||||||
AC_SUBST(NACL_LIB_PATH, "${nacl_cv_libpath}")
|
|
||||||
AC_CHECK_TOOLS(CC, [clang gcc])
|
|
||||||
AC_CHECK_TOOLS(CXX, [clang++ g++])
|
|
||||||
])])
|
|
||||||
|
|
||||||
AC_DEFUN([RUBY_NACL_CHECK_PEPPER_TYPES],
|
|
||||||
[AS_CASE(["${host_os}"],
|
|
||||||
[nacl], [
|
|
||||||
AC_CHECK_TYPES([struct PPB_Core, struct PPB_Messaging, struct PPB_Var,
|
|
||||||
struct PPB_URLLoader, struct PPB_URLRequestInfo,
|
|
||||||
struct PPB_URLResponseInfo, struct PPB_FileRef,
|
|
||||||
struct PPP_Instance])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([RUBY_CPPOUTFILE],
|
AC_DEFUN([RUBY_CPPOUTFILE],
|
||||||
[AC_CACHE_CHECK(whether ${CPP} accepts -o, rb_cv_cppoutfile,
|
[AC_CACHE_CHECK(whether ${CPP} accepts -o, rb_cv_cppoutfile,
|
||||||
[save_CPPFLAGS="$CPPFLAGS"
|
[save_CPPFLAGS="$CPPFLAGS"
|
||||||
@ -472,7 +358,6 @@ AS_IF([test -z "${CXXFLAGS+set}"], [
|
|||||||
cxxflags="$cxxflags "'${optflags} ${debugflags} ${warnflags}'
|
cxxflags="$cxxflags "'${optflags} ${debugflags} ${warnflags}'
|
||||||
])
|
])
|
||||||
|
|
||||||
RUBY_NACL
|
|
||||||
AS_CASE(["$host_os:$build_os"],
|
AS_CASE(["$host_os:$build_os"],
|
||||||
[darwin*:darwin*], [
|
[darwin*:darwin*], [
|
||||||
AC_CHECK_TOOLS(CC, [clang gcc cc])
|
AC_CHECK_TOOLS(CC, [clang gcc cc])
|
||||||
@ -707,7 +592,6 @@ AS_IF([test "$cross_compiling:$ac_cv_prog_DTRACE" = no: -a -n "$ac_tool_prefix"]
|
|||||||
|
|
||||||
AC_CHECK_PROGS(DOT, dot)
|
AC_CHECK_PROGS(DOT, dot)
|
||||||
AC_CHECK_PROGS(DOXYGEN, doxygen)
|
AC_CHECK_PROGS(DOXYGEN, doxygen)
|
||||||
AS_CASE(["${host_os}"], [nacl], [AC_PATH_PROG(PYTHON, python)])
|
|
||||||
|
|
||||||
AC_CHECK_PROG(PKG_CONFIG, pkg-config, [pkg-config], [], [],
|
AC_CHECK_PROG(PKG_CONFIG, pkg-config, [pkg-config], [], [],
|
||||||
[`"$as_dir/$ac_word$ac_exec_ext" --print-errors --version > /dev/null 2>&1 || echo "$as_dir/$ac_word$ac_exec_ext"`])
|
[`"$as_dir/$ac_word$ac_exec_ext" --print-errors --version > /dev/null 2>&1 || echo "$as_dir/$ac_word$ac_exec_ext"`])
|
||||||
@ -931,20 +815,16 @@ AC_ARG_WITH(compress-debug-sections,
|
|||||||
[compress_debug_sections=$withval], [compress_debug_sections=])
|
[compress_debug_sections=$withval], [compress_debug_sections=])
|
||||||
|
|
||||||
AS_IF([test "$GCC" = yes], [
|
AS_IF([test "$GCC" = yes], [
|
||||||
# NaCl's glibc build generates undefined references to __memset_chk.
|
# -D_FORTIFY_SOURCE
|
||||||
# TODO(sbc): Remove this once NaCl's glibc is fixed.
|
# When defined _FORTIFY_SOURCE, glibc enables some additional sanity
|
||||||
AS_CASE(["$target_os"], [nacl], [], [
|
# argument check. The performance drop is very little and Ubuntu enables
|
||||||
# -D_FORTIFY_SOURCE
|
# _FORTIFY_SOURCE=2 by default. So, let's support it for protecting us from
|
||||||
# When defined _FORTIFY_SOURCE, glibc enables some additional sanity
|
# a mistake of silly C extensions.
|
||||||
# argument check. The performance drop is very little and Ubuntu enables
|
RUBY_TRY_CFLAGS(-D_FORTIFY_SOURCE=2, [RUBY_APPEND_OPTION(XCFLAGS, -D_FORTIFY_SOURCE=2)])
|
||||||
# _FORTIFY_SOURCE=2 by default. So, let's support it for protecting us from
|
|
||||||
# a mistake of silly C extensions.
|
|
||||||
RUBY_TRY_CFLAGS(-D_FORTIFY_SOURCE=2, [RUBY_APPEND_OPTION(XCFLAGS, -D_FORTIFY_SOURCE=2)])
|
|
||||||
])
|
|
||||||
|
|
||||||
# -fstack-protector
|
# -fstack-protector
|
||||||
AS_CASE(["$target_os"],
|
AS_CASE(["$target_os"],
|
||||||
[mingw*|nacl], [
|
[mingw*], [
|
||||||
stack_protector=no
|
stack_protector=no
|
||||||
])
|
])
|
||||||
AS_IF([test -z "${stack_protector+set}"], [
|
AS_IF([test -z "${stack_protector+set}"], [
|
||||||
@ -1003,7 +883,7 @@ AS_IF([test "$GCC" = yes], [
|
|||||||
AC_DEFINE(RUBY_MINGW64_BROKEN_FREXP_MODF)
|
AC_DEFINE(RUBY_MINGW64_BROKEN_FREXP_MODF)
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
[cygwin*|darwin*|netbsd*|nacl], [
|
[cygwin*|darwin*|netbsd*], [
|
||||||
# need lgamma_r(), finite()
|
# need lgamma_r(), finite()
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@ -1042,7 +922,7 @@ AS_IF([test "$GCC" = yes], [
|
|||||||
], [
|
], [
|
||||||
RUBY_TRY_LDFLAGS([-Wl,-unexported_symbol,_Init_*], [visibility_option=ld], [visibility_option=no])
|
RUBY_TRY_LDFLAGS([-Wl,-unexported_symbol,_Init_*], [visibility_option=ld], [visibility_option=no])
|
||||||
])
|
])
|
||||||
test "$visibility_option" = no -o "$host_os" = nacl || OBJCOPY=:
|
test "$visibility_option" = no || OBJCOPY=:
|
||||||
])
|
])
|
||||||
|
|
||||||
AS_IF([test "$GCC" = yes], [
|
AS_IF([test "$GCC" = yes], [
|
||||||
@ -1358,14 +1238,6 @@ main()
|
|||||||
[aix*],[ LIBS="-lm $LIBS"
|
[aix*],[ LIBS="-lm $LIBS"
|
||||||
ac_cv_func_round=no
|
ac_cv_func_round=no
|
||||||
],
|
],
|
||||||
[nacl], [
|
|
||||||
LIBS="-lm $LIBS"
|
|
||||||
AS_IF([test "${nacl_cv_build_variant}" = "newlib"], [
|
|
||||||
RUBY_APPEND_OPTION(CPPFLAGS, -DNACL_NEWLIB)
|
|
||||||
], [
|
|
||||||
RUBY_APPEND_OPTION(XCFLAGS, -fPIC)
|
|
||||||
])
|
|
||||||
],
|
|
||||||
[ LIBS="-lm $LIBS"])
|
[ LIBS="-lm $LIBS"])
|
||||||
|
|
||||||
AC_CHECK_LIB(crypt, crypt) # glibc (GNU/Linux, GNU/Hurd, GNU/kFreeBSD)
|
AC_CHECK_LIB(crypt, crypt) # glibc (GNU/Linux, GNU/Hurd, GNU/kFreeBSD)
|
||||||
@ -2220,8 +2092,6 @@ RUBY_DEFINT(intptr_t, void*)
|
|||||||
RUBY_DEFINT(uintptr_t, void*, unsigned)
|
RUBY_DEFINT(uintptr_t, void*, unsigned)
|
||||||
RUBY_DEFINT(ssize_t, size_t, [], [@%:@include <sys/types.h>]) dnl may differ from int, so not use AC_TYPE_SSIZE_T.
|
RUBY_DEFINT(ssize_t, size_t, [], [@%:@include <sys/types.h>]) dnl may differ from int, so not use AC_TYPE_SSIZE_T.
|
||||||
|
|
||||||
RUBY_NACL_CHECK_PEPPER_TYPES
|
|
||||||
|
|
||||||
AC_CACHE_CHECK(for stack end address, rb_cv_stack_end_address,
|
AC_CACHE_CHECK(for stack end address, rb_cv_stack_end_address,
|
||||||
[rb_cv_stack_end_address=no
|
[rb_cv_stack_end_address=no
|
||||||
AC_TRY_LINK(
|
AC_TRY_LINK(
|
||||||
@ -3083,17 +2953,12 @@ AS_IF([test x"$enable_pthread" = xyes], [
|
|||||||
AC_DEFINE(NON_SCALAR_THREAD_ID)
|
AC_DEFINE(NON_SCALAR_THREAD_ID)
|
||||||
])
|
])
|
||||||
AC_CHECK_FUNCS(sched_yield pthread_attr_setinheritsched \
|
AC_CHECK_FUNCS(sched_yield pthread_attr_setinheritsched \
|
||||||
pthread_attr_get_np pthread_attr_getstack\
|
pthread_attr_get_np pthread_attr_getstack pthread_attr_init \
|
||||||
pthread_get_stackaddr_np pthread_get_stacksize_np \
|
pthread_get_stackaddr_np pthread_get_stacksize_np \
|
||||||
thr_stksegment pthread_stackseg_np pthread_getthrds_np \
|
thr_stksegment pthread_stackseg_np pthread_getthrds_np \
|
||||||
pthread_cond_init pthread_condattr_setclock pthread_condattr_init \
|
pthread_cond_init pthread_condattr_setclock pthread_condattr_init \
|
||||||
pthread_sigmask pthread_setname_np pthread_set_name_np)
|
pthread_sigmask pthread_setname_np pthread_set_name_np)
|
||||||
AS_CASE(["$target_os"],[aix*],[ac_cv_func_pthread_getattr_np=no],[AC_CHECK_FUNCS(pthread_getattr_np)])
|
AS_CASE(["$target_os"],[aix*],[ac_cv_func_pthread_getattr_np=no],[AC_CHECK_FUNCS(pthread_getattr_np)])
|
||||||
AS_IF([test "${host_os}" = "nacl"], [
|
|
||||||
ac_cv_func_pthread_attr_init=no
|
|
||||||
], [
|
|
||||||
AC_CHECK_FUNCS(pthread_attr_init)
|
|
||||||
])
|
|
||||||
set_current_thread_name=
|
set_current_thread_name=
|
||||||
AS_IF([test "$ac_cv_func_pthread_setname_np" = yes], [
|
AS_IF([test "$ac_cv_func_pthread_setname_np" = yes], [
|
||||||
AC_CACHE_CHECK([arguments of pthread_setname_np], [rb_cv_func_pthread_setname_np_arguments],
|
AC_CACHE_CHECK([arguments of pthread_setname_np], [rb_cv_func_pthread_setname_np_arguments],
|
||||||
@ -3265,7 +3130,7 @@ AS_IF([test "$rb_cv_binary_elf" = yes], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
AS_CASE(["$target_os"],
|
AS_CASE(["$target_os"],
|
||||||
[linux* | gnu* | k*bsd*-gnu | bsdi* | kopensolaris*-gnu | nacl], [
|
[linux* | gnu* | k*bsd*-gnu | bsdi* | kopensolaris*-gnu], [
|
||||||
AS_IF([test "$rb_cv_binary_elf" = no], [
|
AS_IF([test "$rb_cv_binary_elf" = no], [
|
||||||
with_dln_a_out=yes
|
with_dln_a_out=yes
|
||||||
], [
|
], [
|
||||||
@ -3409,7 +3274,6 @@ AS_IF([test "$with_dln_a_out" != yes], [
|
|||||||
[hiuxmpp], [ : ${LDSHARED='$(LD) -r'}],
|
[hiuxmpp], [ : ${LDSHARED='$(LD) -r'}],
|
||||||
[atheos*], [ : ${LDSHARED='$(CC) -shared'}
|
[atheos*], [ : ${LDSHARED='$(CC) -shared'}
|
||||||
rb_cv_dlopen=yes],
|
rb_cv_dlopen=yes],
|
||||||
[nacl], [ LDSHARED='$(CC) -shared' ],
|
|
||||||
[ : ${LDSHARED='$(LD)'}])
|
[ : ${LDSHARED='$(LD)'}])
|
||||||
AC_MSG_RESULT($rb_cv_dlopen)
|
AC_MSG_RESULT($rb_cv_dlopen)
|
||||||
|
|
||||||
@ -3722,20 +3586,6 @@ AS_IF([test x"$cross_compiling" = xyes], [
|
|||||||
BOOTSTRAPRUBY='$(BASERUBY)'
|
BOOTSTRAPRUBY='$(BASERUBY)'
|
||||||
TEST_RUNNABLE=no
|
TEST_RUNNABLE=no
|
||||||
CROSS_COMPILING=yes
|
CROSS_COMPILING=yes
|
||||||
|
|
||||||
AS_IF([test "$host_os" = "nacl"], [
|
|
||||||
AS_IF([test "$build_cpu" = "$host_cpu" || test "${nacl_cv_cpu_nick}" = "x86" -a "$host_cpu" = "i686"], [
|
|
||||||
nacl_cv_sel_ldr='`$(MINIRUBY) $(srcdir)/nacl/nacl-config.rb sel_ldr`'
|
|
||||||
nacl_cv_irt_core='`$(MINIRUBY) $(srcdir)/nacl/nacl-config.rb irt_core`'
|
|
||||||
nacl_cv_runnable_ld='`$(MINIRUBY) $(srcdir)/nacl/nacl-config.rb runnable_ld`'
|
|
||||||
nacl_cv_host_lib='`$(MINIRUBY) $(srcdir)/nacl/nacl-config.rb host_lib`'
|
|
||||||
TEST_RUNNABLE=yes
|
|
||||||
BTESTRUBY="${nacl_cv_sel_ldr} -a -B ${nacl_cv_irt_core} -w 1:3 -w 2:4"
|
|
||||||
BTESTRUBY="$BTESTRUBY -- ${nacl_cv_runnable_ld} --library-path ${nacl_cv_host_lib}"
|
|
||||||
BTESTRUBY="$BTESTRUBY `pwd`/"'miniruby$(EXEEXT) -I`cd $(srcdir)/lib; pwd` -I.'
|
|
||||||
BTESTRUBY="$BTESTRUBY"' -I$(EXTOUT)/common 3>&1 4>&2 1>/dev/null 2>/dev/null '
|
|
||||||
])
|
|
||||||
])
|
|
||||||
], [
|
], [
|
||||||
MINIRUBY='./miniruby$(EXEEXT) -I$(srcdir)/lib -I.'
|
MINIRUBY='./miniruby$(EXEEXT) -I$(srcdir)/lib -I.'
|
||||||
MINIRUBY="$MINIRUBY"' -I$(EXTOUT)/common'
|
MINIRUBY="$MINIRUBY"' -I$(EXTOUT)/common'
|
||||||
@ -3938,11 +3788,6 @@ AS_CASE("$enable_shared", [yes], [
|
|||||||
AC_ARG_ENABLE(pie,
|
AC_ARG_ENABLE(pie,
|
||||||
AS_HELP_STRING([--disable-pie], [disable PIE feature]),
|
AS_HELP_STRING([--disable-pie], [disable PIE feature]),
|
||||||
[pie=$enableval], [pie=])
|
[pie=$enableval], [pie=])
|
||||||
AS_CASE(["$target_os"],
|
|
||||||
[nacl], [
|
|
||||||
# -pie implies -shared for NaCl.
|
|
||||||
pie=no
|
|
||||||
])
|
|
||||||
AS_IF([test "$GCC" = yes -a -z "$EXTSTATIC" -a "x$pie" != xno], [
|
AS_IF([test "$GCC" = yes -a -z "$EXTSTATIC" -a "x$pie" != xno], [
|
||||||
RUBY_TRY_CFLAGS(-fPIE, [pie=yes], [pie=no])
|
RUBY_TRY_CFLAGS(-fPIE, [pie=yes], [pie=no])
|
||||||
AS_IF([test "$pie" = yes], [
|
AS_IF([test "$pie" = yes], [
|
||||||
@ -4184,10 +4029,8 @@ AS_CASE(["$target_os"],
|
|||||||
AS_CASE(["$YACC"],[*yacc*], [
|
AS_CASE(["$YACC"],[*yacc*], [
|
||||||
XCFLAGS="$XCFLAGS -DYYMAXDEPTH=300"
|
XCFLAGS="$XCFLAGS -DYYMAXDEPTH=300"
|
||||||
YACC="$YACC -Nl40000 -Nm40000"
|
YACC="$YACC -Nl40000 -Nm40000"
|
||||||
])],
|
|
||||||
[nacl], [
|
|
||||||
FIRSTMAKEFILE=GNUmakefile:nacl/GNUmakefile.in
|
|
||||||
])
|
])
|
||||||
|
])
|
||||||
|
|
||||||
MINIOBJS="$MINIDLNOBJ"
|
MINIOBJS="$MINIDLNOBJ"
|
||||||
|
|
||||||
@ -4472,7 +4315,6 @@ AS_IF([test "${universal_binary-no}" = yes ], [
|
|||||||
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "universal."RUBY_PLATFORM_CPU"-"RUBY_PLATFORM_OS)
|
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "universal."RUBY_PLATFORM_CPU"-"RUBY_PLATFORM_OS)
|
||||||
], [
|
], [
|
||||||
arch="${target_cpu}-${target_os}"
|
arch="${target_cpu}-${target_os}"
|
||||||
AS_CASE(["$arch"], [le32-nacl], [arch="pnacl"])
|
|
||||||
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "$arch")
|
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "$arch")
|
||||||
])
|
])
|
||||||
|
|
||||||
|
4
dir.c
4
dir.c
@ -61,10 +61,6 @@
|
|||||||
# include "win32/dir.h"
|
# include "win32/dir.h"
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(__native_client__) && defined(NACL_NEWLIB)
|
|
||||||
# include "nacl/dirent.h"
|
|
||||||
# include "nacl/stat.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
37
file.c
37
file.c
@ -72,16 +72,6 @@ int flock(int, int);
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#if defined(__native_client__)
|
|
||||||
# if defined(NACL_NEWLIB)
|
|
||||||
# include "nacl/utime.h"
|
|
||||||
# include "nacl/stat.h"
|
|
||||||
# include "nacl/unistd.h"
|
|
||||||
# else
|
|
||||||
# undef HAVE_UTIMENSAT
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_MKDEV_H
|
#ifdef HAVE_SYS_MKDEV_H
|
||||||
#include <sys/mkdev.h>
|
#include <sys/mkdev.h>
|
||||||
#endif
|
#endif
|
||||||
@ -1322,15 +1312,6 @@ rb_group_member(GETGROUPS_T gid)
|
|||||||
#define USE_GETEUID 1
|
#define USE_GETEUID 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __native_client__
|
|
||||||
// Although the NaCl toolchain contain eaccess() is it not yet
|
|
||||||
// overridden by nacl_io.
|
|
||||||
// TODO(sbc): Remove this once eaccess() is wired up correctly
|
|
||||||
// in NaCl.
|
|
||||||
# undef HAVE_EACCESS
|
|
||||||
# undef USE_GETEUID
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_EACCESS
|
#ifndef HAVE_EACCESS
|
||||||
int
|
int
|
||||||
eaccess(const char *path, int mode)
|
eaccess(const char *path, int mode)
|
||||||
@ -3846,19 +3827,6 @@ rb_file_s_absolute_path(int argc, const VALUE *argv)
|
|||||||
return rb_file_absolute_path(argv[0], argc > 1 ? argv[1] : Qnil);
|
return rb_file_absolute_path(argv[0], argc > 1 ? argv[1] : Qnil);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __native_client__
|
|
||||||
VALUE
|
|
||||||
rb_realpath_internal(VALUE basedir, VALUE path, int strict)
|
|
||||||
{
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
VALUE
|
|
||||||
rb_check_realpath(VALUE basedir, VALUE path)
|
|
||||||
{
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
enum rb_realpath_mode {
|
enum rb_realpath_mode {
|
||||||
RB_REALPATH_CHECK,
|
RB_REALPATH_CHECK,
|
||||||
RB_REALPATH_DIR,
|
RB_REALPATH_DIR,
|
||||||
@ -3922,11 +3890,7 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved,
|
|||||||
else {
|
else {
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
int ret;
|
int ret;
|
||||||
#ifdef __native_client__
|
|
||||||
ret = stat(RSTRING_PTR(testpath), &sbuf);
|
|
||||||
#else
|
|
||||||
ret = lstat_without_gvl(RSTRING_PTR(testpath), &sbuf);
|
ret = lstat_without_gvl(RSTRING_PTR(testpath), &sbuf);
|
||||||
#endif
|
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
int e = errno;
|
int e = errno;
|
||||||
if (mode == RB_REALPATH_CHECK) return -1;
|
if (mode == RB_REALPATH_CHECK) return -1;
|
||||||
@ -4087,7 +4051,6 @@ rb_check_realpath(VALUE basedir, VALUE path)
|
|||||||
{
|
{
|
||||||
return rb_check_realpath_internal(basedir, path, RB_REALPATH_CHECK);
|
return rb_check_realpath_internal(basedir, path, RB_REALPATH_CHECK);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
|
6
gc.c
6
gc.c
@ -72,12 +72,6 @@
|
|||||||
|
|
||||||
#ifdef HAVE_SYS_RESOURCE_H
|
#ifdef HAVE_SYS_RESOURCE_H
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif
|
|
||||||
#if defined(__native_client__) && defined(NACL_NEWLIB)
|
|
||||||
# include "nacl/resource.h"
|
|
||||||
# undef HAVE_POSIX_MEMALIGN
|
|
||||||
# undef HAVE_MEMALIGN
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined _WIN32 || defined __CYGWIN__
|
#if defined _WIN32 || defined __CYGWIN__
|
||||||
|
4
gc.h
4
gc.h
@ -2,9 +2,9 @@
|
|||||||
#ifndef RUBY_GC_H
|
#ifndef RUBY_GC_H
|
||||||
#define RUBY_GC_H 1
|
#define RUBY_GC_H 1
|
||||||
|
|
||||||
#if defined(__x86_64__) && !defined(_ILP32) && defined(__GNUC__) && !defined(__native_client__)
|
#if defined(__x86_64__) && !defined(_ILP32) && defined(__GNUC__)
|
||||||
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movq\t%%rsp, %0" : "=r" (*(p)))
|
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movq\t%%rsp, %0" : "=r" (*(p)))
|
||||||
#elif defined(__i386) && defined(__GNUC__) && !defined(__native_client__)
|
#elif defined(__i386) && defined(__GNUC__)
|
||||||
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movl\t%%esp, %0" : "=r" (*(p)))
|
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movl\t%%esp, %0" : "=r" (*(p)))
|
||||||
#else
|
#else
|
||||||
NOINLINE(void rb_gc_set_stack_end(VALUE **stack_end_p));
|
NOINLINE(void rb_gc_set_stack_end(VALUE **stack_end_p));
|
||||||
|
15
io.c
15
io.c
@ -120,13 +120,6 @@
|
|||||||
off_t __syscall(quad_t number, ...);
|
off_t __syscall(quad_t number, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __native_client__
|
|
||||||
# undef F_GETFD
|
|
||||||
# ifdef NACL_NEWLIB
|
|
||||||
# undef HAVE_IOCTL
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define IO_RBUF_CAPA_MIN 8192
|
#define IO_RBUF_CAPA_MIN 8192
|
||||||
#define IO_CBUF_CAPA_MIN (128*1024)
|
#define IO_CBUF_CAPA_MIN (128*1024)
|
||||||
#define IO_RBUF_CAPA_FOR(fptr) (NEED_READCONV(fptr) ? IO_CBUF_CAPA_MIN : IO_RBUF_CAPA_MIN)
|
#define IO_RBUF_CAPA_FOR(fptr) (NEED_READCONV(fptr) ? IO_CBUF_CAPA_MIN : IO_RBUF_CAPA_MIN)
|
||||||
@ -9441,14 +9434,6 @@ typedef long fcntl_arg_t;
|
|||||||
typedef int fcntl_arg_t;
|
typedef int fcntl_arg_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined __native_client__ && !defined __GLIBC__
|
|
||||||
// struct flock is currently missing the NaCl newlib headers
|
|
||||||
// TODO(sbc): remove this once it gets added.
|
|
||||||
#undef F_GETLK
|
|
||||||
#undef F_SETLK
|
|
||||||
#undef F_SETLKW
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static long
|
static long
|
||||||
fcntl_narg_len(int cmd)
|
fcntl_narg_len(int cmd)
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "ruby/ruby.h"
|
#include "ruby/ruby.h"
|
||||||
|
|
||||||
#if defined _WIN32
|
#if defined _WIN32
|
||||||
#elif defined HAVE_FCNTL && defined HAVE_FCNTL_H && !defined(__native_client__)
|
#elif defined HAVE_FCNTL && defined HAVE_FCNTL_H
|
||||||
|
|
||||||
/* These are the flock() constants. Since this systems doesn't have
|
/* These are the flock() constants. Since this systems doesn't have
|
||||||
flock(), the values of the constants are probably not available.
|
flock(), the values of the constants are probably not available.
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
# Copyright 2012 Google Inc. All Rights Reserved.
|
|
||||||
# Author: yugui@google.com (Yugui Sonoda)
|
|
||||||
|
|
||||||
include Makefile
|
|
||||||
-include uncommon.mk
|
|
||||||
|
|
||||||
NACL_SDK_ROOT=@NACL_SDK_ROOT@
|
|
||||||
NACL_TOOLCHAIN=@NACL_TOOLCHAIN@
|
|
||||||
NACL_TOOLCHAIN_DIR=$(NACL_SDK_ROOT)/toolchain/$(NACL_TOOLCHAIN)
|
|
||||||
CXX=@CXX@
|
|
||||||
|
|
||||||
# Don't override CC/LD/etc if they are already set to absolute
|
|
||||||
# paths (this is the case when building in the naclports tree).
|
|
||||||
ifeq ($(dir $(CC)),./)
|
|
||||||
CC:=$(NACL_TOOLCHAIN_DIR)/bin/$(CC)
|
|
||||||
endif
|
|
||||||
ifeq ($(dir $(CXX)),./)
|
|
||||||
CXX:=$(NACL_TOOLCHAIN_DIR)/bin/$(CXX)
|
|
||||||
endif
|
|
||||||
ifeq ($(dir $(LD)),./)
|
|
||||||
LD:=$(NACL_TOOLCHAIN_DIR)/bin/$(LD)
|
|
||||||
endif
|
|
||||||
ifeq ($(dir $(NM)),./)
|
|
||||||
NM:=$(NACL_TOOLCHAIN_DIR)/bin/$(NM)
|
|
||||||
endif
|
|
||||||
ifeq ($(dir $(AR)),./)
|
|
||||||
AR:=$(NACL_TOOLCHAIN_DIR)/bin/$(AR)
|
|
||||||
endif
|
|
||||||
ifeq ($(dir $(AS)),./)
|
|
||||||
AS:=$(NACL_TOOLCHAIN_DIR)/bin/$(AS)
|
|
||||||
endif
|
|
||||||
ifeq ($(dir $(RANLIB)),./)
|
|
||||||
RANLIB:=$(NACL_TOOLCHAIN_DIR)/bin/$(RANLIB)
|
|
||||||
endif
|
|
||||||
ifeq ($(dir $(OBJDUMP)),./)
|
|
||||||
OBJDUMP:=$(NACL_TOOLCHAIN_DIR)/bin/$(OBJDUMP)
|
|
||||||
endif
|
|
||||||
ifeq ($(dir $(OBJCOPY)),./)
|
|
||||||
OBJCOPY:=$(NACL_TOOLCHAIN_DIR)/bin/$(OBJCOPY)
|
|
||||||
endif
|
|
||||||
PYTHON=@PYTHON@
|
|
||||||
|
|
||||||
PPROGRAM=pepper-$(PROGRAM)
|
|
||||||
PEPPER_LIBS=-lppapi -lnacl_io
|
|
||||||
PROGRAM_NMF=$(PROGRAM:$(EXEEXT)=.nmf)
|
|
||||||
PPROGRAM_NMF=$(PPROGRAM:$(EXEEXT)=.nmf)
|
|
||||||
|
|
||||||
GNUmakefile: $(srcdir)/nacl/GNUmakefile.in
|
|
||||||
$(PPROGRAM): $(PROGRAM) pepper_main.$(OBJEXT)
|
|
||||||
$(Q)$(MAKE) $(MFLAGS) PROGRAM=$(PPROGRAM) MAINOBJ="pepper_main.$(OBJEXT)" LIBS="$(LIBS) $(PEPPER_LIBS)" CC="$(CXX)" program
|
|
||||||
$(PROGRAM_NMF) $(PPROGRAM_NMF): $(@:.nmf=$(EXEEXT)) nacl/create_nmf.rb
|
|
||||||
|
|
||||||
.PHONY: pprogram package show_naclflags
|
|
||||||
.SUFFIXES: $(EXEEXT) .nmf
|
|
||||||
$(EXEEXT).nmf:
|
|
||||||
$(ECHO) generating manifest $@
|
|
||||||
$(Q)$(MINIRUBY) $(srcdir)/nacl/create_nmf.rb --verbose=$(V) $(@:.nmf=$(EXEEXT)) $@
|
|
||||||
|
|
||||||
pepper_main.$(OBJEXT): $(srcdir)/nacl/pepper_main.c
|
|
||||||
@$(ECHO) compiling nacl/pepper_main.c
|
|
||||||
$(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(srcdir)/nacl/pepper_main.c
|
|
||||||
|
|
||||||
.rbconfig.time:
|
|
||||||
@$(MAKE) .rbconfig.raw.time RBCONFIG=.rbconfig.raw.time
|
|
||||||
@sed \
|
|
||||||
-e 's!CONFIG\["CC"\] = .*!CONFIG\["CC"\] = "$(CC)"!' \
|
|
||||||
-e 's!CONFIG\["LD"\] = .*!CONFIG\["LD"\] = "$(LD)"!' \
|
|
||||||
-e 's!CONFIG\["NM"\] = .*!CONFIG\["NM"\] = "$(NM)"!' \
|
|
||||||
-e 's!CONFIG\["AR"\] = .*!CONFIG\["AR"\] = "$(AR)"!' \
|
|
||||||
-e 's!CONFIG\["AS"\] = .*!CONFIG\["AS"\] = "$(AS)"!' \
|
|
||||||
-e 's!CONFIG\["RANLIB"\] = .*!CONFIG\["RANLIB"\] = "$(RANLIB)"!' \
|
|
||||||
-e 's!CONFIG\["OBJDUMP"\] = .*!CONFIG\["OBJDUMP"\] = "$(OBJDUMP)"!' \
|
|
||||||
-e 's!CONFIG\["OBJCOPY"\] = .*!CONFIG\["OBJCOPY"\] = "$(OBJCOPY)"!' \
|
|
||||||
-i.bak rbconfig.rb
|
|
||||||
@touch .rbconfig.time
|
|
||||||
|
|
||||||
all: pprogram
|
|
||||||
main: $(PROGRAM_NMF)
|
|
||||||
pprogram: showflags $(PPROGRAM) $(PPROGRAM_NMF)
|
|
||||||
program: $(PROGRAM_NMF)
|
|
||||||
prog: pprogram
|
|
||||||
|
|
||||||
package: pprogram install-lib install-ext-comm install-ext-arch
|
|
||||||
$(INSTALL_DATA) $(srcdir)/nacl/example.html $(prefix)
|
|
||||||
$(ECHO) generating manifest $@
|
|
||||||
$(Q)$(MINIRUBY) $(srcdir)/nacl/package.rb $(prefix)
|
|
||||||
|
|
||||||
showflags: show_naclflags
|
|
||||||
|
|
||||||
show_naclflags:
|
|
||||||
@echo " NACL_SDK_ROOT = $(NACL_SDK_ROOT)"
|
|
||||||
@echo " NM = $(NM)"
|
|
||||||
@echo " AR = $(AR)"
|
|
||||||
@echo " AS = $(AS)"
|
|
||||||
@echo " RANLIB = $(RANLIB)"
|
|
||||||
@echo " OBJDUMP = $(OBJDUMP)"
|
|
||||||
@echo " OBJCOPY = $(OBJCOPY)"
|
|
||||||
|
|
||||||
clean-local::
|
|
||||||
-$(RM) $(PPROGRAM) pepper_main.$(OBJEXT) $(PROGRAM_NMF) $(PPRGORAM_NMF)
|
|
@ -1,51 +0,0 @@
|
|||||||
=begin
|
|
||||||
= Native Client port of Ruby
|
|
||||||
|
|
||||||
= How to build
|
|
||||||
== Prerequisites
|
|
||||||
You need to install the following things before building NaCl port of Ruby.
|
|
||||||
* Ruby 1.9.3 or later
|
|
||||||
* Python 2.6 or later
|
|
||||||
* NativeClient SDK pepper 37 or later
|
|
||||||
* GNU make
|
|
||||||
|
|
||||||
== Steps
|
|
||||||
(1) Extract all files from the tarball:
|
|
||||||
$ tar xzf ruby-X.Y.Z.tar.gz
|
|
||||||
(2) Set NACL_SDK_ROOT environment variable to the path to the Native Client SDK you installed:
|
|
||||||
$ export NACL_SDK_ROOT=/home/yugui/src/nacl_sdk/pepper_37
|
|
||||||
(3) Configure
|
|
||||||
$ ./configure --prefix=/tmp/nacl-ruby --host=x86_64-nacl --with-baseruby=/path/to/ruby-1.9.3-or-later
|
|
||||||
(4) Make
|
|
||||||
$ make
|
|
||||||
$ make package
|
|
||||||
|
|
||||||
Now you have ruby.nexe. You can run it by sel_ldr in NaCl SDK.
|
|
||||||
|
|
||||||
"make package" installs "pepper-ruby.nexe", an example Pepper application that
|
|
||||||
embeds Ruby", and libraries to $prefix. You can run it by the following steps:
|
|
||||||
(5) Publish the $prefix directory on a web server
|
|
||||||
(6) Visit the example.html on the web server by a browser that implements Pepper 18 or later.
|
|
||||||
-- e.g., Chrome 18 implements Pepper 18, Chrome 19 implements Pepper 19, ...
|
|
||||||
|
|
||||||
=== Example Configurations
|
|
||||||
* x86_32 Native Client
|
|
||||||
$ ./configure --prefix=/tmp/nacl-ruby \
|
|
||||||
--host=i686-nacl \
|
|
||||||
--with-baseruby=/path/to/ruby-1.9.3-or-later
|
|
||||||
* arm Native Client
|
|
||||||
$ ./configure --prefix=/tmp/nacl-ruby \
|
|
||||||
--host=arm-nacl \
|
|
||||||
--with-newlib \
|
|
||||||
--with-baseruby=/path/to/ruby-1.9.3-or-later
|
|
||||||
* Portable Native Client
|
|
||||||
$ ./configure --prefix=/tmp/nacl-ruby \
|
|
||||||
--host=le32-nacl \
|
|
||||||
--with-newlib \
|
|
||||||
--with-static-linked-ext \
|
|
||||||
--with-baseruby=/path/to/ruby-1.9.3-or-later
|
|
||||||
|
|
||||||
= Copyright
|
|
||||||
* Copyright 2012 Google Inc. All Rights Reserved.
|
|
||||||
* Author: yugui@google.com (Yugui Sonoda)
|
|
||||||
=end
|
|
@ -1,70 +0,0 @@
|
|||||||
#!/usr/bin/ruby
|
|
||||||
# Copyright:: Copyright 2012 Google Inc.
|
|
||||||
# License:: All Rights Reserved.
|
|
||||||
# Original Author:: Yugui Sonoda (mailto:yugui@google.com)
|
|
||||||
#
|
|
||||||
# Wrapper for create_nmf.py / generate_nmf.py
|
|
||||||
|
|
||||||
require File.join(File.dirname(__FILE__), 'nacl-config')
|
|
||||||
|
|
||||||
include NaClConfig
|
|
||||||
$verbosity = 0
|
|
||||||
|
|
||||||
def usage_and_exit
|
|
||||||
$stderr.puts "Usage: #{$PROGRAM_NAME} [--verbose=N] path/to/input.nexe path/to/output.nmf"
|
|
||||||
exit false
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_dynamically_linked(nmf, exe)
|
|
||||||
cmd = [
|
|
||||||
PYTHON, CREATE_NMF,
|
|
||||||
'-o', nmf,
|
|
||||||
'-D', OBJDUMP,
|
|
||||||
'-L', HOST_LIB,
|
|
||||||
exe
|
|
||||||
]
|
|
||||||
puts cmd.join(' ') if $verbosity > 0
|
|
||||||
exec(*cmd)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_statically_linked(nmf, exe)
|
|
||||||
File.open(nmf, "w") {|f|
|
|
||||||
f.write <<-EOS.gsub(/^ {6}/, '')
|
|
||||||
{
|
|
||||||
"program": {
|
|
||||||
"#{ARCH}": {
|
|
||||||
"url": "#{exe}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOS
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def main
|
|
||||||
while m = ARGV.first.match(/--([a-z-]+)(?:=(\S+))?/)
|
|
||||||
case m[1]
|
|
||||||
when 'verbose'
|
|
||||||
usage_and_exit unless m[2][/\A[0-9]+\z/]
|
|
||||||
$verbosity = m[2].to_i
|
|
||||||
when 'help'
|
|
||||||
usage_end_exit
|
|
||||||
end
|
|
||||||
ARGV.shift
|
|
||||||
end
|
|
||||||
|
|
||||||
usage_and_exit if ARGV.size < 2
|
|
||||||
|
|
||||||
exe, nmf = ARGV[0], ARGV[1]
|
|
||||||
if newlib?
|
|
||||||
create_statically_linked(nmf, exe)
|
|
||||||
else
|
|
||||||
create_dynamically_linked(nmf, exe)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if __FILE__ == $0
|
|
||||||
main()
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 Google Inc. All Rights Reserved.
|
|
||||||
* Author: yugui@google.com (Yugui Sonoda)
|
|
||||||
*/
|
|
||||||
#ifndef RUBY_NACL_DIRENT_H
|
|
||||||
#define RUBY_NACL_DIRENT_H
|
|
||||||
|
|
||||||
/* NaCl SDK 0.3 has implementations of dir functions but no declaration in
|
|
||||||
* dirent.h */
|
|
||||||
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
|
|
||||||
void rewinddir(DIR *dirp);
|
|
||||||
long telldir(DIR *dirp);
|
|
||||||
void seekdir(DIR *dirp, long offset);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,150 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Ruby Example</title>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
RubyModule = null; // Global application object.
|
|
||||||
statusText = 'NO-STATUS';
|
|
||||||
rubyReady = false;
|
|
||||||
|
|
||||||
// Indicate load success.
|
|
||||||
function moduleDidLoad() {
|
|
||||||
RubyModule = document.getElementById('ruby');
|
|
||||||
form = document.getElementById('source-form');
|
|
||||||
form.style.display = "block";
|
|
||||||
updateStatus('SUCCESS');
|
|
||||||
}
|
|
||||||
|
|
||||||
function evalSource() {
|
|
||||||
if (rubyReady) {
|
|
||||||
RubyModule.postMessage('eval:' + document.getElementById("source").value);
|
|
||||||
} else {
|
|
||||||
throw "Not yet ready";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function RubyError(message) {
|
|
||||||
this.message = message;
|
|
||||||
this.toString = function() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function FatalError(message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The 'message' event handler. This handler is fired when the NaCl module
|
|
||||||
// posts a message to the browser by calling PPB_Messaging.PostMessage()
|
|
||||||
// (in C) or pp::Instance.PostMessage() (in C++). This implementation
|
|
||||||
// simply displays the content of the message in an alert panel.
|
|
||||||
function handleMessage(message_event) {
|
|
||||||
var raw = message_event.data;
|
|
||||||
var components;
|
|
||||||
if (raw.indexOf("error") == 0) {
|
|
||||||
components = raw.split(":", 2);
|
|
||||||
throw new RubyError(components[1]);
|
|
||||||
} else if (raw.indexOf("return") == 0) {
|
|
||||||
components = raw.split(":", 2);
|
|
||||||
document.getElementById("result").value = components[1];
|
|
||||||
} else if (raw == "rubyReady") {
|
|
||||||
rubyReady = true;
|
|
||||||
} else {
|
|
||||||
throw new FatalError(raw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the page loads before the Native Client module loads, then set the
|
|
||||||
// status message indicating that the module is still loading. Otherwise,
|
|
||||||
// do not change the status message.
|
|
||||||
function pageDidLoad() {
|
|
||||||
if (RubyModule == null) {
|
|
||||||
updateStatus('LOADING...');
|
|
||||||
} else {
|
|
||||||
// It's possible that the Native Client module onload event fired
|
|
||||||
// before the page's onload event. In this case, the status message
|
|
||||||
// will reflect 'SUCCESS', but won't be displayed. This call will
|
|
||||||
// display the current message.
|
|
||||||
updateStatus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the global status message. If the element with id 'statusField'
|
|
||||||
// exists, then set its HTML to the status message as well.
|
|
||||||
// opt_message The message test. If this is null or undefined, then
|
|
||||||
// attempt to set the element with id 'statusField' to the value of
|
|
||||||
// |statusText|.
|
|
||||||
function updateStatus(opt_message) {
|
|
||||||
if (opt_message)
|
|
||||||
statusText = opt_message;
|
|
||||||
var statusField = document.getElementById('status_field');
|
|
||||||
if (statusField) {
|
|
||||||
statusField.innerHTML = statusText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload="pageDidLoad()">
|
|
||||||
|
|
||||||
<h1>Native Client Module Ruby</h1>
|
|
||||||
<p>
|
|
||||||
<!-- Load the published .nexe. This includes the 'nacl' attribute which
|
|
||||||
shows how to load multi-architecture modules. Each entry in the "nexes"
|
|
||||||
object in the .nmf manifest file is a key-value pair: the key is the
|
|
||||||
instruction set architecture ('x86-32', 'x86-64', etc.); the value is a URL
|
|
||||||
for the desired NaCl module.
|
|
||||||
To load the debug versions of your .nexes, set the 'nacl' attribute to the
|
|
||||||
_dbg.nmf version of the manifest file.
|
|
||||||
|
|
||||||
Note: Since this NaCl module does not use any real-estate in the browser,
|
|
||||||
it's width and height are set to 0.
|
|
||||||
|
|
||||||
Note: The <EMBED> element is wrapped inside a <DIV>, which has both a 'load'
|
|
||||||
and a 'message' event listener attached. This wrapping method is used
|
|
||||||
instead of attaching the event listeners directly to the <EMBED> element to
|
|
||||||
ensure that the listeners are active before the NaCl module 'load' event
|
|
||||||
fires. This also allows you to use PPB_Messaging.PostMessage() (in C) or
|
|
||||||
pp::Instance.PostMessage() (in C++) from within the initialization code in
|
|
||||||
your NaCl module.
|
|
||||||
-->
|
|
||||||
<div id="listener">
|
|
||||||
<script type="text/javascript">
|
|
||||||
var listener = document.getElementById('listener');
|
|
||||||
listener.addEventListener('load', moduleDidLoad, true);
|
|
||||||
listener.addEventListener('message', handleMessage, true);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<embed name="nacl_module"
|
|
||||||
id="ruby"
|
|
||||||
width="0" height="0"
|
|
||||||
src="ruby.nmf"
|
|
||||||
type="application/x-nacl" />
|
|
||||||
<form id="source-form" action="#" method="post" style="display:none"
|
|
||||||
onsubmit="evalSource(); return false">
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th>Source</th>
|
|
||||||
<td>
|
|
||||||
<textarea rows="10" cols="80" id="source"></textarea>
|
|
||||||
<input type="submit" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Result</th>
|
|
||||||
<td>
|
|
||||||
<textarea rows="10" cols="80" id="result"></textarea>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Status</h2>
|
|
||||||
<div id="status_field">NO-STATUS</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,61 +0,0 @@
|
|||||||
#!/usr/bin/ruby
|
|
||||||
#
|
|
||||||
# Copyright:: Copyright 2012 Google Inc.
|
|
||||||
# License:: All Rights Reserved.
|
|
||||||
# Original Author:: Yugui Sonoda (mailto:yugui@google.com)
|
|
||||||
#
|
|
||||||
# Convenient functions/constants for native client specific configurations.
|
|
||||||
require 'rbconfig'
|
|
||||||
|
|
||||||
module NaClConfig
|
|
||||||
config = RbConfig::CONFIG
|
|
||||||
|
|
||||||
cpu_nick = config['host_alias'].sub(/-gnu$|-newlib$/, '').sub(/-nacl$/, '').sub(/i.86/, 'x86_32')
|
|
||||||
ARCH = cpu_nick.sub('x86_64', 'x86-64').sub('x86_32', 'x86-32')
|
|
||||||
HOST = ARCH.sub(/x86-../, 'x86_64') + '-nacl'
|
|
||||||
|
|
||||||
lib_suffix = config['host_cpu'][/i.86/] ? '32' : ''
|
|
||||||
PYTHON = config['PYTHON']
|
|
||||||
OBJDUMP = config['OBJDUMP']
|
|
||||||
SDK_ROOT = config['NACL_SDK_ROOT']
|
|
||||||
CREATE_NMF = [
|
|
||||||
File.join(SDK_ROOT, 'build_tools', 'nacl_sdk_scons', 'site_tools', 'create_nmf.py'),
|
|
||||||
File.join(SDK_ROOT, 'tools', 'create_nmf.py')
|
|
||||||
].find{|path| File.exist?(path) } or raise "No create_nmf found"
|
|
||||||
HOST_LIB = File.join(SDK_ROOT, 'toolchain', config['NACL_TOOLCHAIN'], HOST, "lib#{lib_suffix}")
|
|
||||||
|
|
||||||
NACL_LIB = File.join(SDK_ROOT, 'lib', config['NACL_LIB_PATH'], 'Release')
|
|
||||||
|
|
||||||
INSTALL_PROGRAM = config['INSTALL_PROGRAM']
|
|
||||||
INSTALL_LIBRARY = config['INSTALL_DATA']
|
|
||||||
|
|
||||||
if cpu_nick == 'x86_64' or cpu_nick == 'x86_32'
|
|
||||||
SEL_LDR = File.join(SDK_ROOT, 'tools', "sel_ldr_#{cpu_nick}")
|
|
||||||
IRT_CORE = File.join(SDK_ROOT, 'tools', "irt_core_#{cpu_nick}.nexe")
|
|
||||||
raise "No sel_ldr found" if not File.executable?(SEL_LDR)
|
|
||||||
raise "No irt_core found" if not File.exists?(IRT_CORE)
|
|
||||||
end
|
|
||||||
RUNNABLE_LD = File.join(HOST_LIB, 'runnable-ld.so')
|
|
||||||
|
|
||||||
module_function
|
|
||||||
|
|
||||||
def newlib?
|
|
||||||
RbConfig::CONFIG['NACL_SDK_VARIANT'] == 'newlib'
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.config(name)
|
|
||||||
if NaClConfig::const_defined?(name.upcase)
|
|
||||||
NaClConfig::const_get(name.upcase)
|
|
||||||
elsif NaClConfig::respond_to?(name) and NaClConfig::method(name).arity == 0
|
|
||||||
NaClConfig::send(name)
|
|
||||||
else
|
|
||||||
raise ArgumentError, "No such config: #{name}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if $0 == __FILE__
|
|
||||||
ARGV.each do |arg|
|
|
||||||
puts NaClConfig::config(arg)
|
|
||||||
end
|
|
||||||
end
|
|
113
nacl/package.rb
113
nacl/package.rb
@ -1,113 +0,0 @@
|
|||||||
#!/usr/bin/ruby
|
|
||||||
# Copyright:: Copyright 2012 Google Inc.
|
|
||||||
# License:: All Rights Reserved.
|
|
||||||
# Original Author:: Yugui Sonoda (mailto:yugui@google.com)
|
|
||||||
#
|
|
||||||
# Generates a runnable package of the pepper API example.
|
|
||||||
|
|
||||||
require File.join(File.dirname(__FILE__), 'nacl-config')
|
|
||||||
require 'json'
|
|
||||||
require 'find'
|
|
||||||
require 'fileutils'
|
|
||||||
|
|
||||||
include NaClConfig
|
|
||||||
|
|
||||||
class Installation
|
|
||||||
include NaClConfig
|
|
||||||
|
|
||||||
SRC_DIRS = [
|
|
||||||
Dir.pwd,
|
|
||||||
HOST_LIB,
|
|
||||||
NACL_LIB,
|
|
||||||
]
|
|
||||||
|
|
||||||
def initialize(destdir)
|
|
||||||
@destdir = destdir
|
|
||||||
@manifest = {
|
|
||||||
"files" => {}
|
|
||||||
}
|
|
||||||
ruby_libs.each do |path|
|
|
||||||
raise "Collision of #{path}" if @manifest['files'].key? path
|
|
||||||
@manifest['files'][path] = {
|
|
||||||
ARCH => {
|
|
||||||
"url" => path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if path[/\.so$/]
|
|
||||||
alternate_path = path.gsub('/', "_")
|
|
||||||
raise "Collision of #{alternate_path}" if @manifest['files'].key? alternate_path
|
|
||||||
@manifest['files'][alternate_path] = {
|
|
||||||
ARCH => {
|
|
||||||
"url" => path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def manifest
|
|
||||||
@manifest.dup
|
|
||||||
end
|
|
||||||
|
|
||||||
def install_program(basename)
|
|
||||||
do_install_binary(basename, File.join(@destdir, "bin", ARCH))
|
|
||||||
@manifest["program"] = {
|
|
||||||
ARCH => {
|
|
||||||
"url" => File.join("bin", ARCH, basename)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def install_library(name, basename)
|
|
||||||
do_install_binary(basename, File.join(@destdir, "lib", ARCH))
|
|
||||||
@manifest["files"][name] = {
|
|
||||||
ARCH => {
|
|
||||||
"url" => File.join("lib", ARCH, basename)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def do_install_binary(basename, dest_dir)
|
|
||||||
full_path = nil
|
|
||||||
catch(:found) {
|
|
||||||
SRC_DIRS.each do |path|
|
|
||||||
full_path = File.join(path, basename)
|
|
||||||
if File.exist? full_path
|
|
||||||
throw :found
|
|
||||||
end
|
|
||||||
end
|
|
||||||
raise Errno::ENOENT, "No such file to install: %s" % basename
|
|
||||||
}
|
|
||||||
FileUtils.mkdir_p dest_dir
|
|
||||||
system("#{INSTALL_PROGRAM} #{full_path} #{dest_dir}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def ruby_libs
|
|
||||||
Find.find(RbConfig::CONFIG['rubylibdir']).select{|path| File.file?(path) }.map{|path| path.sub("#{@destdir}/", "") }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def install(destdir)
|
|
||||||
inst = Installation.new(destdir)
|
|
||||||
manifest = JSON.parse(File.read("pepper-ruby.nmf"))
|
|
||||||
|
|
||||||
program = File.basename(manifest['program'][ARCH]['url'])
|
|
||||||
inst.install_program(program)
|
|
||||||
|
|
||||||
manifest['files'].each do |name, attr|
|
|
||||||
inst.install_library(name, File.basename(attr[ARCH]["url"]))
|
|
||||||
end
|
|
||||||
|
|
||||||
File.open(File.join(destdir, "ruby.nmf"), "w") {|f|
|
|
||||||
f.puts JSON.pretty_generate(inst.manifest)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def main
|
|
||||||
install(ARGV[0])
|
|
||||||
end
|
|
||||||
|
|
||||||
if __FILE__ == $0
|
|
||||||
main()
|
|
||||||
end
|
|
@ -1,732 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
Copyright 2012 Google Inc. All Rights Reserved.
|
|
||||||
Author: yugui@google.com (Yugui Sonoda)
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include "ppapi/c/pp_errors.h"
|
|
||||||
#include "ppapi/c/pp_module.h"
|
|
||||||
#include "ppapi/c/pp_var.h"
|
|
||||||
#include "ppapi/c/ppb.h"
|
|
||||||
#include "ppapi/c/ppb_core.h"
|
|
||||||
#include "ppapi/c/ppb_file_ref.h"
|
|
||||||
#include "ppapi/c/ppb_instance.h"
|
|
||||||
#include "ppapi/c/ppb_messaging.h"
|
|
||||||
#include "ppapi/c/ppb_url_loader.h"
|
|
||||||
#include "ppapi/c/ppb_url_request_info.h"
|
|
||||||
#include "ppapi/c/ppb_url_response_info.h"
|
|
||||||
#include "ppapi/c/ppb_var.h"
|
|
||||||
#include "ppapi/c/ppp.h"
|
|
||||||
#include "ppapi/c/ppp_instance.h"
|
|
||||||
#include "ppapi/c/ppp_messaging.h"
|
|
||||||
#include "nacl_io/nacl_io.h"
|
|
||||||
|
|
||||||
#include "verconf.h"
|
|
||||||
#include "ruby/ruby.h"
|
|
||||||
#include "version.h"
|
|
||||||
#include "gc.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_PPB_CORE
|
|
||||||
typedef struct PPB_Core PPB_Core;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STRUCT_PPB_MESSAGING
|
|
||||||
typedef struct PPB_Messaging PPB_Messaging;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STRUCT_PPB_VAR
|
|
||||||
typedef struct PPB_Var PPB_Var;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STRUCT_PPB_URLLOADER
|
|
||||||
typedef struct PPB_URLLoader PPB_URLLoader;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STRUCT_PPB_URLREQUESTINFO
|
|
||||||
typedef struct PPB_URLRequestInfo PPB_URLRequestInfo;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STRUCT_PPB_URLRESPONSEINFO
|
|
||||||
typedef struct PPB_URLResponseInfo PPB_URLResponseInfo;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STRUCT_PPP_INSTANCE
|
|
||||||
typedef struct PPP_Instance PPP_Instance;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static PP_Module module_id = 0;
|
|
||||||
static PPB_GetInterface get_browser_interface = NULL;
|
|
||||||
static PPB_Core* core_interface = NULL;
|
|
||||||
static PPB_Messaging* messaging_interface = NULL;
|
|
||||||
static PPB_Var* var_interface = NULL;
|
|
||||||
static PPB_URLLoader* loader_interface = NULL;
|
|
||||||
static PPB_URLRequestInfo* request_interface = NULL;
|
|
||||||
static PPB_URLResponseInfo* response_interface = NULL;
|
|
||||||
static PPB_FileRef* fileref_interface = NULL;
|
|
||||||
static struct st_table* instance_data = NULL;
|
|
||||||
|
|
||||||
static VALUE instance_table = Qundef;
|
|
||||||
|
|
||||||
static PP_Instance current_instance = 0;
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* State of instance
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static void inst_mark(void *const ptr);
|
|
||||||
static void inst_free(void *const ptr);
|
|
||||||
static size_t inst_memsize(void *const ptr);
|
|
||||||
static const rb_data_type_t pepper_instance_data_type = {
|
|
||||||
"PepperInstance",
|
|
||||||
{ inst_mark, inst_free, inst_memsize }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PepperInstance {
|
|
||||||
PP_Instance instance;
|
|
||||||
PP_Resource url_loader;
|
|
||||||
VALUE self;
|
|
||||||
void* async_call_args;
|
|
||||||
union {
|
|
||||||
int32_t as_int;
|
|
||||||
const char* as_str;
|
|
||||||
VALUE as_value;
|
|
||||||
} async_call_result;
|
|
||||||
char buf[1000];
|
|
||||||
|
|
||||||
pthread_t th;
|
|
||||||
pthread_mutex_t mutex;
|
|
||||||
pthread_cond_t cond;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PepperInstance*
|
|
||||||
pruby_get_instance(PP_Instance instance)
|
|
||||||
{
|
|
||||||
VALUE self = rb_hash_aref(instance_table, INT2FIX(instance));
|
|
||||||
if (RTEST(self)) {
|
|
||||||
struct PepperInstance *inst;
|
|
||||||
TypedData_Get_Struct(self, struct PepperInstance, &pepper_instance_data_type, inst);
|
|
||||||
return inst;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GET_PEPPER_INSTANCE() (pruby_get_instance(current_instance))
|
|
||||||
|
|
||||||
struct PepperInstance*
|
|
||||||
pruby_register_instance(PP_Instance instance)
|
|
||||||
{
|
|
||||||
VALUE obj;
|
|
||||||
struct PepperInstance *data;
|
|
||||||
obj = TypedData_Make_Struct(rb_cData, struct PepperInstance, &pepper_instance_data_type, data);
|
|
||||||
data->self = obj;
|
|
||||||
data->instance = instance;
|
|
||||||
data->url_loader = 0;
|
|
||||||
|
|
||||||
pthread_mutex_init(&data->mutex, NULL);
|
|
||||||
pthread_cond_init(&data->cond, NULL);
|
|
||||||
|
|
||||||
rb_hash_aset(instance_table, INT2FIX(instance), obj);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
pruby_unregister_instance(PP_Instance instance)
|
|
||||||
{
|
|
||||||
VALUE inst = rb_hash_delete(instance_table, INT2FIX(instance));
|
|
||||||
return RTEST(inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
inst_mark(void *const ptr)
|
|
||||||
{
|
|
||||||
RUBY_MARK_ENTER("PepperInstance"0);
|
|
||||||
if (ptr) {
|
|
||||||
const struct PepperInstance* inst = (struct PepperInstance*)ptr;
|
|
||||||
RUBY_MARK_UNLESS_NULL(inst->async_call_result.as_value);
|
|
||||||
}
|
|
||||||
RUBY_MARK_LEAVE("PepperInstance"0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
inst_free(void *const ptr)
|
|
||||||
{
|
|
||||||
ruby_xfree(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
inst_memsize(void *const ptr)
|
|
||||||
{
|
|
||||||
if (ptr) {
|
|
||||||
const struct PepperInstance* inst = (struct PepperInstance*)ptr;
|
|
||||||
return sizeof(*inst);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pruby_async_return_int(void* data, int32_t result)
|
|
||||||
{
|
|
||||||
/* PPAPI main thread */
|
|
||||||
struct PepperInstance* const instance = (struct PepperInstance*)data;
|
|
||||||
instance->async_call_result.as_int = result;
|
|
||||||
if (pthread_cond_signal(&instance->cond)) {
|
|
||||||
perror("pepper-ruby:pthread_cond_signal");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pruby_async_return_str(void* data, const char *result)
|
|
||||||
{
|
|
||||||
/* PPAPI main thread */
|
|
||||||
struct PepperInstance* const instance = (struct PepperInstance*)data;
|
|
||||||
instance->async_call_result.as_str = result;
|
|
||||||
if (pthread_cond_signal(&instance->cond)) {
|
|
||||||
perror("pepper-ruby:pthread_cond_signal");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pruby_async_return_value(void* data, VALUE value)
|
|
||||||
{
|
|
||||||
/* PPAPI main thread */
|
|
||||||
struct PepperInstance* const instance = (struct PepperInstance*)data;
|
|
||||||
instance->async_call_result.as_value = value;
|
|
||||||
if (pthread_cond_signal(&instance->cond)) {
|
|
||||||
perror("pepper-ruby:pthread_cond_signal");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/******************************************************************************
|
|
||||||
* Conversion between Ruby's VALUE, Pepper's Var and C string
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new string PP_Var from C string. The resulting object will be a
|
|
||||||
* refcounted string object. It will be AddRef()ed for the caller. When the
|
|
||||||
* caller is done with it, it should be Release()d.
|
|
||||||
* @param[in] str C string to be converted to PP_Var
|
|
||||||
* @return PP_Var containing string.
|
|
||||||
*/
|
|
||||||
static struct PP_Var
|
|
||||||
pruby_cstr_to_var(const char* str)
|
|
||||||
{
|
|
||||||
#ifndef PPB_VAR_INTERFACE_1_1
|
|
||||||
if (var_interface != NULL)
|
|
||||||
return var_interface->VarFromUtf8(module_id, str, strlen(str));
|
|
||||||
return PP_MakeUndefined();
|
|
||||||
#else
|
|
||||||
return var_interface->VarFromUtf8(str, strlen(str));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a mutable C string contained in the @a var or NULL if @a var is not
|
|
||||||
* string. This makes a copy of the string in the @a var and adds a NULL
|
|
||||||
* terminator. Note that VarToUtf8() does not guarantee the NULL terminator on
|
|
||||||
* the returned string. See the comments for VarToUtf8() in ppapi/c/ppb_var.h
|
|
||||||
* for more info. The caller is responsible for freeing the returned memory.
|
|
||||||
* @param[in] var PP_Var containing string.
|
|
||||||
* @return a mutable C string representation of @a var.
|
|
||||||
* @note The caller is responsible for freeing the returned string.
|
|
||||||
*/
|
|
||||||
static char*
|
|
||||||
pruby_var_to_cstr(struct PP_Var var)
|
|
||||||
{
|
|
||||||
uint32_t len = 0;
|
|
||||||
if (var_interface != NULL) {
|
|
||||||
const char* var_c_str = var_interface->VarToUtf8(var, &len);
|
|
||||||
if (len > 0) {
|
|
||||||
char* c_str = (char*)malloc(len + 1);
|
|
||||||
memcpy(c_str, var_c_str, len);
|
|
||||||
c_str[len] = '\0';
|
|
||||||
return c_str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct PP_Var
|
|
||||||
pruby_str_to_var(volatile VALUE str)
|
|
||||||
{
|
|
||||||
if (!RB_TYPE_P(str, T_STRING)) {
|
|
||||||
fprintf(stderr, "[BUG] Unexpected object type: %x\n", TYPE(str));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
#ifndef PPB_VAR_INTERFACE_1_1
|
|
||||||
if (var_interface != NULL) {
|
|
||||||
return var_interface->VarFromUtf8(module_id, RSTRING_PTR(str), RSTRING_LEN(str));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return var_interface->VarFromUtf8(RSTRING_PTR(str), RSTRING_LEN(str));
|
|
||||||
#endif
|
|
||||||
return PP_MakeUndefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct PP_Var
|
|
||||||
pruby_obj_to_var(volatile VALUE obj)
|
|
||||||
{
|
|
||||||
static const char* const error =
|
|
||||||
"throw 'Failed to convert the result to a JavaScript object';";
|
|
||||||
int state;
|
|
||||||
obj = rb_protect(&rb_obj_as_string, obj, &state);
|
|
||||||
if (!state) {
|
|
||||||
return pruby_str_to_var(obj);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return pruby_cstr_to_var(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
pruby_var_equal_to_cstr_p(struct PP_Var lhs, const char* rhs)
|
|
||||||
{
|
|
||||||
uint32_t len = 0;
|
|
||||||
if (var_interface == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const char* const cstr = var_interface->VarToUtf8(lhs, &len);
|
|
||||||
return strncmp(cstr, rhs, len) == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
pruby_var_prefixed_p(struct PP_Var var, const char* prefix)
|
|
||||||
{
|
|
||||||
uint32_t len = 0;
|
|
||||||
if (var_interface == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const char* const cstr = var_interface->VarToUtf8(var, &len);
|
|
||||||
const size_t prefix_len = strlen(prefix);
|
|
||||||
return len >= prefix_len && memcmp(cstr, prefix, len) == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Messaging
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* Posts the given C string as a message.
|
|
||||||
* @param data pointer to a NULL-terminated string */
|
|
||||||
void
|
|
||||||
pruby_post_cstr(void* data)
|
|
||||||
{
|
|
||||||
/* PPAPI main thread */
|
|
||||||
struct PepperInstance* const instance = (struct PepperInstance*)data;
|
|
||||||
const char* const msg = (const char*)instance->async_call_args;
|
|
||||||
messaging_interface->PostMessage(instance->instance,
|
|
||||||
pruby_cstr_to_var(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Posts the given Ruby VALUE as a message.
|
|
||||||
* @param data a VALUE casted to void* */
|
|
||||||
void
|
|
||||||
pruby_post_value(void* data)
|
|
||||||
{
|
|
||||||
/* PPAPI main thread */
|
|
||||||
struct PepperInstance* const instance = (struct PepperInstance*)data;
|
|
||||||
volatile VALUE value = (VALUE)instance->async_call_args;
|
|
||||||
messaging_interface->PostMessage(instance->instance, pruby_obj_to_var(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Ruby initialization
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static void
|
|
||||||
init_loadpath(void)
|
|
||||||
{
|
|
||||||
ruby_incpush("lib/ruby/"RUBY_LIB_VERSION);
|
|
||||||
ruby_incpush("lib/ruby/"RUBY_LIB_VERSION"/"RUBY_PLATFORM);
|
|
||||||
ruby_incpush(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
|
||||||
init_libraries_internal(VALUE unused)
|
|
||||||
{
|
|
||||||
extern void Init_enc();
|
|
||||||
extern void Init_ext();
|
|
||||||
|
|
||||||
init_loadpath();
|
|
||||||
Init_enc();
|
|
||||||
Init_ext();
|
|
||||||
return Qnil;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
init_libraries(void* data)
|
|
||||||
{
|
|
||||||
int state;
|
|
||||||
struct PepperInstance* const instance = (struct PepperInstance*)data;
|
|
||||||
current_instance = instance->instance;
|
|
||||||
|
|
||||||
if (pthread_mutex_lock(&instance->mutex)) {
|
|
||||||
perror("pepper-ruby:pthread_mutex_lock");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
rb_protect(&init_libraries_internal, Qnil, &state);
|
|
||||||
pthread_mutex_unlock(&instance->mutex);
|
|
||||||
|
|
||||||
if (state) {
|
|
||||||
volatile VALUE err = rb_errinfo();
|
|
||||||
err = rb_obj_as_string(err);
|
|
||||||
} else {
|
|
||||||
instance->async_call_args = (void*)"rubyReady";
|
|
||||||
core_interface->CallOnMainThread(
|
|
||||||
0, PP_MakeCompletionCallback(pruby_post_cstr, instance), 0);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
init_libraries_if_necessary(void)
|
|
||||||
{
|
|
||||||
static int initialized = 0;
|
|
||||||
if (!initialized) {
|
|
||||||
struct PepperInstance* const instance = GET_PEPPER_INSTANCE();
|
|
||||||
int err;
|
|
||||||
initialized = 1;
|
|
||||||
err = pthread_create(&instance->th, NULL, &init_libraries, instance);
|
|
||||||
if (err) {
|
|
||||||
fprintf(stderr, "pepper_ruby:pthread_create: %s\n", strerror(err));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
pthread_detach(instance->th);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
reopen_fd(int fd, const char* path, int flags) {
|
|
||||||
int fd2 = open(path, flags);
|
|
||||||
if (fd2 < 0) {
|
|
||||||
perror("open fd");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (dup2(fd2, fd) < 0) {
|
|
||||||
perror("dup2 fd");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (close(fd2)) {
|
|
||||||
perror("close old fd");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
pruby_init(void)
|
|
||||||
{
|
|
||||||
RUBY_INIT_STACK;
|
|
||||||
ruby_init();
|
|
||||||
|
|
||||||
instance_table = rb_hash_new();
|
|
||||||
rb_gc_register_mark_object(instance_table);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Ruby evaluation
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static void*
|
|
||||||
pruby_eval(void* data)
|
|
||||||
{
|
|
||||||
extern VALUE ruby_eval_string_from_file_protect(const char* src, const char* path, int* state);
|
|
||||||
struct PepperInstance* const instance = (struct PepperInstance*)data;
|
|
||||||
volatile VALUE src = (VALUE)instance->async_call_args;
|
|
||||||
volatile VALUE result = Qnil;
|
|
||||||
volatile int state;
|
|
||||||
|
|
||||||
RUBY_INIT_STACK;
|
|
||||||
|
|
||||||
if (pthread_mutex_lock(&instance->mutex)) {
|
|
||||||
perror("pepper-ruby:pthread_mutex_lock");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
result = ruby_eval_string_from_file_protect(
|
|
||||||
RSTRING_PTR(src), "(pepper-ruby)", &state);
|
|
||||||
pthread_mutex_unlock(&instance->mutex);
|
|
||||||
|
|
||||||
if (!state) {
|
|
||||||
instance->async_call_args =
|
|
||||||
rb_str_concat(rb_usascii_str_new_cstr("return:"),
|
|
||||||
rb_obj_as_string(result));
|
|
||||||
core_interface->CallOnMainThread(
|
|
||||||
0, PP_MakeCompletionCallback(pruby_post_value, instance), 0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rb_set_errinfo(Qnil);
|
|
||||||
instance->async_call_args =
|
|
||||||
rb_str_concat(rb_usascii_str_new_cstr("error:"),
|
|
||||||
rb_obj_as_string(result));
|
|
||||||
core_interface->CallOnMainThread(
|
|
||||||
0, PP_MakeCompletionCallback(pruby_post_value, instance), 0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Pepper Module callbacks
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the NaCl module is instantiated on the web page. The identifier
|
|
||||||
* of the new instance will be passed in as the first argument (this value is
|
|
||||||
* generated by the browser and is an opaque handle). This is called for each
|
|
||||||
* instantiation of the NaCl module, which is each time the <embed> tag for
|
|
||||||
* this module is encountered.
|
|
||||||
*
|
|
||||||
* If this function reports a failure (by returning @a PP_FALSE), the NaCl
|
|
||||||
* module will be deleted and DidDestroy will be called.
|
|
||||||
* @param[in] instance The identifier of the new instance representing this
|
|
||||||
* NaCl module.
|
|
||||||
* @param[in] argc The number of arguments contained in @a argn and @a argv.
|
|
||||||
* @param[in] argn An array of argument names. These argument names are
|
|
||||||
* supplied in the <embed> tag, for example:
|
|
||||||
* <embed id="nacl_module" dimensions="2">
|
|
||||||
* will produce two arguments, one named "id" and one named "dimensions".
|
|
||||||
* @param[in] argv An array of argument values. These are the values of the
|
|
||||||
* arguments listed in the <embed> tag. In the above example, there will
|
|
||||||
* be two elements in this array, "nacl_module" and "2". The indices of
|
|
||||||
* these values match the indices of the corresponding names in @a argn.
|
|
||||||
* @return @a PP_TRUE on success.
|
|
||||||
*/
|
|
||||||
static PP_Bool
|
|
||||||
Instance_DidCreate(PP_Instance instance,
|
|
||||||
uint32_t argc, const char* argn[], const char* argv[])
|
|
||||||
{
|
|
||||||
struct PepperInstance* data = pruby_register_instance(instance);
|
|
||||||
current_instance = instance;
|
|
||||||
|
|
||||||
nacl_io_init_ppapi(instance, get_browser_interface);
|
|
||||||
|
|
||||||
if (mount("", "/dev2", "dev", 0, "")) {
|
|
||||||
perror("mount dev");
|
|
||||||
return PP_FALSE;
|
|
||||||
}
|
|
||||||
if (reopen_fd(0, "/dev2/stdin", O_RDONLY) < 0) {
|
|
||||||
perror("reopen stdin");
|
|
||||||
return PP_FALSE;
|
|
||||||
}
|
|
||||||
if (reopen_fd(1, "/dev2/stdout", O_WRONLY) < 0) {
|
|
||||||
perror("reopen stdout");
|
|
||||||
return PP_FALSE;
|
|
||||||
}
|
|
||||||
if (reopen_fd(2, "/dev2/console1", O_WRONLY) < 0) {
|
|
||||||
perror("reopen stderr");
|
|
||||||
return PP_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO(yugui) Unmount original /dev */
|
|
||||||
|
|
||||||
if (mount("/lib", "/lib", "httpfs",
|
|
||||||
0, "allow_cross_origin_requests=false")) {
|
|
||||||
perror("mount httpfs");
|
|
||||||
return PP_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return init_libraries_if_necessary() ? PP_FALSE : PP_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the NaCl module is destroyed. This will always be called,
|
|
||||||
* even if DidCreate returned failure. This routine should deallocate any data
|
|
||||||
* associated with the instance.
|
|
||||||
* @param[in] instance The identifier of the instance representing this NaCl
|
|
||||||
* module.
|
|
||||||
*/
|
|
||||||
static void Instance_DidDestroy(PP_Instance instance) {
|
|
||||||
struct PepperInstance* data = pruby_get_instance(instance);
|
|
||||||
core_interface->ReleaseResource(data->url_loader);
|
|
||||||
pruby_unregister_instance(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the position, the size, or the clip rect of the element in the
|
|
||||||
* browser that corresponds to this NaCl module has changed.
|
|
||||||
* @param[in] instance The identifier of the instance representing this NaCl
|
|
||||||
* module.
|
|
||||||
* @param[in] position The location on the page of this NaCl module. This is
|
|
||||||
* relative to the top left corner of the viewport, which changes as the
|
|
||||||
* page is scrolled.
|
|
||||||
* @param[in] clip The visible region of the NaCl module. This is relative to
|
|
||||||
* the top left of the plugin's coordinate system (not the page). If the
|
|
||||||
* plugin is invisible, @a clip will be (0, 0, 0, 0).
|
|
||||||
*/
|
|
||||||
#ifndef PPP_INSTANCE_INTERFACE_1_1
|
|
||||||
static void
|
|
||||||
Instance_DidChangeView(PP_Instance instance,
|
|
||||||
const struct PP_Rect* position,
|
|
||||||
const struct PP_Rect* clip)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static void
|
|
||||||
Instance_DidChangeView(PP_Instance instance, PP_Resource view_resource)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notification that the given NaCl module has gained or lost focus.
|
|
||||||
* Having focus means that keyboard events will be sent to the NaCl module
|
|
||||||
* represented by @a instance. A NaCl module's default condition is that it
|
|
||||||
* will not have focus.
|
|
||||||
*
|
|
||||||
* Note: clicks on NaCl modules will give focus only if you handle the
|
|
||||||
* click event. You signal if you handled it by returning @a true from
|
|
||||||
* HandleInputEvent. Otherwise the browser will bubble the event and give
|
|
||||||
* focus to the element on the page that actually did end up consuming it.
|
|
||||||
* If you're not getting focus, check to make sure you're returning true from
|
|
||||||
* the mouse click in HandleInputEvent.
|
|
||||||
* @param[in] instance The identifier of the instance representing this NaCl
|
|
||||||
* module.
|
|
||||||
* @param[in] has_focus Indicates whether this NaCl module gained or lost
|
|
||||||
* event focus.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler that gets called after a full-frame module is instantiated based on
|
|
||||||
* registered MIME types. This function is not called on NaCl modules. This
|
|
||||||
* function is essentially a place-holder for the required function pointer in
|
|
||||||
* the PPP_Instance structure.
|
|
||||||
* @param[in] instance The identifier of the instance representing this NaCl
|
|
||||||
* module.
|
|
||||||
* @param[in] url_loader A PP_Resource an open PPB_URLLoader instance.
|
|
||||||
* @return PP_FALSE.
|
|
||||||
*/
|
|
||||||
static PP_Bool
|
|
||||||
Instance_HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader)
|
|
||||||
{
|
|
||||||
/* NaCl modules do not need to handle the document load function. */
|
|
||||||
return PP_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for messages coming in from the browser via postMessage. The
|
|
||||||
* @a var_message can contain anything: a JSON string; a string that encodes
|
|
||||||
* method names and arguments; etc. For example, you could use JSON.stringify
|
|
||||||
* in the browser to create a message that contains a method name and some
|
|
||||||
* parameters, something like this:
|
|
||||||
* var json_message = JSON.stringify({ "myMethod" : "3.14159" });
|
|
||||||
* nacl_module.postMessage(json_message);
|
|
||||||
* On receipt of this message in @a var_message, you could parse the JSON to
|
|
||||||
* retrieve the method name, match it to a function call, and then call it with
|
|
||||||
* the parameter.
|
|
||||||
* @param[in] instance The instance ID.
|
|
||||||
* @param[in] message The contents, copied by value, of the message sent from
|
|
||||||
* browser via postMessage.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
Messaging_HandleMessage(PP_Instance instance, struct PP_Var var_message)
|
|
||||||
{
|
|
||||||
char* const message = pruby_var_to_cstr(var_message);
|
|
||||||
size_t message_len = strlen(message);
|
|
||||||
current_instance = instance;
|
|
||||||
|
|
||||||
if (strstr(message, "eval:") != NULL) {
|
|
||||||
volatile VALUE src;
|
|
||||||
struct PepperInstance* const instance_data = GET_PEPPER_INSTANCE();
|
|
||||||
int err;
|
|
||||||
#define EVAL_PREFIX_LEN 5
|
|
||||||
src = rb_str_new(message + EVAL_PREFIX_LEN, message_len - EVAL_PREFIX_LEN);
|
|
||||||
instance_data->async_call_args = (void*)src;
|
|
||||||
err = pthread_create(&instance_data->th, NULL, &pruby_eval, instance_data);
|
|
||||||
if (err) {
|
|
||||||
fprintf(stderr, "pepper_ruby:pthread_create: %s\n", strerror(err));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
pthread_detach(instance_data->th);
|
|
||||||
}
|
|
||||||
free(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Entry points for the module.
|
|
||||||
* Initialize instance interface and scriptable object class.
|
|
||||||
* @param[in] a_module_id Module ID
|
|
||||||
* @param[in] get_browser_interface Pointer to PPB_GetInterface
|
|
||||||
* @return PP_OK on success, any other value on failure.
|
|
||||||
*/
|
|
||||||
PP_EXPORT int32_t
|
|
||||||
PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface a_get_browser_interface)
|
|
||||||
{
|
|
||||||
module_id = a_module_id;
|
|
||||||
get_browser_interface = a_get_browser_interface;
|
|
||||||
core_interface = (PPB_Core*)(get_browser_interface(PPB_CORE_INTERFACE));
|
|
||||||
if (core_interface == NULL) return PP_ERROR_NOINTERFACE;
|
|
||||||
|
|
||||||
var_interface = (PPB_Var*)(get_browser_interface(PPB_VAR_INTERFACE));
|
|
||||||
if (var_interface == NULL) return PP_ERROR_NOINTERFACE;
|
|
||||||
|
|
||||||
messaging_interface = (PPB_Messaging*)(get_browser_interface(PPB_MESSAGING_INTERFACE));
|
|
||||||
if (messaging_interface == NULL) return PP_ERROR_NOINTERFACE;
|
|
||||||
|
|
||||||
loader_interface = (PPB_URLLoader*)(get_browser_interface(PPB_URLLOADER_INTERFACE));
|
|
||||||
if (loader_interface == NULL) return PP_ERROR_NOINTERFACE;
|
|
||||||
|
|
||||||
request_interface = (PPB_URLRequestInfo*)(get_browser_interface(PPB_URLREQUESTINFO_INTERFACE));
|
|
||||||
if (request_interface == NULL) return PP_ERROR_NOINTERFACE;
|
|
||||||
|
|
||||||
response_interface = (PPB_URLResponseInfo*)(get_browser_interface(PPB_URLRESPONSEINFO_INTERFACE));
|
|
||||||
if (response_interface == NULL) return PP_ERROR_NOINTERFACE;
|
|
||||||
|
|
||||||
fileref_interface = (PPB_FileRef*)(get_browser_interface(PPB_FILEREF_INTERFACE));
|
|
||||||
if (fileref_interface == NULL) return PP_ERROR_NOINTERFACE;
|
|
||||||
|
|
||||||
return pruby_init() ? PP_ERROR_FAILED : PP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an interface pointer for the interface of the given name, or NULL
|
|
||||||
* if the interface is not supported.
|
|
||||||
* @param[in] interface_name name of the interface
|
|
||||||
* @return pointer to the interface
|
|
||||||
*/
|
|
||||||
PP_EXPORT const void*
|
|
||||||
PPP_GetInterface(const char* interface_name)
|
|
||||||
{
|
|
||||||
if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
|
|
||||||
static PPP_Instance instance_interface = {
|
|
||||||
&Instance_DidCreate,
|
|
||||||
&Instance_DidDestroy,
|
|
||||||
&Instance_DidChangeView,
|
|
||||||
&Instance_DidChangeFocus,
|
|
||||||
&Instance_HandleDocumentLoad
|
|
||||||
};
|
|
||||||
return &instance_interface;
|
|
||||||
} else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) {
|
|
||||||
static PPP_Messaging messaging_interface = {
|
|
||||||
&Messaging_HandleMessage
|
|
||||||
};
|
|
||||||
return &messaging_interface;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called before the plugin module is unloaded.
|
|
||||||
*/
|
|
||||||
PP_EXPORT void
|
|
||||||
PPP_ShutdownModule(void)
|
|
||||||
{
|
|
||||||
ruby_cleanup(0);
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 Google Inc. All Rights Reserved.
|
|
||||||
* Author: yugui@google.com (Yugui Sonoda)
|
|
||||||
* */
|
|
||||||
#ifndef RUBY_NACL_RESOURCE_H
|
|
||||||
#define RUBY_NACL_RESOURCE_H
|
|
||||||
int getrusage(int who, struct rusage *usage);
|
|
||||||
#endif
|
|
@ -1,7 +0,0 @@
|
|||||||
// Copyright 2012 Google Inc. All Rights Reserved.
|
|
||||||
// Author: yugui@google.com (Yugui Sonoda)
|
|
||||||
#ifndef RUBY_NACL_SELECT_H
|
|
||||||
#define RUBY_NACL_SELECT_H
|
|
||||||
int select(int num_fds, fd_set *in_fds, fd_set *out_fds,
|
|
||||||
fd_set *ex_fds, struct timeval *timeout);
|
|
||||||
#endif
|
|
@ -1,6 +0,0 @@
|
|||||||
// Copyright 2012 Google Inc. All Rights Reserved.
|
|
||||||
// Author: yugui@google.com (Yugui Sonoda)
|
|
||||||
#ifndef RUBY_NACL_SIGNAL_H
|
|
||||||
#define RUBY_NACL_SIGNAL_H
|
|
||||||
int kill(pid_t pid, int signal);
|
|
||||||
#endif
|
|
10
nacl/stat.h
10
nacl/stat.h
@ -1,10 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 Google Inc. All Rights Reserved.
|
|
||||||
* Author: yugui@google.com (Yugui Sonoda)
|
|
||||||
* */
|
|
||||||
#ifndef RUBY_NACL_STAT_H
|
|
||||||
#define RUBY_NACL_STAT_H
|
|
||||||
mode_t umask(mode_t mask);
|
|
||||||
struct stat;
|
|
||||||
int lstat(const char* path, struct stat* result);
|
|
||||||
#endif
|
|
@ -1,9 +0,0 @@
|
|||||||
// Copyright 2012 Google Inc. All Rights Reserved.
|
|
||||||
// Author: yugui@google.com (Yugui Sonoda)
|
|
||||||
#ifndef RUBY_NACL_UNISTD_H
|
|
||||||
#define RUBY_NACL_UNISTD_H
|
|
||||||
int seteuid(pid_t pid);
|
|
||||||
int setegid(pid_t pid);
|
|
||||||
int truncate(const char* path, off_t new_size);
|
|
||||||
int ftruncate(int fd, off_t new_size);
|
|
||||||
#endif
|
|
11
nacl/utime.h
11
nacl/utime.h
@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 Google Inc. All Rights Reserved.
|
|
||||||
* Author: yugui@google.com (Yugui Sonoda)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RUBY_NACL_UTIME_H
|
|
||||||
#define RUBY_NACL_UTIME_H
|
|
||||||
#include <utime.h>
|
|
||||||
int utime(const char *filename, const struct utimbuf *times);
|
|
||||||
int utimes(const char *filename, const struct timeval times[2]);
|
|
||||||
#endif
|
|
19
process.c
19
process.c
@ -61,13 +61,6 @@
|
|||||||
#include "ruby/st.h"
|
#include "ruby/st.h"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#if defined(__native_client__) && defined(NACL_NEWLIB)
|
|
||||||
# include <sys/unistd.h>
|
|
||||||
# include "nacl/stat.h"
|
|
||||||
# include "nacl/unistd.h"
|
|
||||||
# include "nacl/resource.h"
|
|
||||||
# undef HAVE_ISSETUGID
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -1219,7 +1212,7 @@ security(const char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_WORKING_FORK) && !defined(__native_client__)
|
#if defined(HAVE_WORKING_FORK)
|
||||||
|
|
||||||
/* try_with_sh and exec_with_sh should be async-signal-safe. Actually it is.*/
|
/* try_with_sh and exec_with_sh should be async-signal-safe. Actually it is.*/
|
||||||
#define try_with_sh(prog, argv, envp) ((saved_errno == ENOEXEC) ? exec_with_sh((prog), (argv), (envp)) : (void)0)
|
#define try_with_sh(prog, argv, envp) ((saved_errno == ENOEXEC) ? exec_with_sh((prog), (argv), (envp)) : (void)0)
|
||||||
@ -1242,10 +1235,6 @@ exec_with_sh(const char *prog, char **argv, char **envp)
|
|||||||
static int
|
static int
|
||||||
proc_exec_cmd(const char *prog, VALUE argv_str, VALUE envp_str)
|
proc_exec_cmd(const char *prog, VALUE argv_str, VALUE envp_str)
|
||||||
{
|
{
|
||||||
#ifdef __native_client__
|
|
||||||
rb_notimplement();
|
|
||||||
UNREACHABLE;
|
|
||||||
#else
|
|
||||||
char **argv;
|
char **argv;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
char **envp;
|
char **envp;
|
||||||
@ -1269,17 +1258,12 @@ proc_exec_cmd(const char *prog, VALUE argv_str, VALUE envp_str)
|
|||||||
preserving_errno(try_with_sh(prog, argv, envp)); /* try_with_sh() is async-signal-safe. */
|
preserving_errno(try_with_sh(prog, argv, envp)); /* try_with_sh() is async-signal-safe. */
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function should be async-signal-safe. Actually it is. */
|
/* This function should be async-signal-safe. Actually it is. */
|
||||||
static int
|
static int
|
||||||
proc_exec_sh(const char *str, VALUE envp_str)
|
proc_exec_sh(const char *str, VALUE envp_str)
|
||||||
{
|
{
|
||||||
#ifdef __native_client__
|
|
||||||
rb_notimplement();
|
|
||||||
UNREACHABLE;
|
|
||||||
#else
|
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
s = str;
|
s = str;
|
||||||
@ -1315,7 +1299,6 @@ proc_exec_sh(const char *str, VALUE envp_str)
|
|||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
10
signal.c
10
signal.c
@ -41,10 +41,6 @@
|
|||||||
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
|
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__native_client__) && defined(NACL_NEWLIB)
|
|
||||||
# include "nacl/signal.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern ID ruby_static_id_signo;
|
extern ID ruby_static_id_signo;
|
||||||
#define id_signo ruby_static_id_signo
|
#define id_signo ruby_static_id_signo
|
||||||
|
|
||||||
@ -1407,10 +1403,9 @@ install_sighandler(int signum, sighandler_t handler)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifndef __native_client__
|
|
||||||
# define install_sighandler(signum, handler) \
|
# define install_sighandler(signum, handler) \
|
||||||
INSTALL_SIGHANDLER(install_sighandler(signum, handler), #signum, signum)
|
INSTALL_SIGHANDLER(install_sighandler(signum, handler), #signum, signum)
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(SIGCLD) || defined(SIGCHLD)
|
#if defined(SIGCLD) || defined(SIGCHLD)
|
||||||
static int
|
static int
|
||||||
@ -1428,10 +1423,9 @@ init_sigchld(int sig)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
# ifndef __native_client__
|
|
||||||
# define init_sigchld(signum) \
|
# define init_sigchld(signum) \
|
||||||
INSTALL_SIGHANDLER(init_sigchld(signum), #signum, signum)
|
INSTALL_SIGHANDLER(init_sigchld(signum), #signum, signum)
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
|
5
thread.c
5
thread.c
@ -3574,11 +3574,6 @@ rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src)
|
|||||||
memcpy(dst->fdset, src->fdset, size);
|
memcpy(dst->fdset, src->fdset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __native_client__
|
|
||||||
int select(int nfds, fd_set *readfds, fd_set *writefds,
|
|
||||||
fd_set *exceptfds, struct timeval *timeout);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
int
|
||||||
rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout)
|
rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout)
|
||||||
{
|
{
|
||||||
|
@ -27,9 +27,6 @@
|
|||||||
#ifdef HAVE_SYS_PRCTL_H
|
#ifdef HAVE_SYS_PRCTL_H
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#endif
|
#endif
|
||||||
#if defined(__native_client__) && defined(NACL_NEWLIB)
|
|
||||||
# include "nacl/select.h"
|
|
||||||
#endif
|
|
||||||
#if defined(HAVE_SYS_TIME_H)
|
#if defined(HAVE_SYS_TIME_H)
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
@ -64,7 +61,7 @@ static struct {
|
|||||||
#define USE_MONOTONIC_COND 0
|
#define USE_MONOTONIC_COND 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_POLL) && defined(HAVE_FCNTL) && defined(F_GETFL) && defined(F_SETFL) && defined(O_NONBLOCK) && !defined(__native_client__)
|
#if defined(HAVE_POLL) && defined(HAVE_FCNTL) && defined(F_GETFL) && defined(F_SETFL) && defined(O_NONBLOCK)
|
||||||
/* The timer thread sleeps while only one Ruby thread is running. */
|
/* The timer thread sleeps while only one Ruby thread is running. */
|
||||||
# define USE_SLEEPY_TIMER_THREAD 1
|
# define USE_SLEEPY_TIMER_THREAD 1
|
||||||
#else
|
#else
|
||||||
@ -460,9 +457,7 @@ Init_native_thread(void)
|
|||||||
#ifdef USE_UBF_LIST
|
#ifdef USE_UBF_LIST
|
||||||
native_mutex_initialize(&ubf_list_lock);
|
native_mutex_initialize(&ubf_list_lock);
|
||||||
#endif
|
#endif
|
||||||
#ifndef __native_client__
|
|
||||||
posix_signal(SIGVTALRM, null_func);
|
posix_signal(SIGVTALRM, null_func);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
5
util.c
5
util.c
@ -507,10 +507,7 @@ ruby_strdup(const char *str)
|
|||||||
char *
|
char *
|
||||||
ruby_getcwd(void)
|
ruby_getcwd(void)
|
||||||
{
|
{
|
||||||
#if defined __native_client__
|
#if defined HAVE_GETCWD
|
||||||
char *buf = xmalloc(2);
|
|
||||||
strcpy(buf, ".");
|
|
||||||
#elif defined HAVE_GETCWD
|
|
||||||
# undef RUBY_UNTYPED_DATA_WARNING
|
# undef RUBY_UNTYPED_DATA_WARNING
|
||||||
# define RUBY_UNTYPED_DATA_WARNING 0
|
# define RUBY_UNTYPED_DATA_WARNING 0
|
||||||
# if defined NO_GETCWD_MALLOC
|
# if defined NO_GETCWD_MALLOC
|
||||||
|
@ -132,10 +132,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __native_client__
|
|
||||||
#undef OPT_DIRECT_THREADED_CODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* call threaded code */
|
/* call threaded code */
|
||||||
#if OPT_CALL_THREADED_CODE
|
#if OPT_CALL_THREADED_CODE
|
||||||
#if OPT_DIRECT_THREADED_CODE
|
#if OPT_DIRECT_THREADED_CODE
|
||||||
|
@ -50,7 +50,7 @@ vm_exec_core(rb_thread_t *th, VALUE initial)
|
|||||||
|
|
||||||
#if OPT_STACK_CACHING
|
#if OPT_STACK_CACHING
|
||||||
#if 0
|
#if 0
|
||||||
#elif __GNUC__ && __x86_64__ && !defined(__native_client__)
|
#elif __GNUC__ && __x86_64__
|
||||||
DECL_SC_REG(VALUE, a, "12");
|
DECL_SC_REG(VALUE, a, "12");
|
||||||
DECL_SC_REG(VALUE, b, "13");
|
DECL_SC_REG(VALUE, b, "13");
|
||||||
#else
|
#else
|
||||||
@ -66,11 +66,7 @@ vm_exec_core(rb_thread_t *th, VALUE initial)
|
|||||||
|
|
||||||
#elif defined(__GNUC__) && defined(__x86_64__)
|
#elif defined(__GNUC__) && defined(__x86_64__)
|
||||||
DECL_SC_REG(const VALUE *, pc, "14");
|
DECL_SC_REG(const VALUE *, pc, "14");
|
||||||
# if defined(__native_client__)
|
|
||||||
DECL_SC_REG(rb_control_frame_t *, cfp, "13");
|
|
||||||
# else
|
|
||||||
DECL_SC_REG(rb_control_frame_t *, cfp, "15");
|
DECL_SC_REG(rb_control_frame_t *, cfp, "15");
|
||||||
# endif
|
|
||||||
#define USE_MACHINE_REGS 1
|
#define USE_MACHINE_REGS 1
|
||||||
|
|
||||||
#elif defined(__GNUC__) && defined(__powerpc64__)
|
#elif defined(__GNUC__) && defined(__powerpc64__)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user