Skip to content

Instantly share code, notes, and snippets.

@f5io
Created January 3, 2020 13:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save f5io/cf4f865064bd8cf4c686804b0379b009 to your computer and use it in GitHub Desktop.
Save f5io/cf4f865064bd8cf4c686804b0379b009 to your computer and use it in GitHub Desktop.
qjs vs qjsc

Currently experiencing issues with qjsc.

With qjs index.js, I receive the expected output:

$ qjs index.js
🎾  Ball hit 1 time(s), wiff!
🎾  Ball hit 2 time(s), waff!
🎾  Ball hit 3 time(s), wiff!
🎾  Ball hit 4 time(s), waff!
🎾  Ball hit 5 time(s), wiff!
🎾  Ball hit 6 time(s), waff!
🎾  Ball hit 7 time(s), wiff!
🎾  Ball hit 8 time(s), waff!
🎾  Ball hit 9 time(s), wiff!
... (ad infinitum)

However when attempting to compile with qjsc, I receive the following error:

$ qjsc index.js
/tmp/out13043.c:344:16: error: redefinition of 'qjsc_index_size'
const uint32_t qjsc_index_size = 691;
               ^
/tmp/out13043.c:5:16: note: previous definition is here
const uint32_t qjsc_index_size = 2670;
               ^
/tmp/out13043.c:346:15: error: redefinition of 'qjsc_index' with a different type: 'const uint8_t [691]'
      vs 'const uint8_t [2670]'
const uint8_t qjsc_index[691] = {
              ^
/tmp/out13043.c:7:15: note: previous definition is here
const uint8_t qjsc_index[2670] = {
              ^
2 errors generated.
const messages = Symbol('messages');
const putters = Symbol('putters');
const takers = Symbol('takers');
const racers = Symbol('racers');
/* private methods */
function race(ch) {
return new Promise(resolve => {
ch[racers].unshift(resolve);
if (ch[putters].length)
ch[racers].pop()(ch);
});
}
function map(sel, fn) {
if (sel instanceof Set) {
return [...sel.values()].map(ch => fn(ch, ch));
}
else if (sel instanceof Map) {
return [...sel.entries()].map(([k, v]) => fn(v, k));
}
else if (Array.isArray(sel)) {
return sel.map(fn);
}
return Object.entries(sel).map(([k, v]) => fn(v, k));
}
function forEach(sel, fn) {
if (sel instanceof Set) {
return sel.forEach(fn);
}
else if (sel instanceof Map) {
return sel.forEach(fn);
}
else if (Array.isArray(sel)) {
return sel.forEach(fn);
}
return Object.values(sel).forEach(fn);
}
/* public methods */
function channel() {
return {
[messages]: [],
[putters]: [],
[takers]: [],
[racers]: [],
async *[Symbol.asyncIterator]() {
while (true) {
yield await _take(this);
}
}
};
}
function put(ch, msg) {
return new Promise(resolve => {
ch[messages].unshift(msg);
ch[putters].unshift(resolve);
if (ch[takers].length) {
ch[putters].pop()();
ch[takers].pop()(ch[messages].pop());
}
if (ch[racers].length)
ch[racers].pop()(ch);
});
}
function _take(ch) {
return new Promise(resolve => {
ch[takers].unshift(resolve);
if (ch[putters].length) {
ch[putters].pop()();
ch[takers].pop()(ch[messages].pop());
}
});
}
function take(ch) {
const promise = _take(ch);
return Object.assign(promise, {
async *[Symbol.asyncIterator]() {
yield await promise;
while (true) {
yield await _take(ch);
}
}
});
}
function _alts(...chs) {
return Promise
.race(chs.map(ch => race(ch)))
.then(ch => {
chs.forEach(c => c !== ch && c[racers].pop());
ch[putters].pop()();
return ch[messages].pop();
});
}
function alts(...chs) {
const promise = _alts(...chs);
return Object.assign(promise, {
async *[Symbol.asyncIterator]() {
yield await promise;
while (true) {
yield await _alts(...chs);
}
}
});
}
function _select(chs) {
return Promise
.race(map(chs, (ch, key) => race(ch).then(result => [key, result])))
.then(([key, ch]) => {
forEach(chs, c => c !== ch && c[racers].pop());
ch[putters].pop()();
return [key, ch[messages].pop()];
});
}
function select(chs) {
const promise = _select(chs);
return Object.assign(promise, {
async *[Symbol.asyncIterator]() {
yield await promise;
while (true) {
yield await _select(chs);
}
}
});
}
function drain(ch) {
const msgs = [];
while (ch[messages].length)
msgs.push(take(ch));
return Promise.all(msgs);
}
export { channel, put, take, alts, select, drain };
import { setTimeout } from 'os';
import { channel, put, take } from './csp.js';
const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));
const wiff = channel();
const waff = channel();
const createBall = () => ({ hits: 0, status: '' });
const createBat = async (inbound, outbound) => {
for await (const ball of take(inbound)) {
ball.hits++;
ball.status = ball.status === 'wiff!' ? 'waff!' : 'wiff!';
console.log(`🎾 Ball hit ${ball.hits} time(s), ${ball.status}`);
await timeout(500); // assume it's going to take a bit to hit the ball
await put(outbound, ball); // smash the ball back
}
};
createBat(waff, wiff); // create a bat that will wiff waffs
createBat(wiff, waff); // create a bat that will waff wiffs
put(waff, createBall());
@Alhadis
Copy link

Alhadis commented Mar 27, 2020

@f5io I found this Gist whilst googling "error: redefinition of 'qjsc_index_size'". My issue turned out to be an outdated version of these files:

/usr/local/lib/quickjs/libquickjs.a
/usr/local/lib/quickjs/libquickjs.lto.a
/usr/local/include/quickjs/quickjs-libc.h
/usr/local/include/quickjs/quickjs.h

I naïvely built QuickJS using make instead of make install, and manually symlinked the resulting qjsc binary. When I ran make install, the error disappeared and the executable ran perfectly fine.

Hope that helps. 👍

@matthewmueller
Copy link

Thank you @Alhadis! I was stuck and your comment was a lightbulb moment for me and pointed me towards the solution 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment