jbarnette-johnson 1.0.0.200806240111

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.
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
+ }