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)