Skip to content

Commit

Permalink
support EXT1, EXT2, EXT4
Browse files Browse the repository at this point in the history
  • Loading branch information
ewfian committed Apr 16, 2023
1 parent b32a08f commit ce25cb3
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 11 deletions.
12 changes: 12 additions & 0 deletions examples/ext.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import copyreg, copy, pickle

class MyList(list):
sample = [1, 2, 3]

copyreg.add_extension(__name__, "MyList", 0x60000023)
x = MyList([1, 2, 3])
x.foo = 42
x.bar = "hello"

filehandler = open(b"ext.pkl", "wb")
pickle.dump(x, filehandler, 2)
58 changes: 47 additions & 11 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,29 @@ import { OP } from './opcode';
import { Reader } from './reader';
import { Registry } from './registry';

export interface ParserOptions {
onPersistentLoad: (pid: string) => any;
onExtensionLoad: (extCode: number) => any;
}

const DefualtParserOptions: ParserOptions = {
onPersistentLoad(pid) {
throw new Error(`Unregistered persistent id: \`${pid}\`.`);
},
onExtensionLoad(extCode) {
throw new Error(`Unregistered extension code: \`${extCode.toString(16)}\`.`);
},
};

export class Parser {
private _reader: Reader;
public persistent_load: (pid: string) => any;

options: ParserOptions;
registry: Registry = new Registry();

constructor(buffer: Uint8Array | Int8Array | Uint8ClampedArray, persistent_load?: (pid: string) => any) {
constructor(buffer: Uint8Array | Int8Array | Uint8ClampedArray, options: ParserOptions = DefualtParserOptions) {
this._reader = new Reader(buffer);
this.persistent_load =
persistent_load ||
((pid: string) => {
throw new Error(`Unsupported persistent id: \`${pid}\`.`);
});
this.options = options;
}

load() {
Expand Down Expand Up @@ -280,6 +290,26 @@ export class Parser {
break;
}

// Exts
case OP.EXT1: {
const extCode = reader.byte();
const cls = this.options.onExtensionLoad(extCode);
stack.push(cls);
break;
}
case OP.EXT2: {
const extCode = reader.uint16();
const cls = this.options.onExtensionLoad(extCode);
stack.push(cls);
break;
}
case OP.EXT4: {
const extCode = reader.uint32();
const cls = this.options.onExtensionLoad(extCode);
stack.push(cls);
break;
}

// Module globals
case OP.GLOBAL: {
const module = reader.line();
Expand Down Expand Up @@ -333,12 +363,18 @@ export class Parser {
stack.push(obj);
break;
}
case OP.PERSID:
stack.push(this.persistent_load(reader.line()));
case OP.PERSID: {
const pid = reader.line();
const cls = this.options.onPersistentLoad(pid);
stack.push(cls);
break;
case OP.BINPERSID:
stack.push(this.persistent_load(stack.pop()));
}
case OP.BINPERSID: {
const pid = stack.pop();
const cls = this.options.onPersistentLoad(pid);
stack.push(cls);
break;
}
case OP.REDUCE: {
const args = stack.pop();
const func = stack.pop();
Expand Down

0 comments on commit ce25cb3

Please sign in to comment.