envjs 0.1.3 → 0.1.4

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.
@@ -0,0 +1,204 @@
1
+ (function(){
2
+ if ($master.eventLoop) {
3
+ throw new Error("event loop multiply defined");
4
+ }
5
+ var el = $master.eventLoop = {};
6
+
7
+ var $env = {};
8
+ $env.sync = function(f){return f;};
9
+ $env.error = function(s){
10
+ print("timer error: "+s);
11
+ if (s.stack) {
12
+ print("timer error: "+s.stack);
13
+ }
14
+ };
15
+ $env.sleep = function(t){ Ruby.sleep(t/1000.); };
16
+
17
+ var $timers = [];
18
+ var $event_loop_running = false;
19
+ $timers.lock = $env.sync(function(fn){fn();});
20
+
21
+ var $timer = function(w, fn, interval){
22
+ this.w = w;
23
+ this.fn = fn;
24
+ this.interval = interval;
25
+ this.at = Date.now() + interval;
26
+ this.running = false; // allows for calling wait() from callbacks
27
+ };
28
+
29
+ var convert_time = function(time) {
30
+ time = time*1;
31
+ if ( isNaN(time) || time < 0 ) {
32
+ time = 0;
33
+ }
34
+ // html5 says this should be at least 4, but the parser is using a setTimeout for the SAX stuff
35
+ // which messes up the world
36
+ var min = /* 4 */ 0;
37
+ if ( $event_loop_running && time < min ) {
38
+ time = min;
39
+ }
40
+ return time;
41
+ };
42
+
43
+ var enter_and_exec = function(w,fn) {
44
+
45
+ };
46
+
47
+ el.setTimeout = function(w, fn, time){
48
+ var num;
49
+ time = convert_time(time);
50
+ $timers.lock(function(){
51
+ num = $timers.length+1;
52
+ var tfn;
53
+ if (typeof fn == 'string') {
54
+ tfn = function() {
55
+ try {
56
+ eval(fn);
57
+ } catch (e) {
58
+ $env.error(e);
59
+ } finally {
60
+ el.clearInterval(num);
61
+ }
62
+ };
63
+ } else {
64
+ tfn = function() {
65
+ try {
66
+ fn();
67
+ } catch (e) {
68
+ $env.error(e);
69
+ } finally {
70
+ el.clearInterval(num);
71
+ }
72
+ };
73
+ }
74
+ $timers[num] = new $timer(w, tfn, time);
75
+ });
76
+ return num;
77
+ };
78
+
79
+ el.setInterval = function(w, fn, time){
80
+ time = convert_time(time);
81
+ if ( time < 10 ) {
82
+ time = 10;
83
+ }
84
+ if (typeof fn == 'string') {
85
+ var fnstr = fn;
86
+ fn = function() {
87
+ eval(fnstr);
88
+ };
89
+ }
90
+ var num;
91
+ $timers.lock(function(){
92
+ num = $timers.length+1;
93
+ $timers[num] = new $timer(w, fn, time);
94
+ });
95
+ return num;
96
+ };
97
+
98
+ el.clear = el.clearInterval = el.clearTimeout = function(num){
99
+ //$log("clearing interval "+num);
100
+ $timers.lock(function(){
101
+ if ( $timers[num] ) {
102
+ delete $timers[num];
103
+ }
104
+ });
105
+ };
106
+
107
+ // wait === null/undefined: execute any timers as they fire, waiting until there are none left
108
+ // wait(n) (n > 0): execute any timers as they fire until there are none left waiting at least n ms
109
+ // but no more, even if there are future events/current threads
110
+ // wait(0): execute any immediately runnable timers and return
111
+ // wait(-n): keep sleeping until the next event is more than n ms in the future
112
+
113
+ // FIX: make a priority queue ...
114
+
115
+ el.wait = function(wait) {
116
+ // print("wait",wait,$event_loop_running);
117
+ var fired = false;
118
+ var delta_wait;
119
+ if (wait < 0) {
120
+ delta_wait = -wait;
121
+ wait = 0;
122
+ }
123
+ var start = Date.now();
124
+ var old_loop_running = $event_loop_running;
125
+ $event_loop_running = true;
126
+ if (wait !== 0 && wait !== null && wait !== undefined){
127
+ wait += Date.now();
128
+ }
129
+ for (;;) {
130
+ var earliest;
131
+ $timers.lock(function(){
132
+ earliest = undefined;
133
+ for(var i in $timers){
134
+ if( isNaN(i*0) ) {
135
+ continue;
136
+ }
137
+ var timer = $timers[i];
138
+ if( !timer.running && ( !earliest || timer.at < earliest.at) ) {
139
+ earliest = timer;
140
+ }
141
+ }
142
+ });
143
+ var sleep = earliest && earliest.at - Date.now();
144
+ if ( earliest && sleep <= 0 ) {
145
+ var f = earliest.fn;
146
+ var previous = $master.first_script_window;
147
+ fired = true;
148
+ try {
149
+ earliest.running = true;
150
+ $master.first_script_window = earliest.w;
151
+ f();
152
+ } catch (e) {
153
+ $env.error(e);
154
+ } finally {
155
+ earliest.running = false;
156
+ $master.first_script_window = previous;
157
+ }
158
+ var goal = earliest.at + earliest.interval;
159
+ var now = Date.now();
160
+ if ( goal < now ) {
161
+ earliest.at = now;
162
+ } else {
163
+ earliest.at = goal;
164
+ }
165
+ continue;
166
+ }
167
+
168
+ // bunch of subtle cases here ...
169
+ if ( !earliest ) {
170
+ // no events in the queue (but maybe XHR will bring in events, so ...
171
+ if ( !wait || wait < Date.now() ) {
172
+ // Loop ends if there are no events and a wait hasn't been requested or has expired
173
+ break;
174
+ }
175
+ // no events, but a wait requested: fall through to sleep
176
+ } else {
177
+ // there are events in the queue, but they aren't firable now
178
+ // print(delta_wait,sleep);
179
+ if ( delta_wait && sleep <= delta_wait ) {
180
+ // if they will happen within the next delta, fall through to sleep
181
+ } else if ( wait === 0 || ( wait > 0 && wait < Date.now () ) ) {
182
+ // loop ends even if there are events but the user specifcally asked not to wait too long
183
+ break;
184
+ }
185
+ // there are events and the user wants to wait: fall through to sleep
186
+ }
187
+
188
+ // Related to ajax threads ... hopefully can go away ..
189
+ var interval = el.wait.interval || 100;
190
+ if ( !sleep || sleep > interval ) {
191
+ sleep = interval;
192
+ }
193
+ // the parser sets the timeout at 1 ... the chances of us getting back through this loop in that amount of time
194
+ // are small, no need to both the driver for something so small; just spin
195
+ if (sleep>1) {
196
+ $env.sleep(sleep);
197
+ }
198
+ }
199
+ $event_loop_running = old_loop_running;
200
+ // print("unwait",earliest,sleep);
201
+ return [ fired, earliest && sleep ];
202
+ };
203
+
204
+ }());
data/lib/envjs/runtime.rb CHANGED
@@ -11,7 +11,59 @@ module Envjs::Runtime
11
11
  def self.extended object
12
12
  object.instance_eval do
13
13
 
14
- evaluate <<'EOJS'
14
+ outer = nil
15
+ scripts = {}
16
+
17
+ master = global["$master"] = evaluate("new Object", nil, nil, nil, global)
18
+
19
+ ( class << self; self; end ).send :define_method, :master do
20
+ master
21
+ end
22
+
23
+ ( class << self; self; end ).send :define_method, :evaluate do |*args|
24
+ ( script, file, line, global, scope, fn ) = *args
25
+ scope ||= outer["$inner"]
26
+ raise "cannot evaluate nil script" if script.nil?
27
+ raise "cannot evaluate without a scope" if scope.nil?
28
+ raise "outer given when inner needed" if !scope == global and !scope["isInner"]
29
+ # print "eval in " + script[0,50].inspect + scope.inspect + " " + ( scope ? scope.isInner.inspect : "none" ) + "\n"
30
+ global = nil
31
+ # scope ||= inner
32
+ if fn
33
+ compiled_script = scripts[fn]
34
+ end
35
+ compiled_script ||= compile(script, file, line, global)
36
+ raise "hell" if !compiled_script
37
+ if fn && !scripts[fn]
38
+ scripts[fn] = compiled_script
39
+ end
40
+ save = master["first_script_window"]
41
+ if false
42
+ p scope
43
+ if master["first_script_window"]
44
+ print "ignored: " + ( scope["location"] ? scope["location"]["href"] : "nil" ) + " using " + ( master["first_script_window"]["location"] ? master["first_script_window"]["location"]["href"] : "nil" ) + "\n"
45
+ else
46
+ print "pushing into " + ( scope["location"] ? scope["location"]["href"] : "nil" ) + "\n"
47
+ end
48
+ end
49
+
50
+ master["first_script_window"] ||= scope
51
+ raise "hell" if !master["first_script_window"]["isInner"] && master["first_script_window"] != self.global
52
+ v = nil
53
+ begin
54
+ v = evaluate_compiled_script(compiled_script,scope)
55
+ # p "pe", v, compiled_script, scope
56
+ rescue Exception => e
57
+ # p "oopsrt", e
58
+ raise e
59
+ ensure
60
+ master["first_script_window"] = save
61
+ end
62
+ # print "done\n"
63
+ v
64
+ end
65
+
66
+ evaluate( <<'EOJS', nil, nil, nil, global )
15
67
  print = function() {
16
68
  var l = arguments.length
17
69
  for( var i = 0; i < l; i++ ) {
@@ -33,7 +85,7 @@ print = function() {
33
85
  };
34
86
  EOJS
35
87
 
36
- evaluate <<'EOJS'
88
+ evaluate <<'EOJS', nil, nil, nil, global
37
89
  debug = function() {
38
90
  var l = arguments.length
39
91
  for( var i = 0; i < l; i++ ) {
@@ -54,7 +106,7 @@ debug = function() {
54
106
  };
55
107
  EOJS
56
108
 
57
- evaluate <<'EOJS'
109
+ evaluate <<'EOJS', nil, nil, nil, global
58
110
  puts = function() {
59
111
  var l = arguments.length
60
112
  for( var i = 0; i < l; i++ ) {
@@ -72,10 +124,15 @@ puts = function() {
72
124
  };
73
125
  EOJS
74
126
 
75
- master = global["$master"] = evaluate("new Object")
76
127
  master["runtime"] = self
77
- master.symbols = [ "Johnson", "Ruby", "print", "debug", "puts", "load", "reload", "whichInterpreter", "multiwindow" ]
128
+ window_index = -1
129
+ master["next_window_index"] = lambda { window_index += 1 }
130
+ master.symbols = [ "Johnson", "Ruby", "print", "debug", "puts", "load", "reload", "whichInterpreter", "multiwindow", "seal" ]
78
131
  master.symbols.each { |symbol| master[symbol] = global[symbol] }
132
+ master["seal"] = lambda do |*args|
133
+ object, deep = *args
134
+ seal object, deep
135
+ end
79
136
 
80
137
  master.whichInterpreter = "Johnson"
81
138
 
@@ -180,8 +237,10 @@ EOJS
180
237
 
181
238
  master.load = lambda { |*files|
182
239
  if files.length == 2 && !(String === files[1])
240
+ # now = Time.now
183
241
  f = files[0]
184
242
  w = files[1]
243
+ # p "load", f, w
185
244
 
186
245
  # Hmmm ...
187
246
  uri = URI.parse f
@@ -206,6 +265,7 @@ EOJS
206
265
  loc = nil
207
266
  add_dep.call w, f
208
267
  evaluate(v, f, 1, w, w, f)
268
+ # print "load #{uri_s}: #{Time.now-now}\n"
209
269
  else
210
270
  load *files
211
271
  end
@@ -265,63 +325,43 @@ EOJS
265
325
  # create an proto window object and proxy
266
326
 
267
327
  outer = new_split_global_outer
268
- window = inner = new_split_global_inner( outer )
328
+ inner = new_split_global_inner( outer )
269
329
 
270
330
  master.symbols.each do |symbol|
271
- window[symbol] = master[symbol]
331
+ inner[symbol] = master[symbol]
272
332
  end
273
333
 
274
- master.first_script_window = window
334
+ inner["$inner"] = inner
335
+ inner["$master"] = master
336
+ inner["$options"] = evaluate("new Object", nil, nil, nil, inner);
337
+ inner["$options"].proxy = outer
275
338
 
276
- window["$inner"] = inner
277
- window["$master"] = master
278
- window["$options"] = evaluate("new Object");
279
- window["$options"].proxy = outer
280
-
281
- window.evaluate = lambda { |s|
282
- return master.evaluate.call(s,window);
339
+ inner.evaluate = lambda { |s|
340
+ return master.evaluate.call(s,inner);
283
341
  }
284
342
 
285
- window.load = lambda { |*files|
343
+ inner.load = lambda { |*files|
286
344
  files.each do |f|
287
- master.load.call f, window
345
+ master.load.call f, inner
288
346
  end
289
347
  }
290
348
 
291
- window.reload = lambda { |*files|
349
+ inner.reload = lambda { |*files|
292
350
  files.each do |f|
293
- master.reload.call f, window
351
+ master.reload.call f, inner
294
352
  end
295
353
  }
296
354
 
297
355
  ( class << self; self; end ).send :define_method, :wait do
298
356
  master["finalize"] && master.finalize.call
299
- master.timers && master.timers.wait
357
+ master.eventLoop && master.eventLoop.wait
300
358
  end
301
359
 
302
- scripts = {}
303
-
304
- ( class << self; self; end ).send :define_method, :become_first_script_window do
360
+ ( class << self; self; end ).send :define_method, :_become_first_script_window do
305
361
  # p "heh ++++++++++++++++++++++++++++", inner, master.first_script_window
306
362
  inner = master.first_script_window
307
363
  end
308
364
 
309
- ( class << self; self; end ).send :define_method, :evaluate do |*args|
310
- ( script, file, line, global, scope, fn ) = *args
311
- raise "cannot evaluate nil script" if script.nil?
312
- # print "eval in " + script[0,50].inspect + scope.inspect + " " + ( scope ? scope.isInner.inspect : "none" ) + "\n"
313
- global = nil
314
- scope ||= inner
315
- if fn
316
- compiled_script = scripts[fn]
317
- end
318
- compiled_script ||= compile(script, file, line, global)
319
- if fn && !scripts[fn]
320
- scripts[fn] = compiled_script
321
- end
322
- evaluate_compiled_script(compiled_script,scope)
323
- end
324
-
325
365
  ( class << self; self; end ).send :define_method, :reevaluate do |*args|
326
366
  ( script, file, line, global, scope, fn ) = *args
327
367
  raise "cannot evaluate nil script" if script.nil?
@@ -332,20 +372,58 @@ EOJS
332
372
  if fn
333
373
  scripts[fn] = compiled_script
334
374
  end
335
- evaluate_compiled_script(compiled_script,scope)
375
+ begin
376
+ evaluate_compiled_script(compiled_script,scope)
377
+ rescue Exception => e
378
+ p e
379
+ raise e
380
+ end
336
381
  end
337
382
 
338
- @envjs = inner
339
-
340
383
  ( class << self; self; end ).send :define_method, :"[]" do |key|
341
- key == "this" && evaluate("this") || @envjs[key]
384
+ # key == "this" && evaluate("this", nil, nil, nil, inner) || @envjs[key]
385
+ key == "this" && outer || outer[key]
342
386
  end
343
387
 
344
388
  ( class << self; self; end ).send :define_method, :"[]=" do |k,v|
345
- @envjs[k] = v
389
+ # inner[k] = v
390
+ outer[k] = v
391
+ end
392
+
393
+ master.load.call Envjs::EVENT_LOOP, global
394
+
395
+ if false
396
+ static_outer = new_split_global_outer
397
+ static_inner = new_split_global_inner static_outer
398
+
399
+ master.symbols.each do |symbol|
400
+ static_inner[symbol] = master[symbol]
401
+ end
402
+
403
+ static_inner["$inner"] = static_inner
404
+ static_inner["$master"] = master
405
+
406
+ master.load.call Envjs::STATIC, static_inner
407
+
408
+ master["static"] = static_inner
409
+ end
410
+ if true
411
+ static = new_global
412
+
413
+ master.symbols.each do |symbol|
414
+ static[symbol] = master[symbol]
346
415
  end
347
416
 
348
- load Envjs::ENVJS
417
+ static["$master"] = master
418
+
419
+ master.load.call Envjs::STATIC, static
420
+
421
+ master["static"] = static
422
+ end
423
+
424
+ master.load.call Envjs::ENVJS, inner
425
+
426
+ inner = nil
349
427
  end
350
428
  end
351
429