Skip to content

Commit

Permalink
add PObject to accommodate unpacked object
Browse files Browse the repository at this point in the history
  • Loading branch information
ewfian committed Apr 13, 2023
1 parent 7364c67 commit d20c21c
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 26 deletions.
7 changes: 2 additions & 5 deletions examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@ import fs from 'node:fs/promises';
import path from 'node:path';
import { Parser } from '../';

class MyClass {}

async function unpickle(fname) {
const pkl = await fs.readFile(path.join(fname), 'binary');
const buffer = Buffer.from(pkl, 'binary');
const parser = new Parser(buffer);
parser.registry.register('__main__', 'MyClass', MyClass);
const obj = parser.load();
console.log(obj);
// =>
// MyClass {
// PObject {
// data: 'test',
// set: [ false, 1, 2, 3, 'abc', null, 4294967295, 9007199254740991 ],
// set: [ false, 1, 2, 3, null, 'abc', 4294967295, 9007199254740991 ],
// fruits: [ 'apple', 'banana', 'cherry', 'orange' ]
// }
}
Expand Down
20 changes: 11 additions & 9 deletions examples/set.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import pickle

class MyClass:
def __init__(self):
def __init__(self, s):
self.data = "test"
self.set = set([1, 2, 3])
self.set = s
self.fruits = ['apple', 'banana', 'cherry']

me = MyClass()
me.set.add('abc')
me.set.add(9007199254740991)
me.set.add(4294967295)
me.set.add(True)
me.set.add(False)
me.set.add(None)
s= set([1, 2, 3])
s.add('abc')
s.add(9007199254740991)
s.add(4294967295)
s.add(True)
s.add(False)
s.add(None)

me = MyClass(s)
me.fruits.append("orange")

filehandler = open(b"index.pkl", "wb")
Expand Down
15 changes: 5 additions & 10 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,14 @@ export class Parser {
const name = stack.pop();
const module = stack.pop();
const cls = this.resolveClass(module, name);
if (cls === undefined) {
throw new Error(`Cannot resolve: ${module}.${name}`);
}
stack.push(cls);
break;
}
case OP.GLOBAL: {
const module = reader.line();
const name = reader.line();
const cls = this.resolveClass(module, name);
if (cls === undefined) {
throw new Error(`Cannot resolve: ${module} ${name}`);
}
stack.push(cls);
break;
}
case OP.EMPTY_TUPLE:
Expand All @@ -62,7 +57,7 @@ export class Parser {
case OP.NEWOBJ: {
const args = stack.pop();
const cls = stack.pop();
const obj = this.newObject(cls, args);
const obj = this.newObject(cls, ...args);
stack.push(obj);
break;
}
Expand Down Expand Up @@ -292,7 +287,7 @@ export class Parser {
default:
// console.log('metastack:', metastack, '\nstack:', stack);
// console.log('\nmemo:', Array.from(memo.entries()));
throw new Error(`Unknown opcode '${opcode}'.`);
throw new Error(`Unsupported opcode '${opcode}'.`);
}
}
throw new Error('Unexpected end of file.');
Expand Down Expand Up @@ -326,11 +321,11 @@ export class Parser {
return number;
}

resolveClass(module: string, name: string): (new (...args: any[]) => any) | undefined {
resolveClass(module: string, name: string): new (...args: any[]) => any {
return this.registry.resolve(module, name);
}

newObject(cls: new (...args: any[]) => any, ...args: any[]) {
return new cls(args);
return new cls(...args);
}
}
18 changes: 16 additions & 2 deletions src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,26 @@ export class Registry extends Map<string, new (...args: any[]) => any> {
}
this.set(id, cls);
}
resolve(module: string, name: string): (new (...args: any[]) => any) | undefined {
resolve(module: string, name: string): new (...args: any[]) => any {
const id = this.getIdentity(name, module);
return this.get(id);
return this.get(id) || this.createNewPObject(module, name);
}

private getIdentity(module: string, name: string) {
return module + '.' + name;
}

private createNewPObject(module: string, name: string): new (...args: any[]) => any {
const PObject = function (this: any, ...args: any[]): any {
Object.defineProperty(this, 'args', {
value: args,
enumerable: false,
configurable: false,
writable: false,
});
} as unknown as new (...args: any[]) => any;
PObject.prototype.module = module;
PObject.prototype.name = name;
return PObject;
}
}

0 comments on commit d20c21c

Please sign in to comment.