duktape 1.3.0.4 → 1.3.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a83f9f94bcb9062672ab5f4b394379b3c6b3bb3a
4
- data.tar.gz: 61109c31d8865a66852a004a4a393c1edb72ca7b
3
+ metadata.gz: 28cb600087093cad9368ab6b897a04c555f17572
4
+ data.tar.gz: f768cc0a2b9d71f6a4df6dbed8a216ef5a8b7acb
5
5
  SHA512:
6
- metadata.gz: 6564704f5eaa7bdfd87894ba1bb70d854d2818a68740d984fe96e4f249fe2991ce4369a91bbeadb4538cbe09f2cb00572a94221339d73ec328c825776978d9c3
7
- data.tar.gz: 9f42fbed534b7c41ff92dfac44a08227301e701297eea9cbc7c6d7f7ca07ae89465aebe630e0c82d05ecf1d77ef11b5b4f7411de1ba99a3d95e292748540f540
6
+ metadata.gz: 505392082298a898dfe7658e5d518deeba13843edd47c31c55a57a14aa71e555b42adab9c8433e48406f974b9d6de345a53b3743d33980270159fef0215018df
7
+ data.tar.gz: 20ca551193c9403aa527804963487249b889f505483a11efeab923aa28aee902e96140f95cf7b8f7f263ebf7984cbc2aff7ed67cbf15b265f4fe555864c4c6ea
@@ -1,5 +1,13 @@
1
1
  # ChangeLog
2
2
 
3
+ ## v1.3.0.6 (2016-03-27)
4
+
5
+ * Implement `#define_function` (#16, judofyr, did)
6
+
7
+ ## v1.3.0.5 (2016-01-22)
8
+
9
+ * Convert symbols to strings (judofyr, Jean-Baptiste Aviat)
10
+
3
11
  ## v1.3.0.4 (2015-11-23)
4
12
 
5
13
  * Support Illumos and Solaris (#33, F4S4K4N)
data/README.md CHANGED
@@ -52,6 +52,17 @@ ctx.call_prop('process', 'some data', a: 1, b: 2)
52
52
  - `call_prop` - Call a defined function with the given parameters and return
53
53
  the value as a Ruby Object.
54
54
 
55
+ ### Defining functions
56
+
57
+ You can define simple functions in Ruby that can be called from
58
+ JavaScript:
59
+
60
+ ```ruby
61
+ ctx.define_function("leftpad") do |str, n, ch=' '|
62
+ str.rjust(n, ch)
63
+ end
64
+ ```
65
+
55
66
  ### Exceptions
56
67
 
57
68
  Executing JS may raise two classes of errors: `Duktape::Error` and
@@ -40,6 +40,7 @@ struct state {
40
40
  duk_context *ctx;
41
41
  VALUE complex_object;
42
42
  int was_complex;
43
+ VALUE blocks;
43
44
  };
44
45
 
45
46
  static void ctx_dealloc(void *ptr)
@@ -52,6 +53,7 @@ static void ctx_dealloc(void *ptr)
52
53
  static void ctx_mark(struct state *state)
53
54
  {
54
55
  rb_gc_mark(state->complex_object);
56
+ rb_gc_mark(state->blocks);
55
57
  }
56
58
 
57
59
  static VALUE ctx_alloc(VALUE klass)
@@ -67,6 +69,7 @@ static VALUE ctx_alloc(VALUE klass)
67
69
  struct state *state = malloc(sizeof(struct state));
68
70
  state->ctx = ctx;
69
71
  state->complex_object = oComplexObject;
72
+ state->blocks = rb_ary_new();
70
73
  return Data_Wrap_Struct(klass, ctx_mark, ctx_dealloc, state);
71
74
  }
72
75
 
@@ -255,6 +258,14 @@ static void ctx_push_ruby_object(struct state *state, VALUE obj)
255
258
  duk_push_number(ctx, NUM2DBL(obj));
256
259
  return;
257
260
 
261
+ case T_SYMBOL:
262
+ #ifdef HAVE_RB_SYM2STR
263
+ obj = rb_sym2str(obj);
264
+ #else
265
+ obj = rb_id2str(SYM2ID(obj));
266
+ #endif
267
+ // Intentional fall-through:
268
+
258
269
  case T_STRING:
259
270
  str = encode_cesu8(state, obj);
260
271
  duk_push_lstring(ctx, RSTRING_PTR(str), RSTRING_LEN(str));
@@ -298,8 +309,15 @@ static int ctx_push_hash_element(VALUE key, VALUE val, VALUE extra)
298
309
  struct state *state = (struct state*) extra;
299
310
  duk_context *ctx = state->ctx;
300
311
 
301
- Check_Type(key, T_STRING);
302
- duk_push_lstring(ctx, RSTRING_PTR(key), RSTRING_LEN(key));
312
+ switch (TYPE(key)) {
313
+ case T_SYMBOL:
314
+ case T_STRING:
315
+ ctx_push_ruby_object(state, key);
316
+ break;
317
+ default:
318
+ clean_raise(ctx, rb_eTypeError, "invalid key type %s", rb_obj_classname(key));
319
+ }
320
+
303
321
  ctx_push_ruby_object(state, val);
304
322
  duk_put_prop(ctx, -3);
305
323
  return ST_CONTINUE;
@@ -519,6 +537,80 @@ static VALUE ctx_call_prop(int argc, VALUE* argv, VALUE self)
519
537
  return res;
520
538
  }
521
539
 
540
+ static duk_ret_t ctx_call_pushed_function(duk_context *ctx) {
541
+ VALUE block; // the block to yield
542
+ struct state *state;
543
+ int nargs = duk_get_top(ctx); // number of arguments of the block (arity)
544
+ VALUE args = rb_ary_new(); // the block to yield needs an array of arguments
545
+ VALUE result; // the result returned by yielding the block
546
+
547
+ duk_push_current_function(ctx);
548
+
549
+ // get the block which is a property of the pushed function
550
+ duk_get_prop_string(ctx, -1, "block");
551
+ block = (VALUE) duk_get_pointer(ctx, -1);
552
+ duk_pop(ctx);
553
+
554
+ // get the state so that we don't need to a create a new one
555
+ duk_get_prop_string(ctx, -1, "state");
556
+ state = (struct state *) duk_get_pointer(ctx, -1);
557
+ duk_pop(ctx);
558
+
559
+ // before pushing each argument to the array, each one needs to be converted into a ruby value
560
+ for (int i = 0; i < nargs; i++)
561
+ rb_ary_push(args, ctx_stack_to_value(state, i));
562
+
563
+ result = rb_proc_call(block, args); // yield
564
+ ctx_push_ruby_object(state, result);
565
+
566
+ return 1;
567
+ }
568
+
569
+ /*
570
+ * call-seq:
571
+ * ctx_define_function(name, &block) -> nil
572
+ *
573
+ * Define a function defined in the global scope and identified by a name.
574
+ *
575
+ * ctx.ctx_define_function("hello_world") { |ctx| 'Hello world' } #=> nil
576
+ *
577
+ */
578
+ static VALUE ctx_define_function(VALUE self, VALUE prop)
579
+ {
580
+ VALUE block;
581
+ struct state *state;
582
+ duk_context *ctx;
583
+
584
+ // a block is required
585
+ if (!rb_block_given_p())
586
+ rb_raise(rb_eArgError, "Expected block");
587
+
588
+ // get the context
589
+ Data_Get_Struct(self, struct state, state);
590
+ ctx = state->ctx;
591
+
592
+ // the c function is available in the global scope
593
+ duk_push_global_object(ctx);
594
+
595
+ duk_push_c_function(ctx, ctx_call_pushed_function, DUK_VARARGS);
596
+
597
+ block = rb_block_proc();
598
+ rb_ary_push(state->blocks, block); // block will be properly garbage collected
599
+
600
+ // both block and state are required by the pushed function
601
+ duk_push_string(ctx, "block");
602
+ duk_push_pointer(ctx, (void *) block);
603
+ duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE | 0);
604
+
605
+ duk_push_string(ctx, "state");
606
+ duk_push_pointer(ctx, (void *) state);
607
+ duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE | 0);
608
+
609
+ duk_put_prop_string(ctx, -2, StringValueCStr(prop));
610
+
611
+ return Qnil;
612
+ }
613
+
522
614
  /*
523
615
  * :nodoc:
524
616
  *
@@ -624,6 +716,7 @@ void Init_duktape_ext()
624
716
  rb_define_method(cContext, "exec_string", ctx_exec_string, -1);
625
717
  rb_define_method(cContext, "get_prop", ctx_get_prop, 1);
626
718
  rb_define_method(cContext, "call_prop", ctx_call_prop, -1);
719
+ rb_define_method(cContext, "define_function", ctx_define_function, 1);
627
720
  rb_define_method(cContext, "_valid?", ctx_is_valid, 0);
628
721
 
629
722
  oComplexObject = rb_obj_alloc(cComplexObject);
@@ -2,5 +2,6 @@ require 'mkmf'
2
2
  require 'zlib'
3
3
 
4
4
  $CFLAGS += ' -std=c99'
5
+ have_func 'rb_sym2str'
5
6
  create_makefile 'duktape_ext'
6
7
 
@@ -1,3 +1,3 @@
1
1
  module Duktape
2
- VERSION = "1.3.0.4"
2
+ VERSION = "1.3.0.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duktape
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0.4
4
+ version: 1.3.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Magnus Holm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-23 00:00:00.000000000 Z
11
+ date: 2016-03-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: judofyr@gmail.com