kopia lustrzana https://github.com/backface/turtlestitch
fixed JS stack overflow issue for MAP primitive
rodzic
2ce7caf4f4
commit
fd7f8f803d
|
@ -67,6 +67,9 @@
|
||||||
* German
|
* German
|
||||||
* French
|
* French
|
||||||
|
|
||||||
|
### 2019-04-23
|
||||||
|
* Threads: fixed JS stack overflow issue for MAP primitive
|
||||||
|
|
||||||
### 2019-04-22
|
### 2019-04-22
|
||||||
* Threads: fixed variable binding for "arguments", turned dictionary key into a Symbol
|
* Threads: fixed variable binding for "arguments", turned dictionary key into a Symbol
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<script type="text/javascript" src="src/morphic.js?version=2019-02-07"></script>
|
<script type="text/javascript" src="src/morphic.js?version=2019-02-07"></script>
|
||||||
<script type="text/javascript" src="src/widgets.js?version=2019-04-05"></script>
|
<script type="text/javascript" src="src/widgets.js?version=2019-04-05"></script>
|
||||||
<script type="text/javascript" src="src/blocks.js?version=2019-04-11"></script>
|
<script type="text/javascript" src="src/blocks.js?version=2019-04-11"></script>
|
||||||
<script type="text/javascript" src="src/threads.js?version=2019-04-22"></script>
|
<script type="text/javascript" src="src/threads.js?version=2019-04-23"></script>
|
||||||
<script type="text/javascript" src="src/objects.js?version=2019-04-12"></script>
|
<script type="text/javascript" src="src/objects.js?version=2019-04-12"></script>
|
||||||
<script type="text/javascript" src="src/gui.js?version=2019-04-10"></script>
|
<script type="text/javascript" src="src/gui.js?version=2019-04-10"></script>
|
||||||
<script type="text/javascript" src="src/paint.js?version=2019-02-22"></script>
|
<script type="text/javascript" src="src/paint.js?version=2019-02-22"></script>
|
||||||
|
|
|
@ -62,7 +62,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy,
|
||||||
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, Color,
|
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, Color,
|
||||||
TableFrameMorph, ColorSlotMorph, isSnapObject, Map, newCanvas, Symbol*/
|
TableFrameMorph, ColorSlotMorph, isSnapObject, Map, newCanvas, Symbol*/
|
||||||
|
|
||||||
modules.threads = '2019-April-22';
|
modules.threads = '2019-April-23';
|
||||||
|
|
||||||
var ThreadManager;
|
var ThreadManager;
|
||||||
var Process;
|
var Process;
|
||||||
|
@ -1075,11 +1075,9 @@ Process.prototype.evaluate = function (
|
||||||
) {
|
) {
|
||||||
if (!context) {return null; }
|
if (!context) {return null; }
|
||||||
if (context instanceof Function) {
|
if (context instanceof Function) {
|
||||||
/*
|
// if (!this.enableJS) {
|
||||||
if (!this.enableJS) {
|
// throw new Error('JavaScript is not enabled');
|
||||||
throw new Error('JavaScript is not enabled');
|
// }
|
||||||
}
|
|
||||||
*/
|
|
||||||
return context.apply(
|
return context.apply(
|
||||||
this.blockReceiver(),
|
this.blockReceiver(),
|
||||||
args.asArray().concat([this])
|
args.asArray().concat([this])
|
||||||
|
@ -2071,58 +2069,59 @@ Process.prototype.reportMap = function (reporter, list) {
|
||||||
// answer a new list containing the results of the reporter applied
|
// answer a new list containing the results of the reporter applied
|
||||||
// to each value of the given list. Distinguish between linked and
|
// to each value of the given list. Distinguish between linked and
|
||||||
// arrayed lists.
|
// arrayed lists.
|
||||||
// Note: This method utilizes the current context's inputs array to
|
|
||||||
// manage temporary variables, whose allocation to which slot are
|
// this.context.inputs:
|
||||||
// documented in each of the variants' code (linked or arrayed) below
|
// [0] - reporter
|
||||||
|
// [1] - list (original source)
|
||||||
|
// -----------------------------
|
||||||
|
// [2] - last reporter evaluation result
|
||||||
|
|
||||||
var next;
|
var next;
|
||||||
if (list.isLinked) {
|
if (list.isLinked) {
|
||||||
// this.context.inputs:
|
if (this.context.aggregation === null) {
|
||||||
// [0] - reporter
|
this.context.aggregation = {
|
||||||
// [1] - list (original source)
|
source : list,
|
||||||
// -----------------------------
|
target : new List(),
|
||||||
// [2] - result list (target)
|
end : null,
|
||||||
// [3] - currently last element of result list
|
remaining : list.length()
|
||||||
// [4] - current source list (what's left to map)
|
};
|
||||||
// [5] - current value of last function call
|
this.context.aggregation.target.isLinked = true;
|
||||||
|
this.context.aggregation.end = this.context.aggregation.target;
|
||||||
if (this.context.inputs.length < 3) {
|
} else if (this.context.inputs.length > 2) {
|
||||||
this.context.addInput(new List());
|
this.context.aggregation.end.rest = list.cons(
|
||||||
this.context.inputs[2].isLinked = true;
|
this.context.inputs.pop()
|
||||||
this.context.addInput(this.context.inputs[2]);
|
);
|
||||||
this.context.addInput(list);
|
this.context.aggregation.end = this.context.aggregation.end.rest;
|
||||||
|
this.context.aggregation.remaining -= 1;
|
||||||
}
|
}
|
||||||
if (this.context.inputs[4].length() === 0) {
|
if (this.context.aggregation.remaining === 0) {
|
||||||
this.context.inputs[3].rest = list.cons(this.context.inputs[5]);
|
this.context.aggregation.end.rest = list.cons(
|
||||||
this.returnValueToParentContext(this.context.inputs[2].cdr());
|
this.context.inputs[2]
|
||||||
return;
|
).cdr();
|
||||||
}
|
|
||||||
if (this.context.inputs.length > 5) {
|
|
||||||
this.context.inputs[3].rest = list.cons(this.context.inputs[5]);
|
|
||||||
this.context.inputs[3] = this.context.inputs[3].rest;
|
|
||||||
this.context.inputs.splice(5);
|
|
||||||
}
|
|
||||||
next = this.context.inputs[4].at(1);
|
|
||||||
this.context.inputs[4] = this.context.inputs[4].cdr();
|
|
||||||
this.pushContext();
|
|
||||||
this.evaluate(reporter, new List([next]));
|
|
||||||
} else { // arrayed
|
|
||||||
// this.context.inputs:
|
|
||||||
// [0] - reporter
|
|
||||||
// [1] - list (original source)
|
|
||||||
// -----------------------------
|
|
||||||
// [2..n] - result values (target)
|
|
||||||
|
|
||||||
if (this.context.inputs.length - 2 === list.length()) {
|
|
||||||
this.returnValueToParentContext(
|
this.returnValueToParentContext(
|
||||||
new List(this.context.inputs.slice(2))
|
this.context.aggregation.target.cdr()
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
next = list.at(this.context.inputs.length - 1);
|
|
||||||
this.pushContext();
|
next = this.context.aggregation.source.at(1);
|
||||||
this.evaluate(reporter, new List([next]));
|
this.context.aggregation.source = this.context.aggregation.source.cdr();
|
||||||
|
} else { // arrayed
|
||||||
|
if (this.context.aggregation === null) {
|
||||||
|
this.context.aggregation = [];
|
||||||
|
} else if (this.context.inputs.length > 2) {
|
||||||
|
this.context.aggregation.push(this.context.inputs.pop());
|
||||||
|
}
|
||||||
|
if (this.context.aggregation.length === list.length()) {
|
||||||
|
this.returnValueToParentContext(
|
||||||
|
new List(this.context.aggregation)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
next = list.at(this.context.aggregation.length + 1);
|
||||||
}
|
}
|
||||||
|
this.pushContext();
|
||||||
|
this.evaluate(reporter, new List([next]));
|
||||||
};
|
};
|
||||||
|
|
||||||
Process.prototype.doForEach = function (upvar, list, script) {
|
Process.prototype.doForEach = function (upvar, list, script) {
|
||||||
|
@ -4819,6 +4818,7 @@ Process.prototype.reportAtomicGroup = function (list, reporter) {
|
||||||
tag string or number to optionally identify the Context,
|
tag string or number to optionally identify the Context,
|
||||||
as a "return" target (for the "stop block" primitive)
|
as a "return" target (for the "stop block" primitive)
|
||||||
isFlashing flag for single-stepping
|
isFlashing flag for single-stepping
|
||||||
|
aggregation slot for collecting data from reentrant visits
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Context(
|
function Context(
|
||||||
|
@ -4849,6 +4849,7 @@ function Context(
|
||||||
this.emptySlots = 0; // used for block reification
|
this.emptySlots = 0; // used for block reification
|
||||||
this.tag = null; // lexical catch-tag for custom blocks
|
this.tag = null; // lexical catch-tag for custom blocks
|
||||||
this.isFlashing = false; // for single-stepping
|
this.isFlashing = false; // for single-stepping
|
||||||
|
this.aggregation = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.prototype.toString = function () {
|
Context.prototype.toString = function () {
|
||||||
|
|
Ładowanie…
Reference in New Issue