2014-08-07 04:04:44 +04:00
|
|
|
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
2014-08-07 10:57:44 +04:00
|
|
|
function Runtime(vm) {
|
|
|
|
this.vm = vm;
|
2014-08-07 23:31:48 +04:00
|
|
|
this.status = 1; // NEW
|
2014-08-07 21:10:54 +04:00
|
|
|
this.waiting = [];
|
|
|
|
this.threadCount = 0;
|
2014-08-07 04:15:04 +04:00
|
|
|
this.initialized = {};
|
|
|
|
this.pending = {};
|
|
|
|
this.staticFields = {};
|
2014-08-07 21:10:54 +04:00
|
|
|
this.classObjects = {};
|
|
|
|
}
|
|
|
|
|
2014-08-07 22:46:11 +04:00
|
|
|
Runtime.prototype.waitStatus = function(callback) {
|
|
|
|
this.waiting.push(callback);
|
|
|
|
}
|
|
|
|
|
2014-08-07 23:31:48 +04:00
|
|
|
Runtime.prototype.updateStatus = function(status) {
|
2014-08-07 22:46:11 +04:00
|
|
|
this.status = status;
|
2014-08-07 23:12:57 +04:00
|
|
|
var waiting = this.waiting;
|
|
|
|
this.waiting = [];
|
|
|
|
waiting.forEach(function(callback) {
|
2014-08-08 01:29:25 +04:00
|
|
|
try {
|
2014-08-07 22:46:11 +04:00
|
|
|
callback();
|
2014-08-08 02:08:56 +04:00
|
|
|
} catch(ex) {
|
2014-08-08 01:29:25 +04:00
|
|
|
// If the callback calls Runtime.prototype.waitStatus to continue waiting,
|
2014-08-08 02:08:56 +04:00
|
|
|
// then waitStatus will throw VM.Pause, which shouldn't propagate up to
|
|
|
|
// the caller of Runtime.prototype.updateStatus, so we silently ignore it
|
|
|
|
// (along with any other exceptions thrown by the callback, so they don't
|
|
|
|
// propagate to the caller of updateStatus).
|
2014-08-08 01:29:25 +04:00
|
|
|
}
|
2014-08-07 22:46:11 +04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-08-09 00:04:40 +04:00
|
|
|
Runtime.all = new Set();
|
|
|
|
|
2014-08-07 21:10:54 +04:00
|
|
|
Runtime.prototype.addContext = function(ctx) {
|
|
|
|
++this.threadCount;
|
2014-08-09 00:04:40 +04:00
|
|
|
Runtime.all.add(this);
|
2014-08-07 21:10:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
Runtime.prototype.removeContext = function(ctx) {
|
2014-08-09 00:04:40 +04:00
|
|
|
if (!--this.threadCount) {
|
|
|
|
Runtime.all.delete(this);
|
2014-08-07 23:31:48 +04:00
|
|
|
this.updateStatus(4); // STOPPED
|
2014-08-09 00:04:40 +04:00
|
|
|
}
|
2014-08-07 04:04:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
Runtime.prototype.newPrimitiveArray = function(type, size) {
|
|
|
|
var constructor = ARRAYS[type];
|
|
|
|
if (!constructor.prototype.class)
|
|
|
|
CLASSES.initPrimitiveArrayType(type, constructor);
|
|
|
|
return new constructor(size);
|
|
|
|
}
|
|
|
|
|
|
|
|
Runtime.prototype.newArray = function(typeName, size) {
|
|
|
|
return new (CLASSES.getClass(typeName).constructor)(size);
|
|
|
|
}
|
|
|
|
|
|
|
|
Runtime.prototype.newMultiArray = function(typeName, lengths) {
|
|
|
|
var length = lengths[0];
|
|
|
|
var array = this.newArray(typeName, length);
|
|
|
|
if (lengths.length > 1) {
|
|
|
|
lengths = lengths.slice(1);
|
|
|
|
for (var i=0; i<length; i++)
|
|
|
|
array[i] = this.newMultiArray(typeName.substr(1), lengths);
|
|
|
|
}
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
|
|
|
|
Runtime.prototype.newObject = function(classInfo) {
|
|
|
|
return new (classInfo.constructor)();
|
|
|
|
}
|
|
|
|
|
|
|
|
Runtime.prototype.newString = function(s) {
|
|
|
|
var obj = this.newObject(CLASSES.java_lang_String);
|
2014-09-26 21:57:15 +04:00
|
|
|
obj.str = s;
|
2014-09-24 23:52:39 +04:00
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2014-08-07 09:06:14 +04:00
|
|
|
Runtime.prototype.setStatic = function(field, value) {
|
|
|
|
this.staticFields[field.id] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
Runtime.prototype.getStatic = function(field) {
|
|
|
|
return this.staticFields[field.id];
|
|
|
|
}
|