envjs 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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