Skip to content

Commit

Permalink
Upgrade to quickjs-ng
Browse files Browse the repository at this point in the history
  • Loading branch information
kvinwang committed Feb 20, 2024
1 parent c7b0c68 commit 55a7849
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 14 deletions.
2 changes: 1 addition & 1 deletion qjs-sys
Submodule qjs-sys updated 52 files
+3 −0 .gitmodules
+0 −1 qjs-sys/Cargo.toml
+7 −16 qjs-sys/build.rs
+10 −10 qjs-sys/csrc/Makefile
+1 −1 qjs-sys/csrc/c2rust.sh
+0 −631 qjs-sys/csrc/cutils.c
+0 −297 qjs-sys/csrc/cutils.h
+0 −816 qjs-sys/csrc/ext/buffer-utils.c
+0 −346 qjs-sys/csrc/ext/buffer-utils.h
+0 −432 qjs-sys/csrc/ext/char-utils.h
+0 −165 qjs-sys/csrc/ext/debug.h
+0 −179 qjs-sys/csrc/ext/defines.h
+0 −149 qjs-sys/csrc/ext/js-utils.c
+0 −40 qjs-sys/csrc/ext/js-utils.h
+0 −172 qjs-sys/csrc/ext/queue.c
+0 −76 qjs-sys/csrc/ext/queue.h
+0 −289 qjs-sys/csrc/ext/quickjs-blob.c
+0 −52 qjs-sys/csrc/ext/quickjs-blob.h
+0 −40 qjs-sys/csrc/ext/quickjs-ext.c
+0 −26 qjs-sys/csrc/ext/quickjs-ext.h
+0 −1,755 qjs-sys/csrc/ext/quickjs-stream.c
+0 −181 qjs-sys/csrc/ext/quickjs-stream.h
+0 −305 qjs-sys/csrc/ext/stream-utils.c
+0 −78 qjs-sys/csrc/ext/stream-utils.h
+0 −3,179 qjs-sys/csrc/ext/utils.c
+0 −1,153 qjs-sys/csrc/ext/utils.h
+0 −299 qjs-sys/csrc/ext/vector.c
+0 −242 qjs-sys/csrc/ext/vector.h
+0 −8,476 qjs-sys/csrc/libbf.c
+0 −535 qjs-sys/csrc/libbf.h
+0 −57 qjs-sys/csrc/libregexp-opcode.h
+0 −2,529 qjs-sys/csrc/libregexp.c
+0 −93 qjs-sys/csrc/libregexp.h
+0 −4,486 qjs-sys/csrc/libunicode-table.h
+0 −1,788 qjs-sys/csrc/libunicode.c
+0 −127 qjs-sys/csrc/libunicode.h
+0 −99 qjs-sys/csrc/list.h
+1 −1 qjs-sys/csrc/qjs-pink.c
+1 −4 qjs-sys/csrc/qjs-pink.h
+0 −564 qjs-sys/csrc/qjs.c
+1 −0 qjs-sys/csrc/quickjs
+0 −273 qjs-sys/csrc/quickjs-atom.h
+0 −60 qjs-sys/csrc/quickjs-libc.h
+0 −372 qjs-sys/csrc/quickjs-opcode.h
+0 −55,664 qjs-sys/csrc/quickjs.c
+0 −1,191 qjs-sys/csrc/quickjs.h
+0 −2,958 qjs-sys/csrc/repl.c
+0 −1,591 qjs-sys/csrc/repl.js
+66 −76 qjs-sys/src/inline32.rs
+61 −79 qjs-sys/src/inline64.rs
+0 −1 qjsbind/Cargo.toml
+1 −1 qjsbind/src/value.rs
2 changes: 1 addition & 1 deletion sidevm-quickjs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ Cargo.lock
node_modules
yarn.lock
/web/dist
web.tar.gz
phatjs-web.tar.gz
3 changes: 1 addition & 2 deletions sidevm-quickjs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sidevm-quickjs"
version = "0.9.6"
version = "0.10.0"
authors = ["[your_name] <[your_email]>"]
edition = "2021"

Expand Down Expand Up @@ -60,7 +60,6 @@ js-url = []
js-http-listen = []
js-hash = ["sha2", "sha3", "blake2"]

stream = ["js/stream"]
sidevm = []
web = ["js-sys", "web-sys", "wasm-bindgen", "wasm-bindgen-futures", "reqwest"]
mem-stats = ["phala-allocator", "js/pink-allocator"]
Expand Down
1 change: 1 addition & 0 deletions sidevm-quickjs/bootcode/js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "./polyfill-url";
import "./polyfill-xhr";
import "./sidevm";
import "./polyfill-abortcontroller";
import "./polyfill-blob";

import { Headers } from "headers-polyfill";
globalThis.Headers = Headers;
244 changes: 244 additions & 0 deletions sidevm-quickjs/bootcode/js/src/polyfill-blob.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
// 64 KiB (same size chrome slice theirs blob into Uint8array's)
const POOL_SIZE = 65536;
const { isView } = ArrayBuffer;

/**
* @param {(Blob | Uint8Array)[]} parts
* @returns {AsyncIterableIterator<Uint8Array>}
*/
async function * toIterator (parts) {
for (const part of parts) {
if (isView(part)) {
let position = part.byteOffset;
const end = part.byteOffset + part.byteLength;

while (position !== end) {
const size = Math.min(end - position, POOL_SIZE);
const chunk = part.buffer.slice(position, position + size);

position += chunk.byteLength;
yield new Uint8Array(chunk);
}
} else {
yield * part.stream();
}
}
}

class Blob {
/** @type {Array.<(Blob|Uint8Array)>} */
__parts = [];
#type = '';
__size = 0;
#endings = 'transparent';

/**
* The Blob() constructor returns a new Blob object. The content
* of the blob consists of the concatenation of the values given
* in the parameter array.
*
* @param {*} blobParts
* @param {{ type?: string, endings?: string }} [options]
*/
constructor (blobParts = [], options = {}) {
if (typeof blobParts !== 'object' || blobParts === null) {
throw new TypeError('Failed to construct \'Blob\': The provided value cannot be converted to a sequence.');
}

if (typeof blobParts[Symbol.iterator] !== 'function') {
throw new TypeError('Failed to construct \'Blob\': The object must have a callable @@iterator property.');
}

if (typeof options !== 'object' && typeof options !== 'function') {
throw new TypeError('Failed to construct \'Blob\': parameter 2 cannot convert to dictionary.');
}

if (options === null) {
options = {};
}


const encoder = new TextEncoder();

for (const element of blobParts) {
let part;

if (isView(element)) {
part = new Uint8Array(
element.buffer.slice(
element.byteOffset,
element.byteOffset + element.byteLength
)
);
} else if (element instanceof ArrayBuffer) {
part = new Uint8Array(element.slice(0));
} else if (element instanceof Blob) {
part = element;
} else {
part = encoder.encode(`${element}`);
}

const size = isView(part) ? part.byteLength : part.size;

// Avoid pushing empty parts into the array to better GC them
if (size) {
this.__size += size;
this.__parts.push(part);
}
}

this.#endings = `${options.endings === undefined ? 'transparent' : options.endings}`;
const type = options.type === undefined ? '' : String(options.type);

this.#type = /^[\x20-\x7E]*$/.test(type) ? type : '';
}

/**
* The Blob interface's size property returns the
* size of the Blob in bytes.
*/
get size () {
return this.__size;
}

/**
* The type property of a Blob object returns the MIME type of the file.
*/
get type () {
return this.#type;
}

/**
* The text() method in the Blob interface returns a Promise
* that resolves with a string containing the contents of
* the blob, interpreted as UTF-8.
*
* @return {Promise<string>}
*/
async text () {
// More optimized than using this.arrayBuffer()
// that requires twice as much ram
const decoder = new TextDecoder();
let str = '';

for await (const part of this.stream()) {
str += decoder.decode(part, { stream: true });
}

// Remaining
str += decoder.decode();

return str;
}

/**
* The arrayBuffer() method in the Blob interface returns a
* Promise that resolves with the contents of the blob as
* binary data contained in an ArrayBuffer.
*
* @return {Promise<ArrayBuffer>}
*/
async arrayBuffer () {
const data = new Uint8Array(this.size);
let offset = 0;

for await (const chunk of this.stream()) {
data.set(chunk, offset);
offset += chunk.length;
}

return data.buffer;
}

stream () {
const it = toIterator(this.__parts);

return new ReadableStream({
type: 'bytes',
async pull (ctrl) {
const chunk = await it.next();

chunk.done ? ctrl.close() : ctrl.enqueue(chunk.value);
},

async cancel () {
await it.return();
}
});
}

/**
* The Blob interface's slice() method creates and returns a
* new Blob object which contains data from a subset of the
* blob on which it's called.
*
* @param {number} [start]
* @param {number} [end]
* @param {string} [type]
*/
slice (start = 0, end = this.size, type = '') {
const { size } = this;

let relativeStart = start < 0 ? Math.max(size + start, 0) : Math.min(start, size);
let relativeEnd = end < 0 ? Math.max(size + end, 0) : Math.min(end, size);

const span = Math.max(relativeEnd - relativeStart, 0);
const parts = this.__parts;
const blobParts = [];
let added = 0;

for (const part of parts) {
// don't add the overflow to new blobParts
if (added >= span) {
break;
}

const size = isView(part) ? part.byteLength : part.size;

if (relativeStart && size <= relativeStart) {
// Skip the beginning and change the relative
// start & end position as we skip the unwanted parts
relativeStart -= size;
relativeEnd -= size;
} else {
let chunk;

if (isView(part)) {
chunk = part.subarray(relativeStart, Math.min(size, relativeEnd));
added += chunk.byteLength;
} else {
chunk = part.slice(relativeStart, Math.min(size, relativeEnd));
added += chunk.size;
}

relativeEnd -= size;
blobParts.push(chunk);
relativeStart = 0; // All next sequential parts should start at 0
}
}

const blob = new Blob([], { type: `${type}` });

blob.__size = span;
blob.__parts = blobParts;

return blob;
}

get [Symbol.toStringTag] () {
return 'Blob';
}
}

Object.defineProperties(Blob.prototype, {
size: { enumerable: true },
type: { enumerable: true },
slice: { enumerable: true }
});

Object.defineProperty(globalThis, 'Blob', {
enumerable: true,
configurable: true,
writable: true,
value: Blob
});
10 changes: 0 additions & 10 deletions sidevm-quickjs/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,22 +132,12 @@ impl Default for ServiceState {
}
}

pub fn ctx_init(ctx: &js::Context) {
unsafe {
let ctx = ctx.as_ptr();
#[cfg(feature = "stream")]
c::js_stream_init(ctx);
c::js_blob_init(ctx);
};
}

impl Service {
pub(crate) fn new(weak_self: ServiceWeakRef) -> Self {
let runtime = js::Runtime::new();
let ctx = runtime.new_context();
let boxed_self = Box::into_raw(Box::new(weak_self));
unsafe { c::JS_SetContextOpaque(ctx.as_ptr(), boxed_self as *mut _) };
ctx_init(&ctx);
setup_host_functions(&ctx).expect("Failed to setup host functions");
let bootcode = Code::Bytecode(bootcode::BOOT_CODE);
ctx.eval(&bootcode).expect("Failed to eval bootcode");
Expand Down

0 comments on commit 55a7849

Please sign in to comment.