mirror of
https://github.com/bellard/quickjs.git
synced 2025-09-30 23:07:42 +03:00
2020-07-05 release
This commit is contained in:
@@ -31,6 +31,7 @@ static JSValue js_bjson_read(JSContext *ctx, JSValueConst this_val,
|
||||
uint64_t pos, len;
|
||||
JSValue obj;
|
||||
size_t size;
|
||||
int flags;
|
||||
|
||||
if (JS_ToIndex(ctx, &pos, argv[1]))
|
||||
return JS_EXCEPTION;
|
||||
@@ -41,7 +42,10 @@ static JSValue js_bjson_read(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_EXCEPTION;
|
||||
if (pos + len > size)
|
||||
return JS_ThrowRangeError(ctx, "array buffer overflow");
|
||||
obj = JS_ReadObject(ctx, buf + pos, len, 0);
|
||||
flags = 0;
|
||||
if (JS_ToBool(ctx, argv[3]))
|
||||
flags |= JS_READ_OBJ_REFERENCE;
|
||||
obj = JS_ReadObject(ctx, buf + pos, len, flags);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -51,8 +55,12 @@ static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val,
|
||||
size_t len;
|
||||
uint8_t *buf;
|
||||
JSValue array;
|
||||
int flags;
|
||||
|
||||
buf = JS_WriteObject(ctx, &len, argv[0], 0);
|
||||
flags = 0;
|
||||
if (JS_ToBool(ctx, argv[1]))
|
||||
flags |= JS_WRITE_OBJ_REFERENCE;
|
||||
buf = JS_WriteObject(ctx, &len, argv[0], flags);
|
||||
if (!buf)
|
||||
return JS_EXCEPTION;
|
||||
array = JS_NewArrayBufferCopy(ctx, buf, len);
|
||||
@@ -61,8 +69,8 @@ static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val,
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_bjson_funcs[] = {
|
||||
JS_CFUNC_DEF("read", 3, js_bjson_read ),
|
||||
JS_CFUNC_DEF("write", 1, js_bjson_write ),
|
||||
JS_CFUNC_DEF("read", 4, js_bjson_read ),
|
||||
JS_CFUNC_DEF("write", 2, js_bjson_write ),
|
||||
};
|
||||
|
||||
static int js_bjson_init(JSContext *ctx, JSModuleDef *m)
|
||||
|
@@ -228,6 +228,19 @@ function prop_create(n)
|
||||
return n * 4;
|
||||
}
|
||||
|
||||
function prop_delete(n)
|
||||
{
|
||||
var obj, j;
|
||||
obj = {};
|
||||
for(j = 0; j < n; j++) {
|
||||
obj[j] = 1;
|
||||
}
|
||||
for(j = 0; j < n; j++) {
|
||||
delete obj[j];
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
function array_read(n)
|
||||
{
|
||||
var tab, len, sum, i, j;
|
||||
@@ -945,6 +958,7 @@ function main(argc, argv, g)
|
||||
prop_read,
|
||||
prop_write,
|
||||
prop_create,
|
||||
prop_delete,
|
||||
array_read,
|
||||
array_write,
|
||||
array_prop_create,
|
||||
|
@@ -1,12 +1,20 @@
|
||||
import * as bjson from "./bjson.so";
|
||||
|
||||
function assert(b, str)
|
||||
{
|
||||
if (b) {
|
||||
function assert(actual, expected, message) {
|
||||
if (arguments.length == 1)
|
||||
expected = true;
|
||||
|
||||
if (actual === expected)
|
||||
return;
|
||||
} else {
|
||||
throw Error("assertion failed: " + str);
|
||||
}
|
||||
|
||||
if (actual !== null && expected !== null
|
||||
&& typeof actual == 'object' && typeof expected == 'object'
|
||||
&& actual.toString() === expected.toString())
|
||||
return;
|
||||
|
||||
throw Error("assertion failed: got |" + actual + "|" +
|
||||
", expected |" + expected + "|" +
|
||||
(message ? " (" + message + ")" : ""));
|
||||
}
|
||||
|
||||
function toHex(a)
|
||||
@@ -24,6 +32,20 @@ function toHex(a)
|
||||
return s;
|
||||
}
|
||||
|
||||
function isArrayLike(a)
|
||||
{
|
||||
return Array.isArray(a) ||
|
||||
(a instanceof Uint8ClampedArray) ||
|
||||
(a instanceof Uint8Array) ||
|
||||
(a instanceof Uint16Array) ||
|
||||
(a instanceof Uint32Array) ||
|
||||
(a instanceof Int8Array) ||
|
||||
(a instanceof Int16Array) ||
|
||||
(a instanceof Int32Array) ||
|
||||
(a instanceof Float32Array) ||
|
||||
(a instanceof Float64Array);
|
||||
}
|
||||
|
||||
function toStr(a)
|
||||
{
|
||||
var s, i, props, prop;
|
||||
@@ -32,7 +54,15 @@ function toStr(a)
|
||||
case "object":
|
||||
if (a === null)
|
||||
return "null";
|
||||
if (Array.isArray(a)) {
|
||||
if (a instanceof Date) {
|
||||
s = "Date(" + toStr(a.valueOf()) + ")";
|
||||
} else if (a instanceof Number) {
|
||||
s = "Number(" + toStr(a.valueOf()) + ")";
|
||||
} else if (a instanceof String) {
|
||||
s = "String(" + toStr(a.valueOf()) + ")";
|
||||
} else if (a instanceof Boolean) {
|
||||
s = "Boolean(" + toStr(a.valueOf()) + ")";
|
||||
} else if (isArrayLike(a)) {
|
||||
s = "[";
|
||||
for(i = 0; i < a.length; i++) {
|
||||
if (i != 0)
|
||||
@@ -85,6 +115,35 @@ function bjson_test(a)
|
||||
}
|
||||
}
|
||||
|
||||
/* test multiple references to an object including circular
|
||||
references */
|
||||
function bjson_test_reference()
|
||||
{
|
||||
var array, buf, i, n, array_buffer;
|
||||
n = 16;
|
||||
array = [];
|
||||
for(i = 0; i < n; i++)
|
||||
array[i] = {};
|
||||
array_buffer = new ArrayBuffer(n);
|
||||
for(i = 0; i < n; i++) {
|
||||
array[i].next = array[(i + 1) % n];
|
||||
array[i].idx = i;
|
||||
array[i].typed_array = new Uint8Array(array_buffer, i, 1);
|
||||
}
|
||||
buf = bjson.write(array, true);
|
||||
|
||||
array = bjson.read(buf, 0, buf.byteLength, true);
|
||||
|
||||
/* check the result */
|
||||
for(i = 0; i < n; i++) {
|
||||
assert(array[i].next, array[(i + 1) % n]);
|
||||
assert(array[i].idx, i);
|
||||
assert(array[i].typed_array.buffer, array_buffer);
|
||||
assert(array[i].typed_array.length, 1);
|
||||
assert(array[i].typed_array.byteOffset, i);
|
||||
}
|
||||
}
|
||||
|
||||
function bjson_test_all()
|
||||
{
|
||||
var obj;
|
||||
@@ -111,6 +170,11 @@ function bjson_test_all()
|
||||
BigDecimal("1.233e-1000")]);
|
||||
}
|
||||
|
||||
bjson_test([new Date(1234), new String("abc"), new Number(-12.1), new Boolean(true)]);
|
||||
|
||||
bjson_test(new Int32Array([123123, 222111, -32222]));
|
||||
bjson_test(new Float64Array([123123, 222111.5]));
|
||||
|
||||
/* tested with a circular reference */
|
||||
obj = {};
|
||||
obj.x = obj;
|
||||
@@ -120,6 +184,8 @@ function bjson_test_all()
|
||||
} catch(e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
bjson_test_reference();
|
||||
}
|
||||
|
||||
bjson_test_all();
|
||||
|
@@ -287,6 +287,10 @@ function test_math()
|
||||
assert(Math.ceil(a), 2);
|
||||
assert(Math.imul(0x12345678, 123), -1088058456);
|
||||
assert(Math.fround(0.1), 0.10000000149011612);
|
||||
assert(Math.hypot() == 0);
|
||||
assert(Math.hypot(-2) == 2);
|
||||
assert(Math.hypot(3, 4) == 5);
|
||||
assert(Math.abs(Math.hypot(3, 4, 5) - 7.0710678118654755) <= 1e-15);
|
||||
}
|
||||
|
||||
function test_number()
|
||||
|
@@ -311,10 +311,21 @@ function test_template()
|
||||
var a, b;
|
||||
b = 123;
|
||||
a = `abc${b}d`;
|
||||
assert(a === "abc123d");
|
||||
assert(a, "abc123d");
|
||||
|
||||
a = String.raw `abc${b}d`;
|
||||
assert(a === "abc123d");
|
||||
assert(a, "abc123d");
|
||||
|
||||
a = "aaa";
|
||||
b = "bbb";
|
||||
assert(`aaa${a, b}ccc`, "aaabbbccc");
|
||||
}
|
||||
|
||||
function test_template_skip()
|
||||
{
|
||||
var a = "Bar";
|
||||
var { b = `${a + `a${a}` }baz` } = {};
|
||||
assert(b, "BaraBarbaz");
|
||||
}
|
||||
|
||||
function test_object_literal()
|
||||
@@ -358,6 +369,7 @@ test_prototype();
|
||||
test_arguments();
|
||||
test_class();
|
||||
test_template();
|
||||
test_template_skip();
|
||||
test_object_literal();
|
||||
test_regexp_skip();
|
||||
test_labels();
|
@@ -26,6 +26,12 @@ try { std.loadScript("test_assert.js"); } catch(e) {}
|
||||
function test_printf()
|
||||
{
|
||||
assert(std.sprintf("a=%d s=%s", 123, "abc"), "a=123 s=abc");
|
||||
assert(std.sprintf("%010d", 123), "0000000123");
|
||||
assert(std.sprintf("%x", -2), "fffffffe");
|
||||
assert(std.sprintf("%lx", -2), "fffffffffffffffe");
|
||||
assert(std.sprintf("%10.1f", 2.1), " 2.1");
|
||||
assert(std.sprintf("%*.*f", 10, 2, -2.13), " -2.13");
|
||||
assert(std.sprintf("%#lx", 0x7fffffffffffffffn), "0x7fffffffffffffff");
|
||||
}
|
||||
|
||||
function test_file1()
|
||||
@@ -119,6 +125,20 @@ function test_popen()
|
||||
os.remove(fname);
|
||||
}
|
||||
|
||||
function test_ext_json()
|
||||
{
|
||||
var expected, input, obj;
|
||||
expected = '{"x":false,"y":true,"z2":null,"a":[1,8,160],"s":"str"}';
|
||||
input = `{ "x":false, /*comments are allowed */
|
||||
"y":true, // also a comment
|
||||
z2:null, // unquoted property names
|
||||
"a":[+1,0o10,0xa0,], // plus prefix, octal, hexadecimal
|
||||
"s":"str",} // trailing comma in objects and arrays
|
||||
`;
|
||||
obj = std.parseExtJSON(input);
|
||||
assert(JSON.stringify(obj), expected);
|
||||
}
|
||||
|
||||
function test_os()
|
||||
{
|
||||
var fd, fpath, fname, fdir, buf, buf2, i, files, err, fdate, st, link_path;
|
||||
@@ -258,3 +278,4 @@ test_popen();
|
||||
test_os();
|
||||
test_os_exec();
|
||||
test_timer();
|
||||
test_ext_json();
|
||||
|
93
tests/test_worker.js
Normal file
93
tests/test_worker.js
Normal file
@@ -0,0 +1,93 @@
|
||||
/* os.Worker API test */
|
||||
import * as std from "std";
|
||||
import * as os from "os";
|
||||
|
||||
function assert(actual, expected, message) {
|
||||
if (arguments.length == 1)
|
||||
expected = true;
|
||||
|
||||
if (actual === expected)
|
||||
return;
|
||||
|
||||
if (actual !== null && expected !== null
|
||||
&& typeof actual == 'object' && typeof expected == 'object'
|
||||
&& actual.toString() === expected.toString())
|
||||
return;
|
||||
|
||||
throw Error("assertion failed: got |" + actual + "|" +
|
||||
", expected |" + expected + "|" +
|
||||
(message ? " (" + message + ")" : ""));
|
||||
}
|
||||
|
||||
var worker;
|
||||
|
||||
function test_worker()
|
||||
{
|
||||
var counter;
|
||||
|
||||
/* Note: can use std.loadFile() to read from a file */
|
||||
worker = new os.Worker(`
|
||||
import * as std from "std";
|
||||
import * as os from "os";
|
||||
|
||||
var parent = os.Worker.parent;
|
||||
|
||||
function handle_msg(e) {
|
||||
var ev = e.data;
|
||||
// print("child_recv", JSON.stringify(ev));
|
||||
switch(ev.type) {
|
||||
case "abort":
|
||||
parent.postMessage({ type: "done" });
|
||||
break;
|
||||
case "sab":
|
||||
/* modify the SharedArrayBuffer */
|
||||
ev.buf[2] = 10;
|
||||
parent.postMessage({ type: "sab_done", buf: ev.buf });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function worker_main() {
|
||||
var i;
|
||||
|
||||
parent.onmessage = handle_msg;
|
||||
for(i = 0; i < 10; i++) {
|
||||
parent.postMessage({ type: "num", num: i });
|
||||
}
|
||||
}
|
||||
worker_main();
|
||||
`);
|
||||
|
||||
counter = 0;
|
||||
worker.onmessage = function (e) {
|
||||
var ev = e.data;
|
||||
// print("recv", JSON.stringify(ev));
|
||||
switch(ev.type) {
|
||||
case "num":
|
||||
assert(ev.num, counter);
|
||||
counter++;
|
||||
if (counter == 10) {
|
||||
/* test SharedArrayBuffer modification */
|
||||
let sab = new SharedArrayBuffer(10);
|
||||
let buf = new Uint8Array(sab);
|
||||
worker.postMessage({ type: "sab", buf: buf });
|
||||
}
|
||||
break;
|
||||
case "sab_done":
|
||||
{
|
||||
let buf = ev.buf;
|
||||
/* check that the SharedArrayBuffer was modified */
|
||||
assert(buf[2], 10);
|
||||
worker.postMessage({ type: "abort" });
|
||||
}
|
||||
break;
|
||||
case "done":
|
||||
/* terminate */
|
||||
worker.onmessage = null;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
test_worker();
|
Reference in New Issue
Block a user