Starts playing with the execution stack

This commit is contained in:
Vivien Nicolas 2011-06-01 20:40:25 +02:00
parent e936f305d7
commit e739bcc515

View File

@ -155,9 +155,19 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
}, },
peek: function() { peek: function() {
if (!this.length)
return null;
return this.__innerStack__[this.__innerStack__.length - 1]; return this.__innerStack__[this.__innerStack__.length - 1];
}, },
toString: function() {
log("=== Start Dumping operandStack ===");
var str = [];
for (var i = 0; i < this.__innerStack__.length; i++)
log(this.__innerStack__[i]);
log("=== End Dumping operandStack ===");
},
get length() { get length() {
return this.__innerStack__.length; return this.__innerStack__.length;
} }
@ -194,9 +204,15 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
}, },
peek: function() { peek: function() {
if (!this.length)
return null;
return this.__innerStack__[this.__innerStack__.length - 1]; return this.__innerStack__[this.__innerStack__.length - 1];
}, },
get: function(aIndex) {
return this.__innerStack__[aIndex];
},
get length() { get length() {
return this.__innerStack__.length; return this.__innerStack__.length;
} }
@ -212,7 +228,42 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
* object off the execution stack and resumes executing the suspended object * object off the execution stack and resumes executing the suspended object
* beneath it. * beneath it.
*/ */
var executionStack = []; var executionStack = {
__innerStack__: [],
push: function(aProcedure) {
this.__innerStack__.push(aProcedure);
},
pop: function() {
return this.__innerStack__.pop();
},
peek: function() {
if (!this.length)
return null;
return this.__innerStack__[this.__innerStack__.length - 1];
},
get: function(aIndex) {
return this.__innerStack__[aIndex];
},
get length() {
return this.__innerStack__.length;
}
}
function nextInStack() {
var currentProcedure = executionStack.peek();
if (currentProcedure) {
var command = currentProcedure.shift();
if (!currentProcedure.length)
executionStack.pop();
}
return lexer.getObj();
}
/* /*
@ -222,29 +273,65 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
* The method thrown an error if it encounters an unknown token. * The method thrown an error if it encounters an unknown token.
*/ */
this.getObj = function() { this.getObj = function() {
var obj = lexer.getObj(); var obj = nextInStack();
if (operandIsArray && !IsCmd(obj, "{") && !IsCmd(obj, "[") && if (operandIsArray && !IsCmd(obj, "{") && !IsCmd(obj, "[") &&
!IsCmd(obj, "}") && !IsCmd(obj, "]")) { !IsCmd(obj, "}") && !IsCmd(obj, "]")) {
dump("Adding: " + obj);
operandStack.peek().push(obj); operandStack.peek().push(obj);
this.getObj(); this.getObj();
} else if (IsCmd(obj, "{") || IsCmd(obj, "[")) { } else if (IsCmd(obj, "{") || IsCmd(obj, "[")) {
dump("Start Array: " + obj); dump("Start" + (obj.cmd == "{" ? " Executable " : " ") + "Array");
operandStack.push([]); operandIsArray ? operandStack.peek().push([]) : operandStack.push([]);
operandIsArray++; operandIsArray++;
this.getObj(); this.getObj();
} else if (IsCmd(obj, "}") || IsCmd(obj, "]")) { } else if (IsCmd(obj, "}") || IsCmd(obj, "]")) {
dump("End Array: " + obj); dump("End" + (obj.cmd == "}" ? " Executable " : " ") + "Array");
operandIsArray--; operandIsArray--;
this.getObj(); this.getObj();
} else if (IsCmd(obj, "if")) {
log("if");
var procedure = operandStack.pop();
var bool = operandStack.pop();
if (!IsBool(bool)) {
executionStack.push(bool);
log(".....");
this.getObj();
}
log(bool);
if (bool)
executionStack.push(procedure);
this.getObj();
} else if (IsCmd(obj, "ifelse")) {
log("ifelse");
var procedure1 = operandStack.pop();
var procedure2 = operandStack.pop();
var bool = !!operandStack.pop();
operandStack.push(bool ? procedure1 : procedure2);
this.getObj();
} else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) { } else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) {
//dump("Value: " + obj); dump("Value: " + obj);
operandStack.push(obj); operandStack.push(obj);
this.getObj(); this.getObj();
} else if (IsCmd(obj, "dup")) { } else if (IsCmd(obj, "dup")) {
dump("Duplicate"); dump("Duplicate");
operandStack.push(operandStack.peek()); operandStack.push(operandStack.peek());
this.getObj(); this.getObj();
} else if (IsCmd(obj, "put") || IsCmd(obj, "NP")) {
operandStack.toString();
var data = operandStack.pop();
var indexOrKey = operandStack.pop();
var object = operandStack.pop();
log(object);
log("put " + data + " in " + obj + "[" + indexOrKey + "]");
if (object.set)
object.set(indexOrKey, data);
else
object[indexOrKey] = data;
this.getObj();
} else if (IsCmd(obj, "currentdict")) { } else if (IsCmd(obj, "currentdict")) {
dump("currentdict"); dump("currentdict");
operandStack.push(dictionaryStack.peek()); operandStack.push(dictionaryStack.peek());
@ -254,13 +341,18 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
operandStack.push(systemDict); operandStack.push(systemDict);
this.getObj(); this.getObj();
} else if (IsCmd(obj, "readonly") || IsCmd(obj, "executeonly") || } else if (IsCmd(obj, "readonly") || IsCmd(obj, "executeonly") ||
IsCmd(obj, "currentfile") || IsCmd(obj, "NP")) { IsCmd(obj, "noaccess") || IsCmd(obj, "currentfile")) {
// Do nothing for the moment // Do nothing for the moment
this.getObj(); this.getObj();
} else if (IsName(obj)) { } else if (IsName(obj)) {
//dump("Name: " + obj.name); //dump("Name: " + obj.name);
operandStack.push(obj.name); operandStack.push(obj.name);
this.getObj(); this.getObj();
} else if (IsCmd(obj, "array")) {
var size = operandStack.pop();
var array = new Array(size);
operandStack.push(array);
this.getObj();
} else if (IsCmd(obj, "dict")) { } else if (IsCmd(obj, "dict")) {
dump("Dict: " + obj); dump("Dict: " + obj);
var size = operandStack.pop(); var size = operandStack.pop();
@ -275,10 +367,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
dump("Ending a dictionary"); dump("Ending a dictionary");
dictionaryStack.pop(); dictionaryStack.pop();
this.getObj(); this.getObj();
} else if (IsCmd(obj, "def")) { } else if (IsCmd(obj, "def") || IsCmd(obj, "ND")) {
var value = operandStack.pop(); var value = operandStack.pop();
var key = operandStack.pop(); var key = operandStack.pop();
dump("def: " + key + " = " + value); log("def: " + key + " = " + value);
dictionaryStack.peek().set(key, value); dictionaryStack.peek().set(key, value);
this.getObj(); this.getObj();
} else if (IsCmd(obj, "eexec")) { } else if (IsCmd(obj, "eexec")) {
@ -292,8 +384,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
dump("known"); dump("known");
var name = operandStack.pop(); var name = operandStack.pop();
var dict = operandStack.pop(); var dict = operandStack.pop();
// returns dict.hasKey(name); operandStack.push(!!dict.get(name));
this.getObj(); this.getObj();
} else if (IsCmd(obj, "RD")) { } else if (IsCmd(obj, "RD")) {
dump("RD"); dump("RD");
@ -311,21 +402,50 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
dictionaryStack.peek().set(key, charStream); dictionaryStack.peek().set(key, charStream);
var decodedCharString = decodeCharString(charStream); var decodedCharString = decodeCharString(charStream);
log(decodedCharString); dump(decodedCharString);
this.getObj(); this.getObj();
} else if (IsCmd(obj, "LenIV")) { } else if (IsCmd(obj, "LenIV")) {
error("LenIV: argh! we need to modify the length of discard characters for charStrings"); error("LenIV: argh! we need to modify the length of discard characters for charStrings");
} else if (IsCmd(obj, "closefile")) { } else if (IsCmd(obj, "closefile")) {
// End of binary data; // End of binary data;
} else if (IsCmd(obj, "index")) {
var operands = [];
var size = operandStack.pop();
for (var i = 0; i < size; i++)
operands.push(operandStack.pop());
var newOperand = operandStack.peek();
for (var i = 0; i < operands.length; i++)
operandStack.push(operands.pop());
operandStack.push(newOperand);
this.getObj();
} else if (IsCmd(obj, "StandardEncoding")) { } else if (IsCmd(obj, "StandardEncoding")) {
// For some reason the value is considered as a command, maybe it is // For some reason the value is considered as a command, maybe it is
// because of the uppercae 'S' // because of the uppercae 'S'
operandStack.push(obj.cmd); operandStack.push(obj.cmd);
this.getObj(); this.getObj();
} else { } else {
dump(obj); var command = null;
error("Unknow token while parsing font"); if (IsCmd(obj)) {
for (var i = 0; i < dictionaryStack.length; i++) {
command = dictionaryStack.get(i).get(obj.cmd);
if (command)
break;
}
}
if (command) {
// XXX add the command to the execution stack
this.getObj();
} else {
log("operandStack: " + operandStack);
log("dictionaryStack: " + dictionaryStack);
dump(obj);
error("Unknow token while parsing font");
}
} }
return operandStack.peek(); return operandStack.peek();