duktape 0.11.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,184 @@
1
+ #include "ruby.h"
2
+ #include "duktape.h"
3
+
4
+ static VALUE mDuktape;
5
+ static VALUE cContext;
6
+ static VALUE eContextError;
7
+ static void error_handler(duk_context *, int);
8
+
9
+ static void ctx_dealloc(void *ctx)
10
+ {
11
+ duk_destroy_heap((duk_context *)ctx);
12
+ }
13
+
14
+ static VALUE ctx_alloc(VALUE klass)
15
+ {
16
+ duk_context *ctx = duk_create_heap(NULL, NULL, NULL, NULL, error_handler);
17
+ return Data_Wrap_Struct(klass, NULL, ctx_dealloc, ctx);
18
+ }
19
+
20
+ static VALUE ctx_stack_to_value(duk_context *ctx, int index)
21
+ {
22
+ size_t len;
23
+ const char *buf;
24
+ int type;
25
+
26
+ type = duk_get_type(ctx, index);
27
+ switch (type) {
28
+ case DUK_TYPE_NULL:
29
+ case DUK_TYPE_UNDEFINED:
30
+ return Qnil;
31
+
32
+ case DUK_TYPE_NUMBER:
33
+ return rb_float_new(duk_get_number(ctx, index));
34
+
35
+ case DUK_TYPE_BOOLEAN:
36
+ return duk_get_boolean(ctx, index) ? Qtrue : Qfalse;
37
+
38
+ case DUK_TYPE_STRING:
39
+ buf = duk_get_lstring(ctx, index, &len);
40
+ return rb_str_new(buf, len);
41
+
42
+ case DUK_TYPE_OBJECT:
43
+ case DUK_TYPE_BUFFER:
44
+ case DUK_TYPE_POINTER:
45
+ default:
46
+ rb_raise(eContextError, "cannot convert complex object");
47
+ }
48
+
49
+ return Qnil;
50
+ }
51
+
52
+ static int ctx_push_ruby_object(duk_context *ctx, VALUE obj)
53
+ {
54
+ switch (TYPE(obj)) {
55
+ case T_FIXNUM:
56
+ duk_push_int(ctx, NUM2INT(obj));
57
+ break;
58
+
59
+ case T_FLOAT:
60
+ duk_push_number(ctx, NUM2DBL(obj));
61
+ break;
62
+
63
+ case T_STRING:
64
+ duk_push_lstring(ctx, RSTRING_PTR(obj), RSTRING_LEN(obj));
65
+ break;
66
+
67
+ case T_TRUE:
68
+ duk_push_true(ctx);
69
+ break;
70
+
71
+ case T_FALSE:
72
+ duk_push_false(ctx);
73
+ break;
74
+
75
+ case T_NIL:
76
+ duk_push_null(ctx);
77
+ break;
78
+
79
+ default:
80
+ // Cannot convert
81
+ return 0;
82
+ }
83
+
84
+ // Everything is fine
85
+ return 1;
86
+ }
87
+
88
+ static VALUE ctx_eval_string(VALUE self, VALUE source, VALUE filename)
89
+ {
90
+ duk_context *ctx;
91
+ Data_Get_Struct(self, duk_context, ctx);
92
+
93
+ duk_push_lstring(ctx, RSTRING_PTR(source), RSTRING_LEN(source));
94
+ duk_push_lstring(ctx, RSTRING_PTR(filename), RSTRING_LEN(filename));
95
+ duk_compile(ctx, DUK_COMPILE_EVAL);
96
+ duk_call(ctx, 0);
97
+
98
+ VALUE res = ctx_stack_to_value(ctx, -1);
99
+ duk_set_top(ctx, 0);
100
+ return res;
101
+ }
102
+
103
+ static VALUE ctx_exec_string(VALUE self, VALUE source, VALUE filename)
104
+ {
105
+ duk_context *ctx;
106
+ Data_Get_Struct(self, duk_context, ctx);
107
+
108
+ duk_push_lstring(ctx, RSTRING_PTR(source), RSTRING_LEN(source));
109
+ duk_push_lstring(ctx, RSTRING_PTR(filename), RSTRING_LEN(filename));
110
+ duk_compile(ctx, 0);
111
+ duk_call(ctx, 0);
112
+ duk_set_top(ctx, 0);
113
+ return Qnil;
114
+ }
115
+
116
+ static VALUE ctx_get_prop(VALUE self, VALUE prop)
117
+ {
118
+ duk_context *ctx;
119
+ Data_Get_Struct(self, duk_context, ctx);
120
+
121
+ Check_Type(prop, T_STRING);
122
+
123
+ duk_push_global_object(ctx);
124
+ duk_push_lstring(ctx, RSTRING_PTR(prop), RSTRING_LEN(prop));
125
+ if (!duk_get_prop(ctx, -2)) {
126
+ duk_set_top(ctx, 0);
127
+ const char *str = StringValueCStr(prop);
128
+ rb_raise(eContextError, "no such prop: %s", str);
129
+ }
130
+
131
+ VALUE res = ctx_stack_to_value(ctx, -1);
132
+ duk_set_top(ctx, 0);
133
+ return res;
134
+ }
135
+
136
+ static VALUE ctx_call_prop(int argc, VALUE* argv, VALUE self)
137
+ {
138
+ duk_context *ctx;
139
+ Data_Get_Struct(self, duk_context, ctx);
140
+
141
+ VALUE prop;
142
+ VALUE *prop_args;
143
+ rb_scan_args(argc, argv, "1*", &prop, &prop_args);
144
+
145
+ Check_Type(prop, T_STRING);
146
+
147
+ duk_push_global_object(ctx);
148
+ duk_push_lstring(ctx, RSTRING_PTR(prop), RSTRING_LEN(prop));
149
+
150
+ for (int i = 1; i < argc; i++) {
151
+ if (!ctx_push_ruby_object(ctx, argv[i])) {
152
+ duk_set_top(ctx, 0);
153
+ VALUE tmp = rb_inspect(argv[i]);
154
+ const char *str = StringValueCStr(tmp);
155
+ rb_raise(eContextError, "unknown object: %s", str);
156
+ }
157
+ }
158
+
159
+ duk_call_prop(ctx, -(argc + 1), (argc - 1));
160
+ VALUE res = ctx_stack_to_value(ctx, -1);
161
+ duk_set_top(ctx, 0);
162
+ return res;
163
+ }
164
+
165
+ static void error_handler(duk_context *ctx, int code)
166
+ {
167
+ duk_set_top(ctx, 0);
168
+ rb_raise(eContextError, "fatal duktape error: %d", code);
169
+ }
170
+
171
+ void Init_duktape_ext()
172
+ {
173
+ mDuktape = rb_define_module("Duktape");
174
+ cContext = rb_define_class_under(mDuktape, "Context", rb_cObject);
175
+ eContextError = rb_define_class_under(mDuktape, "ContextError", rb_eStandardError);
176
+
177
+ rb_define_alloc_func(cContext, ctx_alloc);
178
+
179
+ rb_define_method(cContext, "eval_string", ctx_eval_string, 2);
180
+ rb_define_method(cContext, "exec_string", ctx_exec_string, 2);
181
+ rb_define_method(cContext, "get_prop", ctx_get_prop, 1);
182
+ rb_define_method(cContext, "call_prop", ctx_call_prop, -1);
183
+ }
184
+
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+ require 'zlib'
3
+
4
+ $CFLAGS += ' -std=c99'
5
+ create_makefile 'duktape_ext'
6
+
@@ -0,0 +1,6 @@
1
+ require 'duktape_ext'
2
+ require 'duktape/version'
3
+
4
+ module Duktape
5
+ end
6
+
@@ -0,0 +1,4 @@
1
+ module Duktape
2
+ VERSION = "0.11.0.0"
3
+ end
4
+
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: duktape
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.11.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Magnus Holm
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: judofyr@gmail.com
15
+ executables: []
16
+ extensions:
17
+ - ext/duktape/extconf.rb
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ext/duktape/duktape.c
21
+ - ext/duktape/duktape.h
22
+ - ext/duktape/duktape_ext.c
23
+ - ext/duktape/extconf.rb
24
+ - lib/duktape.rb
25
+ - lib/duktape/version.rb
26
+ homepage: https://github.com/judofyr/duktape.rb
27
+ licenses:
28
+ - MIT
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: 1.9.3
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubyforge_project:
46
+ rubygems_version: 2.2.2
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: Bindings to the Duktape JavaScript interpreter
50
+ test_files: []