in the middle of namespacing the exports from the runtime
This commit is contained in:
parent
c461152e39
commit
7b8eb2b04f
|
@ -46,7 +46,7 @@
|
||||||
[(EnvPrefixReference? target)
|
[(EnvPrefixReference? target)
|
||||||
(assemble-prefix-reference target)]
|
(assemble-prefix-reference target)]
|
||||||
[(PrimitivesReference? target)
|
[(PrimitivesReference? target)
|
||||||
(format "Primitives[~s]" (symbol->string (PrimitivesReference-name target)))]))
|
(format "MACHINE.primitives[~s]" (symbol->string (PrimitivesReference-name target)))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
23
assemble.rkt
23
assemble.rkt
|
@ -24,6 +24,7 @@
|
||||||
(let ([basic-blocks (fracture stmts)])
|
(let ([basic-blocks (fracture stmts)])
|
||||||
(fprintf op "(function(MACHINE, success, fail, params) {\n")
|
(fprintf op "(function(MACHINE, success, fail, params) {\n")
|
||||||
(fprintf op "var param;\n")
|
(fprintf op "var param;\n")
|
||||||
|
(fprintf op "var RUNTIME = plt.runtime;\n")
|
||||||
(for-each (lambda: ([basic-block : BasicBlock])
|
(for-each (lambda: ([basic-block : BasicBlock])
|
||||||
(displayln (assemble-basic-block basic-block) op)
|
(displayln (assemble-basic-block basic-block) op)
|
||||||
(newline op))
|
(newline op))
|
||||||
|
@ -38,7 +39,7 @@ for (param in params) {
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
(fprintf op "trampoline(MACHINE, ~a); })"
|
(fprintf op "RUNTIME.trampoline(MACHINE, ~a); })"
|
||||||
(BasicBlock-name (first basic-blocks)))))
|
(BasicBlock-name (first basic-blocks)))))
|
||||||
|
|
||||||
|
|
||||||
|
@ -265,10 +266,10 @@ EOF
|
||||||
(assemble-jump (GotoStatement-target stmt))]
|
(assemble-jump (GotoStatement-target stmt))]
|
||||||
|
|
||||||
[(PushControlFrame? stmt)
|
[(PushControlFrame? stmt)
|
||||||
(format "MACHINE.control.push(new CallFrame(~a, MACHINE.proc));" (PushControlFrame-label stmt))]
|
(format "MACHINE.control.push(new RUNTIME.CallFrame(~a, MACHINE.proc));" (PushControlFrame-label stmt))]
|
||||||
[(PushControlFrame/Prompt? stmt)
|
[(PushControlFrame/Prompt? stmt)
|
||||||
;; fixme: use a different frame structure
|
;; fixme: use a different frame structure
|
||||||
(format "MACHINE.control.push(new PromptFrame(~a, ~a));"
|
(format "MACHINE.control.push(new RUNTIME.PromptFrame(~a, ~a));"
|
||||||
(PushControlFrame/Prompt-label stmt)
|
(PushControlFrame/Prompt-label stmt)
|
||||||
(let ([tag (PushControlFrame/Prompt-tag stmt)])
|
(let ([tag (PushControlFrame/Prompt-tag stmt)])
|
||||||
(cond
|
(cond
|
||||||
|
@ -332,7 +333,7 @@ EOF
|
||||||
"MACHINE.proc.label"]
|
"MACHINE.proc.label"]
|
||||||
|
|
||||||
[(MakeCompiledProcedure? op)
|
[(MakeCompiledProcedure? op)
|
||||||
(format "new Closure(~a, ~a, [~a], ~a)"
|
(format "new RUNTIME.Closure(~a, ~a, [~a], ~a)"
|
||||||
(MakeCompiledProcedure-label op)
|
(MakeCompiledProcedure-label op)
|
||||||
(MakeCompiledProcedure-arity op)
|
(MakeCompiledProcedure-arity op)
|
||||||
(string-join (map assemble-env-reference/closure-capture
|
(string-join (map assemble-env-reference/closure-capture
|
||||||
|
@ -345,7 +346,7 @@ EOF
|
||||||
(assemble-display-name (MakeCompiledProcedure-display-name op)))]
|
(assemble-display-name (MakeCompiledProcedure-display-name op)))]
|
||||||
|
|
||||||
[(MakeCompiledProcedureShell? op)
|
[(MakeCompiledProcedureShell? op)
|
||||||
(format "new Closure(~a, ~a, undefined, ~a)"
|
(format "new RUNTIME.Closure(~a, ~a, undefined, ~a)"
|
||||||
(MakeCompiledProcedureShell-label op)
|
(MakeCompiledProcedureShell-label op)
|
||||||
(MakeCompiledProcedureShell-arity op)
|
(MakeCompiledProcedureShell-arity op)
|
||||||
(assemble-display-name (MakeCompiledProcedureShell-display-name op)))]
|
(assemble-display-name (MakeCompiledProcedureShell-display-name op)))]
|
||||||
|
@ -362,7 +363,7 @@ EOF
|
||||||
(CaptureEnvironment-skip op))]
|
(CaptureEnvironment-skip op))]
|
||||||
|
|
||||||
[(CaptureControl? op)
|
[(CaptureControl? op)
|
||||||
(format "captureControl(MACHINE, ~a, ~a)"
|
(format "RUNTIME.captureControl(MACHINE, ~a, ~a)"
|
||||||
(CaptureControl-skip op)
|
(CaptureControl-skip op)
|
||||||
(let ([tag (CaptureControl-tag op)])
|
(let ([tag (CaptureControl-tag op)])
|
||||||
(cond [(DefaultContinuationPromptTag? tag)
|
(cond [(DefaultContinuationPromptTag? tag)
|
||||||
|
@ -381,7 +382,7 @@ EOF
|
||||||
|
|
||||||
(: assemble-default-continuation-prompt-tag (-> String))
|
(: assemble-default-continuation-prompt-tag (-> String))
|
||||||
(define (assemble-default-continuation-prompt-tag)
|
(define (assemble-default-continuation-prompt-tag)
|
||||||
"DEFAULT_CONTINUATION_PROMPT_TAG")
|
"RUNTIME.DEFAULT_CONTINUATION_PROMPT_TAG")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -399,7 +400,7 @@ EOF
|
||||||
(CheckToplevelBound!-pos op))]
|
(CheckToplevelBound!-pos op))]
|
||||||
|
|
||||||
[(CheckClosureArity!? op)
|
[(CheckClosureArity!? op)
|
||||||
(format "if (! (MACHINE.proc instanceof Closure && MACHINE.proc.arity === ~a)) { if (! (MACHINE.proc instanceof Closure)) { throw new Error(\"not a closure\"); } else { throw new Error(\"arity failure\"); } }"
|
(format "if (! (MACHINE.proc instanceof RUNTIME.Closure && MACHINE.proc.arity === ~a)) { if (! (MACHINE.proc instanceof RUNTIME.Closure)) { throw new Error(\"not a closure\"); } else { throw new Error(\"arity failure\"); } }"
|
||||||
(CheckClosureArity!-arity op))]
|
(CheckClosureArity!-arity op))]
|
||||||
|
|
||||||
[(ExtendEnvironment/Prefix!? op)
|
[(ExtendEnvironment/Prefix!? op)
|
||||||
|
@ -407,13 +408,13 @@ EOF
|
||||||
(format "MACHINE.env.push([~a]); MACHINE.env[MACHINE.env.length-1].names = [~a];"
|
(format "MACHINE.env.push([~a]); MACHINE.env[MACHINE.env.length-1].names = [~a];"
|
||||||
(string-join (map (lambda: ([n : (U Symbol False ModuleVariable)])
|
(string-join (map (lambda: ([n : (U Symbol False ModuleVariable)])
|
||||||
(cond [(symbol? n)
|
(cond [(symbol? n)
|
||||||
(format "MACHINE.params.currentNamespace[~s] || Primitives[~s]"
|
(format "MACHINE.params.currentNamespace[~s] || MACHINE.primitives[~s]"
|
||||||
(symbol->string n)
|
(symbol->string n)
|
||||||
(symbol->string n))]
|
(symbol->string n))]
|
||||||
[(eq? n #f)
|
[(eq? n #f)
|
||||||
"false"]
|
"false"]
|
||||||
[(ModuleVariable? n)
|
[(ModuleVariable? n)
|
||||||
(format "Primitives[~s]"
|
(format "MACHINE.primitives[~s]"
|
||||||
(symbol->string (ModuleVariable-name n)))]))
|
(symbol->string (ModuleVariable-name n)))]))
|
||||||
names)
|
names)
|
||||||
",")
|
",")
|
||||||
|
@ -433,7 +434,7 @@ EOF
|
||||||
[(RestoreEnvironment!? op)
|
[(RestoreEnvironment!? op)
|
||||||
"MACHINE.env = MACHINE.env[MACHINE.env.length - 2].slice(0);"]
|
"MACHINE.env = MACHINE.env[MACHINE.env.length - 2].slice(0);"]
|
||||||
[(RestoreControl!? op)
|
[(RestoreControl!? op)
|
||||||
(format "restoreControl(MACHINE, ~a);"
|
(format "RUNTIME.restoreControl(MACHINE, ~a);"
|
||||||
(let ([tag (RestoreControl!-tag op)])
|
(let ([tag (RestoreControl!-tag op)])
|
||||||
(cond
|
(cond
|
||||||
[(DefaultContinuationPromptTag? tag)
|
[(DefaultContinuationPromptTag? tag)
|
||||||
|
|
157
runtime.js
157
runtime.js
|
@ -1,53 +1,111 @@
|
||||||
// Type representations:
|
if(this['plt'] === undefined) {
|
||||||
|
this['plt'] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// All of the values here are namespaced under "plt.runtime".
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
this['plt']['runtime'] = {};
|
||||||
|
var exports = this['plt']['runtime'];
|
||||||
|
|
||||||
|
|
||||||
|
var Machine = function() {
|
||||||
|
this.callsBeforeTrampoline = 100;
|
||||||
|
this.val = undefined;
|
||||||
|
this.proc = undefined;
|
||||||
|
this.env = [];
|
||||||
|
this.control = []; // Arrayof (U CallFrame PromptFrame)
|
||||||
|
this.running = false;
|
||||||
|
this.params = { currentDisplayer: function(v) {},
|
||||||
|
|
||||||
|
currentSuccessHandler: function(MACHINE) {},
|
||||||
|
currentErrorHandler: function(MACHINE, exn) {},
|
||||||
|
|
||||||
|
currentNamespace: {},
|
||||||
|
|
||||||
|
// These parameters control how often
|
||||||
|
// control yields back to the browser
|
||||||
|
// for response. The implementation is a
|
||||||
|
// simple PID controller.
|
||||||
//
|
//
|
||||||
// number are numbers
|
// To tune this, adjust desiredYieldsPerSecond.
|
||||||
//
|
// Do no touch numBouncesBeforeYield or
|
||||||
// cons pairs are [first, rest]
|
// maxNumBouncesBeforeYield, because those
|
||||||
//
|
// are adjusted automatically by the
|
||||||
// function closures are Closures
|
// recomputeMaxNumBouncesBeforeYield
|
||||||
// primitive procedures are regular functions.
|
// procedure.
|
||||||
|
desiredYieldsPerSecond: 5,
|
||||||
|
numBouncesBeforeYield: 2000, // self-adjusting
|
||||||
|
maxNumBouncesBeforeYield: 2000 // self-adjusting
|
||||||
|
};
|
||||||
|
this.primitives = Primitives;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// No error trapping at the moment.
|
// Control stack elements:
|
||||||
|
|
||||||
|
|
||||||
|
// A CallFrame represents a call stack frame.
|
||||||
var CallFrame = function(label, proc) {
|
var CallFrame = function(label, proc) {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.proc = proc;
|
this.proc = proc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// PromptFrame represents a prompt frame.
|
||||||
var PromptFrame = function(label, tag) {
|
var PromptFrame = function(label, tag) {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.tag = tag;
|
this.tag = tag; // ContinuationPromptTag
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Function types: a function is either a Primitive or a Closure.
|
||||||
|
|
||||||
|
// A Primitive is a function that's expected to return. It is not
|
||||||
|
// allowed to call into Closures. Its caller is expected to pop off
|
||||||
|
// its argument stack space.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// A Closure is a function that takes on more responsibilities: it is
|
||||||
|
// responsible for popping off stack space before it finishes, and it
|
||||||
|
// is also explicitly responsible for continuing the computation by
|
||||||
|
// popping off the control stack and doing the jump. Because of this,
|
||||||
|
// closures can do pretty much anything to the machine.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// A closure consists of its free variables as well as a label
|
// A closure consists of its free variables as well as a label
|
||||||
// into its text segment.
|
// into its text segment.
|
||||||
var Closure = function(label, arity, closedVals, displayName) {
|
var Closure = function(label, arity, closedVals, displayName) {
|
||||||
this.label = label;
|
this.label = label; // (MACHINE -> void)
|
||||||
this.arity = arity;
|
this.arity = arity; // number
|
||||||
this.closedVals = closedVals;
|
this.closedVals = closedVals; // arrayof number
|
||||||
this.displayName = displayName;
|
this.displayName = displayName; // string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// A continuation prompt tag labels a prompt frame.
|
||||||
var ContinuationPromptTag = function(name) {
|
var ContinuationPromptTag = function(name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// There is a single, distinguished default continuation prompt tag
|
||||||
|
// that's used to wrap around toplevel prompts.
|
||||||
var DEFAULT_CONTINUATION_PROMPT_TAG =
|
var DEFAULT_CONTINUATION_PROMPT_TAG =
|
||||||
new ContinuationPromptTag("default-continuation-prompt-tag");
|
new ContinuationPromptTag("default-continuation-prompt-tag");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// A primitive function is just a Javascript function.
|
// A primitive function is just a Javascript function.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// testArgument: (X -> boolean) X number string string -> boolean
|
// testArgument: (X -> boolean) X number string string -> boolean
|
||||||
// Produces true if val is true, and otherwise raises an error.
|
// Produces true if val is true, and otherwise raises an error.
|
||||||
var testArgument = function(expectedTypeName,
|
var testArgument = function(expectedTypeName,
|
||||||
|
@ -67,7 +125,9 @@ var testArgument = function(expectedTypeName,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// captureControl implements the continuation-capturing part of
|
||||||
|
// call/cc. It grabs the control frames up to (but not including) the
|
||||||
|
// prompt tagged by the given tag.
|
||||||
var captureControl = function(MACHINE, skip, tag) {
|
var captureControl = function(MACHINE, skip, tag) {
|
||||||
var i;
|
var i;
|
||||||
for (i = MACHINE.control.length - 1 - skip; i >= 0; i--) {
|
for (i = MACHINE.control.length - 1 - skip; i >= 0; i--) {
|
||||||
|
@ -80,6 +140,11 @@ var captureControl = function(MACHINE, skip, tag) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// restoreControl clears the control stack (up to, but not including the
|
||||||
|
// prompt tagged by tag), and then appends the rest of the control frames.
|
||||||
|
// At the moment, the rest of the control frames is assumed to be in the
|
||||||
|
// top of the environment.
|
||||||
var restoreControl = function(MACHINE, tag) {
|
var restoreControl = function(MACHINE, tag) {
|
||||||
var i;
|
var i;
|
||||||
for (i = MACHINE.control.length - 1; i >= 0; i--) {
|
for (i = MACHINE.control.length - 1; i >= 0; i--) {
|
||||||
|
@ -103,8 +168,13 @@ var isNumber = function(x) { return typeof(x) === 'number'; };
|
||||||
var raise = function(e) { throw e; }
|
var raise = function(e) { throw e; }
|
||||||
|
|
||||||
|
|
||||||
var Primitives = (function() {
|
|
||||||
var NULL = [];
|
var NULL = [];
|
||||||
|
|
||||||
|
|
||||||
|
// Primtitives are the set of primitive values. Not all primitives
|
||||||
|
// are coded here; several of them (including call/cc) are injected by
|
||||||
|
// the bootstrapping code.
|
||||||
|
var Primitives = (function() {
|
||||||
return {
|
return {
|
||||||
'display': function(MACHINE, arity) {
|
'display': function(MACHINE, arity) {
|
||||||
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
var firstArg = MACHINE.env[MACHINE.env.length-1];
|
||||||
|
@ -424,40 +494,10 @@ var Primitives = (function() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var MACHINE = { callsBeforeTrampoline: 100,
|
|
||||||
val:undefined,
|
|
||||||
proc:undefined,
|
|
||||||
env: [],
|
|
||||||
control : [],
|
|
||||||
running : false,
|
|
||||||
params: { currentDisplayer: function(v) {},
|
|
||||||
|
|
||||||
currentSuccessHandler: function(MACHINE) {},
|
|
||||||
currentErrorHandler: function(MACHINE, exn) {},
|
|
||||||
|
|
||||||
currentNamespace: {},
|
|
||||||
|
|
||||||
// These parameters control how often
|
|
||||||
// control yields back to the browser
|
|
||||||
// for response. The implementation is a
|
|
||||||
// simple PID controller.
|
|
||||||
//
|
|
||||||
// To tune this, adjust desiredYieldsPerSecond.
|
|
||||||
// Do no touch numBouncesBeforeYield or
|
|
||||||
// maxNumBouncesBeforeYield, because those
|
|
||||||
// are adjusted automatically by the
|
|
||||||
// recomputeMaxNumBouncesBeforeYield
|
|
||||||
// procedure.
|
|
||||||
desiredYieldsPerSecond: 5,
|
|
||||||
numBouncesBeforeYield: 2000, // self-adjusting
|
|
||||||
maxNumBouncesBeforeYield: 2000 // self-adjusting
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// recomputeGas: state number -> number
|
// recomputeGas: state number -> number
|
||||||
var recomputeMaxNumBouncesBeforeYield = function(observedDelay) {
|
var recomputeMaxNumBouncesBeforeYield = function(MACHINE, observedDelay) {
|
||||||
// We'd like to see a delay of DESIRED_DELAY_BETWEEN_BOUNCES so
|
// We'd like to see a delay of DESIRED_DELAY_BETWEEN_BOUNCES so
|
||||||
// that we get MACHINE.params.desiredYieldsPerSecond bounces per
|
// that we get MACHINE.params.desiredYieldsPerSecond bounces per
|
||||||
// second.
|
// second.
|
||||||
|
@ -492,6 +532,7 @@ var trampoline = function(MACHINE, initialJump) {
|
||||||
|
|
||||||
if (MACHINE.params.numBouncesBeforeYield-- < 0) {
|
if (MACHINE.params.numBouncesBeforeYield-- < 0) {
|
||||||
recomputeMaxNumBouncesBeforeYield(
|
recomputeMaxNumBouncesBeforeYield(
|
||||||
|
MACHINE,
|
||||||
(new Date()).valueOf() - startTime);
|
(new Date()).valueOf() - startTime);
|
||||||
setTimeout(
|
setTimeout(
|
||||||
function() {
|
function() {
|
||||||
|
@ -509,3 +550,23 @@ var trampoline = function(MACHINE, initialJump) {
|
||||||
MACHINE.running = false;
|
MACHINE.running = false;
|
||||||
return MACHINE.params.currentSuccessHandler(MACHINE);
|
return MACHINE.params.currentSuccessHandler(MACHINE);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Exports
|
||||||
|
exports.Machine = Machine;
|
||||||
|
exports.CallFrame = CallFrame;
|
||||||
|
exports.PromptFrame = PromptFrame;
|
||||||
|
exports.Closure = Closure;
|
||||||
|
exports.ContinuationPromptTag = ContinuationPromptTag;
|
||||||
|
exports.DEFAULT_CONTINUATION_PROMPT_TAG = DEFAULT_CONTINUATION_PROMPT_TAG;
|
||||||
|
exports.testArgument = testArgument;
|
||||||
|
exports.captureControl = captureControl;
|
||||||
|
exports.restoreControl = restoreControl;
|
||||||
|
exports.isNumber = isNumber;
|
||||||
|
exports.raise = raise;
|
||||||
|
exports.NULL = NULL;
|
||||||
|
exports.trampoline = trampoline;
|
||||||
|
|
||||||
|
}).call(this);
|
|
@ -43,6 +43,7 @@
|
||||||
"(function() { "
|
"(function() { "
|
||||||
|
|
||||||
runtime
|
runtime
|
||||||
|
"var MACHINE = new plt.runtime.Machine();\n"
|
||||||
|
|
||||||
"return function(success, fail, params){"
|
"return function(success, fail, params){"
|
||||||
snippet
|
snippet
|
||||||
|
@ -59,10 +60,9 @@
|
||||||
(let* ([a-statement (car a-statement+inspector)]
|
(let* ([a-statement (car a-statement+inspector)]
|
||||||
[inspector (cdr a-statement+inspector)])
|
[inspector (cdr a-statement+inspector)])
|
||||||
|
|
||||||
(display "(function() { " op)
|
|
||||||
|
|
||||||
(display runtime op)
|
(display runtime op)
|
||||||
|
(display "var MACHINE = new plt.runtime.Machine();\n" op)
|
||||||
|
(display "(function() { " op)
|
||||||
(display "var myInvoke = " op)
|
(display "var myInvoke = " op)
|
||||||
(assemble/write-invoke a-statement op)
|
(assemble/write-invoke a-statement op)
|
||||||
(display ";" op)
|
(display ";" op)
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
(fprintf op #<<EOF
|
(fprintf op #<<EOF
|
||||||
return (function(succ, fail, params) {
|
return (function(succ, fail, params) {
|
||||||
return innerInvoke(MACHINE, succ, fail, params);
|
return innerInvoke(new plt.runtime.Machine(), succ, fail, params);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
EOF
|
EOF
|
||||||
|
|
Loading…
Reference in New Issue
Block a user