jbarnette-johnson 1.0.0.200806240111

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. data/CHANGELOG +5 -0
  2. data/MANIFEST +385 -0
  3. data/MINGW32.mk +124 -0
  4. data/README.rdoc +51 -0
  5. data/Rakefile +166 -0
  6. data/bin/johnson +107 -0
  7. data/cross-compile.txt +38 -0
  8. data/ext/spidermonkey/context.c +122 -0
  9. data/ext/spidermonkey/context.h +19 -0
  10. data/ext/spidermonkey/conversions.c +286 -0
  11. data/ext/spidermonkey/conversions.h +18 -0
  12. data/ext/spidermonkey/debugger.c +208 -0
  13. data/ext/spidermonkey/debugger.h +9 -0
  14. data/ext/spidermonkey/extconf.rb +25 -0
  15. data/ext/spidermonkey/extensions.c +37 -0
  16. data/ext/spidermonkey/extensions.h +12 -0
  17. data/ext/spidermonkey/global.c +40 -0
  18. data/ext/spidermonkey/global.h +11 -0
  19. data/ext/spidermonkey/idhash.c +16 -0
  20. data/ext/spidermonkey/idhash.h +8 -0
  21. data/ext/spidermonkey/immutable_node.c.erb +522 -0
  22. data/ext/spidermonkey/immutable_node.h +22 -0
  23. data/ext/spidermonkey/jroot.h +187 -0
  24. data/ext/spidermonkey/js_land_proxy.c +609 -0
  25. data/ext/spidermonkey/js_land_proxy.h +20 -0
  26. data/ext/spidermonkey/ruby_land_proxy.c +537 -0
  27. data/ext/spidermonkey/ruby_land_proxy.h +17 -0
  28. data/ext/spidermonkey/runtime.c +304 -0
  29. data/ext/spidermonkey/runtime.h +25 -0
  30. data/ext/spidermonkey/spidermonkey.c +20 -0
  31. data/ext/spidermonkey/spidermonkey.h +29 -0
  32. data/js/johnson/browser.js +9 -0
  33. data/js/johnson/browser/env.js +687 -0
  34. data/js/johnson/browser/jquery.js +3444 -0
  35. data/js/johnson/browser/xmlsax.js +1564 -0
  36. data/js/johnson/browser/xmlw3cdom.js +4189 -0
  37. data/js/johnson/cli.js +30 -0
  38. data/js/johnson/prelude.js +80 -0
  39. data/js/johnson/template.js +29 -0
  40. data/lib/hoe.rb +748 -0
  41. data/lib/johnson.rb +46 -0
  42. data/lib/johnson/cli.rb +7 -0
  43. data/lib/johnson/cli/options.rb +56 -0
  44. data/lib/johnson/error.rb +4 -0
  45. data/lib/johnson/nodes.rb +7 -0
  46. data/lib/johnson/nodes/binary_node.rb +64 -0
  47. data/lib/johnson/nodes/for.rb +14 -0
  48. data/lib/johnson/nodes/for_in.rb +12 -0
  49. data/lib/johnson/nodes/function.rb +13 -0
  50. data/lib/johnson/nodes/list.rb +27 -0
  51. data/lib/johnson/nodes/node.rb +68 -0
  52. data/lib/johnson/nodes/ternary_node.rb +20 -0
  53. data/lib/johnson/parser.rb +21 -0
  54. data/lib/johnson/parser/syntax_error.rb +13 -0
  55. data/lib/johnson/runtime.rb +55 -0
  56. data/lib/johnson/spidermonkey/context.rb +10 -0
  57. data/lib/johnson/spidermonkey/debugger.rb +67 -0
  58. data/lib/johnson/spidermonkey/immutable_node.rb +280 -0
  59. data/lib/johnson/spidermonkey/js_land_proxy.rb +62 -0
  60. data/lib/johnson/spidermonkey/mutable_tree_visitor.rb +233 -0
  61. data/lib/johnson/spidermonkey/ruby_land_proxy.rb +52 -0
  62. data/lib/johnson/spidermonkey/runtime.rb +94 -0
  63. data/lib/johnson/version.rb +4 -0
  64. data/lib/johnson/visitable.rb +16 -0
  65. data/lib/johnson/visitors.rb +4 -0
  66. data/lib/johnson/visitors/dot_visitor.rb +167 -0
  67. data/lib/johnson/visitors/ecma_visitor.rb +315 -0
  68. data/lib/johnson/visitors/enumerating_visitor.rb +115 -0
  69. data/lib/johnson/visitors/sexp_visitor.rb +172 -0
  70. data/lib/rails/init.rb +37 -0
  71. data/test/assets/index.html +38 -0
  72. data/test/assets/jquery_test.html +186 -0
  73. data/test/helper.rb +58 -0
  74. data/test/johnson/browser_test.rb +38 -0
  75. data/test/johnson/conversions/array_test.rb +32 -0
  76. data/test/johnson/conversions/boolean_test.rb +17 -0
  77. data/test/johnson/conversions/callable_test.rb +34 -0
  78. data/test/johnson/conversions/file_test.rb +15 -0
  79. data/test/johnson/conversions/nil_test.rb +20 -0
  80. data/test/johnson/conversions/number_test.rb +34 -0
  81. data/test/johnson/conversions/regexp_test.rb +24 -0
  82. data/test/johnson/conversions/string_test.rb +26 -0
  83. data/test/johnson/conversions/struct_test.rb +15 -0
  84. data/test/johnson/conversions/symbol_test.rb +19 -0
  85. data/test/johnson/conversions/thread_test.rb +24 -0
  86. data/test/johnson/error_test.rb +9 -0
  87. data/test/johnson/extensions_test.rb +56 -0
  88. data/test/johnson/nodes/array_literal_test.rb +57 -0
  89. data/test/johnson/nodes/array_node_test.rb +26 -0
  90. data/test/johnson/nodes/binary_node_test.rb +61 -0
  91. data/test/johnson/nodes/bracket_access_test.rb +16 -0
  92. data/test/johnson/nodes/delete_test.rb +11 -0
  93. data/test/johnson/nodes/do_while_test.rb +12 -0
  94. data/test/johnson/nodes/dot_accessor_test.rb +15 -0
  95. data/test/johnson/nodes/export_test.rb +9 -0
  96. data/test/johnson/nodes/for_test.rb +54 -0
  97. data/test/johnson/nodes/function_test.rb +71 -0
  98. data/test/johnson/nodes/if_test.rb +41 -0
  99. data/test/johnson/nodes/import_test.rb +13 -0
  100. data/test/johnson/nodes/label_test.rb +19 -0
  101. data/test/johnson/nodes/object_literal_test.rb +110 -0
  102. data/test/johnson/nodes/return_test.rb +16 -0
  103. data/test/johnson/nodes/semi_test.rb +8 -0
  104. data/test/johnson/nodes/switch_test.rb +55 -0
  105. data/test/johnson/nodes/ternary_test.rb +25 -0
  106. data/test/johnson/nodes/throw_test.rb +9 -0
  107. data/test/johnson/nodes/try_node_test.rb +59 -0
  108. data/test/johnson/nodes/typeof_test.rb +11 -0
  109. data/test/johnson/nodes/unary_node_test.rb +23 -0
  110. data/test/johnson/nodes/void_test.rb +11 -0
  111. data/test/johnson/nodes/while_test.rb +26 -0
  112. data/test/johnson/nodes/with_test.rb +10 -0
  113. data/test/johnson/prelude_test.rb +56 -0
  114. data/test/johnson/runtime_test.rb +46 -0
  115. data/test/johnson/spidermonkey/context_test.rb +21 -0
  116. data/test/johnson/spidermonkey/immutable_node_test.rb +34 -0
  117. data/test/johnson/spidermonkey/js_land_proxy_test.rb +236 -0
  118. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +225 -0
  119. data/test/johnson/spidermonkey/runtime_test.rb +17 -0
  120. data/test/johnson/version_test.rb +13 -0
  121. data/test/johnson/visitors/dot_visitor_test.rb +39 -0
  122. data/test/johnson/visitors/enumerating_visitor_test.rb +12 -0
  123. data/test/johnson_test.rb +16 -0
  124. data/test/jquery_units/test.js +27 -0
  125. data/test/jquery_units/test_helper.js +197 -0
  126. data/test/jquery_units/units/ajax.js +795 -0
  127. data/test/jquery_units/units/core.js +1563 -0
  128. data/test/jquery_units/units/event.js +299 -0
  129. data/test/jquery_units/units/fx.js +427 -0
  130. data/test/jquery_units/units/offset.js +112 -0
  131. data/test/jquery_units/units/selector.js +224 -0
  132. data/test/jspec/helper.js +7 -0
  133. data/test/jspec/jspec.js +192 -0
  134. data/test/jspec/simple_spec.js +68 -0
  135. data/test/parser_test.rb +276 -0
  136. data/todo/.keep +0 -0
  137. metadata +501 -0
data/README.rdoc ADDED
@@ -0,0 +1,51 @@
1
+ = Johnson
2
+
3
+ Johnson wraps JavaScript in a loving Ruby embrace.
4
+
5
+ * {Source Code}[http://github.com/jbarnette/johnson]
6
+ * {Bug Tracker}[http://johnson.lighthouseapp.com]
7
+ * {RubyForge Project}[http://johnson.rubyforge.org]
8
+
9
+ == Usage
10
+
11
+ # FIXME: write some decent examples
12
+ require "johnson"
13
+
14
+ Johnson.evaluate("4 + 4") # => 8
15
+ Johnson.evaluate("4 + foo", :foo => 4) # => 8
16
+
17
+ == Installing
18
+
19
+ [sudo] gem install johnson
20
+
21
+ == Installing Development Versions
22
+
23
+ We periodically update Johnson's gemspec on Github. Rather than installing the
24
+ official releases (hosted on RubyForge), you can track the development version.
25
+ Development versions will have a timestamped version number, like 1.0.0.200806232349.
26
+
27
+ [sudo] gem sources -a http://gems.github.com # if you haven't already
28
+ [sudo] gem install jbarnette-johnson
29
+
30
+ == License
31
+
32
+ Copyright 2008 John Barnette, Aaron Patterson, Yehuda Katz, Matthew Draper
33
+
34
+ Permission is hereby granted, free of charge, to any person obtaining
35
+ a copy of this software and associated documentation files (the
36
+ 'Software'), to deal in the Software without restriction, including
37
+ without limitation the rights to use, copy, modify, merge, publish,
38
+ distribute, sublicense, and/or sell copies of the Software, and to
39
+ permit persons to whom the Software is furnished to do so, subject to
40
+ the following conditions:
41
+
42
+ The above copyright notice and this permission notice shall be
43
+ included in all copies or substantial portions of the Software.
44
+
45
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
46
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
47
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
48
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
49
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
50
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
51
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,166 @@
1
+ require "erb"
2
+
3
+ require "./lib/hoe.rb"
4
+ require "./lib/johnson/version.rb"
5
+
6
+ # what sort of extension are we building?
7
+ kind = Config::CONFIG["DLEXT"]
8
+
9
+ CROSS = ENV["CROSS"]
10
+ LIBJS = FileList["vendor/spidermonkey/#{CROSS || ''}*.OBJ/libjs.{#{kind},so}"].first || :libjs
11
+
12
+ GENERATED_NODE = "ext/spidermonkey/immutable_node.c"
13
+
14
+ HOE = Hoe.new("johnson", Johnson::VERSION) do |p|
15
+ p.author = ["John Barnette", "Aaron Patterson", "Yehuda Katz", "Matthew Draper"]
16
+ p.changes = p.paragraphs_of("CHANGELOG", 0..1).join("\n\n")
17
+ p.email = "johnson-talk@googlegroups.com"
18
+ p.rubyforge_name = "johnson"
19
+ p.description = "Johnson wraps JavaScript in a loving Ruby embrace."
20
+ p.summary = p.description
21
+ p.url = "http://github.com/jbarnette/johnson/wikis"
22
+
23
+ p.clean_globs = [
24
+ "lib/johnson/spidermonkey.#{kind}",
25
+ "ext/spidermonkey/Makefile",
26
+ "ext/spidermonkey/*.{o,so,bundle,log}",
27
+ GENERATED_NODE,
28
+ "vendor/spidermonkey/**/*.OBJ"]
29
+
30
+ p.test_globs = ["test/**/*_test.rb"]
31
+ p.spec_extras = { :extensions => ["Rakefile"] }
32
+ p.extra_deps = ["rake"]
33
+ end
34
+
35
+ namespace :gem do
36
+ namespace :spec do
37
+ task :generate do
38
+ File.open("johnson.gemspec", "w") do |f|
39
+ f.puts(HOE.spec.to_ruby)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ namespace :test do
46
+ Rake::TestTask.new("todo") do |t|
47
+ t.test_files = FileList["todo/**/*_test.rb"]
48
+ t.verbose = true
49
+ end
50
+
51
+ task :jspec => :extensions do
52
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/lib")
53
+ Johnson.send(:remove_const, :VERSION)
54
+ require "johnson"
55
+
56
+ Dir["test/jspec/**/*_spec.js"].each do |file|
57
+ Johnson::Runtime.new.load(file)
58
+ end
59
+ end
60
+ end
61
+
62
+ # make sure the C bits are up-to-date when testing
63
+ Rake::Task[:test].prerequisites << :extensions
64
+ Rake::Task["test:todo"].prerequisites << :extensions
65
+
66
+ Rake::Task[:check_manifest].prerequisites << GENERATED_NODE
67
+
68
+ task :build => :extensions
69
+ task :extension => :build
70
+
71
+ task :extensions => ["lib/johnson/spidermonkey.#{kind}"]
72
+
73
+ namespace :extensions do
74
+ task :clean do
75
+ Dir.chdir("ext/spidermonkey") do
76
+ sh "rm -f Makefile"
77
+ sh "rm -f *.{o,so,bundle,log}"
78
+ end
79
+ end
80
+ end
81
+
82
+ build_sm = lambda do
83
+ cmd = "make -f Makefile.ref"
84
+ cmd << " OS_CONFIG=#{CROSS}" if CROSS
85
+ Dir.chdir("vendor/spidermonkey") { sh cmd }
86
+ end
87
+
88
+ if Symbol === LIBJS
89
+ task LIBJS, &build_sm
90
+ else
91
+ file LIBJS, &build_sm
92
+
93
+ task LIBJS => "vendor/spidermonkey/Makefile.ref"
94
+ task LIBJS => Dir["vendor/spidermonkey/*.[ch]"]
95
+ task LIBJS => Dir["vendor/spidermonkey/config/*.mk"]
96
+ end
97
+
98
+ task LIBJS => "vendor/spidermonkey/jsapi.h"
99
+ task LIBJS => "vendor/spidermonkey/config/#{CROSS}.mk" if CROSS
100
+
101
+ file "vendor/spidermonkey/config/MINGW32.mk" => "MINGW32.mk" do |t|
102
+ cp t.prerequisites.first, t.name
103
+ end
104
+
105
+ file "vendor/spidermonkey/jsapi.h" do
106
+ # if this file's missing, pull in the submodule
107
+ sh "git submodule init && git submodule update"
108
+ end
109
+
110
+ file "ext/spidermonkey/spidermonkey.#{kind}" =>
111
+ ["ext/spidermonkey/Makefile"] + FileList["ext/spidermonkey/*.{c,h}"].to_a do |t|
112
+
113
+ old_time = File.mtime(t.name) rescue nil
114
+ Dir.chdir("ext/spidermonkey") { sh "make" }
115
+
116
+ # If make chose not to rebuild the file, we'll touch it, so we don't
117
+ # bother to call make again next time.
118
+ sh "touch #{t.name}" if old_time && File.mtime(t.name) <= old_time
119
+ end
120
+
121
+ # for testing, we toss the SpiderMonkey extension in lib/johnson
122
+ file "lib/johnson/spidermonkey.#{kind}" =>
123
+ "ext/spidermonkey/spidermonkey.#{kind}" do |t|
124
+
125
+ cp t.prerequisites.first, t.name
126
+ end
127
+
128
+ file "ext/spidermonkey/Makefile" =>
129
+ [LIBJS, GENERATED_NODE, "ext/spidermonkey/extconf.rb"] do
130
+
131
+ dirs = (CROSS ? [ENV["CROSSLIB"]] : []) + $:
132
+ command = ["ruby"] + dirs.map{|dir| "-I#{File.expand_path dir}"} + ["extconf.rb"]
133
+ Dir.chdir("ext/spidermonkey") { sh *command }
134
+ end
135
+
136
+ def jsops
137
+ ops = []
138
+ File.open("vendor/spidermonkey/jsopcode.tbl", "rb") { |f|
139
+ f.each_line do |line|
140
+ if line =~ /^OPDEF\((\w+),/
141
+ ops << $1
142
+ end
143
+ end
144
+ }
145
+ ops
146
+ end
147
+
148
+ def tokens
149
+ toks = []
150
+ File.open("vendor/spidermonkey/jsscan.h", "rb") { |f|
151
+ f.each_line do |line|
152
+ line.scan(/TOK_\w+/).each do |token|
153
+ next if token == "TOK_ERROR"
154
+ toks << token
155
+ end
156
+ end
157
+ }
158
+ toks.uniq
159
+ end
160
+
161
+ file GENERATED_NODE => ["ext/spidermonkey/immutable_node.c.erb", "vendor/spidermonkey/jsopcode.tbl", "vendor/spidermonkey/jsscan.h"] do |t|
162
+ template = ERB.new(File.open(t.prerequisites.first, "rb") { |x| x.read })
163
+ File.open(GENERATED_NODE, "wb") { |f|
164
+ f.write template.result(binding)
165
+ }
166
+ end
data/bin/johnson ADDED
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require "johnson"
5
+ rescue LoadError
6
+ require "rubygems"
7
+ require "johnson"
8
+ end
9
+
10
+ require "readline"
11
+
12
+ RUNTIME = js = Johnson::Runtime.new
13
+ RUNTIME.evaluate(Johnson::CLI::JS)
14
+
15
+ EXIT_VERBS = [nil] + %w(exit quit)
16
+
17
+ local_binding = binding
18
+ ruby_readline = []
19
+
20
+ def copy_history
21
+ new_history = []
22
+ until Readline::HISTORY.empty?
23
+ new_history.push(Readline::HISTORY.pop)
24
+ end
25
+ new_history
26
+ end
27
+
28
+ def paste_history(old_history)
29
+ until old_history.empty?
30
+ Readline::HISTORY << old_history.pop
31
+ end
32
+ end
33
+
34
+ def handle_exit(input)
35
+ if EXIT_VERBS.include?(input)
36
+ puts if input.nil?
37
+ exit
38
+ end
39
+ end
40
+
41
+ def rescued(&block)
42
+ yield
43
+ rescue Exception => e
44
+ exit if SystemExit === e
45
+
46
+ puts e.message
47
+ puts e.backtrace.reject { |l| l =~ /bin\/johnson/ }
48
+ end
49
+
50
+ def eval_in_js(expression)
51
+ rescued { puts "=> " + RUNTIME.evaluate(expression, "(console)").inspect }
52
+ end
53
+
54
+ def eval_in_ruby(expression, bind_to)
55
+ rescued { puts "=> " + eval(expression, bind_to).inspect }
56
+ end
57
+
58
+ options = Johnson::CLI::Options.parse!(ARGV)
59
+ options.load_paths.each { |d| $LOAD_PATH << d }
60
+ options.files_to_preload.each { |f| RUNTIME.load(f) }
61
+
62
+ unless options.expressions.empty?
63
+ # magic comment, do not remove
64
+ options.expressions.each { |e| RUNTIME.evaluate(e, '-e') }
65
+ exit if !options.file_to_evaluate
66
+ end
67
+
68
+ if options.file_to_evaluate
69
+ RUNTIME[:arguments] = options.arguments
70
+ RUNTIME.load(options.file_to_evaluate)
71
+ exit
72
+ end
73
+
74
+ loop do
75
+ input = Readline.readline("js> ", true)
76
+ handle_exit(input)
77
+
78
+ if input =~ /^rb\s+(.+)$/
79
+ eval_in_ruby($1, local_binding)
80
+ next
81
+ end
82
+
83
+ if input == "rb"
84
+ js_readline = copy_history
85
+ paste_history(ruby_readline)
86
+
87
+ loop do
88
+ input = Readline.readline("rb> ", true)
89
+ handle_exit(input)
90
+
91
+ break if input == "js"
92
+
93
+ if input =~ /^js\s+(.+)$/
94
+ eval_in_js($1)
95
+ next
96
+ end
97
+
98
+ eval_in_ruby(input, local_binding)
99
+ end
100
+
101
+ ruby_readline = copy_history
102
+ paste_history(js_readline)
103
+ next
104
+ end
105
+
106
+ eval_in_js(input)
107
+ end
data/cross-compile.txt ADDED
@@ -0,0 +1,38 @@
1
+
2
+ CROSS-COMPILING FOR WINDOWS
3
+
4
+ Based on http://eigenclass.org/hiki.rb?cross+compiling+rcovrt
5
+
6
+
7
+ *) Install the MinGW cross-compiler
8
+
9
+ Debian: apt-get install mingw32 mingw32-binutils mingw32-runtime
10
+
11
+ *) Download & extract a ruby distribution archive
12
+
13
+ *) Double the backslashes in the ALT_SEPARATOR definition in Makefile.in
14
+
15
+ *) Build & install it:
16
+
17
+ env ac_cv_func_getpgrp_void=no \
18
+ ac_cv_func_setpgrp_void=yes \
19
+ rb_cv_negative_time_t=no \
20
+ ac_cv_func_memcmp_working=yes \
21
+ rb_cv_binary_elf=no \
22
+ ./configure \
23
+ --host=i586-mingw32msvc \
24
+ --target=i386-mingw32 \
25
+ --build=i686-linux \
26
+ --prefix=~/ruby-mingw32
27
+
28
+ make ruby
29
+
30
+ make install
31
+
32
+ *) Build the extension (rake will build spidermonkey for you)
33
+
34
+ # Remove any native binaries that are already built
35
+ rake clean
36
+
37
+ rake build CROSS=MINGW32 CROSSLIB=~/ruby-mingw32/lib/ruby/1.8/i386-mingw32
38
+
@@ -0,0 +1,122 @@
1
+ #include "context.h"
2
+ #include "conversions.h"
3
+ #include "global.h"
4
+ #include "extensions.h"
5
+ #include "idhash.h"
6
+ #include "jsdbgapi.h"
7
+
8
+ // callback for JS_SetErrorReporter
9
+ static void report_js_error(JSContext* js, const char* message, JSErrorReport* UNUSED(report))
10
+ {
11
+ // first we find ourselves
12
+ VALUE self = (VALUE)JS_GetContextPrivate(js);
13
+
14
+ // then we find our bridge
15
+ JohnsonContext* context;
16
+ Data_Get_Struct(self, JohnsonContext, context);
17
+
18
+ // NOTE: SpiderMonkey REALLY doesn't like being interrupted. If we
19
+ // jump over to Ruby and raise here, segfaults and such ensue.
20
+ // Instead, we store the exception (if any) and the error message
21
+ // on the context. They're dealt with in the if (!ok) block of evaluate().
22
+
23
+ strncpy(context->msg, message, MAX_EXCEPTION_MESSAGE_SIZE);
24
+ JS_GetPendingException(context->js, &context->ex);
25
+ }
26
+
27
+ // callback for JS_SetBranchCallback
28
+ static JSBool branch_callback(JSContext* js, JSScript* UNUSED(script))
29
+ {
30
+ static unsigned long branch_counter = 0;
31
+ if( ++branch_counter % 0x1000 == 0 )
32
+ JS_MaybeGC( js );
33
+ return JS_TRUE;
34
+ }
35
+
36
+ /*
37
+ * call-seq:
38
+ * native_initialize(options={})
39
+ *
40
+ * Initializes the native spidermonkey values.
41
+ */
42
+ static VALUE
43
+ initialize_native(VALUE self, VALUE rb_runtime, VALUE UNUSED(options))
44
+ {
45
+ JohnsonContext* context;
46
+ JohnsonRuntime* runtime;
47
+
48
+ Data_Get_Struct(self, JohnsonContext, context);
49
+ Data_Get_Struct(rb_runtime, JohnsonRuntime, runtime);
50
+
51
+ if ((context->js = JS_NewContext(runtime->js, 8192)))
52
+ {
53
+ // See if the runtime already has a shared global object.
54
+ JSObject* global = runtime->global;
55
+
56
+ // If it does, use it. If not,
57
+ if (!global)
58
+ // create one of our global objects.
59
+ global = johnson_create_global_object(context->js);
60
+
61
+ // Manually set the context's global object.
62
+ JS_SetGlobalObject(context->js, global);
63
+ JS_SetErrorReporter(context->js, report_js_error);
64
+ JS_SetBranchCallback(context->js, branch_callback);
65
+ JS_SetContextPrivate(context->js, (void *)self);
66
+
67
+ JS_SetOptions(context->js, JS_GetOptions(context->js)
68
+ #ifdef JSOPTION_DONT_REPORT_UNCAUGHT
69
+ | JSOPTION_DONT_REPORT_UNCAUGHT
70
+ #endif
71
+ #ifdef JSOPTION_VAROBJFIX
72
+ | JSOPTION_VAROBJFIX
73
+ #endif
74
+ // #ifdef JSOPTION_XML
75
+ // | JSOPTION_XML
76
+ // #endif
77
+ );
78
+
79
+ // Success.
80
+ return init_spidermonkey_extensions(context, self);
81
+ }
82
+
83
+ if (context->js) JS_DestroyContext(context->js);
84
+
85
+ rb_raise(rb_eRuntimeError, "Failed to initialize SpiderMonkey context");
86
+ }
87
+
88
+ ///////////////////////////////////////////////////////////////////////////
89
+ //// INFRASTRUCTURE BELOW HERE ////////////////////////////////////////////
90
+ ///////////////////////////////////////////////////////////////////////////
91
+
92
+ static void deallocate(JohnsonContext* context)
93
+ {
94
+ JS_SetContextPrivate(context->js, 0);
95
+ JS_DestroyContext(context->js);
96
+ free(context);
97
+ }
98
+
99
+ static VALUE allocate(VALUE klass)
100
+ {
101
+ JohnsonContext* context = calloc(1, sizeof(JohnsonContext));
102
+ return Data_Wrap_Struct(klass, 0, deallocate, context);
103
+ }
104
+
105
+ void init_Johnson_SpiderMonkey_Context(VALUE spidermonkey)
106
+ {
107
+ /* HACK: These comments are *only* to make RDoc happy.
108
+ VALUE johnson = rb_define_module("Johnson");
109
+ VALUE spidermonkey = rb_define_module_under(johnson, "SpiderMonkey");
110
+ */
111
+
112
+ /* This is the private context used for SpiderMonkey. */
113
+ VALUE context = rb_define_class_under(spidermonkey, "Context", rb_cObject);
114
+
115
+ rb_define_alloc_func(context, allocate);
116
+ rb_define_private_method(context, "initialize_native", initialize_native, 2);
117
+ }
118
+
119
+ VALUE Johnson_SpiderMonkey_JSLandProxy()
120
+ {
121
+ return rb_eval_string("Johnson::SpiderMonkey::JSLandProxy");
122
+ }