duktape 1.3.0.4 → 1.3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +11 -0
- data/ext/duktape/duktape_ext.c +95 -2
- data/ext/duktape/extconf.rb +1 -0
- data/lib/duktape/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28cb600087093cad9368ab6b897a04c555f17572
|
4
|
+
data.tar.gz: f768cc0a2b9d71f6a4df6dbed8a216ef5a8b7acb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 505392082298a898dfe7658e5d518deeba13843edd47c31c55a57a14aa71e555b42adab9c8433e48406f974b9d6de345a53b3743d33980270159fef0215018df
|
7
|
+
data.tar.gz: 20ca551193c9403aa527804963487249b889f505483a11efeab923aa28aee902e96140f95cf7b8f7f263ebf7984cbc2aff7ed67cbf15b265f4fe555864c4c6ea
|
data/CHANGELOG.md
CHANGED
@@ -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
|
data/ext/duktape/duktape_ext.c
CHANGED
@@ -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
|
-
|
302
|
-
|
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);
|
data/ext/duktape/extconf.rb
CHANGED
data/lib/duktape/version.rb
CHANGED
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
|
+
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:
|
11
|
+
date: 2016-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: judofyr@gmail.com
|