11 #include <sys/mount.h>    14 #include "ppapi/c/pp_errors.h"    15 #include "ppapi/c/pp_module.h"    16 #include "ppapi/c/pp_var.h"    17 #include "ppapi/c/ppb.h"    18 #include "ppapi/c/ppb_core.h"    19 #include "ppapi/c/ppb_file_ref.h"    20 #include "ppapi/c/ppb_instance.h"    21 #include "ppapi/c/ppb_messaging.h"    22 #include "ppapi/c/ppb_url_loader.h"    23 #include "ppapi/c/ppb_url_request_info.h"    24 #include "ppapi/c/ppb_url_response_info.h"    25 #include "ppapi/c/ppb_var.h"    26 #include "ppapi/c/ppp.h"    27 #include "ppapi/c/ppp_instance.h"    28 #include "ppapi/c/ppp_messaging.h"    29 #include "nacl_io/nacl_io.h"    36 #ifdef HAVE_STRUCT_PPB_CORE    37 typedef struct PPB_Core PPB_Core;
    39 #ifdef HAVE_STRUCT_PPB_MESSAGING    40 typedef struct PPB_Messaging PPB_Messaging;
    42 #ifdef HAVE_STRUCT_PPB_VAR    43 typedef struct PPB_Var PPB_Var;
    45 #ifdef HAVE_STRUCT_PPB_URLLOADER    46 typedef struct PPB_URLLoader PPB_URLLoader;
    48 #ifdef HAVE_STRUCT_PPB_URLREQUESTINFO    49 typedef struct PPB_URLRequestInfo PPB_URLRequestInfo;
    51 #ifdef HAVE_STRUCT_PPB_URLRESPONSEINFO    52 typedef struct PPB_URLResponseInfo PPB_URLResponseInfo;
    54 #ifdef HAVE_STRUCT_PPP_INSTANCE    55 typedef struct PPP_Instance PPP_Instance;
    58 static PP_Module module_id = 0;
    59 static PPB_GetInterface get_browser_interface = 
NULL;
    60 static PPB_Core* core_interface = 
NULL;
    61 static PPB_Messaging* messaging_interface = 
NULL;
    62 static PPB_Var* var_interface = 
NULL;
    63 static PPB_URLLoader* loader_interface = 
NULL;
    64 static PPB_URLRequestInfo* request_interface = 
NULL;
    65 static PPB_URLResponseInfo* response_interface = 
NULL;
    66 static PPB_FileRef* fileref_interface = 
NULL;
    71 static PP_Instance current_instance = 0;
    77 static void inst_mark(
void *
const ptr);
    78 static void inst_free(
void *
const ptr);
    79 static size_t inst_memsize(
void *
const ptr);
    82   { inst_mark, inst_free, inst_memsize }
   116 #define GET_PEPPER_INSTANCE() (pruby_get_instance(current_instance))   129   pthread_cond_init(&data->
cond, 
NULL);
   143 inst_mark(
void *
const ptr)
   154 inst_free(
void *
const ptr)
   160 inst_memsize(
void *
const ptr)
   164     return sizeof(*inst);
   176   if (pthread_cond_signal(&instance->
cond)) {
   177     perror(
"pepper-ruby:pthread_cond_signal");
   187   if (pthread_cond_signal(&instance->
cond)) {
   188     perror(
"pepper-ruby:pthread_cond_signal");
   198   if (pthread_cond_signal(&instance->
cond)) {
   199     perror(
"pepper-ruby:pthread_cond_signal");
   214 pruby_cstr_to_var(
const char* str)
   216 #ifndef PPB_VAR_INTERFACE_1_1   217   if (var_interface != 
NULL)
   218     return var_interface->VarFromUtf8(module_id, str, 
strlen(str));
   219   return PP_MakeUndefined();
   221   return var_interface->VarFromUtf8(str, 
strlen(str));
   236 pruby_var_to_cstr(
struct PP_Var var)
   239   if (var_interface != 
NULL) {
   240     const char* var_c_str = var_interface->VarToUtf8(var, &len);
   242       char* c_str = (
char*)
malloc(len + 1);
   243       memcpy(c_str, var_c_str, len);
   252 pruby_str_to_var(volatile 
VALUE str)
   255     fprintf(stderr, 
"[BUG] Unexpected object type: %x\n", 
TYPE(str));
   258 #ifndef PPB_VAR_INTERFACE_1_1   259   if (var_interface != 
NULL) {
   265   return PP_MakeUndefined();
   269 pruby_obj_to_var(volatile VALUE obj)
   271   static const char* 
const error =
   272       "throw 'Failed to convert the result to a JavaScript object';";
   276       return pruby_str_to_var(obj);
   279       return pruby_cstr_to_var(error);
   287   if (var_interface == 
NULL) {
   291     const char* 
const cstr = var_interface->VarToUtf8(lhs, &len);
   292     return strncmp(cstr, rhs, len) == 0;
   300   if (var_interface == 
NULL) {
   304     const char* 
const cstr = var_interface->VarToUtf8(var, &len);
   305     const size_t prefix_len = 
strlen(prefix);
   306     return len >= prefix_len && 
memcmp(cstr, prefix, len) == 0;
   323   messaging_interface->PostMessage(instance->
instance,
   324                                    pruby_cstr_to_var(msg));
   335   messaging_interface->PostMessage(instance->
instance, pruby_obj_to_var(value));
   353 init_libraries_internal(VALUE unused)
   365 init_libraries(
void* data)
   369   current_instance = instance->
instance;
   371   if (pthread_mutex_lock(&instance->
mutex)) {
   372     perror(
"pepper-ruby:pthread_mutex_lock");
   376   pthread_mutex_unlock(&instance->
mutex);
   383     core_interface->CallOnMainThread(
   390 init_libraries_if_necessary(
void)
   392   static int initialized = 0;
   397     err = pthread_create(&instance->
th, 
NULL, &init_libraries, instance);
   399       fprintf(stderr, 
"pepper_ruby:pthread_create: %s\n", 
strerror(err));
   402     pthread_detach(instance->
th);
   408 reopen_fd(
int fd, 
const char* path, 
int flags) {
   409   int fd2 = open(path, flags);
   414   if (
dup2(fd2, fd) < 0) {
   419     perror(
"close old fd");
   443 pruby_eval(
void* data)
   448   volatile VALUE result = 
Qnil;
   453   if (pthread_mutex_lock(&instance->
mutex)) {
   454     perror(
"pepper-ruby:pthread_mutex_lock");
   459   pthread_mutex_unlock(&instance->
mutex);
   465       core_interface->CallOnMainThread(
   474       core_interface->CallOnMainThread(
   508 Instance_DidCreate(PP_Instance 
instance,
   514   nacl_io_init_ppapi(
instance, get_browser_interface);
   516   if (mount(
"", 
"/dev2", 
"dev", 0, 
"")) {
   520   if (reopen_fd(0, 
"/dev2/stdin", O_RDONLY) < 0) {
   521     perror(
"reopen stdin");
   524   if (reopen_fd(1, 
"/dev2/stdout", O_WRONLY) < 0) {
   525     perror(
"reopen stdout");
   528   if (reopen_fd(2, 
"/dev2/console1", O_WRONLY) < 0) {
   529     perror(
"reopen stderr");
   535   if (mount(
"/lib", 
"/lib", 
"httpfs",
   536         0, 
"allow_cross_origin_requests=false")) {
   537     perror(
"mount httpfs");
   541   return init_libraries_if_necessary() ? PP_FALSE : PP_TRUE;
   551 static void Instance_DidDestroy(PP_Instance 
instance) {
   553   core_interface->ReleaseResource(data->
url_loader);
   569 #ifndef PPP_INSTANCE_INTERFACE_1_1   571 Instance_DidChangeView(PP_Instance 
instance,
   572                        const struct PP_Rect* position,
   573                        const struct PP_Rect* clip)
   578 Instance_DidChangeView(PP_Instance 
instance, PP_Resource view_resource)
   601 Instance_DidChangeFocus(PP_Instance 
instance, PP_Bool has_focus)
   641   char* 
const message = pruby_var_to_cstr(var_message);
   642   size_t message_len = 
strlen(message);
   649 #define EVAL_PREFIX_LEN 5   652     err = pthread_create(&instance_data->
th, 
NULL, &pruby_eval, instance_data);
   654       fprintf(stderr, 
"pepper_ruby:pthread_create: %s\n", 
strerror(err));
   657     pthread_detach(instance_data->
th);
   672   module_id = a_module_id;
   673   get_browser_interface = a_get_browser_interface;
   674   core_interface = (PPB_Core*)(get_browser_interface(PPB_CORE_INTERFACE));
   675   if (core_interface == 
NULL) 
return PP_ERROR_NOINTERFACE;
   677   var_interface = (PPB_Var*)(get_browser_interface(PPB_VAR_INTERFACE));
   678   if (var_interface == 
NULL) 
return PP_ERROR_NOINTERFACE;
   680   messaging_interface = (PPB_Messaging*)(get_browser_interface(PPB_MESSAGING_INTERFACE));
   681   if (messaging_interface == 
NULL) 
return PP_ERROR_NOINTERFACE;
   683   loader_interface = (PPB_URLLoader*)(get_browser_interface(PPB_URLLOADER_INTERFACE));
   684   if (loader_interface == 
NULL) 
return PP_ERROR_NOINTERFACE;
   686   request_interface = (PPB_URLRequestInfo*)(get_browser_interface(PPB_URLREQUESTINFO_INTERFACE));
   687   if (request_interface == 
NULL) 
return PP_ERROR_NOINTERFACE;
   689   response_interface = (PPB_URLResponseInfo*)(get_browser_interface(PPB_URLRESPONSEINFO_INTERFACE));
   690   if (response_interface == 
NULL) 
return PP_ERROR_NOINTERFACE;
   692   fileref_interface = (PPB_FileRef*)(get_browser_interface(PPB_FILEREF_INTERFACE));
   693   if (fileref_interface == 
NULL) 
return PP_ERROR_NOINTERFACE;
   695   return pruby_init() ? PP_ERROR_FAILED : PP_OK;
   704 PP_EXPORT 
const void*
   707   if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
   708     static PPP_Instance instance_interface = {
   710       &Instance_DidDestroy,
   711       &Instance_DidChangeView,
   712       &Instance_DidChangeFocus,
   713       &Instance_HandleDocumentLoad
   715     return &instance_interface;
   716   } 
else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) {
   717     static PPP_Messaging messaging_interface = {
   720     return &messaging_interface;
 
RUBY_EXTERN VALUE rb_cData
 
int ruby_cleanup(volatile int ex)
Destructs the VM. 
 
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function. 
 
size_t strlen(const char *)
 
int pruby_unregister_instance(PP_Instance instance)
 
#define TypedData_Get_Struct(obj, type, data_type, sval)
 
struct PepperInstance * pruby_register_instance(PP_Instance instance)
 
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
 
VALUE rb_str_concat(VALUE, VALUE)
 
#define RUBY_MARK_LEAVE(msg)
 
PP_EXPORT const void * PPP_GetInterface(const char *interface_name)
Returns an interface pointer for the interface of the given name, or NULL if the interface is not sup...
 
void pruby_async_return_str(void *data, const char *result)
 
void ruby_incpush(const char *)
 
#define RB_TYPE_P(obj, type)
 
int pruby_var_equal_to_cstr_p(struct PP_Var lhs, const char *rhs)
 
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
 
void ruby_init(void)
Calls ruby_setup() and check error. 
 
RUBY_EXTERN char * strstr(const char *, const char *)
 
VALUE rb_obj_as_string(VALUE)
 
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value. 
 
PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface a_get_browser_interface)
Entry points for the module. 
 
#define RUBY_MARK_ENTER(msg)
 
void rb_gc_register_mark_object(VALUE obj)
 
struct PepperInstance * pruby_get_instance(PP_Instance instance)
 
VALUE rb_hash_delete(VALUE hash, VALUE key)
 
union PepperInstance::@87 async_call_result
 
void pruby_post_value(void *data)
 
int memcmp(const void *s1, const void *s2, size_t len)
 
register unsigned int len
 
#define GET_PEPPER_INSTANCE()
 
PP_EXPORT void PPP_ShutdownModule(void)
Called before the plugin module is unloaded. 
 
VALUE rb_hash_aref(VALUE hash, VALUE key)
 
VALUE ruby_eval_string_from_file_protect(const char *str, const char *filename, int *state)
 
RUBY_EXTERN char * strerror(int)
 
void pruby_post_cstr(void *data)
 
int pruby_var_prefixed_p(struct PP_Var var, const char *prefix)
 
#define RUBY_MARK_UNLESS_NULL(ptr)
 
VALUE rb_errinfo(void)
The current exception in the current thread. 
 
#define TypedData_Make_Struct(klass, type, data_type, sval)
 
#define RUBY_INIT_STACK
A convenience macro to call ruby_init_stack(). 
 
RUBY_EXTERN int dup2(int, int)
 
void Messaging_HandleMessage(PP_Instance instance, struct PP_Var var_message)
Handler for messages coming in from the browser via postMessage. 
 
void pruby_async_return_value(void *data, VALUE value)
 
VALUE rb_usascii_str_new_cstr(const char *)
 
void pruby_async_return_int(void *data, int32_t result)
 
VALUE rb_str_new(const char *, long)