Ruby  2.5.0dev(2017-10-22revision60238)
pepper_main.c
Go to the documentation of this file.
1 /******************************************************************************
2  Copyright 2012 Google Inc. All Rights Reserved.
3  Author: yugui@google.com (Yugui Sonoda)
4  ******************************************************************************/
5 
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <pthread.h>
10 #include <sys/stat.h>
11 #include <sys/mount.h>
12 #include <fcntl.h>
13 #include <pthread.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"
30 
31 #include "verconf.h"
32 #include "ruby/ruby.h"
33 #include "version.h"
34 #include "gc.h"
35 
36 #ifdef HAVE_STRUCT_PPB_CORE
37 typedef struct PPB_Core PPB_Core;
38 #endif
39 #ifdef HAVE_STRUCT_PPB_MESSAGING
40 typedef struct PPB_Messaging PPB_Messaging;
41 #endif
42 #ifdef HAVE_STRUCT_PPB_VAR
43 typedef struct PPB_Var PPB_Var;
44 #endif
45 #ifdef HAVE_STRUCT_PPB_URLLOADER
46 typedef struct PPB_URLLoader PPB_URLLoader;
47 #endif
48 #ifdef HAVE_STRUCT_PPB_URLREQUESTINFO
49 typedef struct PPB_URLRequestInfo PPB_URLRequestInfo;
50 #endif
51 #ifdef HAVE_STRUCT_PPB_URLRESPONSEINFO
52 typedef struct PPB_URLResponseInfo PPB_URLResponseInfo;
53 #endif
54 #ifdef HAVE_STRUCT_PPP_INSTANCE
55 typedef struct PPP_Instance PPP_Instance;
56 #endif
57 
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;
67 static struct st_table* instance_data = NULL;
68 
69 static VALUE instance_table = Qundef;
70 
71 static PP_Instance current_instance = 0;
72 
73 /******************************************************************************
74  * State of instance
75  ******************************************************************************/
76 
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);
80 static const rb_data_type_t pepper_instance_data_type = {
81  "PepperInstance",
82  { inst_mark, inst_free, inst_memsize }
83 };
84 
86  PP_Instance instance;
87  PP_Resource url_loader;
88  VALUE self;
90  union {
91  int32_t as_int;
92  const char* as_str;
95  char buf[1000];
96 
97  pthread_t th;
98  pthread_mutex_t mutex;
99  pthread_cond_t cond;
100 };
101 
102 struct PepperInstance*
104 {
105  VALUE self = rb_hash_aref(instance_table, INT2FIX(instance));
106  if (RTEST(self)) {
107  struct PepperInstance *inst;
108  TypedData_Get_Struct(self, struct PepperInstance, &pepper_instance_data_type, inst);
109  return inst;
110  }
111  else {
112  return NULL;
113  }
114 }
115 
116 #define GET_PEPPER_INSTANCE() (pruby_get_instance(current_instance))
117 
118 struct PepperInstance*
120 {
121  VALUE obj;
122  struct PepperInstance *data;
123  obj = TypedData_Make_Struct(rb_cData, struct PepperInstance, &pepper_instance_data_type, data);
124  data->self = obj;
125  data->instance = instance;
126  data->url_loader = 0;
127 
128  pthread_mutex_init(&data->mutex, NULL);
129  pthread_cond_init(&data->cond, NULL);
130 
131  rb_hash_aset(instance_table, INT2FIX(instance), obj);
132  return data;
133 }
134 
135 int
137 {
138  VALUE inst = rb_hash_delete(instance_table, INT2FIX(instance));
139  return RTEST(inst);
140 }
141 
142 static void
143 inst_mark(void *const ptr)
144 {
145  RUBY_MARK_ENTER("PepperInstance"0);
146  if (ptr) {
147  const struct PepperInstance* inst = (struct PepperInstance*)ptr;
149  }
150  RUBY_MARK_LEAVE("PepperInstance"0);
151 }
152 
153 static void
154 inst_free(void *const ptr)
155 {
156  ruby_xfree(ptr);
157 }
158 
159 static size_t
160 inst_memsize(void *const ptr)
161 {
162  if (ptr) {
163  const struct PepperInstance* inst = (struct PepperInstance*)ptr;
164  return sizeof(*inst);
165  } else {
166  return 0;
167  }
168 }
169 
170 void
171 pruby_async_return_int(void* data, int32_t result)
172 {
173  /* PPAPI main thread */
174  struct PepperInstance* const instance = (struct PepperInstance*)data;
175  instance->async_call_result.as_int = result;
176  if (pthread_cond_signal(&instance->cond)) {
177  perror("pepper-ruby:pthread_cond_signal");
178  }
179 }
180 
181 void
182 pruby_async_return_str(void* data, const char *result)
183 {
184  /* PPAPI main thread */
185  struct PepperInstance* const instance = (struct PepperInstance*)data;
186  instance->async_call_result.as_str = result;
187  if (pthread_cond_signal(&instance->cond)) {
188  perror("pepper-ruby:pthread_cond_signal");
189  }
190 }
191 
192 void
193 pruby_async_return_value(void* data, VALUE value)
194 {
195  /* PPAPI main thread */
196  struct PepperInstance* const instance = (struct PepperInstance*)data;
197  instance->async_call_result.as_value = value;
198  if (pthread_cond_signal(&instance->cond)) {
199  perror("pepper-ruby:pthread_cond_signal");
200  }
201 }
202 /******************************************************************************
203  * Conversion between Ruby's VALUE, Pepper's Var and C string
204  ******************************************************************************/
205 
213 static struct PP_Var
214 pruby_cstr_to_var(const char* str)
215 {
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();
220 #else
221  return var_interface->VarFromUtf8(str, strlen(str));
222 #endif
223 }
224 
235 static char*
236 pruby_var_to_cstr(struct PP_Var var)
237 {
238  uint32_t len = 0;
239  if (var_interface != NULL) {
240  const char* var_c_str = var_interface->VarToUtf8(var, &len);
241  if (len > 0) {
242  char* c_str = (char*)malloc(len + 1);
243  memcpy(c_str, var_c_str, len);
244  c_str[len] = '\0';
245  return c_str;
246  }
247  }
248  return NULL;
249 }
250 
251 static struct PP_Var
252 pruby_str_to_var(volatile VALUE str)
253 {
254  if (!RB_TYPE_P(str, T_STRING)) {
255  fprintf(stderr, "[BUG] Unexpected object type: %x\n", TYPE(str));
256  exit(EXIT_FAILURE);
257  }
258 #ifndef PPB_VAR_INTERFACE_1_1
259  if (var_interface != NULL) {
260  return var_interface->VarFromUtf8(module_id, RSTRING_PTR(str), RSTRING_LEN(str));
261  }
262 #else
263  return var_interface->VarFromUtf8(RSTRING_PTR(str), RSTRING_LEN(str));
264 #endif
265  return PP_MakeUndefined();
266 }
267 
268 static struct PP_Var
269 pruby_obj_to_var(volatile VALUE obj)
270 {
271  static const char* const error =
272  "throw 'Failed to convert the result to a JavaScript object';";
273  int state;
274  obj = rb_protect(&rb_obj_as_string, obj, &state);
275  if (!state) {
276  return pruby_str_to_var(obj);
277  }
278  else {
279  return pruby_cstr_to_var(error);
280  }
281 }
282 
283 int
284 pruby_var_equal_to_cstr_p(struct PP_Var lhs, const char* rhs)
285 {
286  uint32_t len = 0;
287  if (var_interface == NULL) {
288  return 0;
289  }
290  else {
291  const char* const cstr = var_interface->VarToUtf8(lhs, &len);
292  return strncmp(cstr, rhs, len) == 0;
293  }
294 }
295 
296 int
297 pruby_var_prefixed_p(struct PP_Var var, const char* prefix)
298 {
299  uint32_t len = 0;
300  if (var_interface == NULL) {
301  return 0;
302  }
303  else {
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;
307  }
308 }
309 
310 
311 /******************************************************************************
312  * Messaging
313  ******************************************************************************/
314 
315 /* Posts the given C string as a message.
316  * @param data pointer to a NULL-terminated string */
317 void
318 pruby_post_cstr(void* data)
319 {
320  /* PPAPI main thread */
321  struct PepperInstance* const instance = (struct PepperInstance*)data;
322  const char* const msg = (const char*)instance->async_call_args;
323  messaging_interface->PostMessage(instance->instance,
324  pruby_cstr_to_var(msg));
325 }
326 
327 /* Posts the given Ruby VALUE as a message.
328  * @param data a VALUE casted to void* */
329 void
330 pruby_post_value(void* data)
331 {
332  /* PPAPI main thread */
333  struct PepperInstance* const instance = (struct PepperInstance*)data;
334  volatile VALUE value = (VALUE)instance->async_call_args;
335  messaging_interface->PostMessage(instance->instance, pruby_obj_to_var(value));
336 }
337 
338 
339 
340 /******************************************************************************
341  * Ruby initialization
342  ******************************************************************************/
343 
344 static void
345 init_loadpath(void)
346 {
347  ruby_incpush("lib/ruby/"RUBY_LIB_VERSION);
348  ruby_incpush("lib/ruby/"RUBY_LIB_VERSION"/"RUBY_PLATFORM);
349  ruby_incpush(".");
350 }
351 
352 static VALUE
353 init_libraries_internal(VALUE unused)
354 {
355  extern void Init_enc();
356  extern void Init_ext();
357 
358  init_loadpath();
359  Init_enc();
360  Init_ext();
361  return Qnil;
362 }
363 
364 static void*
365 init_libraries(void* data)
366 {
367  int state;
368  struct PepperInstance* const instance = (struct PepperInstance*)data;
369  current_instance = instance->instance;
370 
371  if (pthread_mutex_lock(&instance->mutex)) {
372  perror("pepper-ruby:pthread_mutex_lock");
373  return 0;
374  }
375  rb_protect(&init_libraries_internal, Qnil, &state);
376  pthread_mutex_unlock(&instance->mutex);
377 
378  if (state) {
379  volatile VALUE err = rb_errinfo();
380  err = rb_obj_as_string(err);
381  } else {
382  instance->async_call_args = (void*)"rubyReady";
383  core_interface->CallOnMainThread(
384  0, PP_MakeCompletionCallback(pruby_post_cstr, instance), 0);
385  }
386  return NULL;
387 }
388 
389 static int
390 init_libraries_if_necessary(void)
391 {
392  static int initialized = 0;
393  if (!initialized) {
394  struct PepperInstance* const instance = GET_PEPPER_INSTANCE();
395  int err;
396  initialized = 1;
397  err = pthread_create(&instance->th, NULL, &init_libraries, instance);
398  if (err) {
399  fprintf(stderr, "pepper_ruby:pthread_create: %s\n", strerror(err));
400  exit(EXIT_FAILURE);
401  }
402  pthread_detach(instance->th);
403  }
404  return 0;
405 }
406 
407 static int
408 reopen_fd(int fd, const char* path, int flags) {
409  int fd2 = open(path, flags);
410  if (fd2 < 0) {
411  perror("open fd");
412  return -1;
413  }
414  if (dup2(fd2, fd) < 0) {
415  perror("dup2 fd");
416  return -1;
417  }
418  if (close(fd2)) {
419  perror("close old fd");
420  return -1;
421  }
422  return fd;
423 }
424 
425 static int
426 pruby_init(void)
427 {
429  ruby_init();
430 
431  instance_table = rb_hash_new();
432  rb_gc_register_mark_object(instance_table);
433 
434  return 0;
435 }
436 
437 
438 /******************************************************************************
439  * Ruby evaluation
440  ******************************************************************************/
441 
442 static void*
443 pruby_eval(void* data)
444 {
445  extern VALUE ruby_eval_string_from_file_protect(const char* src, const char* path, int* state);
446  struct PepperInstance* const instance = (struct PepperInstance*)data;
447  volatile VALUE src = (VALUE)instance->async_call_args;
448  volatile VALUE result = Qnil;
449  volatile int state;
450 
452 
453  if (pthread_mutex_lock(&instance->mutex)) {
454  perror("pepper-ruby:pthread_mutex_lock");
455  return 0;
456  }
458  RSTRING_PTR(src), "(pepper-ruby)", &state);
459  pthread_mutex_unlock(&instance->mutex);
460 
461  if (!state) {
462  instance->async_call_args =
464  rb_obj_as_string(result));
465  core_interface->CallOnMainThread(
466  0, PP_MakeCompletionCallback(pruby_post_value, instance), 0);
467  return NULL;
468  }
469  else {
471  instance->async_call_args =
473  rb_obj_as_string(result));
474  core_interface->CallOnMainThread(
475  0, PP_MakeCompletionCallback(pruby_post_value, instance), 0);
476  return NULL;
477  }
478 }
479 
480 
481 /******************************************************************************
482  * Pepper Module callbacks
483  ******************************************************************************/
484 
507 static PP_Bool
508 Instance_DidCreate(PP_Instance instance,
509  uint32_t argc, const char* argn[], const char* argv[])
510 {
512  current_instance = instance;
513 
514  nacl_io_init_ppapi(instance, get_browser_interface);
515 
516  if (mount("", "/dev2", "dev", 0, "")) {
517  perror("mount dev");
518  return PP_FALSE;
519  }
520  if (reopen_fd(0, "/dev2/stdin", O_RDONLY) < 0) {
521  perror("reopen stdin");
522  return PP_FALSE;
523  }
524  if (reopen_fd(1, "/dev2/stdout", O_WRONLY) < 0) {
525  perror("reopen stdout");
526  return PP_FALSE;
527  }
528  if (reopen_fd(2, "/dev2/console1", O_WRONLY) < 0) {
529  perror("reopen stderr");
530  return PP_FALSE;
531  }
532 
533  /* TODO(yugui) Unmount original /dev */
534 
535  if (mount("/lib", "/lib", "httpfs",
536  0, "allow_cross_origin_requests=false")) {
537  perror("mount httpfs");
538  return PP_FALSE;
539  }
540 
541  return init_libraries_if_necessary() ? PP_FALSE : PP_TRUE;
542 }
543 
551 static void Instance_DidDestroy(PP_Instance instance) {
552  struct PepperInstance* data = pruby_get_instance(instance);
553  core_interface->ReleaseResource(data->url_loader);
554  pruby_unregister_instance(instance);
555 }
556 
569 #ifndef PPP_INSTANCE_INTERFACE_1_1
570 static void
571 Instance_DidChangeView(PP_Instance instance,
572  const struct PP_Rect* position,
573  const struct PP_Rect* clip)
574 {
575 }
576 #else
577 static void
578 Instance_DidChangeView(PP_Instance instance, PP_Resource view_resource)
579 {
580 }
581 #endif
582 
600 static void
601 Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus)
602 {
603 }
604 
615 static PP_Bool
616 Instance_HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader)
617 {
618  /* NaCl modules do not need to handle the document load function. */
619  return PP_FALSE;
620 }
621 
622 
638 void
639 Messaging_HandleMessage(PP_Instance instance, struct PP_Var var_message)
640 {
641  char* const message = pruby_var_to_cstr(var_message);
642  size_t message_len = strlen(message);
643  current_instance = instance;
644 
645  if (strstr(message, "eval:") != NULL) {
646  volatile VALUE src;
647  struct PepperInstance* const instance_data = GET_PEPPER_INSTANCE();
648  int err;
649 #define EVAL_PREFIX_LEN 5
650  src = rb_str_new(message + EVAL_PREFIX_LEN, message_len - EVAL_PREFIX_LEN);
651  instance_data->async_call_args = (void*)src;
652  err = pthread_create(&instance_data->th, NULL, &pruby_eval, instance_data);
653  if (err) {
654  fprintf(stderr, "pepper_ruby:pthread_create: %s\n", strerror(err));
655  exit(EXIT_FAILURE);
656  }
657  pthread_detach(instance_data->th);
658  }
659  free(message);
660 }
661 
669 PP_EXPORT int32_t
670 PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface a_get_browser_interface)
671 {
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;
676 
677  var_interface = (PPB_Var*)(get_browser_interface(PPB_VAR_INTERFACE));
678  if (var_interface == NULL) return PP_ERROR_NOINTERFACE;
679 
680  messaging_interface = (PPB_Messaging*)(get_browser_interface(PPB_MESSAGING_INTERFACE));
681  if (messaging_interface == NULL) return PP_ERROR_NOINTERFACE;
682 
683  loader_interface = (PPB_URLLoader*)(get_browser_interface(PPB_URLLOADER_INTERFACE));
684  if (loader_interface == NULL) return PP_ERROR_NOINTERFACE;
685 
686  request_interface = (PPB_URLRequestInfo*)(get_browser_interface(PPB_URLREQUESTINFO_INTERFACE));
687  if (request_interface == NULL) return PP_ERROR_NOINTERFACE;
688 
689  response_interface = (PPB_URLResponseInfo*)(get_browser_interface(PPB_URLRESPONSEINFO_INTERFACE));
690  if (response_interface == NULL) return PP_ERROR_NOINTERFACE;
691 
692  fileref_interface = (PPB_FileRef*)(get_browser_interface(PPB_FILEREF_INTERFACE));
693  if (fileref_interface == NULL) return PP_ERROR_NOINTERFACE;
694 
695  return pruby_init() ? PP_ERROR_FAILED : PP_OK;
696 }
697 
704 PP_EXPORT const void*
705 PPP_GetInterface(const char* interface_name)
706 {
707  if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
708  static PPP_Instance instance_interface = {
709  &Instance_DidCreate,
710  &Instance_DidDestroy,
711  &Instance_DidChangeView,
712  &Instance_DidChangeFocus,
713  &Instance_HandleDocumentLoad
714  };
715  return &instance_interface;
716  } else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) {
717  static PPP_Messaging messaging_interface = {
719  };
720  return &messaging_interface;
721  }
722  return NULL;
723 }
724 
728 PP_EXPORT void
730 {
731  ruby_cleanup(0);
732 }
RUBY_EXTERN VALUE rb_cData
Definition: ruby.h:1902
int ruby_cleanup(volatile int ex)
Destructs the VM.
Definition: eval.c:161
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:992
int32_t as_int
Definition: pepper_main.c:91
size_t strlen(const char *)
Definition: st.h:79
int pruby_unregister_instance(PP_Instance instance)
Definition: pepper_main.c:136
void Init_enc(void)
Definition: dmyenc.c:5
PP_Instance instance
Definition: pepper_main.c:86
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1183
struct PepperInstance * pruby_register_instance(PP_Instance instance)
Definition: pepper_main.c:119
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
Definition: zonetab.h:883
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:2999
#define RUBY_MARK_LEAVE(msg)
Definition: gc.h:54
pthread_cond_t cond
Definition: pepper_main.c:99
void Init_ext(void)
Definition: dmyext.c:2
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...
Definition: pepper_main.c:705
void pruby_async_return_str(void *data, const char *result)
Definition: pepper_main.c:182
void ruby_incpush(const char *)
Definition: ruby.c:369
pthread_mutex_t mutex
Definition: pepper_main.c:98
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
int pruby_var_equal_to_cstr_p(struct PP_Var lhs, const char *rhs)
Definition: pepper_main.c:284
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1616
void ruby_init(void)
Calls ruby_setup() and check error.
Definition: eval.c:76
RUBY_EXTERN char * strstr(const char *, const char *)
Definition: strstr.c:8
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1410
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
Definition: eval.c:1792
PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface a_get_browser_interface)
Entry points for the module.
Definition: pepper_main.c:670
#define EVAL_PREFIX_LEN
const char * as_str
Definition: pepper_main.c:92
#define RUBY_MARK_ENTER(msg)
Definition: gc.h:53
#define TYPE(x)
Definition: ruby.h:521
int argc
Definition: ruby.c:187
void rb_gc_register_mark_object(VALUE obj)
Definition: gc.c:6227
int err
Definition: win32.c:135
struct PepperInstance * pruby_get_instance(PP_Instance instance)
Definition: pepper_main.c:103
#define EXIT_FAILURE
Definition: eval_intern.h:33
#define RSTRING_LEN(str)
Definition: ruby.h:971
VALUE rb_hash_delete(VALUE hash, VALUE key)
Definition: hash.c:1119
#define const
Definition: strftime.c:103
#define malloc
Definition: ripper.c:358
VALUE rb_hash_new(void)
Definition: hash.c:424
void ruby_xfree(void *x)
Definition: gc.c:8085
union PepperInstance::@87 async_call_result
#define Qnil
Definition: ruby.h:438
unsigned long VALUE
Definition: ruby.h:85
void pruby_post_value(void *data)
Definition: pepper_main.c:330
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
unsigned int uint32_t
Definition: sha2.h:101
register unsigned int len
Definition: zonetab.h:51
PP_Resource url_loader
Definition: pepper_main.c:87
#define RSTRING_PTR(str)
Definition: ruby.h:975
#define RUBY_PLATFORM
Definition: defines.h:325
#define GET_PEPPER_INSTANCE()
Definition: pepper_main.c:116
#define INT2FIX(i)
Definition: ruby.h:232
PP_EXPORT void PPP_ShutdownModule(void)
Called before the plugin module is unloaded.
Definition: pepper_main.c:729
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:831
VALUE ruby_eval_string_from_file_protect(const char *str, const char *filename, int *state)
Definition: vm_eval.c:1426
RUBY_EXTERN char * strerror(int)
Definition: strerror.c:11
#define RTEST(v)
Definition: ruby.h:450
#define T_STRING
Definition: ruby.h:496
void pruby_post_cstr(void *data)
Definition: pepper_main.c:318
int pruby_var_prefixed_p(struct PP_Var var, const char *prefix)
Definition: pepper_main.c:297
#define RUBY_MARK_UNLESS_NULL(ptr)
Definition: gc.h:60
VALUE rb_errinfo(void)
The current exception in the current thread.
Definition: eval.c:1777
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1175
#define RUBY_INIT_STACK
A convenience macro to call ruby_init_stack().
Definition: ruby.h:2502
void * async_call_args
Definition: pepper_main.c:89
RUBY_EXTERN int dup2(int, int)
Definition: dup2.c:27
void Messaging_HandleMessage(PP_Instance instance, struct PP_Var var_message)
Handler for messages coming in from the browser via postMessage.
Definition: pepper_main.c:639
char buf[1000]
Definition: pepper_main.c:95
void pruby_async_return_value(void *data, VALUE value)
Definition: pepper_main.c:193
#define NULL
Definition: _sdbm.c:102
#define Qundef
Definition: ruby.h:439
free(psz)
pthread_t th
Definition: pepper_main.c:97
VALUE rb_usascii_str_new_cstr(const char *)
Definition: string.c:778
char ** argv
Definition: ruby.c:188
void pruby_async_return_int(void *data, int32_t result)
Definition: pepper_main.c:171
VALUE rb_str_new(const char *, long)
Definition: string.c:737